# Identity and sign-in

> How people prove who they are, and how every app trusts that.

Source: https://docs.dashfordevs.com/v1/how-it-works/identity-and-sign-in · Topic: How the platform works · Updated: 2026-11-07

**accounts.dashfordevs.com** is the platform's identity provider. Every other app (hub, dashboard, organizations, Cloud, admin) is a relying party that signs people in through it with [OpenID Connect](https://openid.net/developers/how-connect-works/).

```dfd-diagram
{
  "type": "sequence",
  "title": "Signing in to the dashboard",
  "actors": [
    { "id": "user", "label": "Browser" },
    { "id": "dash", "label": "Dashboard server" },
    { "id": "acc", "label": "accounts" }
  ],
  "messages": [
    { "from": "user", "to": "dash", "label": "open dashboard" },
    { "from": "dash", "to": "user", "label": "redirect to accounts (PKCE)", "reply": true },
    { "from": "user", "to": "acc", "label": "password + second factor" },
    { "from": "acc", "to": "user", "label": "redirect back with a one-time code", "reply": true },
    { "from": "user", "to": "dash", "label": "code" },
    { "from": "dash", "to": "acc", "label": "exchange code (client secret)" },
    { "from": "acc", "to": "dash", "label": "access + refresh tokens", "reply": true },
    { "from": "dash", "to": "user", "label": "encrypted session cookie for this host only", "reply": true }
  ],
  "steps": [
    { "title": "Go sign in", "focus": [0, 1], "text": "The dashboard sends the browser to accounts with a PKCE challenge." },
    { "title": "Prove it", "focus": [2, 3], "text": "Password, then the second factor if enabled. accounts returns a one-time code." },
    { "title": "Server-side exchange", "focus": [4, 5, 6], "text": "The dashboard's server, not the browser, exchanges the code with its client secret." },
    { "title": "No tokens in the browser", "focus": [7], "text": "The browser only gets an httpOnly, encrypted cookie for dashboard.dashfordevs.com. Tokens stay on the server." }
  ]
}
```

## The rules

-   **Access tokens live 10 minutes.** Refresh tokens live 30 days and **rotate** on every use. Reusing an old refresh token revokes the whole family, the signal that one was stolen.
-   **Tokens are signed with RS256**; public keys are at `/.well-known/jwks.json`.
-   **No token ever reaches browser JavaScript.** Every app is a confidential client with a server that holds the tokens.
-   **The sign-in cookie lives on accounts.dashfordevs.com only**, never on `.dashfordevs.com`, so a bug on another subdomain cannot steal it.
-   **The `amr` claim** says how this session authenticated (for example `["pwd", "otp"]`). Sensitive actions check that the session actually passed two-factor, not just that the account has it on.
-   **`?next=` is allowlisted.** After sign-in you return to the app that sent you, if it is a known DashForDevs app; otherwise you land on the hub.
-   **Staff always need two-factor**, independent of any organization's policy.

## Endpoints

```
GET  /.well-known/openid-configuration
GET  /.well-known/jwks.json
GET  /oauth/authorize
POST /oauth/token
GET  /oauth/userinfo
POST /oauth/revoke
```

These are for DashForDevs' own apps. Storefronts do not use OIDC; they use [API keys](https://docs.dashfordevs.com/v1/authentication).
