OAuth 2.0 Authentication Flow

Version: 1.0.0
Last Updated: 18-11-2025
Status: Production Ready


Table of Contents


Overview

ChainGuard provides a full OAuth 2.0 authorization server that enables third-party applications to authenticate users and access user data with explicit consent. This document describes the complete OAuth 2.0 authorization code flow, including authentication, 2FA, scope management, and token handling.


OAuth 2.0 Provider Capabilities

ChainGuard Backend Server acts as a full OAuth 2.0 authorization server with the following capabilities:

  • Authorization Code Flow: Standard OAuth 2.0 authorization code flow
  • Token Refresh: Long-lived refresh tokens for token renewal
  • Scope-Based Access Control: Fine-grained permission system
  • Client Authentication: client_id + client_secret authentication
  • Userinfo Endpoint: Standard OAuth userinfo endpoint
  • PKCE Support: (Planned) Code verifier/challenge for enhanced security
  • State Parameter: CSRF protection

Supported Scopes

ChainGuard supports the following OAuth scopes:

ScopeDescriptionData Returned
profileUser profile informationName, email, user ID
emailEmail addressEmail address
walletsLinked wallet addressesArray of wallet addresses
kycKYC verification statusKYC status, verification level (if applicable)

Scope Management:

  • Users approve scopes during OAuth consent screen
  • Users can revoke scopes at any time via OAuth Portal
  • Clients can only access data within approved scopes
  • Scope changes require user re-consent

OAuth Client Registration

Client Registration Process

Clients are registered in the ChainGuard system with:

  • client_id: Unique identifier for the application
  • client_secret: Secret key for server-to-server authentication
  • redirect_uris: Allowed callback URLs (whitelist-based)
  • scopes: Available scopes the client can request
  • Application Name: Display name shown to users
  • Application Description: Description shown on consent screen

Security Requirements

  • Client Secret: Must be kept server-side only, never exposed to frontend
  • Redirect URI Validation: Only registered redirect URIs are accepted
  • HTTPS Required: All redirect URIs must use HTTPS in production
  • State Parameter: Required for CSRF protection

Complete OAuth Flow

OAuth 2.0 Authorization Code Flow

Step-by-Step Flow

Step 1: User Initiates Login

Client Frontend (CL-FE)
  ↓
User clicks "Login with ChainGuard"
  ↓
Redirect to ChainGuard OAuth Portal

URL Format:

https://module.chain-fi.io/oauth/authorize?
  client_id={CLIENT_ID}
  &redirect_uri={REDIRECT_URI}
  &response_type=code
  &scope={SCOPES}
  &state={RANDOM_STATE}

Step 2: User Authentication

ChainGuard OAuth Portal
  ↓
1. User enters email/password
2. Backend validates credentials
3. User completes 2FA (wallet-based signature via Mobile App)
4. Session established with JWT tokens

Authentication Methods:

  • Email/password authentication
  • Wallet-based 2FA (EIP-712 signature)
  • Session management via HttpOnly cookies

Step 3: OAuth Consent Screen

ChainGuard OAuth Portal
  ↓
1. Display consent screen with:
   - Application name and description
   - Requested scopes
   - Data that will be shared
2. User reviews and approves/denies
3. User can modify scope selection (if allowed)

Consent Screen Features:

  • Clear scope descriptions
  • Data sharing transparency
  • User control over permissions
  • Revocation capabilities

Step 4: Authorization Code Issuance

ChainGuard Backend Server
  ↓
1. Validate user consent
2. Generate authorization code
3. Store code with expiration (10 minutes)
4. Associate code with client_id and scopes
  ↓
ChainGuard OAuth Portal
  ↓
Redirect to client redirect_uri with:
  - code={AUTHORIZATION_CODE}
  - state={ORIGINAL_STATE}

Authorization Code Properties:

  • Single-use only
  • 10-minute expiration
  • Tied to specific client_id and redirect_uri
  • Associated with approved scopes

Step 5: Token Exchange

Client Backend (CL-BE)
  ↓
POST to ChainGuard Backend:
  /oauth/token
  {
    grant_type: "authorization_code",
    code: {AUTHORIZATION_CODE},
    redirect_uri: {REDIRECT_URI},
    client_id: {CLIENT_ID},
    client_secret: {CLIENT_SECRET}
  }
  ↓
ChainGuard Backend Server
  ↓
1. Validate authorization code
2. Verify client_id and client_secret
3. Check redirect_uri matches
4. Generate access token and refresh token
5. Return tokens to client backend

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "def50200a1b2c3d4e5f6...",
  "scope": "profile email wallets"
}

Step 6: Token Storage

Client Backend (CL-BE)
  ↓
1. Store access_token and refresh_token (server-side only)
2. Create client session cookie for user
3. Never expose tokens to frontend

Token Storage Requirements:

  • Server-side storage only
  • Secure storage (encrypted at rest)
  • Never in browser localStorage or sessionStorage
  • Never sent to client frontend

Step 7: User Data Retrieval

Client Frontend (CL-FE)
  ↓
Request user profile
  ↓
Client Backend (CL-BE)
  ↓
GET /oauth/userinfo
  Authorization: Bearer {access_token}
  ↓
ChainGuard Backend Server
  ↓
1. Validate access token
2. Check token expiration
3. Verify scopes
4. Return user data within approved scopes

Userinfo Response:

{
  "sub": "user_id",
  "name": "John Doe",
  "email": "user@example.com",
  "wallets": [
    "0x1234...5678",
    "0xabcd...efgh"
  ]
}

Token Refresh Flow

Token Refresh Sequence

When to Refresh

Access tokens are short-lived (typically 1 hour). When a token expires:

Client Backend (CL-BE)
  ↓
1. Detect expired access token (401 response)
2. Use refresh_token to get new access token
  ↓
POST /oauth/token
  {
    grant_type: "refresh_token",
    refresh_token: {REFRESH_TOKEN},
    client_id: {CLIENT_ID},
    client_secret: {CLIENT_SECRET}
  }
  ↓
ChainGuard Backend Server
  ↓
1. Validate refresh token
2. Verify client credentials
3. Issue new access token
4. Optionally issue new refresh token

Refresh Token Properties:

  • Long-lived (typically 30 days)
  • Revocable by user
  • Server-side only
  • Single-use (if rotation enabled)

Token Responsibility Matrix

Token TypeHolderStorage LocationExposure Risk
Authorization CodeClient Backend (temporary)Server memoryLow (10-min expiration)
Access TokenClient Backend onlyServer-side storageNone (never sent to frontend)
Refresh TokenClient Backend onlyServer-side storageNone (never sent to frontend)
client_idClient BackendServer-side storageLow (public identifier)
client_secretClient Backend onlyServer-side storageHigh (must be protected)
Client Session CookieClient Backend → FrontendHttpOnly cookieMinimal (client-controlled)

Key Principles:

  • Tokens never exposed to frontend environments
  • Server-to-server exchanges only
  • HttpOnly cookies prevent XSS attacks
  • Refresh tokens stored server-side only

Security Features

CSRF Protection

State Parameter:

  • Required in authorization request
  • Random, unguessable value
  • Validated on callback
  • Prevents cross-site request forgery

Client Secret Protection

Security Requirements:

  • Never exposed to frontend
  • Server-side storage only
  • Encrypted at rest
  • Rotated periodically
  • Never logged or transmitted insecurely

Token Security

Access Token:

  • Short-lived (1 hour default)
  • Bearer token format
  • HTTPS only transmission
  • Scope-limited access

Refresh Token:

  • Long-lived (30 days default)
  • Server-side only
  • Revocable by user
  • Single-use (if rotation enabled)

Scope Validation

Scope Enforcement:

  • Tokens contain approved scopes
  • API endpoints validate scopes
  • Users can revoke scopes anytime
  • Scope changes require re-consent

Error Handling

Common Error Scenarios

Invalid Authorization Code:

  • Code expired (10 minutes)
  • Code already used
  • Code doesn't match client_id
  • Response: 400 Bad Request

Invalid Client Credentials:

  • Invalid client_id
  • Invalid client_secret
  • Mismatched redirect_uri
  • Response: 401 Unauthorized

Invalid Token:

  • Token expired
  • Token revoked
  • Invalid token format
  • Response: 401 Unauthorized

Insufficient Scope:

  • Token doesn't have required scope
  • Scope revoked by user
  • Response: 403 Forbidden

Integration Examples

Client Backend Integration

Token Exchange (Node.js/Express):

const response = await fetch('https://api.chain-fi.io/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authorizationCode,
    redirect_uri: redirectUri,
    client_id: clientId,
    client_secret: clientSecret,
  }),
});

const tokens = await response.json();
// Store tokens server-side

User Data Retrieval:

const userInfo = await fetch('https://api.chain-fi.io/oauth/userinfo', {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
  },
});

const userData = await userInfo.json();

Token Refresh:

const response = await fetch('https://api.chain-fi.io/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    grant_type: 'refresh_token',
    refresh_token: refreshToken,
    client_id: clientId,
    client_secret: clientSecret,
  }),
});

const newTokens = await response.json();

User Consent Management

Consent Screen

Displayed Information:

  • Application name and description
  • Requested scopes with descriptions
  • Data that will be shared
  • User's ability to modify scopes

User Actions:

  • Approve all requested scopes
  • Approve selected scopes only
  • Deny access
  • Review application details

Scope Revocation

User Control:

  • Users can revoke scopes at any time via OAuth Portal
  • Revocation immediately invalidates related tokens
  • Clients receive 401 Unauthorized on next API call
  • Clients must re-authenticate to regain access

Revocation Process:

  1. User accesses OAuth Portal
  2. Navigates to Application Access Control
  3. Disables specific scopes
  4. Backend invalidates related tokens
  5. Client receives error on next API call

Best Practices

For Client Developers

Security:

  • Never expose client_secret to frontend
  • Store tokens server-side only
  • Use HTTPS for all communications
  • Validate state parameter
  • Implement token refresh logic

User Experience:

  • Request only necessary scopes
  • Provide clear application description
  • Handle errors gracefully
  • Implement proper logout flow

Token Management:

  • Monitor token expiration
  • Implement automatic token refresh
  • Handle token revocation
  • Store tokens securely

For ChainGuard Users

Privacy:

  • Review requested scopes carefully
  • Only approve necessary permissions
  • Revoke access when no longer needed
  • Monitor application access in portal

Security:

  • Use strong passwords
  • Enable 2FA
  • Review activity history regularly
  • Report suspicious applications

Related Documentation


Document Version: 1.0.0
Last Updated: 18-11-2025
Status: Production Ready

ChainGuard OAuth 2.0 Flow | Technical Documentation | ChainGuard