Authentication
Authentication is the process of proving identity. In Roled, it answers the question: “Who are you?”
Authentication vs. Authorization
Authentication happens before authorization. Until a user or client proves their identity, they cannot access any protected resource.
| Authentication | Authorization | |
|---|---|---|
| Question | Who are you? | What are you allowed to do? |
| Roled mechanism | OAuth 2.0 flows | Permission middleware |
| Output | JWT access token | 200 OK or 403 Forbidden |
Authenticating Users
Users authenticate through the OAuth 2.0 Authorization Code Flow with PKCE. This is a browser-based flow where the user is redirected to the Roled Auth page, logs in, and is redirected back to your application.
sequenceDiagram
autonumber
participant U as User
participant Y as Your App
participant R as Roled
U->>Y: Clicks "Login"
Y->>Y: Generate PKCE code_verifier & code_challenge
Y->>R: Redirect to /authorize?client_id=...&code_challenge=...
R->>U: Show login form
U->>R: Enter email + password
R->>R: Verify credentials
R->>Y: Redirect to redirect_uri?code=AUTH_CODE
Y->>R: POST /api/v1/tokens (exchange code for tokens)
R-->>Y: access_token + refresh_token
Y->>U: Logged in
PKCE — Why It Matters
PKCE (Proof Key for Code Exchange) protects against authorization code interception attacks. Your application generates a random code_verifier, computes code_challenge = SHA256(code_verifier), and sends the challenge to Roled. When exchanging the code for tokens, you must provide the original code_verifier — proving you initiated the flow.
Roled requires PKCE for all Authorization Code flows. Only the S256 method is supported (plain is not allowed).
Login Page
Roled provides a ready-to-use login page at:
https://auth.roled.id/authorize?client_id=...&redirect_uri=...&response_type=code&code_challenge=...&code_challenge_method=S256Users can log in or create a new account on this page (if signup is enabled for the project). After successful authentication, they are redirected to your redirect_uri with the authorization code.
Supported Auth Features for Users
| Feature | Description |
|---|---|
| Login | Standard email + password login |
| Sign up | Self-registration (if enabled for the project) |
| Email verification | Verify email before allowing login (if enabled) |
| Forgot password | Password reset via email (if enabled) |
These features are controlled per-project in the project settings.
Authenticating Clients
Clients (machine identities) authenticate using the OAuth 2.0 Client Credentials Flow. There is no browser or user involved.
sequenceDiagram
autonumber
participant Service as Backend Service
participant Roled
Service->>Roled: POST /api/v1/tokens<br/>Authorization: Basic base64(client_id:client_secret)<br/>grant_type=client_credentials
Roled->>Roled: Validate client credentials
Roled->>Roled: Issue access token for client
Roled-->>Service: access_token (no refresh token)
Credentials are passed using HTTP Basic Authentication:
# Build the credentials string
CREDENTIALS=$(echo -n "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" | base64)
curl --request POST \
--url https://auth.roled.id/api/v1/tokens \
--header "Authorization: Basic $CREDENTIALS" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials'How Roled Validates Authentication
On every request to a protected endpoint, Roled validates the incoming JWT:
flowchart TD
A["Request arrives with Bearer JWT"] --> B{JWT present?}
B -- No --> Z["401 Unauthorized"]
B -- Yes --> C{Valid signature?}
C -- No --> Z
C -- Yes --> D{Token expired?}
D -- Yes --> Z
D -- No --> E["Look up token record in database"]
E --> F{Token status active?}
F -- No (revoked/expired) --> Z
F -- Yes --> G["Extract identity: user_id or client_id"]
G --> H["Continue to permission check"]
What Roled Checks
- JWT signature — validates the token was signed by Roled’s signing key.
- Token expiry — checks the
expclaim is in the future. - Token record — looks up the token in the database to confirm it hasn’t been revoked.
- Token claims — verifies that
project_id,client_id, anduser_idin the database match the JWT claims.
This means a revoked token is rejected immediately, even if it hasn’t expired yet. Roled does not rely solely on JWT expiry for security.
Using the Access Token
After authentication, include the token in the Authorization header of every request:
curl --request GET \
--url https://auth.roled.id/api/v1/projects/2JUSLUee46xG6iEwG8JwPc/users \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJo...'Session Management with Refresh Tokens
User tokens (from the Authorization Code flow) include a refresh token. When the access token expires, use the refresh token to get a new one without forcing the user to log in:
curl --request POST \
--url https://auth.roled.id/api/v1/tokens \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token' \
--data 'client_id=2JRYkzSeBV89itqcU9mraF' \
--data 'refresh_token=M8MmHrhqzcBgUwCQ5enp4wTuRVBgi2txChS44Q3FYJGRgzX...'Refresh tokens are single-use — each use returns a new access token and a new refresh token.
Key Points
- Authentication answers “Who are you?” and produces a JWT access token.
- Users authenticate via Authorization Code Flow + PKCE (browser-based).
- Clients authenticate via Client Credentials Flow (direct API call, no browser).
- Roled validates every token against the database on each request — revoked tokens are rejected immediately.
- User tokens include a refresh token for seamless session renewal.
- PKCE is required for all Authorization Code flows — only
S256is supported.