diff --git a/service/policy/db/migrations/20240805000000_add_comments.sql b/service/policy/db/migrations/20240805000000_add_comments.sql new file mode 100644 index 000000000..53aa7f72b --- /dev/null +++ b/service/policy/db/migrations/20240805000000_add_comments.sql @@ -0,0 +1,133 @@ +-- +goose Up +-- +goose StatementBegin + +-- Add comments to every column and table + +COMMENT ON TABLE attribute_fqns IS 'Table to store the fully qualified names of attributes for reverse lookup at their object IDs'; +COMMENT ON COLUMN attribute_fqns.id IS 'Primary key for the table'; +COMMENT ON COLUMN attribute_fqns.fqn IS 'Fully qualified name of the attribute (i.e. https:///attr//value/)'; +COMMENT ON COLUMN attribute_fqns.namespace_id IS 'Foreign key to the namespace of the attribute'; +COMMENT ON COLUMN attribute_fqns.attribute_id IS 'Foreign key to the attribute definition'; +COMMENT ON COLUMN attribute_fqns.value_id IS 'Foreign key to the attribute value'; + +COMMENT ON TABLE attribute_namespaces IS 'Table to store the parent namespaces of platform policy attributes and related policy objects'; +COMMENT ON COLUMN attribute_namespaces.id IS 'Primary key for the table'; +COMMENT ON COLUMN attribute_namespaces.name IS 'Name of the namespace (i.e. example.com)'; +COMMENT ON COLUMN attribute_namespaces.metadata IS 'Metadata for the namespace (see protos for structure)'; +COMMENT ON COLUMN attribute_namespaces.active IS 'Active/Inactive state'; + +COMMENT ON TABLE attribute_definitions IS 'Table to store the definitions of attributes'; +COMMENT ON COLUMN attribute_definitions.id IS 'Primary key for the table'; +COMMENT ON COLUMN attribute_definitions.namespace_id IS 'Foreign key to the parent namespace of the attribute definition'; +COMMENT ON COLUMN attribute_definitions.name IS 'Name of the attribute (i.e. organization or classification), unique within the namespace'; +COMMENT ON COLUMN attribute_definitions.rule IS 'Rule for the attribute (see protos for options)'; +COMMENT ON COLUMN attribute_definitions.metadata IS 'Metadata for the attribute definition (see protos for structure)'; +COMMENT ON COLUMN attribute_definitions.active IS 'Active/Inactive state'; +COMMENT ON COLUMN attribute_definitions.values_order IS 'Order of value ids for the attribute (important for hierarchy rule)'; + +COMMENT ON TABLE attribute_values IS 'Table to store the values of attributes'; +COMMENT ON COLUMN attribute_values.id IS 'Primary key for the table'; +COMMENT ON COLUMN attribute_values.attribute_definition_id IS 'Foreign key to the parent attribute definition'; +COMMENT ON COLUMN attribute_values.value IS 'Value of the attribute (i.e. "manager" or "admin" on an attribute for titles), unique within the definition'; +COMMENT ON COLUMN attribute_values.metadata IS 'Metadata for the attribute value (see protos for structure)'; +COMMENT ON COLUMN attribute_values.active IS 'Active/Inactive state'; + +COMMENT ON TABLE key_access_servers IS 'Table to store the known registrations of key access servers (KASs)'; +COMMENT ON COLUMN key_access_servers.id IS 'Primary key for the table'; +COMMENT ON COLUMN key_access_servers.uri IS 'URI of the KAS'; +COMMENT ON COLUMN key_access_servers.public_key IS 'Public key of the KAS (see protos for structure/options)'; +COMMENT ON COLUMN key_access_servers.metadata IS 'Metadata for the KAS (see protos for structure)'; + +COMMENT ON TABLE attribute_definition_key_access_grants IS 'Table to store the grants of key access servers (KASs) to attribute definitions'; +COMMENT ON COLUMN attribute_definition_key_access_grants.attribute_definition_id IS 'Foreign key to the attribute definition'; +COMMENT ON COLUMN attribute_definition_key_access_grants.key_access_server_id IS 'Foreign key to the KAS registration'; + +COMMENT ON TABLE attribute_value_key_access_grants IS 'Table to store the grants of key access servers (KASs) to attribute values'; +COMMENT ON COLUMN attribute_value_key_access_grants.attribute_value_id IS 'Foreign key to the attribute value'; +COMMENT ON COLUMN attribute_value_key_access_grants.key_access_server_id IS 'Foreign key to the KAS registration'; + +COMMENT ON TABLE resource_mappings IS 'Table to store associated terms that should map resource data to attribute values'; +COMMENT ON COLUMN resource_mappings.id IS 'Primary key for the table'; +COMMENT ON COLUMN resource_mappings.attribute_value_id IS 'Foreign key to the attribute value'; +COMMENT ON COLUMN resource_mappings.terms IS 'Terms to match against resource data (i.e. translations "roi", "rey", or "kung" in a terms list could map to the value "/attr/card/value/king")'; +COMMENT ON COLUMN resource_mappings.metadata IS 'Metadata for the resource mapping (see protos for structure)'; + +COMMENT ON TABLE subject_mappings IS 'Table to store conditions that logically entitle subject entity representations to attribute values'; +COMMENT ON COLUMN subject_mappings.id IS 'Primary key for the table'; +COMMENT ON COLUMN subject_mappings.attribute_value_id IS 'Foreign key to the attribute value'; +COMMENT ON COLUMN subject_mappings.subject_condition_set_id IS 'Foreign key to the condition set that entitles the subject entity to the attribute value'; +COMMENT ON COLUMN subject_mappings.actions IS 'Actions that the subject entity can perform on the attribute value (see protos for details)'; +COMMENT ON COLUMN subject_mappings.metadata IS 'Metadata for the subject mapping (see protos for structure)'; + +COMMENT ON TABLE subject_condition_set IS 'Table to store sets of conditions that logically entitle subject entity representations to attribute values via a subject mapping'; +COMMENT ON COLUMN subject_condition_set.id IS 'Primary key for the table'; +COMMENT ON COLUMN subject_condition_set.condition IS 'Conditions that must be met for the subject entity to be entitled to the attribute value (see protos for JSON structure)'; +COMMENT ON COLUMN subject_condition_set.metadata IS 'Metadata for the condition set (see protos for structure)'; + +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin + +COMMENT ON TABLE attribute_fqns IS NULL; +COMMENT ON COLUMN attribute_fqns.id IS NULL; +COMMENT ON COLUMN attribute_fqns.fqn IS NULL; +COMMENT ON COLUMN attribute_fqns.namespace_id IS NULL; +COMMENT ON COLUMN attribute_fqns.attribute_id IS NULL; +COMMENT ON COLUMN attribute_fqns.value_id IS NULL; + +COMMENT ON TABLE attribute_namespaces IS NULL; +COMMENT ON COLUMN attribute_namespaces.id IS NULL; +COMMENT ON COLUMN attribute_namespaces.name IS NULL; +COMMENT ON COLUMN attribute_namespaces.metadata IS NULL; +COMMENT ON COLUMN attribute_namespaces.active IS NULL; + +COMMENT ON TABLE attribute_definitions IS NULL; +COMMENT ON COLUMN attribute_definitions.id IS NULL; +COMMENT ON COLUMN attribute_definitions.namespace_id IS NULL; +COMMENT ON COLUMN attribute_definitions.name IS NULL; +COMMENT ON COLUMN attribute_definitions.rule IS NULL; +COMMENT ON COLUMN attribute_definitions.metadata IS NULL; +COMMENT ON COLUMN attribute_definitions.active IS NULL; +COMMENT ON COLUMN attribute_definitions.values_order IS NULL; + +COMMENT ON TABLE attribute_values IS NULL; +COMMENT ON COLUMN attribute_values.id IS NULL; +COMMENT ON COLUMN attribute_values.attribute_definition_id IS NULL; +COMMENT ON COLUMN attribute_values.value IS NULL; +COMMENT ON COLUMN attribute_values.metadata IS NULL; +COMMENT ON COLUMN attribute_values.active IS NULL; + +COMMENT ON TABLE key_access_servers IS NULL; +COMMENT ON COLUMN key_access_servers.id IS NULL; +COMMENT ON COLUMN key_access_servers.uri IS NULL; +COMMENT ON COLUMN key_access_servers.public_key IS NULL; +COMMENT ON COLUMN key_access_servers.metadata IS NULL; + +COMMENT ON TABLE attribute_definition_key_access_grants IS NULL; +COMMENT ON COLUMN attribute_definition_key_access_grants.attribute_definition_id IS NULL; +COMMENT ON COLUMN attribute_definition_key_access_grants.key_access_server_id IS NULL; + +COMMENT ON TABLE attribute_value_key_access_grants IS NULL; +COMMENT ON COLUMN attribute_value_key_access_grants.attribute_value_id IS NULL; +COMMENT ON COLUMN attribute_value_key_access_grants.key_access_server_id IS NULL; + +COMMENT ON TABLE resource_mappings IS NULL; +COMMENT ON COLUMN resource_mappings.id IS NULL; +COMMENT ON COLUMN resource_mappings.attribute_value_id IS NULL; +COMMENT ON COLUMN resource_mappings.terms IS NULL; +COMMENT ON COLUMN resource_mappings.metadata IS NULL; + +COMMENT ON TABLE subject_mappings IS NULL; +COMMENT ON COLUMN subject_mappings.id IS NULL; +COMMENT ON COLUMN subject_mappings.attribute_value_id IS NULL; +COMMENT ON COLUMN subject_mappings.subject_condition_set_id IS NULL; +COMMENT ON COLUMN subject_mappings.actions IS NULL; +COMMENT ON COLUMN subject_mappings.metadata IS NULL; + +COMMENT ON TABLE subject_condition_set IS NULL; +COMMENT ON COLUMN subject_condition_set.id IS NULL; +COMMENT ON COLUMN subject_condition_set.condition IS NULL; +COMMENT ON COLUMN subject_condition_set.metadata IS NULL; + +-- +goose StatementEnd \ No newline at end of file diff --git a/service/policy/db/migrations/20240805000001_drop_deprecated_resources_table.sql b/service/policy/db/migrations/20240805000001_drop_deprecated_resources_table.sql new file mode 100644 index 000000000..642d06b08 --- /dev/null +++ b/service/policy/db/migrations/20240805000001_drop_deprecated_resources_table.sql @@ -0,0 +1,26 @@ +-- +goose Up +-- +goose StatementBegin + +-- Remove the 'resources' table that was never used in platform 2.0 and should be removed + +DROP TABLE IF EXISTS resources; + +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin + +CREATE TABLE IF NOT EXISTS resources +( + id SERIAL PRIMARY KEY, + name VARCHAR NOT NULL, + namespace VARCHAR NOT NULL, + version INTEGER NOT NULL, + fqn VARCHAR, + labels JSONB, + description VARCHAR, + policytype VARCHAR NOT NULL, + resource JSONB +); + +-- +goose StatementEnd \ No newline at end of file diff --git a/service/policy/db/models.go b/service/policy/db/models.go index c90edd85e..020c3759e 100644 --- a/service/policy/db/models.go +++ b/service/policy/db/models.go @@ -55,53 +55,84 @@ func (ns NullAttributeDefinitionRule) Value() (driver.Value, error) { return string(ns.AttributeDefinitionRule), nil } +// Table to store the definitions of attributes type AttributeDefinition struct { - ID string `json:"id"` - NamespaceID string `json:"namespace_id"` - Name string `json:"name"` - Rule AttributeDefinitionRule `json:"rule"` - Metadata []byte `json:"metadata"` - Active bool `json:"active"` - CreatedAt pgtype.Timestamptz `json:"created_at"` - UpdatedAt pgtype.Timestamptz `json:"updated_at"` - ValuesOrder []string `json:"values_order"` + // Primary key for the table + ID string `json:"id"` + // Foreign key to the parent namespace of the attribute definition + NamespaceID string `json:"namespace_id"` + // Name of the attribute (i.e. organization or classification), unique within the namespace + Name string `json:"name"` + // Rule for the attribute (see protos for options) + Rule AttributeDefinitionRule `json:"rule"` + // Metadata for the attribute definition (see protos for structure) + Metadata []byte `json:"metadata"` + // Active/Inactive state + Active bool `json:"active"` + CreatedAt pgtype.Timestamptz `json:"created_at"` + UpdatedAt pgtype.Timestamptz `json:"updated_at"` + // Order of value ids for the attribute (important for hierarchy rule) + ValuesOrder []string `json:"values_order"` } +// Table to store the grants of key access servers (KASs) to attribute definitions type AttributeDefinitionKeyAccessGrant struct { + // Foreign key to the attribute definition AttributeDefinitionID string `json:"attribute_definition_id"` - KeyAccessServerID string `json:"key_access_server_id"` + // Foreign key to the KAS registration + KeyAccessServerID string `json:"key_access_server_id"` } +// Table to store the fully qualified names of attributes for reverse lookup at their object IDs type AttributeFqn struct { - ID string `json:"id"` + // Primary key for the table + ID string `json:"id"` + // Foreign key to the namespace of the attribute NamespaceID pgtype.UUID `json:"namespace_id"` + // Foreign key to the attribute definition AttributeID pgtype.UUID `json:"attribute_id"` - ValueID pgtype.UUID `json:"value_id"` - Fqn string `json:"fqn"` + // Foreign key to the attribute value + ValueID pgtype.UUID `json:"value_id"` + // Fully qualified name of the attribute (i.e. https:///attr//value/) + Fqn string `json:"fqn"` } +// Table to store the parent namespaces of platform policy attributes and related policy objects type AttributeNamespace struct { - ID string `json:"id"` - Name string `json:"name"` - Active bool `json:"active"` + // Primary key for the table + ID string `json:"id"` + // Name of the namespace (i.e. example.com) + Name string `json:"name"` + // Active/Inactive state + Active bool `json:"active"` + // Metadata for the namespace (see protos for structure) Metadata []byte `json:"metadata"` CreatedAt pgtype.Timestamptz `json:"created_at"` UpdatedAt pgtype.Timestamptz `json:"updated_at"` } +// Table to store the values of attributes type AttributeValue struct { - ID string `json:"id"` - AttributeDefinitionID string `json:"attribute_definition_id"` - Value string `json:"value"` - Members []string `json:"members"` - Metadata []byte `json:"metadata"` - Active bool `json:"active"` - CreatedAt pgtype.Timestamptz `json:"created_at"` - UpdatedAt pgtype.Timestamptz `json:"updated_at"` + // Primary key for the table + ID string `json:"id"` + // Foreign key to the parent attribute definition + AttributeDefinitionID string `json:"attribute_definition_id"` + // Value of the attribute (i.e. "manager" or "admin" on an attribute for titles), unique within the definition + Value string `json:"value"` + Members []string `json:"members"` + // Metadata for the attribute value (see protos for structure) + Metadata []byte `json:"metadata"` + // Active/Inactive state + Active bool `json:"active"` + CreatedAt pgtype.Timestamptz `json:"created_at"` + UpdatedAt pgtype.Timestamptz `json:"updated_at"` } +// Table to store the grants of key access servers (KASs) to attribute values type AttributeValueKeyAccessGrant struct { - AttributeValueID string `json:"attribute_value_id"` + // Foreign key to the attribute value + AttributeValueID string `json:"attribute_value_id"` + // Foreign key to the KAS registration KeyAccessServerID string `json:"key_access_server_id"` } @@ -111,50 +142,58 @@ type AttributeValueMember struct { MemberID string `json:"member_id"` } +// Table to store the known registrations of key access servers (KASs) type KeyAccessServer struct { - ID string `json:"id"` - Uri string `json:"uri"` - PublicKey []byte `json:"public_key"` + // Primary key for the table + ID string `json:"id"` + // URI of the KAS + Uri string `json:"uri"` + // Public key of the KAS (see protos for structure/options) + PublicKey []byte `json:"public_key"` + // Metadata for the KAS (see protos for structure) Metadata []byte `json:"metadata"` CreatedAt pgtype.Timestamptz `json:"created_at"` UpdatedAt pgtype.Timestamptz `json:"updated_at"` } -type Resource struct { - ID int32 `json:"id"` - Name string `json:"name"` - Namespace string `json:"namespace"` - Version int32 `json:"version"` - Fqn pgtype.Text `json:"fqn"` - Labels []byte `json:"labels"` - Description pgtype.Text `json:"description"` - Policytype string `json:"policytype"` - Resource []byte `json:"resource"` -} - +// Table to store associated terms that should map resource data to attribute values type ResourceMapping struct { - ID string `json:"id"` - AttributeValueID string `json:"attribute_value_id"` - Terms []string `json:"terms"` - Metadata []byte `json:"metadata"` - CreatedAt pgtype.Timestamptz `json:"created_at"` - UpdatedAt pgtype.Timestamptz `json:"updated_at"` + // Primary key for the table + ID string `json:"id"` + // Foreign key to the attribute value + AttributeValueID string `json:"attribute_value_id"` + // Terms to match against resource data (i.e. translations "roi", "rey", or "kung" in a terms list could map to the value "/attr/card/value/king") + Terms []string `json:"terms"` + // Metadata for the resource mapping (see protos for structure) + Metadata []byte `json:"metadata"` + CreatedAt pgtype.Timestamptz `json:"created_at"` + UpdatedAt pgtype.Timestamptz `json:"updated_at"` } +// Table to store sets of conditions that logically entitle subject entity representations to attribute values via a subject mapping type SubjectConditionSet struct { - ID string `json:"id"` - Condition []byte `json:"condition"` + // Primary key for the table + ID string `json:"id"` + // Conditions that must be met for the subject entity to be entitled to the attribute value (see protos for JSON structure) + Condition []byte `json:"condition"` + // Metadata for the condition set (see protos for structure) Metadata []byte `json:"metadata"` CreatedAt pgtype.Timestamptz `json:"created_at"` UpdatedAt pgtype.Timestamptz `json:"updated_at"` } +// Table to store conditions that logically entitle subject entity representations to attribute values type SubjectMapping struct { - ID string `json:"id"` - AttributeValueID string `json:"attribute_value_id"` - Metadata []byte `json:"metadata"` - CreatedAt pgtype.Timestamptz `json:"created_at"` - UpdatedAt pgtype.Timestamptz `json:"updated_at"` - SubjectConditionSetID pgtype.UUID `json:"subject_condition_set_id"` - Actions []byte `json:"actions"` + // Primary key for the table + ID string `json:"id"` + // Foreign key to the attribute value + AttributeValueID string `json:"attribute_value_id"` + // Metadata for the subject mapping (see protos for structure) + Metadata []byte `json:"metadata"` + CreatedAt pgtype.Timestamptz `json:"created_at"` + UpdatedAt pgtype.Timestamptz `json:"updated_at"` + // Foreign key to the condition set that entitles the subject entity to the attribute value + SubjectConditionSetID pgtype.UUID `json:"subject_condition_set_id"` + // Actions that the subject entity can perform on the attribute value (see protos for details) + Actions []byte `json:"actions"` }