Skip to content

Authentication Flow

Token Lifecycle

sequenceDiagram
    participant C as Client
    participant A as Pico-Auth
    participant DB as Database

    C->>A: POST /register (email, password)
    A->>DB: Store user (bcrypt hash)
    A-->>C: User created

    C->>A: POST /login (email, password)
    A->>DB: Verify credentials
    A->>A: Generate JWT (RS256 or ML-DSA)
    A->>DB: Store refresh token (SHA-256 hash)
    A-->>C: access_token + refresh_token

    C->>A: GET /me (Bearer token)
    A->>A: Verify JWT signature + claims
    A-->>C: User profile

    C->>A: POST /refresh (refresh_token)
    A->>DB: Find + delete old token
    A->>A: Generate new JWT
    A->>DB: Store new refresh token
    A-->>C: New access_token + refresh_token

JWT Access Token

  • Algorithm: Configurable via auth.algorithm — RS256 (default), ML-DSA-65, or ML-DSA-87
  • Lifetime: 15 minutes (configurable)
  • Key management: Auto-generated key pair stored in ~/.pico-auth/ (RSA PEM or ML-DSA binary)

Claims

Claim Type Description
sub string User ID
email string User email
role string User role
org_id string Organization ID
iss string Issuer URL
aud string Audience
iat int Issued at (Unix timestamp)
exp int Expiration (Unix timestamp)
groups list[string] Group IDs the user belongs to
jti string Unique token ID (12 hex chars)

Refresh Token Rotation

Refresh tokens use one-time rotation:

  1. Client sends refresh token to /refresh
  2. Server hashes it with SHA-256 and looks up the stored hash
  3. If valid and not expired, the old token is deleted
  4. A new refresh token is generated and stored
  5. New access + refresh tokens are returned

This ensures that if a refresh token is stolen and used, the legitimate user's next refresh will fail, signaling a compromise.

Password Change

When a user changes their password via /me/password:

  1. Old password is verified
  2. New password is bcrypt-hashed and stored
  3. All refresh tokens for the user are deleted (forced re-login on all devices)

RBAC

Role Access
viewer Own profile, change password, list/view groups
operator Same as viewer
org_admin List users, update roles, manage groups and members
superadmin List users, update roles, manage groups and members