Skip to content
OAuth 2.0

OAuth 2.0

OAuth 2.0 is an industry-standard authorization framework. Roled uses it as the foundation for authentication, not because it’s complex, but because it’s a proven and secure way to issue and manage access tokens.

What Is OAuth 2.0?

OAuth 2.0 is a protocol that allows applications to obtain limited access to user accounts or services. At its core, it defines a set of flows (called “grant types”) that describe how a client application can get an access token.

OAuth 2.0 involves four key components:

  • Authorization Server: The central authority that authenticates users and issues access tokens.
  • Client: The application that wants to access the user’s data. The client is identified by a client_id and client_secret.
  • Resource Owner: The user who owns the data that the client wants to access.
  • Resource Server: The server that hosts the user’s data. The resource server validates the access token and returns the requested data.

In the context of Roled, all components are within the Roled infrastructure, excluding the client, which is your own application or service accessing Roled’s protected resources. Roled acts as an authorization server and resource server at the same time, providing the user role and permissions information defined in your projects.

Here is how it works:

    sequenceDiagram
    autonumber
    participant Y as Client (Business App)
    box rgb(255, 245, 173) Roled
    participant A as Authorization Server (Roled Auth)
    participant U as Resource Owner (User)
    participant R as Resource Server (Roled API)
    end

    Y->>U: Request login via Roled

    U->>A: Authenticate
    A-->>Y: Redirect with auth code

    Y->>A: Exchange auth code for tokens
    A-->>Y: access_token, refresh_token

    Y->>R: Call protected endpoint
    R->>R: Validate access_token
    R-->>Y: Return resource data
  

How Roled Uses OAuth 2.0

Roled implements two OAuth 2.0 grant types:

Grant TypeUsed ByPurpose
Authorization CodeHuman usersBrowser-based login flow
Client CredentialsMachine clientsServer-to-server authentication

Roled deliberately does not implement the Implicit flow or Resource Owner Password Credentials flow, as these are considered insecure by modern OAuth 2.0 best practices in RFC 9700 document section 2.1.2 ↗ and section 2.4 ↗.

Authorization Code Flow (with PKCE)

This flow is used when a user (a human) logs in through a browser. Roled implements it with PKCE (Proof Key for Code Exchange) for added security.

PKCE prevents authorization code interception attacks by requiring the client to prove it initiated the flow.

    sequenceDiagram
    autonumber
    participant U as User
    participant Y as Your App
    participant R as Roled

    U->>Y: Request login
    Y->>Y: Generate code_verifier (random string)
    Y->>Y: Generate code_challenge = SHA256(code_verifier)
    Y->>R: GET /authorize?<br/>client_id=...&<br/>redirect_uri=...&<br/>response_type=code&<br/>code_challenge=...&<br/>code_challenge_method=S256
    R-->>U: Display login page
    U->>R: Submit email + password
    R-->>Y: Redirect to redirect_uri?code=AUTH_CODE&...
    Y->>R: POST /api/v1/tokens<br/>grant_type=authorization_code&<br/>code=AUTH_CODE&<br/>code_verifier=...
    R->>R: Verify code + code_verifier
    R-->>Y: access_token + refresh_token
    Y-->>U: Logged in
  

Explanation:

  1. User opens a login page in your app, your app generates a code_verifier (random string) and code_challenge (SHA256 hash of code_verifier)
  2. Your app redirects the user to Roled’s authorization endpoint with:
    • client_id: Your project’s client ID
    • redirect_uri: Where to send the user after login (must be registered in the project)
    • response_type: Always code
    • code_challenge: The generated code challenge, base64url-encoded
    • code_challenge_method: Always S256 (plain is not supported)
    • state: Optional random string to prevent CSRF attacks (recommended)
  3. Roled displays the login page
  4. User submits their email and password
  5. Roled redirects the user back to your redirect_uri with an authorization code
  6. Your app exchanges the authorization code for an access token by sending a POST request to Roled’s token endpoint with:
    • grant_type: authorization_code
    • client_id: Your project’s client ID
    • authorization_code: The code received in the previous step
    • redirect_uri: The same redirect URI used in step 4
    • code_verifier: The original code verifier generated in step 2
  7. Roled verifies the code and code verifier, then returns:
    • access_token: The access token for accessing protected resources
    • refresh_token: The refresh token for getting new access tokens
  8. The user is now logged in and can access protected resources

Exchange the code for an access token:

curl --request POST \
  --url https://auth.roled.id/api/v1/tokens \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'authorization_code=6qxJpdxpyuAoSpfzkEbJUpJvBoncYM3Cnxfmj4WznZty7...' \
  --data-urlencode 'client_id=2JRYkzSeBV89itqcU9mraF' \
  --data-urlencode 'code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk...' \
  --data-urlencode 'redirect_uri=https://example.com/auth/callback' \
  --data-urlencode 'state=e5384378-26b2-45ae-b6a8-3a569a4bff7d'

Client Credentials Flow

This flow is used when a machine (a backend service or script) needs to authenticate. There is no 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)
  
curl --request POST \
  --url https://auth.roled.id/api/v1/tokens \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'Authorization: Basic MkpVjd5QzdnV0V1enU4QlRFWG9ZNTpzZWNfQmFja...' \
  --data-urlencode 'grant_type=client_credentials'

Client tokens do not include a refresh token. When a client token expires, the client simply re-authenticates.

Refresh Token Flow

For user sessions (Authorization Code Flow), Roled also supports the refresh token grant. This allows your application to get a new access token when the current one expires, without forcing the user to log in again.

curl --request POST \
  --url https://auth.roled.id/api/v1/tokens \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode 'client_id=2JRYkzSeBV89itqcU9mraF' \
  --data-urlencode 'refresh_token=M8MmHrhqzcBgUwCQ5enp4wTuRVBgi2txChS44Q3FYJGRgzX...'

OAuth Scopes

In traditional OAuth 2.0 setups, applications request specific scopes during authentication to specify required permissions (e.g., read:users, write:posts).

Roled takes a streamlined approach: user and client permissions are deliberately managed and assigned by project administrators rather than requested dynamically by applications.

Instead of requiring applications to request individual scopes at login, Roled automatically evaluates access based on the roles and permissions assigned to the user or client. Project administrators define exactly who can perform which actions, while applications simply authenticate and let Roled enforce access control.

This has several advantages:

  • Simpler for developers — no need to understand or declare scopes.
  • Centrally managed — administrators change permissions without touching application code.
  • Consistent model — the same authorization logic applies to both users and machine clients.
  • Instant effect — permission changes take effect immediately without requiring token reissuance.

The Authorize Endpoint

The OAuth 2.0 authorization endpoint for Roled is:

GET https://auth.roled.id/authorize

Required query parameters:

ParameterValue
client_idYour client’s ID
redirect_uriA registered redirect URI
response_typecode
code_challengeSHA256 of code_verifier, base64url-encoded
code_challenge_methodS256
state(optional) CSRF protection value

Key Points

  • Roled uses Authorization Code + PKCE for users and Client Credentials for machines.
  • PKCE (code_challenge_method=S256) is required — plain is not supported.
  • Roled does not use OAuth scopes — permissions are managed by project administrators.
  • The Implicit flow and ROPC are intentionally not supported.
  • Every token is issued against a specific project (the aud claim).