Auth & Security

Members

The workspace member roster and its lifecycle — invite, assign roles, disable, reenable, and remove — where a member is modeled as a tenant API key plus its RBAC role bundle.

Members are the operators and services that act inside a workspace. This page is about the member lifecycle — inviting, role assignment, suspension, and removal. The RBAC roles-and-scopes model itself lives in Authorization; this page does not re-explain it.

All endpoints are under /api/v2/members and are served by MemberService.

What a member actually is

Ductor has no first-class user record. A workspace member is modeled honestly as a tenant API key (a tenant_api_key row) plus the RBAC role bundle that key carries. The member's ID is the underlying API key ID.

Because a member is a key, the member roster and your API keys are two views of the same underlying identities. Managing a member's role here changes what that key is authorized to do.

Each member is classified by kind:

  • MEMBER_KIND_HUMAN — an operator-managed key.
  • MEMBER_KIND_SERVICE — an inter-process identity.

A MemberRecord exposes the identity without ever revealing the raw secret:

Prop

Type

The roster

GET /api/v2/members returns the roster for the authenticated tenant; GET /api/v2/members/{id} returns one member by its key ID. Both require the tenant:read scope.

curl http://localhost:8080/api/v2/members \
  -H "X-Tenant-ID: $DUCTOR_TENANT_ID"

Lifecycle

accepted revoke disable reenable remove Invite Pending invite Active member Cancelled Disabled Revoked

Invites

Invites create a pending member before a key is active.

Prop

Type

curl -X POST http://localhost:8080/api/v2/members/invites \
  -H "X-Tenant-ID: $DUCTOR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "roles": ["operator"] }'

Roles and status

Prop

Type

AssignRole sets the bundle for a member. The role names must come from ListRoles (below) — the change is rejected if any name is unknown. Passing an empty role list clears the bundle, after which the member falls back to its per-key scope list, if any.

curl -X POST http://localhost:8080/api/v2/members/$MEMBER_ID/role \
  -H "X-Tenant-ID: $DUCTOR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{ "roles": ["admin"] }'

remove revokes the underlying API key. Any client still presenting that key stops authenticating immediately. Use disable for a reversible suspension.

Role and scope catalogs

Two read-only catalogs back role assignment. They are pass-through accessors over the static RBAC catalogs described in Authorization — consult that page for what the roles and scopes mean.

  • GET /api/v2/members/roles — every role name and the scopes it expands to, including the built-in roles (viewer, operator, admin, service) plus any roles registered by extension modules.
  • GET /api/v2/members/scopes — the full catalog of legal resource:action scope identifiers known to the authorization layer.