Permissions
The five permission classes in ODD Platform — data entity, term, query example, lookup table, and management — with the full enumeration of permission keys and the surfaces each one gates.
There are 5 types of permissions in ODD Platform:
Data entity permissions: Actions related to specific data assets, such as tables, data streams, or dashboards.
Term permissions: Actions concerning the management of the Business Glossary, e.g. terms and their definitions.
Query Example permissions: Actions for creating and managing SQL query examples linked to datasets and terms.
Lookup table permissions: Actions for creating and maintaining operator-managed reference tables — both the table schema and the rows stored in it.
Management permissions: High-level administrative actions for managing the platform's infrastructure and configuration, such as creating data sources, managing users, or defining access control rules.
This list is generated from the Permission enum in the Platform's OpenAPI spec (odd-platform-specification/components.yaml). If a new permission appears in the API but is missing from this page, or vice versa, it is a bug — please open an issue or PR.
This is the full list of permissions divided by types:
Data entity permissions
DATA_ENTITY_ADD_TERM. Allows adding a term to a data entity.DATA_ENTITY_ADD_TO_GROUP. Allows adding a data entity to a manually created group. Operator caveat: the permission is scoped against the child entity in the URL, not the parent group — a caller with this permission against entity X can place X into any manually-created DEG in the catalog, including DEGs owned by other teams. There is no per-DEG authorisation today, and the mutation emits no Activity Feed event. See Data Entity Groups & Domains → Managing DEG Membership.DATA_ENTITY_ALERT_CONFIG_UPDATE. Allows configuring alert settings for a data entity (e.g., backwards-incompatible schema change alert, failed data quality test, failed job, distribution anomaly) and the time period to disable notifications.DATA_ENTITY_ALERT_RESOLVE. Allows resolving alerts for a data entity.DATA_ENTITY_ATTACHMENT_MANAGE. Allows adding, deleting, and managing file attachments and links for a data entity. (See Attachments and links.)DATA_ENTITY_CUSTOM_METADATA_CREATE. Allows creating custom metadata field values on a data entity, and minting new INTERNAL field rows in the deployment-wide field catalogue as a side effect of the create path. Operator caveat: the auto-create-on-miss side-channel makes this an indirect grant of catalogue-write — a caller can mint new field names visible to every other authenticated user on their next autocomplete keystroke. See Custom metadata → Known limitations.DATA_ENTITY_CUSTOM_METADATA_DELETE. Allows deleting a custom metadata field value from a data entity. The catalogue row is not affected by this operation (the field remains visible in the autocomplete picker on other entities). See Custom metadata.DATA_ENTITY_CUSTOM_METADATA_UPDATE. Allows editing an existing custom metadata field value on a data entity. Operator caveat: the platform's update endpoint is declaredupsert*in the API spec but the underlying SQL is a pureUPDATE— issuing a PUT for a field that has not previously been assigned on the target entity silently no-ops (HTTP 200 OK, empty body, "Metadata successfully updated." toast). Pre-flight with a GET, or switch to the Create endpoint on miss. See Custom metadata → Known limitations.DATA_ENTITY_DELETE_FROM_GROUP. Allows removing a data entity from a manually created group. Operator caveat: same write-collaborative posture asDATA_ENTITY_ADD_TO_GROUP— the permission is bound to the child entity in the URL, not the parent group;DELETEis silently idempotent (returns204on no-op without an Activity Feed event). See Data Entity Groups & Domains → Managing DEG Membership.DATA_ENTITY_DELETE_TERM. Allows removing a term from a data entity.DATA_ENTITY_DESCRIPTION_UPDATE. Allows editing and deleting a data entity's custom description. Operator caveat: description text is persisted verbatim with no write-time HTML sanitisation, and the Markdown renderer is configured withrehype-rawand norehype-sanitize— raw HTML embedded in the description renders as live markup for every catalog reader. The same write-collaborative posture applies to five sibling Markdown surfaces (per-column description, term definition, Query Example body, Lookup Table cell values, Slack notification body). See Entity description → Security caveat for the operator-trust framing.DATA_ENTITY_GROUP_UPDATE. Allows editing a manually created data entity group.DATA_ENTITY_INTERNAL_NAME_UPDATE. Allows editing and deleting a data entity's business name. (See Business names.)DATA_ENTITY_OWNERSHIP_CREATE. Allows creating ownership for a data entity.DATA_ENTITY_OWNERSHIP_DELETE. Allows deleting ownership from a data entity.DATA_ENTITY_OWNERSHIP_UPDATE. Allows editing the title of a data entity ownership.DATA_ENTITY_STATUS_UPDATE. Allows changing the lifecycle status of a data entity (e.g., stable, deprecated, deleted, draft, unassigned). (See Data entity statuses.)DATA_ENTITY_TAGS_UPDATE. Allows editing a data entity's tags. Operator caveat: this is one of four permissions through which novel tag names mint new rows in the global tag directory — granting it to rank-and-file users widens vocabulary governance beyondTAG_CREATE. See Manual Object Tagging → Known limitations and operator caveats.DATASET_FIELD_ADD_TERM. Documented as: allows linking a business glossary term to a specific field within a dataset. Operator caveat — silently-misgated endpoint pair: the platform's authorization wiring crosses two endpoints at adjacent lines today. The dataset-field term-add endpoint (POST /api/datasetfields/{dataset_field_id}/terms) is enforced againstDATA_ENTITY_ADD_TERMat runtime, notDATASET_FIELD_ADD_TERM— UI gates on the documented permission, so the Add-term button is enabled forDATASET_FIELD_ADD_TERMholders but the server returns403silently. Separately, the alert-status PUT (PUT /api/alerts/{alert_id}/status) is enforced againstDATASET_FIELD_ADD_TERMrather thanDATA_ENTITY_ALERT_RESOLVE— granting this permission also grants alert-resolution on any entity. See Per-column annotation → Known limitations for the wiring-bug pair and the workaround.DATASET_FIELD_DELETE_TERM. Allows removing a linked business glossary term from a specific field within a dataset. See Per-column annotation.DATASET_FIELD_DESCRIPTION_UPDATE. Allows editing the description of an individual dataset field. The description is rendered through the same Markdown pipeline as the entity-level description and inherits the same security caveat — see Entity description → Security caveat and Per-column annotation.DATASET_FIELD_ENUMS_UPDATE. Allows editing a dataset field's enum values. Operator caveat: the endpoint behind this permission is operationally bulk-replace (despite itscreateEnumValueoperationId) — a partial submission soft-deletes every pre-existing enum row not present in the body. See Per-column annotation → Known limitations.DATASET_FIELD_INTERNAL_NAME_UPDATE. Allows editing the business name of an individual dataset field. (See Business names and Per-column annotation.)DATASET_FIELD_TAGS_UPDATE. Allows adding or removing tags from an individual dataset field. Operator caveat: novel tag names mint new rows in the global tag directory through this path; submitting an empty tag list silently clears every operator-curated (INTERNAL-origin) tag on the column. The audit feed event for column-level tag changes isDATASET_FIELD_TAGS_UPDATED(full before/after payload). See Manual Object Tagging → Known limitations and operator caveats and Per-column annotation → Known limitations.DATASET_TEST_RUN_SET_SEVERITY. Allows setting severity for a dataset's quality tests.
Term permissions
TERM_CREATE. Allows creating a new term in the business glossary.TERM_DELETE. Allows deleting a term from the business glossary.TERM_OWNERSHIP_CREATE. Allows creating ownership for a term.TERM_OWNERSHIP_DELETE. Allows deleting ownership from a term.TERM_OWNERSHIP_UPDATE. Allows editing the title of a term ownership.TERM_TAGS_UPDATE. Allows editing tags for a term. Operator caveat: novel tag names mint new rows in the global tag directory through this path. No activity-feed event is emitted today when term tags change — compliance / audit workflows depending on tag-change history must instrument this path externally. See Manual Object Tagging → Known limitations and operator caveats.TERM_UPDATE. Allows editing the name, namespace, and definition of a term.
Query Example permissions
QUERY_EXAMPLE_CREATE. Allows creating a query example.QUERY_EXAMPLE_DATASET_CREATE. Allows linking a query example to a dataset.QUERY_EXAMPLE_DATASET_DELETE. Allows unlinking a query example from a dataset.QUERY_EXAMPLE_DELETE. Allows deleting a query example.QUERY_EXAMPLE_TERM_CREATE. Allows linking a query example to a term.QUERY_EXAMPLE_TERM_DELETE. Allows unlinking a query example from a term.QUERY_EXAMPLE_UPDATE. Allows editing a query example.
Lookup table permissions
LOOKUP_TABLE_CREATE. Allows creating a lookup table.LOOKUP_TABLE_DATA_CREATE. Allows adding data rows to a lookup table.LOOKUP_TABLE_DATA_DELETE. Allows deleting data rows from a lookup table.LOOKUP_TABLE_DATA_UPDATE. Allows editing data rows in a lookup table.LOOKUP_TABLE_DEFINITION_CREATE. Allows defining the structure (columns) of a lookup table.LOOKUP_TABLE_DEFINITION_DELETE. Allows deleting the structure (columns) of a lookup table.LOOKUP_TABLE_DEFINITION_UPDATE. Allows modifying the structure (columns) of a lookup table.LOOKUP_TABLE_DELETE. Allows deleting a lookup table.LOOKUP_TABLE_UPDATE. Allows editing the name and description of a lookup table.
Management permissions
COLLECTOR_CREATE. Allows registering a new metadata collector.COLLECTOR_DELETE. Allows deleting a collector.COLLECTOR_TOKEN_REGENERATE. Allows regenerating the security token for a collector. Operational caveat: regeneration invalidates the prior token immediately — there is no grace period. The Collector process must be redeployed with the new token before existing ingestion stops.COLLECTOR_UPDATE. Allows editing a collector's configuration.DATA_ENTITY_GROUP_CREATE. Allows creating a new data entity group.DATA_SOURCE_CREATE. Allows creating a new data source connection.DATA_SOURCE_DELETE. Allows deleting a data source.DATA_SOURCE_TOKEN_REGENERATE. Allows regenerating the security token for a data source. Operational caveat: regeneration invalidates the prior token immediately — there is no grace period. The push-client must be redeployed with the new token before existing ingestion stops.DATA_SOURCE_UPDATE. Allows editing an existing data source's configuration.DIRECT_OWNER_SYNC. Allows associating a user with an owner without an approval request. Composition caveat: when the holder submits the home-page form with an owner name that does not exist in the catalog, the platform creates the owner on the requester's behalf and immediately binds them to it — in a single POST. Grant this permission only to principals you also trust to mint owner names (typically a service identity, not an end-user policy). See User-owner association → How DIRECT_OWNER_SYNC changes the user-side flow.NAMESPACE_CREATE. Allows creating a new namespace viaPOST /api/namespaces. Operator caveat — four sister-service side-doors: four other parent permissions (DATA_SOURCE_CREATE,DATA_SOURCE_UPDATE,TERM_CREATE,COLLECTOR_CREATE,DATA_ENTITY_GROUP_CREATE) silently mint namespace rows through theirnamespace_nameform field. Granting any of those parent permissions is an indirect grant of namespace-creation rights. See Namespaces → Auto-create side-door for the four-vertex cluster and the operator-side mitigation.NAMESPACE_DELETE. Allows soft-deleting a namespace. Operator caveat — cascade-block: the delete is blocked withCascadeDeleteException(HTTP 400, error codeUSR004) when any of four referent tables (live data sources, live collectors, live terms, non-deleted data entities) still references the namespace. See Namespaces → Cascade-on-delete guard for the operator workflow and the partial-unique-index reincarnation behaviour after a successful soft-delete.NAMESPACE_UPDATE. Allows editing an existing namespace.OWNER_ASSOCIATION_MANAGE. Allows approving or denying user-owner association requests on the Management → Associations → New requests sub-tab. Also gates visibility of the Associations Management tab itself. Does not grant the admin direct-bind affordance — that requiresOWNER_RELATION_MANAGE(see below). See User-owner association → Approving incoming requests.OWNER_CREATE. Allows creating a new owner entity viaPOST /api/owners. Note: three other service-tier code paths also mint Owner rows without consulting this permission — see Owners → Three service-tier side-doors.OWNER_DELETE. Allows deleting an owner viaDELETE /api/owners/{id}. The delete is gated on no remaining ownership relations, term-ownership relations, or user-Owner bindings — operators see aCascadeDeleteExceptionif any of those are still attached.OWNER_RELATION_MANAGE. Allows directly creating or removing the binding between a user and an owner — the Create association button in the Management → Associations header, and the per-row Remove on the Active associations sub-tab. Operators with this permission bypass the user-self-request and admin-approve workflow entirely. See User-owner association → Creating a binding directly and Removing an existing binding. Downstream-impact note: the binding this permission creates is the single load-bearing anchor for the/api/dataentities/my[/upstream|/downstream]lineage triplet — every regression at the binding-resolution step has cross-owner blast radius on the lineage neighbourhood; see Data Lineage → My-objects triplet for the architecture.OWNER_UPDATE. Allows editing an existing owner viaPUT /api/owners/{id}. Destructive-API caveat: PUT with an empty (or absent)rolesarray silently removes every existing role binding from the Owner — see Owners → PUT with empty roles destroys all role bindings for the safe-pattern fetch-modify-write workflow.
There is no OWNER_READ permission. GET /api/owners is reachable to any authenticated user (and anonymous under auth.type=DISABLED) — it is part of the read-collaborative posture on Management catalogs documented in the warning admonition at the bottom of this section.
POLICY_CREATE. Allows creating a new access policy.POLICY_DELETE. Allows deleting an access policy.POLICY_UPDATE. Allows editing an existing access policy.ROLE_CREATE. Allows creating a new user role.ROLE_DELETE. Allows deleting a user role.ROLE_UPDATE. Allows editing an existing user role.TAG_CREATE. Allows creating a new tag. Operator caveat:TAG_CREATEis not the only path that mints new tags — four*_TAGS_UPDATEpermissions (data entity, dataset field, term) plus collector ingestion all silently create tag rows for novel names. See Manual Object Tagging → Known limitations and operator caveats.TAG_DELETE. Allows deleting a tag.TAG_UPDATE. Allows editing an existing tag.
Read access on Management catalogs is granted to every authenticated user by design. None of the Management permissions above gates the corresponding GET endpoint — withholding OWNER_CREATE, NAMESPACE_CREATE, DATA_SOURCE_CREATE, etc. does not restrict reads of the matching catalog. The endpoints below fall through to the platform's catch-all "any authenticated user" rule:
GET /api/owners— every owner row (name, roles, provider mapping).GET /api/owners/providers— the active identity providers list.GET /api/owner_association_request/activity— the resolved-associations log (the History sub-tab; see User-owner association → Auditing past association requests).GET /api/namespaces— every namespace, including names that may reveal organisational structure.GET /api/datasources— every registered data source (URL, ODDRN, namespace).GET /api/collectors— every collector, including a partially-redacted token until Regenerate is invoked.GET /api/titles— every catalog title vocabulary entry.
Operators who want to restrict read access on a Management catalog cannot do so through this permission set today. Plan deployments accordingly — anything sensitive enough to require read-side RBAC belongs on a different surface.
Comprehensive permissions
ALL. Includes all permissions above.
Permission read surface (two-endpoint orchestration)
Integrators consuming the platform's permission catalogue via the API need both of the endpoints below — the two scopes are orthogonal and the API does not unify them into a single call.
GET /api/resource/{type}/{id}/permissions
Contextual / resource-scoped
The permissions the caller holds in the named resource's context (per-entity, per-term, per-query-example).
DATA_ENTITY, TERM, QUERY_EXAMPLE
GET /api/identity/whoami → Identity.permissions
Non-contextual / management-scope
The permissions the caller holds globally for management operations — Policy / Role / Owner / Datasource / Collector / Namespace / Tag / Lookup Table / Query Example CRUD.
(returned as a flat permission list, no resource ID)
PermissionResourceType.MANAGEMENT is a valid spec enum value but the runtime rejects it on the contextual endpoint. The OpenAPI PermissionResourceType schema declares four values (DATA_ENTITY, TERM, QUERY_EXAMPLE, MANAGEMENT). Calling GET /api/resource/MANAGEMENT/{id}/permissions returns HTTP 400 USR001 with the body Resource type MANAGEMENT does not have context — management-scope permissions are intentionally returned by the /api/identity/whoami endpoint, not the contextual one. SDK code generated from the spec that builds a 4-way switch over PermissionResourceType and dispatches all four to the contextual endpoint will see unexpected 400 responses on MANAGEMENT calls; route those to whoami instead. A spec-side tightening is tracked upstream.
Five categories versus four resource types
The five permission groupings on this page (Data entity / Term / Query Example / Lookup table / Management) are an operator-readable taxonomy — they correspond to where permissions appear in the Management UI and how the runtime services consume them. The PermissionResourceType enum in the OpenAPI spec has four values because LOOKUP_TABLE_* permissions are stored within the Management bucket on the read surface (the runtime treats them as non-contextual / management-scope and returns them from /api/identity/whoami, not from GET /api/resource/LOOKUP_TABLE/... — there is no LOOKUP_TABLE resource type at the API contract).
An integrator dispatching from the four-value enum gets every permission the caller holds; the five-category page taxonomy is the framing operators use when reading the catalogue.
Surfaces without per-resource permission gating today
Some read surfaces that an operator might assume are gated by a per-resource permission are reachable to any authenticated caller. The Management catalogs above (GET /api/owners, GET /api/namespaces, GET /api/datasources, …) are one such cluster — documented in the read-collaborative-posture warning above. The other cluster operators routinely meet is dataset structure / version reads:
GET /api/datasets/{data_entity_id}/structure— the latest schema of any dataset.GET /api/datasets/{data_entity_id}/structure/{version_id}— any historical schema revision.GET /api/datasets/{data_entity_id}/structure/diff?first_version_id=…&second_version_id=…— the side-by-side diff between any two revisions.
The path component {data_entity_id} is consumed by the controller but not used by the underlying query — the query filters on version_id alone. Any authenticated caller enumerating version_id integers reads any dataset's schema; under auth.type=DISABLED, anonymously. The page-side detail (and the multi-tenant operator-mitigation table) lives on Dataset schema diff → Known limitations.
Last updated