> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.adid.dev/llms.txt.
> For full documentation content, see https://docs.adid.dev/llms-full.txt.

# OAuth + DID-Auth Login Flows

**Used in:** §2.3 OAuth Sign-In, §2.4 DID-Auth Challenge Login, §9.2
**Audience:** Holder, Backend Developer
**IA ID:** D23

```mermaid
sequenceDiagram
  autonumber
  participant User
  participant Portal
  participant API
  participant IdP as Google/GitHub
  participant Redis
  participant DB

  rect rgb(240,249,255)
    Note over User,DB: OAuth flow
    User->>Portal: Click "Continue with Google"
    Portal->>API: GET /api/v1/auth/oauth/{provider}
    API-->>Portal: 302 to IdP authorize URL
    Portal->>IdP: redirect
    IdP-->>Portal: callback (code, state)
    Portal->>API: POST /api/v1/auth/oauth/{provider}/callback
    API->>IdP: exchange code → profile
    API->>DB: upsert user, assign role
    API-->>Portal: { accessToken, refreshToken }
  end

  rect rgb(245,243,255)
    Note over User,DB: DID-Auth challenge flow (wallet sign-in)
    User->>Portal: "Sign in with DID"
    Portal->>API: POST /api/v1/auth/challenge { did }
    API->>Redis: store nonce (TTL 5m)
    API-->>Portal: { challenge: nonce }
    Portal->>User: prompt wallet to sign challenge
    User-->>Portal: signature
    Portal->>API: POST /auth/verify-otp or /auth/login-did { did, signature, nonce }
    API->>API: resolve DID, verify signature against verificationMethod
    API->>Redis: consume nonce
    API->>DB: upsert user (role inferred or default holder)
    API-->>Portal: { accessToken, refreshToken }
  end
```

**Reading guide:** Both flows produce the same token pair; the difference is bootstrap proof of identity (IdP cookie vs. DID-controlled signature).

***