← All frames
Frame (e) · route /settings/access

States

Every state a consumer must render is contract, not decoration. Loading, the single-member org, a load failure, an empty role catalogue, and — the one that is most often got wrong — an authorization denial that must never become a sign-in prompt.

(e1) Loading

Members

Loading…

(e2) Single-member org — it's just you

Members

1 person in Northwind

You're the only member

You're the admin of Northwind. Invite teammates to collaborate — they'll get the role you choose when you add them.

(e3) Couldn't load

Members

(e4) No roles to assign — add-member blocked
(e5) Not allowed — 403, never a sign-in redirect

Members

Contract. Loading covers the in-flight GET /v1/security/tenants/{tenantId}/members. Empty is a real, common state — a brand-new org has exactly one member. Error covers a non-2xx list response with data-action="retry". (e4) covers GET /v1/security/tenants/{tenantId}/roles returning { items: [] } — the add/change forms must fail closed, never render a submittable form with zero roles.

⚠ (e5) is the rule this frame exists to enforce. A 403 is an authorization denial, NOT an authentication failure. The member is signed in; their token is valid; they simply lack permission. The UI shows this denial in place and never redirects to sign-in. Only a 401 (no/expired session) triggers re-authentication. Conflating the two — bouncing a permission-denied user to a login page they'll sail straight back through — is the exact failure this state is contract for.

Review · authz-admin approve or reject each flow ↓
access-adminpendingApproveReject