OpenClaw EnterpriseDOCSGitHub

Namespace IAM Policy Flow

Overview

Namespace IAM policy management begins when an authenticated caller uses the OCC API or CLI to list, create, read, or delete a Namespace Role or exact AccessBinding. OCC authorizes the administrator, validates that the policy entry belongs to the requested Namespace, and delegates the policy mutation to the selected IAM Driver. The flow stops after the policy and audit event commit together in the platform state transaction.

Entry Points

Flow

graph TD
  A["Caller invokes Namespace IAM route"] --> B["OCC admits identity and required permissions"]
  B --> C{"Read or mutation?"}
  C -->|read| D["Controller asks selected IAM Driver to read Namespace policy"]
  C -->|create/delete| E["Controller validates Role, subject, and exact target"]
  E --> F["Selected IAM Driver mutates platform IAM policy"]
  F --> G["Controller appends audit event in the same transaction"]
  D --> H["API returns policy metadata"]
  G --> H

Execution Trace

1. Route admission and permission selection

apps/controller/src/index.ts:requiredPermissions

The API route declares IAM operations as Installation administration plus exact Namespace read. Admission and identity resolution remain in apps/controller/src/index.ts; they resolve the caller before dispatching to the IAM handler. The OCC controller uses the selected IAM Driver for both permission checks. Ordinary access to the target resource does not authorize policy delegation.

2. Role and AccessBinding commands reach the controller

apps/controller/src/http/iam.ts:iamHandlers

List and read operations call the corresponding OpenClawController IAM method and return policy metadata. Create and delete operations run inside controller.transact, append an attributable mutation audit event, and return only after the transaction commits. The event's authorization records the Installation administer check. Role events carry the Namespace as resource and roleId plus permissions in details. AccessBinding create and delete events carry the bound target as resource (the Namespace for a Namespace binding) and bindingId, subjectKind, subjectId, and roleId in details. Deletion reads the removed Role or AccessBinding in the same transaction to record it.

3. OCC validates policy ownership

packages/occ/src/index.ts:createIAMAccessBinding

Role creation accepts only nonempty, duplicate-free permissions for Namespace resource kinds; namespace permissions support only read. AccessBinding creation accepts identity subjects and exact targets in the same Namespace, including the Namespace itself when the target ID matches the path Namespace. OCC verifies the target resource exists and that the caller can read it before asking the IAM Driver to create the binding.

4. The IAM Driver persists or reads policy

packages/iam/src/index.ts:NativeIAMDriver

The native IAM Driver implements Namespace policy methods against the platform-provided policy repository. It rejects missing Roles, cross-Namespace targets, unsupported subjects, duplicate IDs, referenced Role deletion, and unknown exact bindings without weakening authorization. Existing human Principals can receive bindings without a Namespace service identity. ServicePrincipal subjects must belong to that exact Namespace.

When the selected native Driver reloads policy during a PostgreSQL State callback, PostgresPlatformState.loadNativeIAMState reads through that State instance's original transaction. Authorization therefore sees that unit's pending grants and removals. Outside a callback, the loader opens its ordinary read transaction. Work that escapes the callback retains its original closed lifetime and fails; it cannot obtain another client after commit, rollback, or an unknown outcome. This transaction binding supplies neither authenticated session custody nor a fence against concurrent policy invalidation.

5. Platform state commits policy and audit together

packages/occ/src/state/postgres-state.ts:PostgresPlatformState

The PostgreSQL state implementation writes Roles and AccessBindings through the same unit of work used by the API audit append. If commit outcome is unknown, State discards the connection without another query. OCC reports dependency failure; a caller must not infer rollback or replay the mutation from that result. Later authorization requests read the current policy through the IAM Driver. Namespace locking serializes grant creation with Namespace deletion; exact resource targets retain their existing deletion locks, and deleting a target resource deletes the bindings on it in the same transaction. Identity foreign keys protect persisted bindings without expanding application-role privileges. Both adapters apply one subject rule on every AccessBinding write: a human without a Namespace, a non-Agent ServicePrincipal of the exact Namespace, or the ServicePrincipal of a live Agent there. PostgreSQL checks the owning Agent in the same query because its Agent owner key is deferred to commit. The in-memory adapter resolves subjects live through its resolveIAMIdentity lookup, so humans enrolled after construction can be bound, then falls back to identities provisioned at construction. Agent-owned ServicePrincipals resolve only through its current Agent state.

State also provides an opt-in Installation authority and native-IAM barrier for an original transaction. Its SQL supplier is unregistered, and the Namespace routes above do not use it. It does not protect these routes until the selected account, session, and policy writers join the same protocol.

Debugging and Verification

Search documentation