mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-30 02:46:23 +02:00
iam: self-service ops, optional workspace filters, Mux service routing (#855)
Three threads, all reinforcing the contract's system-level vs.
workspace-association distinction.
WS Mux service routing
- tg-show-flows (and any workspace-level service over the WS) was
failing with "unknown service" because the post-refactor Mux
unconditionally looked up flow-service:<kind>. Now branches on
the envelope's flow field: with flow → flow-service:<kind>;
without flow → <kind>:<op> from the inner body; with bare op
lookup for service=iam. Resource and parameters come from the
matched op's own extractors — same path the HTTP endpoints take.
Optional workspace on system-level user/key ops
- list-users returns the deployment-wide list when no workspace is
supplied, filters when one is. get-user, update-user,
disable-user, enable-user, delete-user, reset-password,
create-api-key, list-api-keys, revoke-api-key all treat workspace
as an optional integrity check rather than a required argument.
- create-user keeps workspace required — there it's the new user's
home-workspace binding, a parameter rather than an address.
- API keys reclassified as SYSTEM-level resources. By the same
reasoning that makes users system-level, an API key is a
credential record on a deployment-wide registry; the workspace it
authenticates to is a property, not a containment.
Self-service surface
- whoami: returns the caller's own user record. AUTHENTICATED-only;
no users:read capability required. Foundation for UI affordances
that depend on the caller's permissions.
- bootstrap-status: POST /api/v1/auth/bootstrap-status, PUBLIC,
side-effect-free. Returns {bootstrap_available: bool} so a
first-run UI can decide whether to render setup without consuming
the bootstrap op.
- Gateway now injects actor=identity.handle on every authenticated
forward to iam-svc (IamEndpoint and WS Mux iam path), overwriting
any caller-supplied value. Underpins whoami, audit logging, and
future regime-side decisions that need actor identity.
- tg-whoami and tg-update-user CLIs.
Spec polish
- iam-contract.md: actor-injection rule documented; whoami /
bootstrap-status added to operations list; permission-scope
framing tightened (workspace scope is a property of the grant,
not the user or role).
- iam.md: self-service section; gateway flow gains the actor-
injection step; role section reframed so iam-svc constraints
don't leak into contract-level prose.
- iam-protocol.md: ops table updated for whoami, bootstrap-status,
optional-workspace pattern; bootstrap_available added to the
IamResponse listing.
This commit is contained in:
parent
6302eb8c97
commit
9fc1d4527b
15 changed files with 555 additions and 147 deletions
|
|
@ -83,17 +83,16 @@ The four arguments separate concerns:
|
|||
identifier. See *The Resource model* below.
|
||||
- **`parameters`** — operation-specific data that the regime may
|
||||
need to consider beyond the resource identifier. Used when a
|
||||
decision depends on attributes the request supplies — e.g. an
|
||||
admin scoped to one workspace creating a user *with workspace
|
||||
association W*: the resource is the system-level user registry,
|
||||
and W is a parameter the regime checks against the admin's
|
||||
scope.
|
||||
decision depends on attributes the request supplies — e.g.
|
||||
creating a user *with workspace association W*: the resource is
|
||||
the system-level user registry, and W is a parameter the regime
|
||||
checks against the caller's permissions for `users:write`.
|
||||
|
||||
Different regimes use the four arguments differently — the OSS
|
||||
regime checks role bundles against the capability and the role's
|
||||
workspace scope against parameters; an SSO regime might consult an
|
||||
upstream IdP's group memberships; an ABAC regime evaluates a
|
||||
policy with all four as inputs. The contract is unchanged.
|
||||
Different regimes use the four arguments differently — one regime
|
||||
might evaluate role bundles whose grants carry workspace scope;
|
||||
another might consult upstream IdP group memberships; an ABAC
|
||||
regime evaluates a policy with all four as inputs. The contract
|
||||
is unchanged.
|
||||
|
||||
### `authorise_many`
|
||||
|
||||
|
|
@ -129,14 +128,49 @@ most of them) but the operation set the gateway can forward is:
|
|||
`revoke-api-key`, `change-password`, `reset-password`
|
||||
- Workspace management: `create-workspace`, `list-workspaces`,
|
||||
`get-workspace`, `update-workspace`, `disable-workspace`
|
||||
- Session management: `login`
|
||||
- Session management: `login`, `whoami`
|
||||
- Key management: `get-signing-key-public`, `rotate-signing-key`
|
||||
- Bootstrap: `bootstrap`
|
||||
- Bootstrap: `bootstrap`, `bootstrap-status`
|
||||
|
||||
`whoami` is the self-read counterpart to `get-user`: any
|
||||
authenticated caller can read their own identity record without
|
||||
holding a user-management capability. It is the gating-free probe
|
||||
a UI uses to render affordances appropriate to the caller's role.
|
||||
|
||||
`bootstrap-status` is a side-effect-free probe of whether an
|
||||
unconsumed `bootstrap` call would currently succeed. It exists so
|
||||
a first-run UI can decide whether to render setup without invoking
|
||||
the consuming `bootstrap` op. Public — no authentication.
|
||||
|
||||
A regime that does not support one of these (e.g. an SSO regime
|
||||
where users are managed in the IdP) returns a defined "not
|
||||
supported" error; the gateway surfaces it as a 501.
|
||||
|
||||
### Actor injection
|
||||
|
||||
For any management operation forwarded by the gateway after
|
||||
authentication, the gateway injects the authenticated caller's
|
||||
`handle` as an `actor` field on the request. Regimes use `actor`
|
||||
to identify *who is making the request* — distinct from the
|
||||
operation's target (which lives in `user_id` / `key_id` /
|
||||
`workspace_record` / etc.) — for purposes such as:
|
||||
|
||||
- Self-service operations (`whoami`, `change-password`) that
|
||||
resolve "the caller" without taking a target argument.
|
||||
- Audit logging, where the actor is recorded against the change.
|
||||
- Decisions that depend on the resolved resource state. The
|
||||
gateway authorises against the parameters on the request, but it
|
||||
cannot know the resolved resource's actual properties (e.g. the
|
||||
workspace association of a target user) before the regime loads
|
||||
it. When that matters, the regime can re-decide using the
|
||||
actor's permissions and the resolved record — closing a class
|
||||
of cases the gateway-side check can't see.
|
||||
|
||||
Caller-supplied `actor` values on the request body are overwritten
|
||||
by the gateway — the gateway is the only authority for actor
|
||||
identity, and a regime that consults `actor` can rely on it being
|
||||
authentic.
|
||||
|
||||
## The `Identity` surface
|
||||
|
||||
`Identity` is *mostly* opaque. The gateway holds the value as a
|
||||
|
|
@ -327,13 +361,16 @@ contract via:
|
|||
- Credentials are API keys (opaque) or JWTs (Ed25519, locally
|
||||
validated by the gateway against the regime's published public
|
||||
key).
|
||||
- `authorise` reduces to a role-and-workspace-scope check against
|
||||
the role table defined in [`capabilities.md`](capabilities.md).
|
||||
- `authorise` reduces to a lookup against the role bundles in
|
||||
[`capabilities.md`](capabilities.md), with each grant's workspace
|
||||
scope checked against the operation's workspace component.
|
||||
- Identity, user, and workspace records live in Cassandra.
|
||||
|
||||
The OSS regime is deliberately simple — three roles, single
|
||||
home-workspace per user (a regime data-model decision, not a
|
||||
contract assertion), no policy language.
|
||||
The OSS regime is deliberately simple — three roles, a single
|
||||
workspace association per user (a regime data-model decision, not
|
||||
a contract assertion), no policy language. Other regimes can
|
||||
grant the same user different permissions in different workspaces
|
||||
without changing anything outside the regime.
|
||||
|
||||
### Future regimes
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue