Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6911ac8
obligation_definitions table
alkalescent Jul 4, 2025
2f0f405
implicit index
alkalescent Jul 4, 2025
d1da961
obligation_values_standard table
alkalescent Jul 4, 2025
de7106f
obligation fulfillers
alkalescent Jul 4, 2025
1b88775
clean up and add comments
alkalescent Jul 4, 2025
a7eb276
obligation triggers table
alkalescent Jul 7, 2025
3204a33
add time cols to defs and vals
alkalescent Jul 7, 2025
0352bf1
add triggers
alkalescent Jul 7, 2025
c1095a8
modify function
alkalescent Jul 7, 2025
f2e15fa
two functions
alkalescent Jul 7, 2025
eb9ff65
adding optional metadata
alkalescent Jul 7, 2025
fb0afea
no errors so far
alkalescent Jul 7, 2025
aaac715
good so far
alkalescent Jul 7, 2025
ec04ccb
still ok
alkalescent Jul 7, 2025
e1ee54a
fx working
alkalescent Jul 8, 2025
8dace64
working
alkalescent Jul 8, 2025
fa55f2a
clean up
alkalescent Jul 8, 2025
08c3f24
update docs
alkalescent Jul 8, 2025
965252a
remove extraneous uniqueness
alkalescent Jul 8, 2025
de79eca
add uniqueness constraint
alkalescent Jul 8, 2025
3d513dd
update erd
alkalescent Jul 8, 2025
0f3510d
remove table and clean up function
alkalescent Jul 9, 2025
7d9d808
on cascade delete
alkalescent Jul 9, 2025
7f63aae
update erd
alkalescent Jul 9, 2025
c90df0a
move function drop back to down
alkalescent Jul 9, 2025
8267125
move drop fx to up
alkalescent Jul 9, 2025
798480e
gemini suggestions
alkalescent Jul 9, 2025
9d88bb4
merge fxs
alkalescent Jul 10, 2025
212b907
remove functions
alkalescent Jul 12, 2025
5d8daf6
doc
alkalescent Jul 12, 2025
c9bb4ad
Merge branch 'main' of github.com:opentdf/platform into feature/oblig…
alkalescent Jul 17, 2025
1a62807
drop tables in reverse order
alkalescent Jul 21, 2025
6a9c252
move constraints to end
alkalescent Jul 21, 2025
59718e9
Merge branch 'main' of github.com:opentdf/platform into feature/oblig…
alkalescent Jul 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions service/policy/db/migrations/20250703000000_obligations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
[ADR for Obligations](https://github.com/opentdf/platform/issues/1933)

This migration adds the obligation tables for definitions, values, triggers, fulfillers, and action attribute value relationships.

```mermaid
erDiagram
attribute_namespaces ||--o{ obligation_definitions : "belongs_to"
obligation_definitions ||--o{ obligation_values_standard : "has_many"
obligation_values_standard ||--o{ obligation_triggers : "has_many"
obligation_values_standard ||--o{ obligation_fulfillers : "has_many"
obligation_values_standard ||--o{ obligation_action_attribute_values : "has_many"
attribute_values ||--o{ obligation_triggers : "triggers"
actions ||--o{ obligation_action_attribute_values : "requires"
attribute_values ||--o{ obligation_action_attribute_values : "requires"

attribute_namespaces {
UUID id PK
string name
}

obligation_definitions {
UUID id PK
UUID namespace_id FK
string name
jsonb metadata
timestamp created_at
timestamp updated_at
}

obligation_values_standard {
UUID id PK
UUID obligation_definition_id FK
string value
jsonb metadata
timestamp created_at
timestamp updated_at
}

obligation_triggers {
UUID id PK
UUID attribute_value_id FK
UUID obligation_value_id FK
jsonb metadata
timestamp created_at
timestamp updated_at
}

obligation_fulfillers {
UUID id PK
UUID obligation_value_id FK
jsonb conditionals
jsonb metadata
timestamp created_at
timestamp updated_at
}

obligation_action_attribute_values {
UUID id PK
UUID obligation_value_id FK
UUID action_id FK
UUID attribute_value_id FK
timestamp created_at
timestamp updated_at
}

attribute_values {
UUID id PK
string value
}

actions {
UUID id PK
string name
}
```
115 changes: 115 additions & 0 deletions service/policy/db/migrations/20250703000000_obligations.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
-- +goose Up
-- +goose StatementBegin

CREATE TABLE IF NOT EXISTS obligation_definitions
(
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
namespace_id UUID NOT NULL REFERENCES attribute_namespaces(id),
-- name is a unique identifier for the obligation definition within the namespace
name VARCHAR NOT NULL UNIQUE,
-- implicit index on unique (namespace_id, name) combo
-- index name: obligation_definitions_namespace_id_name_key
UNIQUE (namespace_id, name)
);

CREATE TABLE IF NOT EXISTS obligation_values_standard
(
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
obligation_definition_id UUID NOT NULL REFERENCES obligation_definitions(id),
-- value is a unique identifier for the obligation value within the definition
value VARCHAR NOT NULL UNIQUE,
-- implicit index on unique (obligation_definition_id, value) combo
-- index name: obligation_values_standard_obligation_definition_id_value_key
UNIQUE (obligation_definition_id, value)
);

CREATE TABLE IF NOT EXISTS obligation_triggers
(
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
attribute_value_id UUID NOT NULL REFERENCES attribute_values(id),
obligation_value_id UUID NOT NULL REFERENCES obligation_values_standard(id)
);

CREATE TABLE IF NOT EXISTS obligation_fulfillers
(
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
obligation_value_id UUID NOT NULL REFERENCES obligation_values_standard(id),
conditionals JSONB
);

CREATE TABLE IF NOT EXISTS obligation_action_attribute_values
(
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
obligation_value_id UUID NOT NULL REFERENCES obligation_values_standard(id),
action_id UUID NOT NULL REFERENCES actions(id),
attribute_value_id UUID NOT NULL REFERENCES attribute_values(id),
UNIQUE(obligation_value_id, action_id, attribute_value_id)
);

CREATE OR REPLACE FUNCTION get_obligation_tables()
RETURNS text[] AS $$
BEGIN
RETURN ARRAY['obligation_definitions', 'obligation_values_standard',
'obligation_triggers', 'obligation_fulfillers',
'obligation_action_attribute_values'];
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION standardize_table(table_name regclass)
RETURNS void AS $$
BEGIN
-- Add standard columns to the table
EXECUTE FORMAT('
ALTER TABLE %I
ADD COLUMN metadata JSONB,
ADD COLUMN created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
', table_name);

-- Create trigger for updating updated_at column
EXECUTE FORMAT('
CREATE TRIGGER %I_updated_at
BEFORE UPDATE ON %I
FOR EACH ROW
EXECUTE FUNCTION update_updated_at()
', table_name, table_name);
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION standardize_tables(tables text[])
RETURNS void AS $$
DECLARE table_name text;
BEGIN
FOREACH table_name IN ARRAY tables
LOOP
PERFORM standardize_table(table_name::regclass);
END LOOP;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION drop_tables(tables text[])
RETURNS void AS $$
DECLARE table_name text;
BEGIN
FOREACH table_name IN ARRAY tables
LOOP
EXECUTE FORMAT('DROP TABLE IF EXISTS %I', table_name);
END LOOP;
END;
$$ LANGUAGE plpgsql;

SELECT standardize_tables(get_obligation_tables());
ALTER TABLE obligation_action_attribute_values DROP COLUMN IF EXISTS metadata;

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin

SELECT drop_tables(get_obligation_tables());
DROP FUNCTION IF EXISTS get_obligation_tables;
DROP FUNCTION IF EXISTS standardize_table;
DROP FUNCTION IF EXISTS standardize_tables;
DROP FUNCTION IF EXISTS drop_tables;

-- +goose StatementEnd
53 changes: 53 additions & 0 deletions service/policy/db/schema_erd.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,51 @@ erDiagram
character_varying uri UK "URI of the KAS"
}

obligation_action_attribute_values {
uuid action_id FK,UK
uuid attribute_value_id FK,UK
timestamp_with_time_zone created_at
uuid id PK
uuid obligation_value_id FK,UK
timestamp_with_time_zone updated_at
}

obligation_definitions {
timestamp_with_time_zone created_at
uuid id PK
jsonb metadata
character_varying name UK
uuid namespace_id FK,UK
timestamp_with_time_zone updated_at
}

obligation_fulfillers {
jsonb conditionals
timestamp_with_time_zone created_at
uuid id PK
jsonb metadata
uuid obligation_value_id FK
timestamp_with_time_zone updated_at
}

obligation_triggers {
uuid attribute_value_id FK
timestamp_with_time_zone created_at
uuid id PK
jsonb metadata
uuid obligation_value_id FK
timestamp_with_time_zone updated_at
}

obligation_values_standard {
timestamp_with_time_zone created_at
uuid id PK
jsonb metadata
uuid obligation_definition_id FK,UK
timestamp_with_time_zone updated_at
character_varying value UK
}

provider_config {
jsonb config "Configuration details for the key provider"
timestamp_with_time_zone created_at "Timestamp when the provider configuration was created"
Expand Down Expand Up @@ -223,6 +268,7 @@ erDiagram
timestamp_with_time_zone updated_at "Timestamp when the key was last updated"
}

obligation_action_attribute_values }o--|| actions : "action_id"
registered_resource_action_attribute_values }o--|| actions : "action_id"
subject_mapping_actions }o--|| actions : "action_id"
asym_key }o--|| provider_config : "provider_config_id"
Expand All @@ -239,17 +285,24 @@ erDiagram
attribute_namespace_key_access_grants }o--|| key_access_servers : "key_access_server_id"
attribute_namespace_public_key_map }o--|| attribute_namespaces : "namespace_id"
attribute_namespace_public_key_map }o--|| key_access_server_keys : "key_access_server_key_id"
obligation_definitions }o--|| attribute_namespaces : "namespace_id"
resource_mapping_groups }o--|| attribute_namespaces : "namespace_id"
attribute_value_key_access_grants }o--|| attribute_values : "attribute_value_id"
attribute_value_key_access_grants }o--|| key_access_servers : "key_access_server_id"
attribute_value_public_key_map }o--|| attribute_values : "value_id"
attribute_value_public_key_map }o--|| key_access_server_keys : "key_access_server_key_id"
obligation_action_attribute_values }o--|| attribute_values : "attribute_value_id"
obligation_triggers }o--|| attribute_values : "attribute_value_id"
registered_resource_action_attribute_values }o--|| attribute_values : "attribute_value_id"
resource_mappings }o--|| attribute_values : "attribute_value_id"
subject_mappings }o--|| attribute_values : "attribute_value_id"
base_keys }o--|| key_access_server_keys : "key_access_server_key_id"
key_access_server_keys }o--|| key_access_servers : "key_access_server_id"
key_access_server_keys }o--|| provider_config : "provider_config_id"
obligation_action_attribute_values }o--|| obligation_values_standard : "obligation_value_id"
obligation_values_standard }o--|| obligation_definitions : "obligation_definition_id"
obligation_fulfillers }o--|| obligation_values_standard : "obligation_value_id"
obligation_triggers }o--|| obligation_values_standard : "obligation_value_id"
sym_key }o--|| provider_config : "provider_config_id"
registered_resource_action_attribute_values }o--|| registered_resource_values : "registered_resource_value_id"
registered_resource_values }o--|| registered_resources : "registered_resource_id"
Expand Down
Loading