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:
- Client sends refresh token to
/refresh - Server hashes it with SHA-256 and looks up the stored hash
- If valid and not expired, the old token is deleted
- A new refresh token is generated and stored
- 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:
- Old password is verified
- New password is bcrypt-hashed and stored
- 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 |