Skip to content

OAuth 2.0

Authrim implements OAuth 2.0 with modern security best practices, including support for OAuth 2.1 recommendations.

The recommended grant for all clients:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=authorization_code_value
&redirect_uri=https://app.example.com/callback
&client_id=client_id
&code_verifier=pkce_verifier

Exchange a refresh token for new tokens:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
grant_type=refresh_token
&refresh_token=refresh_token_value

For machine-to-machine authentication:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
grant_type=client_credentials
&scope=api.read api.write

For input-constrained devices (see Device Flow):

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:device_code
&device_code=device_code_value
&client_id=client_id

For identity federation with trusted assertion issuers:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=jwt_assertion
&client_id=client_id

Exchange an existing token for a downstream token when the tenant profile enables token exchange:

POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=eyJhbGciOiJSUzI1NiJ9...
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&requested_token_type=urn:ietf:params:oauth:token-type:access_token
EndpointMethodDescription
/.well-known/oauth-authorization-serverGETOAuth authorization server metadata
/.well-known/openid-configurationGETOIDC provider metadata
/authorizeGET/POSTAuthorization endpoint
/tokenPOSTToken endpoint
/revokePOSTToken revocation
/introspectPOSTToken introspection
/parPOSTPushed Authorization Requests
/device_authorizationPOSTDevice authorization endpoint when async flows are enabled

JWT-formatted access tokens containing:

{
"iss": "https://auth.example.com",
"sub": "user-id-123",
"aud": "https://api.example.com",
"exp": 1699880000,
"iat": 1699876400,
"jti": "unique-token-id",
"scope": "read write",
"client_id": "my_client_id"
}

Long-lived tokens for obtaining new access tokens:

  • Rotation: Refresh tokens are rotated on each use
  • Expiration: Configurable lifetime (default: 30 days)
  • Revocation: Can be revoked via /revoke endpoint

HTTP Basic authentication with client credentials:

Authorization: Basic <base64(client_id:client_secret)>

Client credentials in request body:

POST /token
Content-Type: application/x-www-form-urlencoded
client_id=my_client_id
&client_secret=my_client_secret
&grant_type=...

JWT client assertion signed with client’s private key:

POST /token
Content-Type: application/x-www-form-urlencoded
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiJ9...
&grant_type=...

JWT client assertion signed with the client’s shared secret:

POST /token
Content-Type: application/x-www-form-urlencoded
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJIUzI1NiJ9...
&grant_type=...

For public clients (must use PKCE):

POST /token
Content-Type: application/x-www-form-urlencoded
client_id=public_client_id
&grant_type=authorization_code
&code=...
&code_verifier=...

Check if a token is active and get its metadata:

POST /introspect HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
token=access_token_value
&token_type_hint=access_token

Response:

{
"active": true,
"scope": "read write",
"client_id": "my_client_id",
"username": "john@example.com",
"token_type": "Bearer",
"exp": 1699880000,
"iat": 1699876400,
"sub": "user-id-123",
"aud": "https://api.example.com",
"iss": "https://auth.example.com"
}

Revoke an access token or refresh token:

POST /revoke HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
token=token_value
&token_type_hint=refresh_token

Response: 200 OK (always, per RFC 7009)

Authorization code in query string:

https://app.example.com/callback?code=abc123&state=xyz

Token in URL fragment:

https://app.example.com/callback#access_token=abc123&token_type=Bearer

Authorization response submitted via POST:

<form method="post" action="https://app.example.com/callback">
<input type="hidden" name="code" value="abc123">
<input type="hidden" name="state" value="xyz">
</form>

JWT-secured authorization response modes are also advertised for clients that use JARM:

  • query.jwt
  • fragment.jwt
  • form_post.jwt
  • jwt

Standard OAuth 2.0 error format:

{
"error": "invalid_request",
"error_description": "The request is missing a required parameter"
}

Error Codes:

ErrorDescription
invalid_requestMissing or invalid parameter
unauthorized_clientClient not authorized for grant type
access_deniedUser denied authorization
unsupported_response_typeResponse type not supported
invalid_scopeRequested scope is invalid
server_errorServer encountered an error
temporarily_unavailableServer is temporarily unavailable
invalid_clientClient authentication failed
invalid_grantGrant is invalid or expired
unsupported_grant_typeGrant type not supported

Authrim follows OAuth 2.1 recommendations:

  • PKCE required for authorization code flow
  • Refresh token rotation enabled by default
  • No implicit grant for new applications
  • No password grant (removed)
  • Exact redirect URI matching

Discovery metadata can still advertise implicit and hybrid response types for certification and legacy compatibility. New browser and native applications should use authorization code with PKCE.

  1. Use PKCE - Required for all authorization code flows
  2. Use state parameter - Prevent CSRF attacks
  3. Validate redirect URIs - Exact matching only
  4. Use short-lived access tokens - 1 hour or less
  5. Rotate refresh tokens - One-time use
  6. Implement token binding - Consider DPoP for high-security