Namespaces

Logical scoping unit across terms, tags, data sources, collectors, and entity groups — covers the CRUD lifecycle, the four-sister-service auto-create side-door, and the audit-silence caveat.

A Namespace is a logical scoping unit applied across the catalog's taxonomy and resource graph. Every Term and Tag carries an optional namespace; every Data Source and Collector binds to one; Data Entity Groups can inherit a namespace through their parent. Namespaces are the catalog-side analogue of a team-or-domain label — operators use them to keep two teams' "customer" terms from colliding, to keep two teams' data sources visually separated in the catalog, and to scope collector ingestion to a known taxonomy.

This page covers the create / update / soft-delete / list lifecycle, the three permission gates, the cascade-on-delete contract, the case-sensitivity rule, the audit-silence shape Namespace CRUD shares with Owners, and the four-sister-service auto-create side-door that mints namespace rows without NAMESPACE_CREATE.

Where to find it

Open the Management page → Namespaces tab. The page lists every namespace with a pagination header and a free-text filter; the right-side panel renders the create form. Operators with NAMESPACE_CREATE see the Add namespace affordance; operators with NAMESPACE_UPDATE see an in-place edit on each row; operators with NAMESPACE_DELETE see a remove affordance.

Lifecycle

Five operations exist on the Namespace surface:

Operation
Endpoint
Permission

List namespaces (paginated, optional query substring filter)

GET /api/namespaces

Any authenticated user; anonymous under DISABLED

Get a single namespace

GET /api/namespaces/{id}

Any authenticated user; anonymous under DISABLED

Create a namespace

POST /api/namespaces

NAMESPACE_CREATE

Update a namespace

PUT /api/namespaces/{id}

NAMESPACE_UPDATE

Soft-delete a namespace

DELETE /api/namespaces/{id}

NAMESPACE_DELETE

The read endpoints are not gated by a custom-permission entry — the platform's security wiring leaves them at the default .authenticated() level. Under auth.type=DISABLED they are reachable anonymously (see DISABLED authentication).

Case sensitivity

Namespace names are case-sensitive. finance and Finance are two distinct rows in the namespace table — an operator who creates Finance and a teammate who creates finance end up with two parallel namespaces that share no relations. The list endpoint's query parameter applies a case-insensitive substring match for the suggestion list, but resolution against the canonical row is by exact-string match.

Treat namespace names as a controlled vocabulary that benefits from a documented naming convention — snake_case and lowercase-with-hyphens are both common in deployments we have seen. Drift between case-variants is one of the most common Namespace-directory pollution shapes.

Soft-delete and reincarnation

The Namespace delete path is a soft delete — the DELETE /api/namespaces/{id} endpoint sets deleted_at = NOW() on the row rather than removing it from the table. The namespace table carries a partial-unique index on name that scopes uniqueness to rows where deleted_at IS NULL; after a soft-delete, the name slot is free and an operator can create a new namespace with the same name. The previously-deleted row is preserved with its original id; downstream auditing tables that reference the namespace by id retain their integrity.

The reincarnation pattern is operationally useful for "reset this namespace" workflows — an operator who wants to clear a namespace's history can soft-delete it and immediately create a new namespace with the same name. The new namespace has a different id; any prior relations (terms, data sources, collectors) remain attached to the soft-deleted row and do not migrate.

Cascade-on-delete guard

Namespace delete is blocked when any of four referent tables still reference the namespace. The platform's service layer zips four existence-predicates and rejects the operation if any returns true:

Referent table
Operator-visible referent
Where to clear it

data_source (live rows)

A Data Source registered under this namespace

Re-assign the source to a different namespace via Management → Datasources, or remove the source entirely

collector (live rows)

A Collector registered under this namespace

Re-assign the collector or remove it via Management → Collectors

term (live rows)

A Glossary Term scoped to this namespace

Re-assign or delete the term via the Business Glossary

data_entity (non-deleted rows)

A live data entity ingested under this namespace

Re-configure the collector's namespace_name and re-ingest, or soft-delete the entities

When any predicate returns true, the platform returns CascadeDeleteException (HTTP 400, error code USR004) and the namespace remains live. The error message reads "Namespace cannot be deleted: there are still resources attached" — it does not enumerate which of the four classes is blocking the delete. The operator has to walk each referent class themselves.

Auto-create side-door

The Namespace surface carries a load-bearing structural quirk: four sister services on the platform mint Namespace rows through the side-door NamespaceServiceImpl.getOrCreate(name) when their request body carries a non-empty namespace_name field. The four callers are:

Sister service
Endpoint
Gating permission for the parent operation

Data Source service

POST /api/datasources, PUT /api/datasources/{id}

DATA_SOURCE_CREATE, DATA_SOURCE_UPDATE

Term service

POST /api/terms

TERM_CREATE

Collector service

POST /api/collectors

COLLECTOR_CREATE

Data Entity Group service

POST /api/dataentitygroups

DATA_ENTITY_GROUP_CREATE

Each of these calls getOrCreate(name), which does getByName(name).switchIfEmpty(createByName(name)) — the service silently inserts a new Namespace row if the name does not already exist. The caller does not need to hold NAMESPACE_CREATE; holding any one of the four parent permissions is sufficient to mint a Namespace row that becomes immediately visible to every authenticated user via the catalogue read.

A related sibling pattern exists on the Owner surface — Owner CRUD has its own side-door cluster through three resource-creation endpoints. The Namespace cluster is the canonical example because four distinct sister services touch it, but the architectural pattern (auto-create on getOrCreate(name)-style helpers) is general.

Activity trail

Namespace CRUD emits no Activity Feed event. Two independent facts of the platform's design both block it:

  1. No event type exists. The Activity Feed's event-type catalogue has no NAMESPACE_* member at all — there is simply no type the platform could emit for a namespace create, update, or delete.

  2. The activity table requires a data-entity anchor. Even if an event type existed, the activity table is schema-anchored to data_entity_id NOT NULL — every emitted event must reference a single data entity (see Activity Feed → Scope). Namespace lifecycle operations have no data-entity anchor.

Closing one of these alone would not make Namespace CRUD auditable; both would have to change. The same shape applies to Owner CRUD, Role CRUD, Policy CRUD, and every other RBAC and taxonomy mutation; see Audit trail scope for the platform-wide audit-coverage matrix and the compensating-controls catalogue.

For compliance regimes that need who-changed-what-when on Namespaces, instrument the audit externally — an API-gateway access log records every authenticated mutation on /api/namespaces*; the PostgreSQL WAL via pgaudit records the namespace row writes. The audit-of-occurrence lives outside the platform until both the missing event type and the schema-tier data_entity_id NOT NULL anchor are addressed.

Where to next

  • Management — the parent page; covers the tab-visibility model and the read-collaborative posture across the eight non-Associations Management areas.

  • Permissions — the canonical home for NAMESPACE_CREATE, NAMESPACE_UPDATE, NAMESPACE_DELETE and the four sister-service permissions the side-door collapses against.

  • Activity Feed → Scope — the canonical home for the audit-silence pattern Namespace CRUD shares with Owners, Roles, and Policies.

  • Audit trail scope — the compliance-facing summary of what the platform audits today and the external instrumentation patterns for the silent-mutation surfaces.

  • Business Glossary, Manual Object Tagging — the two taxonomy surfaces that scope themselves to a Namespace; one canonical place to clear referents when preparing for a Namespace delete.

Last updated