Administration

Members

How a person joins an organization, how their identity is bound, and how to stop them immediately.

A member is a person inside one organization. The identity provider holds who they are; the engine holds a principal — a UUID it assigns and owns — and everything belonging to that person keys on it.

For administrators specifically — granting org-admin, resetting a password — see Organizations → Administrators. This page is about everyone else, and about the levers that work when something has gone wrong.

The ordinary path needs no operator

Nobody grants org-member. Belonging to the organization is what makes you one, and the token already proves belonging.

  1. The person exists in the application's realm — created there, invited, or federated from your customer's own identity provider.
  2. They are made a member of the organization, in Keycloak.
  3. They sign in selecting it (scope=… organization:acme).
  4. On first sight the engine enrols them as a principal, and they hold org-member.

Step 4 needs no action from you, and neither do the others unless you are also the one running the customer's directory. An operator is involved only to make someone an administrator, or to repair one of the situations below.

Why membership is derived and elevation is not: the organization claim is specific to that organization, so it can be trusted as a statement about it. A realm role is not — it follows its holder into every organization they belong to. See Who decides what a person may do.

Reading a member

curl --user "$ADMIN_USER:$ADMIN_PASSWORD" \
  "$BASE_URL/v1/admin/orgs/$ORG_ID/principals/$PRINCIPAL_ID"

A caller reads their own principal without any admin rights — this is the id to use when granting a dataset, adding someone to a team, or capping spend:

GET /v1/me/usage      # → { "user_id": "<principal uuid>", … }

Use the principal, never the identity provider's sub.

Stopping someone immediately

This is the section to know before you need it.

The engine verifies tokens offline. Disabling a person at the identity provider stops them getting a new token; it does nothing about the one in their hand, which stays valid until it expires. Two levers close that gap:

# Refuse every token minted before now — takes effect on their next request.
curl --user "$ADMIN_USER:$ADMIN_PASSWORD" -X POST \
  "$BASE_URL/v1/admin/orgs/$ORG_ID/principals/$PRINCIPAL_ID/kill"

kill bumps the principal's valid_after. Any token issued before that instant is refused from the next request onward — including one issued thirty seconds ago. It also stops the durable delegations that principal owns, so long-running work started on their authority does not continue after they are gone.

Order matters when offboarding. Disable them at the identity provider first, then kill. The other way round leaves a window in which they can obtain a fresh token that kill does not cover, because it was minted after the cutoff.

Revoking their roles is a separate act with a different meaning: it removes authority while leaving them able to sign in. Use it for a change of duties, not for an exit.

Repairing an identity

The person was deleted and re-created at the provider

Their sub is new; everything they own keys on the principal, which has not changed. Re-point it in one write rather than losing the rows or rewriting each one:

# Detach the old identity.
curl --user "$ADMIN_USER:$ADMIN_PASSWORD" -X DELETE \
  -H "Content-Type: application/json" \
  "$BASE_URL/v1/admin/orgs/$ORG_ID/principals/bindings" \
  -d '{"issuer":"…/realms/deeplinq","subject":"<old sub>"}'

# Attach the new one to the SAME principal.
curl --user "$ADMIN_USER:$ADMIN_PASSWORD" -X POST \
  -H "Content-Type: application/json" \
  "$BASE_URL/v1/admin/orgs/$ORG_ID/principals/$PRINCIPAL_ID/bindings" \
  -d '{"issuer":"…/realms/deeplinq","subject":"<new sub>"}'

Binding an identity that already belongs to another principal is a 409 — including one in another organization, which is the squatting case the rule exists to prevent.

Creating a principal before the person signs in

Rarely needed, because enrolment is automatic. It is useful when you want to grant something ahead of someone's first sign-in:

curl --user "$ADMIN_USER:$ADMIN_PASSWORD" -X POST \
  "$BASE_URL/v1/admin/orgs/$ORG_ID/principals"

Then bind their identity as above. A principal with no binding can hold grants but nobody can sign in as it.

Bringing history with them

If an organization had users before it was on this engine, their rows must land on the right people rather than on new principals. Two surfaces exist for that, and both are for a migration rather than day-to-day use:

  • Principal mappings (/v1/admin/orgs/{id}/principal-mappings) — stage a batch of your identifiers against subjects, review what is unmapped, then apply it.
  • Principal adoption (/v1/admin/orgs/{id}/principal-adoption) — switch an organization over to engine-owned principals once its mapping is complete.

A mapping's subjects are only meaningful against the issuer that minted them, so the organization must be bound to that issuer before applying one.

Teams

Teams are a tenant surface, not an operator one: an org-admin manages them from within the organization at /v1/teams, and membership is by principal.

They exist so a grant can name a group rather than a list of people. See Ownership and access.

Offboarding checklist

  1. Disable or delete the person at the identity provider.
  2. kill their principal — refuses tokens already in the wild and stops their durable delegations.
  3. Revoke any org-admin role, so a re-created identity does not inherit it.
  4. Re-assign what they owned. Their principal stays; owned rows do not move by themselves.

On this page