Skip to content

Checklist identity auth

github-actions[bot] edited this page Nov 12, 2026 · 1 revision

identity-auth

Generated by pnpm gen:checklist-status from docs/qa/platform-checklist/areas/*.json. ⛔ Do not edit this page — edits go to the area JSON and this page follows on the next run. This page is Checklist-identity-auth.

Auth, login, identity

35 active · 0 planned

Active (35)

id title priority status personas
identity-auth.sso-enforced-first-paint ssoEnforced login honors SSO on first paint — no password-wall flash P2 active anonymous visitor at the login page, env owner (break-glass password holder)
identity-auth.phone-signin-surfaces A phone-based user's number shows across the identity surfaces, and the phone capability is advertised honestly P2 active admin
identity-auth.auth-method-matrix Every supported auth method signs in when enabled, is absent when disabled, and is advertised exactly as configured P1 active anonymous visitor, provisioned user per method, admin (for env configuration)
identity-auth.invitation-scope-gates Invitation issuance honors role-scope gates: delegated_admin can invite members but cannot mint admins; a plain member cannot invite at all P1 active delegated_admin org member, plain member, tenant admin (setup only)
identity-auth.admin-lifecycle-operations Admin user-lifecycle operations (ban/unban, set-password, impersonate, create/set-role/remove, revoke-sessions) enforce, persist, and stay closed to non-admins P1 active platform admin, target user, non-admin forger
identity-auth.session-list-revoke Active-session list is owner-scoped, and each revoke primitive terminates exactly the sessions it names P1 active user A (two devices), user B (unrelated, second live session), platform admin
identity-auth.api-key-ui-lifecycle Personal API key: minted show-once on Connect-an-Agent, authenticates as its owner, revoke kills it and restore brings it back — mine-view scoped P1 active a signed-in member (key owner), platform admin, the key itself (machine caller via x-api-key)
identity-auth.self-service-profile-password Self-service profile: name + avatar edits persist through real storage, and password change verifies the current password (passwordless users get set-initial) P1 active a signed-in email+password user, a signed-in passwordless (SSO-only) user
identity-auth.org-membership-team-management Setup Organization page resolves the active org and drives member/invitation/team management through the better-auth org endpoints — non-admins refused server-side P1 active tenant admin / org owner, a target org member, a non-admin org member (forger)
identity-auth.teams-bu-membership Teams and the Business Unit tree: memberships land real rows, and a BU placement widens/narrows a scoped persona's read along the tree P2 active org admin, two members to place on a team, a scope-limited persona whose read follows the BU tree
identity-auth.self-service-password-reset Forgot-password: request → token captured at the dev mail transport → reset; old password refused, expired/reused token refused loudly P1 active anonymous visitor (holds no session), the account owner (before and after reset)
identity-auth.oauth-app-consent-loop OAuth provider: register an app (secret shown once), run the authorization-code consent loop — approve mints tokens + a consent record, deny mints none P2 active an org admin registering the OAuth client, the resource-owner user granting/denying consent
identity-auth.linked-accounts-social Linked accounts: link a social/OIDC identity through the redirect round-trip → a sys_account row appears in mine-view; unlink removes it; provider-less boot degrades honestly P2 active a signed-in user linking a second identity, the same user after unlinking
identity-auth.identity-import-wizard Admin CSV identity import: password-policy auto/temporary drive per-row credentials, imported users sign in, non-admins denied P2 active platform admin (running the import), an imported user (signing in afterwards), a non-admin (forger)
identity-auth.two-factor-enrollment-reveal TOTP enrollment reveal: /two-factor/enable returns a parseable otpauth:// URI + backup codes, the declared reveal dialog's paths resolve against that exact shape, and the live re-reveal endpoint's behavior is recorded P1 active a signed-in user with a known password enrolling their own second factor
identity-auth.two-factor-verify-to-activate Enrollment is inert until one correct TOTP verifies on the session lane — and the run records what sys_two_factor.verified actually carries in between P1 active a signed-in user mid-enrollment (session lane), the same user at the sign-in challenge (cookie lane)
identity-auth.two-factor-backup-codes Backup codes: revealed once at enable, spendable exactly once at the sign-in challenge, and regeneration kills the prior set — and the navigable regenerate surface reveals the new set in a one-shot dialog P1 active a user with a VERIFIED enrollment (run identity-auth.two-factor-verify-to-activate's path first), the same user at the sign-in challenge spending a code
identity-auth.two-factor-disable-lifecycle Disable tears the factor down completely — row gone, flag off, next sign-in unchallenged, stale backup codes dead — is password-gated server-side, and under mfa_required re-gates through the grace-clock machinery P1 active a user with an ACTIVE (verified) enrollment disabling it, the same user post-disable at a fresh sign-in, for the mfa_required clause: the same user under an enforced-MFA boot
identity-auth.first-run-owner-bootstrap Zero-user first-run: the /setup owner wizard serves even under OS_DISABLE_SIGNUP, creates the owner + names the personal org through a full-document exit, and every bootstrap bypass closes the moment an owner exists P1 active anonymous visitor on a zero-user boot (the would-be owner), the created owner (post-bootstrap), a second anonymous visitor (post-bootstrap forger)
identity-auth.self-signup-gate Self-signup gate: the default audience posture (invite_only) refuses at the server with a LOUD code, a pending invitation carves through, and OS_DISABLE_SIGNUP bounces the UI AND the endpoint — the console offers the register form only to a visitor the server would admit (an invitation redirect, or a deployment with no owner) and explains the by-invitation rule to everyone else; the form is never the gate P1 active anonymous uninvited registrant, an invited email's registrant, org admin (mints the invitation), env owner (sets OS_DISABLE_SIGNUP)
identity-auth.email-verification-loop Email verification loop: a challenged sign-up lands a captured verification mail, unverified sign-in is refused EMAIL_NOT_VERIFIED server-side, the link admits, resend works — and the default boot never challenges P2 active a fresh registrant (unverified, then verified), admin (reads state), env owner (configures the verification boot)
identity-auth.workspace-org-switch Workspace switcher: org chrome follows posture × membership count (nothing under single; read-only indicator at one membership; switcher at two), and a switch is a full-document reload after which every tenant-scoped read answers from the new org P2 active a member with one org membership, the same member after gaining a second membership, admin, the walled boot's platform operator (OS_PLATFORM_OWNER_EMAIL): mints the member with POST /api/v1/auth/admin/create-user (RUNNER.md 'A walled boot is a fixture of its own'). On a walled boot Create User joins the administrator's CURRENT organization (ADR-0093 D3 amendment) and the admin starts with none, so first create an organization (POST /api/v1/auth/organization/create) and make it active (POST /api/v1/auth/organization/set-active); without it create-user answers 400 NO_ACTIVE_ORGANIZATION and mints nobody. The member lands as member of that organization, its one membership. The admin does not provision the second org: the member creates that itself (fixtures.requires[1])
identity-auth.implicit-account-linking-ownership Implicit account linking on external sign-in: no implicit link to an unverified local user; after an unlink, implicit sign-in does not re-link; an explicit, signed-in link still works and lifts the refusal; the platform identity provider's exception holds only on its OAuth path P1 active anonymous: the external sign-in caller, before it is anyone, local user U, signed up with email + password and NOT verified. A stock boot never challenges a sign-up, so a fresh sign-up is unverified, the same user U after verifying their email (the verified-row case), U signed in, linking a provider explicitly from account settings, seeded admin: reads sys_account and sys_user to confirm what was and was not written
identity-auth.auth-gate-held-session-raw-host-families A session held by the ADR-0069 credential policy (password expired, forced reset, MFA not enrolled) is refused with the gate's own 403 code on EVERY raw-host route family, and an API key whose owner holds an account-scope posture is refused too P1 active seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot, org member — created by the admin with POST /api/v1/auth/admin/create-user (stock showcase self-registration is closed: audience posture invite_only answers sign-up 403 SELF_REGISTRATION_CLOSED); joins the Default Organization as member, not platform admin, and lands mustChangePassword:true, i.e. a HELD session until it changes its password (POST /api/v1/auth/change-password)
identity-auth.api-key-expiry-lifecycle API-key lifecycle policy: a mint with no expiry gets the default (90 days) echoed back, an expiry past the ceiling is refused 400 API_KEY_EXPIRY_TOO_LONG, and an expired / inactive / revoked key is refused with its own 403 code P1 active seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot
identity-auth.cookie-session-renewal-in-process A cookie session past its updateAge is renewed ONLY by GET /auth/get-session: in-process reads (data, meta, me/permissions, SSO admin) leave sys_session.expires_at unchanged and set no cookie, while bearer-only calls still renew P2 active seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot
identity-auth.default-organization-boot-invariant ADR-0131 single posture: the Default Organization exists from boot BEFORE any sign-up — the first sign-up becomes its owner, later sign-ups its members, every session carries it as active org, and seeded org-columned rows carry it instead of NULL P0 active seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot, org member — created by the admin with POST /api/v1/auth/admin/create-user (stock showcase self-registration is closed: audience posture invite_only answers sign-up 403 SELF_REGISTRATION_CLOSED); joins the Default Organization as member, not platform admin, and lands mustChangePassword:true, i.e. a HELD session until it changes its password (POST /api/v1/auth/change-password)
identity-auth.import-invitation-and-sso-domain-answers Identity import sends the dedicated account-invitation mail whose link opens the console set-password page, and the SSO domain-verification doors answer 404 for an unknown provider when enabled and 400 DOMAIN_VERIFICATION_DISABLED when off P2 active seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot
identity-auth.idp-group-permission-set-mapping A platform administrator maps an identity-provider group to a permission set: a SCIM group push grants the set to the group's members at once, an SSO sign-in grants it from the groups claim, deleting the mapping removes only the grants it made, and a set outside the organization boundary is refused P1 active platform administrator: the mapping doors, an organization administrator: the 403 leg, an identity provider: the SCIM pushes
identity-auth.sso-provider-groups-claim The SSO Providers record shows and edits the groups claim: get-groups-claim answers only the provider id and its claim, set-groups-claim stores it (blank clears it) and changes nothing else in the provider's mapping P2 active platform administrator, an organization administrator: the 403 leg
identity-auth.ai-service-account-lifecycle An AI service account is suspended, resumed, re-owned, retired, and has a key revoked and restored, each by the right holder: the owner may suspend but not resume, retire ends the membership and revokes every key, and an owner leaving the organization suspends the account P1 active organization administrator (membership grade admin or owner): register, mint and the lifecycle doors, the accountable owner, a plain member, a second plain member: the 403 legs, anonymous (no session): the 401 legs
identity-auth.ai-service-account-register-and-key An organization administrator registers an AI service account and mints its key: the account is an agent row owned by a named member, with one plain membership and no sign-in, and its key admits requests as the account in the account's organization P1 active organization administrator (membership grade admin or owner): register, mint and the lifecycle doors, the accountable owner, a plain member, a second plain member: the 403 legs, anonymous (no session): the 401 legs
identity-auth.scim-refused-audit-row A refused SCIM request writes one bounded scim_refused audit row naming the connection, the presented credential kind, the resource, the method and the status, never the bearer P2 active an identity provider calling SCIM 2.0, admin (the seeded admin): the mint and the audit read
identity-auth.console-two-factor-prompt-phone-doors The Console's phone doors on a two-factor account ask for the code: phone + password and the phone code each move to the two-factor step instead of an error, and a code completes the sign-in P1 active a user of this run with an email, a phone number, a known password and a verified TOTP enrollment: every step
identity-auth.console-sign-out-and-ended-session Sign-out leaves none of the signed-out user's browser state and no return link, while a session that ended on the server sends the next in-app navigation to sign-in with its return link P1 active seeded admin (admin@objectos.ai / admin123): the signed-out user and the revoked session, org member — created by the admin with POST /api/v1/auth/admin/create-user, password changed so the session is not held: the next person to sign in

Clone this wiki locally