---
id: WF-PFM-SEC-006
title: Accept an invitation
trigger: The recipient presents an invitation token and chooses password acceptance or provider linking.
product_area: platform
module: security
revision: 1
status: draft
design_intent: confirmed
origin: services-platform:docs/security/console-authentication.md (final acceptance checkpoint); docs/security/invitation-lifecycle.md
implementation_evidence: observed
inference: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
- CAP-PFM-SEC-005
moves:
- STATE-PFM-SEC-004
- STATE-PFM-SEC-005
- STATE-PFM-SEC-006
crosses:
- SVC-PFM-SEC-security
idempotency: Conditional consumption admits one database acceptance winner; an already accepted token for an
  active member returns the prior success. Provider enabling and password setting occur before this transaction
  and can be repeated or raced. Link-session consumption is also conditional; neither database condition proves
  atomic external-provider effects.
concurrency: Acceptance re-evaluates inviter authority before activation and commits token consumption, membership
  activation and pending grants together. Two password requests can both reach the provider before one loses
  database consumption; the credential race remains unresolved.
hops:
- n: 1
  actor_or_service: Acceptance page (public)
  action: Read the token summary and require sign-out when the current session belongs to another person.
  anchor: react-console:components/auth/screens/accept-invite-screen.tsx
  seam: sync
  on_failure: Return neutral unusable-token wording with a next-step reason code.
  left_inconsistent: No membership activation has occurred.
  observer: The acceptance page displays the summary or recovery guidance.
  provenance: observed
  source: services-platform:modules/security/services/invitations/invitation-summary.ts
- n: 2
  actor_or_service: Security service (password path)
  action: Validate token and current inviter authority, then enable the provider account and set the chosen
    password.
  anchor: services-platform:modules/security/services/invitations/accept-invitation.ts
  seam: sync
  on_failure: Leave the token unconsumed on authority or provider refusal.
  left_inconsistent: Provider credentials may change while the membership stays invited; concurrent requests
    can race these effects.
  observer: The recipient receives the acceptance result or retry guidance.
  provenance: observed
  source: services-platform:modules/security/services/invitations/accept-invitation.ts (header)
- n: 3
  actor_or_service: Security service (one transaction)
  action: Consume the usable invitation, activate membership and pending grants, and append attributed history
    atomically.
  anchor: services-platform:modules/security/services/persistence/invitations.ts:acceptInvitation
  seam: sync
  on_failure: Roll back database writes if conditional consumption or activation loses.
  left_inconsistent: Database activation is absent after rollback; earlier provider effects remain.
  observer: The recipient receives success or the refusal code.
  provenance: observed
  source: services-platform:modules/security/services/persistence/invitations.ts:acceptInvitation
- n: 4
  actor_or_service: Security service (Google path, begin)
  action: Create a short-lived, pool-bound link session from invitation proof and return its nonce as sign-in
    state.
  anchor: services-platform:modules/security/services/invitations/google-acceptance.ts:beginGoogleAcceptance
  seam: sync
  on_failure: Apply the same invitation-usability checks as summary.
  left_inconsistent: An unused session may remain until expiry.
  observer: The recipient proceeds to the provider or sees token guidance.
  provenance: observed
  source: services-platform:modules/security/services/invitations/google-acceptance.ts (header)
- n: 5
  actor_or_service: Sign-in pool pre-sign-up trigger
  action: Link a verified Google identity under the matching live pool session and identity uniqueness checks.
  anchor: services-platform:modules/security/services/provisioning/pre-sign-up.ts:authorizeSignUp
  seam: event
  on_failure: Refuse provider linking when any required evidence fails.
  left_inconsistent: Provider linking can succeed before later database completion fails.
  observer: The provider-return flow exposes a neutral refusal.
  provenance: observed
  source: services-platform:modules/security/services/provisioning/pre-sign-up.ts (header)
- n: 6
  actor_or_service: Security service (Google path, complete)
  action: Verify the returned subject, consume the link session and activate the invitation transactionally.
  anchor: services-platform:modules/security/services/invitations/google-acceptance.ts:completeGoogleAcceptance
  seam: sync
  on_failure: Refuse expiry, replay, another subject or lost invitation usability.
  left_inconsistent: A provider identity may remain linked to an invited membership.
  observer: The acceptance flow shows completion or retry guidance.
  provenance: observed
  source: services-platform:modules/security/services/invitations/google-acceptance.ts (header)
branches:
- Re-invitation reuses the retained membership and pool account; acceptance enables that account.
- Active founding staff with a console-pool account can link Google without an invitation through the documented
  founding-staff exception.
waits:
- Invitation validity is seven days; provider link sessions use their separate short deadline.
evidence:
- 'services-platform at ad3f6a65: modules/security/services/invitations/accept-invitation.ts, google-acceptance.ts,
  invitation-summary.ts, invitation-refusals.ts; services/provisioning/pre-sign-up.ts; services/persistence/invitations.ts,
  identity-link-sessions.ts.'
- 'react-console at baf6dae: components/auth/screens/accept-invite-screen.tsx; lib/auth/invitations.ts, invitation-flow.ts.'
examined_at: '2026-10-23'
examiner: codex
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-003, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-SEC-001, TC-SEC-002, TC-SEC-003, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Accept an invitation

## What It Does

Acceptance proves possession of an existing offer and cannot select a different person or privilege set. The password and provider-link paths both prepare external identity effects before database activation.

## The Flow

```mermaid
flowchart TD
    H1["Read invitation"]
    H2["Prepare password credential"]
    H3["Consume invitation and activate"]
    H4["Begin provider link session"]
    H5["Link provider identity"]
    H6["Complete provider acceptance"]
    H1 -->|password path| H2
    H2 --> H3
    H1 -->|Google path| H4
    H4 --> H5
    H5 --> H6
```

The diagram separates the relevant success, alternative and failure paths. The numbered hop rows retain the detailed authority checks, delegated work and retry limits.

## When Something Fails

Single-use applies to conditional database consumption. It does not serialize provider passwords across concurrent acceptances. That race is a finding requiring a test and a product decision rather than a promise of safe retry.

Conditional consumption admits one database acceptance winner; an already accepted token for an active member returns the prior success. Provider enabling and password setting occur before this transaction and can be repeated or raced. Link-session consumption is also conditional; neither database condition proves atomic external-provider effects.

Acceptance re-evaluates inviter authority before activation and commits token consumption, membership activation and pending grants together. Two password requests can both reach the provider before one loses database consumption; the credential race remains unresolved.

## Open Design Questions

The recorded findings retain any stronger planning expectation, missing writer or unproved recovery path. Observed behavior does not approve those outstanding product choices.
