> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth2 Flow & Token Management

> Automated OAuth2 token management with intelligent refresh, rotation, and AES-256 encrypted storage. Never worry about expired tokens again.

# OAuth2 Flow & Token Management

Automate OAuth2 token management with KnoxCall. Never manually refresh tokens again - KnoxCall handles OAuth2 authentication, token refresh, and rotation automatically.

## The OAuth2 Token Problem

Without KnoxCall, managing OAuth2 tokens is painful:

```javascript theme={"dark"}
// Your code becomes a mess of token management
let accessToken = 'ya29.a0AfH6SMB...';
let refreshToken = '1//0gUc-sQZ...';
let expiresAt = Date.now() + 3600000;

async function makeAPICall() {
  // Check if token expired
  if (Date.now() >= expiresAt) {
    // Refresh the token
    const response = await fetch('https://oauth2.googleapis.com/token', {
      method: 'POST',
      body: JSON.stringify({
        client_id: 'YOUR_CLIENT_ID',
        client_secret: 'YOUR_CLIENT_SECRET',
        refresh_token: refreshToken,
        grant_type: 'refresh_token',
      }),
    });

    const data = await response.json();
    accessToken = data.access_token;
    refreshToken = data.refresh_token || refreshToken;
    expiresAt = Date.now() + (data.expires_in * 1000);

    // Save to database
    await saveTokensToDatabase({accessToken, refreshToken, expiresAt});
  }

  // Finally make the actual API call
  return await fetch('https://www.googleapis.com/drive/v3/files', {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
    },
  });
}
```

**Problems:**

* 100+ lines of token management code
* Must securely store tokens
* Handle refresh failures
* Deal with token rotation
* Race conditions in concurrent requests

## With KnoxCall

```javascript theme={"dark"}
// Your code is clean and simple
const response = await fetch('https://a1b2c3d4.acme.knoxcall.com/drive/v3/files', {
  headers: {
    'x-knoxcall-route': 'google-drive',
    'x-knoxcall-key': process.env.KNOXCALL_API_KEY,
  },
});
```

**KnoxCall automatically:**

* ✅ Refreshes tokens before expiry
* ✅ Handles token rotation
* ✅ Stores tokens encrypted (AES-256)
* ✅ Manages concurrent requests
* ✅ Retries on auth failures
* ✅ Zero downtime, zero code

## OAuth Clients page

The **OAuth Clients** page (Settings → Security → OAuth Clients) is the unified surface for managing OAuth 2.1 in KnoxCall. It has three tabs:

| Tab                   | What it shows                                                                            |
| --------------------- | ---------------------------------------------------------------------------------------- |
| **Clients**           | Your registered OAuth2 client applications — client ID, allowed scopes, grant types      |
| **Workload Identity** | Workload Identity Federation bindings — DPoP binding status, last-used timestamp         |
| **Active Tokens**     | Currently live access tokens across all clients — expiry, last-used, DPoP binding status |

<Note>
  There are two distinct OAuth flows in KnoxCall:

  1. **OAuth2 Secrets** (Secrets page) — store provider tokens (Google, Stripe, etc.) that KnoxCall auto-refreshes and injects into route headers. Use these for outbound API calls through your routes.

  2. **OAuth Client Registrations** (OAuth Clients page) — register OAuth clients that grant access to the KnoxCall API itself. Use these for Workload Identity Federation bindings and programmatic API access with DPoP-bound tokens.
</Note>

Use the **Active Tokens** tab as your primary monitoring surface for live token state — you can see which tokens are DPoP-bound, when they expire, and when they were last used, without needing to set up an alert rule.

## Supported OAuth2 Providers

KnoxCall supports all OAuth2-compliant providers:

### Pre-Configured Providers

<CardGroup cols={2}>
  <Card title="Google" icon="google">
    * Google Drive
    * Gmail API
    * Google Calendar
    * Google Sheets
  </Card>

  <Card title="Microsoft" icon="microsoft">
    * Office 365
    * OneDrive
    * Outlook API
    * Microsoft Graph
  </Card>

  <Card title="Salesforce" icon="salesforce">
    * Salesforce API
    * Force.com
  </Card>

  <Card title="Slack" icon="slack">
    * Slack API
    * Slack Webhooks
  </Card>
</CardGroup>

### Custom OAuth2 Providers

Any OAuth2-compliant API:

* Stripe
* GitHub
* Shopify
* QuickBooks
* Custom APIs

## Setting Up OAuth2

### Step 1: Register Your Application

First, register your application with the OAuth2 provider:

<Tabs>
  <Tab title="Google">
    1. Go to [Google Cloud Console](https://console.cloud.google.com/)
    2. Create a new project or select existing
    3. Enable the API you want to use (Drive, Gmail, etc.)
    4. Go to **Credentials** → **Create Credentials** → **OAuth 2.0 Client ID**
    5. Application type: **Web application**
    6. Authorized redirect URIs: `https://oauth.knoxcall.com/callback`
    7. Save **Client ID** and **Client Secret**
  </Tab>

  <Tab title="Microsoft">
    1. Go to [Azure Portal](https://portal.azure.com/)
    2. Navigate to **Azure Active Directory** → **App registrations**
    3. Click **New registration**
    4. Name: Your app name
    5. Redirect URI: `https://oauth.knoxcall.com/callback`
    6. Create and save **Application (client) ID**
    7. Go to **Certificates & secrets** → Create client secret
    8. Save the secret value
  </Tab>

  <Tab title="Custom">
    For custom OAuth2 providers, you need:

    * Authorization URL (e.g., `https://example.com/oauth/authorize`)
    * Token URL (e.g., `https://example.com/oauth/token`)
    * Client ID
    * Client Secret
    * Scopes (permissions needed)
  </Tab>
</Tabs>

### Step 2: Create OAuth2 Secret in KnoxCall

1. Navigate to **Secrets** → **Add Secret**
2. Configure:

**Name:**

```text theme={"dark"}
google-drive-oauth
```

**Type:**

```text theme={"dark"}
OAuth2
```

**Provider:**
Select from dropdown or choose "Custom"

**Client ID:**

```text theme={"dark"}
123456789-abc.apps.googleusercontent.com
```

**Client Secret:**

```text theme={"dark"}
GOCSPX-abc123def456
```

**Scopes:**

```text theme={"dark"}
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive.file
```

**Redirect URI:**

```text theme={"dark"}
https://oauth.knoxcall.com/callback
```

3. Click **Save**

### Step 3: Complete OAuth2 Authorization

After creating the secret, you need to authorize it:

1. Click **Authorize** button next to your OAuth2 secret
2. You'll be redirected to the provider's login page
3. Log in and grant permissions
4. You'll be redirected back to KnoxCall
5. Tokens are automatically saved and encrypted

✅ **Done!** KnoxCall now has your OAuth2 tokens.

### Step 4: Use in Routes

1. Create or edit a route
2. Target Base URL: `https://www.googleapis.com` (for Google APIs)
3. In **Header Injection**, add:

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:google-drive-oauth}}"
}
```

4. Save route

Now all requests to this route will include the OAuth2 token automatically!

## How Token Refresh Works

KnoxCall uses **intelligent token refresh** that adapts to each provider's token lifetime:

### Dynamic Refresh Threshold

Tokens are automatically refreshed when **25% of their lifetime remains** (or 5 minutes before expiry, whichever is greater):

```text theme={"dark"}
Short-lived token (20 min):
    ↓
Refreshes at 15 min (25% = 5 min remaining) ✅
    ↓
Long-lived token (24 hours):
    ↓
Refreshes at 18 hours (25% = 6 hours remaining) ✅
    ↓
Token without expiry info:
    ↓
Refreshes 5 minutes before expiry (fallback) ✅
```

**Example: 1-hour token lifecycle**

```text theme={"dark"}
Token issued: 1:00 PM (expires at 2:00 PM)
    ↓
Request at 1:40 PM ✅ Uses current token (40 min remaining = 67%)
    ↓
Request at 1:46 PM 🔄 Refreshes token (14 min remaining = 23%)
    ↓
New token issued: 1:46 PM (expires at 2:46 PM)
    ↓
Old token still valid until 2:00 PM (overlap period)
    ↓
Request succeeds with new token ✅
```

**Why 75% threshold?**

* **Short tokens (\< 20 min)**: Prevents last-second refresh failures
* **Long tokens (> 1 hour)**: Avoids unnecessary early refreshes
* **Variable tokens**: Adapts to each provider's expiry time
* **Network delays**: Buffer time for slow refresh responses

**Benefits:**

* Adapts to any token lifetime (5 min to 90 days)
* Zero downtime during refresh
* No race conditions
* Automatic retry on failure
* Graceful fallback if `expires_in` missing
* Token rotation handled transparently

## Token Storage & Security

OAuth2 tokens are stored with military-grade security:

### Encryption

* **Algorithm**: AES-256-GCM
* **Key derivation**: PBKDF2 with 100,000 iterations
* **Master key**: Stored in AWS KMS (or your key management)

### Access Control

Tokens are:

* ❌ Never exposed in logs
* ❌ Never returned via API
* ❌ Never visible in dashboard
* ✅ Only decrypted at request time
* ✅ Tenant-isolated
* ✅ RBAC-protected

### Token Versioning

Every token refresh creates a new version:

```text theme={"dark"}
Version 1: Initial authorization
Version 2: First refresh (24 hours later)
Version 3: Second refresh (48 hours later)
...
```

You can:

* View token refresh history
* Roll back to previous version (if needed)
* See when tokens were last refreshed

## Handling Token Revocation

If a user revokes access or tokens expire:

### Automatic Detection

KnoxCall detects revoked tokens:

```text theme={"dark"}
Request to API → 401 Unauthorized
    ↓
KnoxCall attempts refresh → 400 Invalid Grant
    ↓
Token marked as REVOKED
    ↓
Alert sent to admins
    ↓
Requests return: "OAuth token revoked, please reauthorize"
```

### Reauthorization

To reauthorize:

1. Go to **Secrets** → Select OAuth2 secret
2. Status shows: **REVOKED**
3. Click **Reauthorize**
4. Complete OAuth2 flow again
5. New tokens saved

## Multi-User OAuth2

For multi-user applications, each user needs their own tokens:

### Approach 1: Per-User Secrets

Create a separate secret for each user:

```text theme={"dark"}
Secret: user-123-google-oauth
Secret: user-456-google-oauth
Secret: user-789-google-oauth
```

Use client IDs to route to the right secret:

```bash theme={"dark"}
curl https://a1b2c3d4.acme.knoxcall.com/drive/files \
  -H "x-knoxcall-route: google-drive" \
  -H "x-knoxcall-client-id: user-123" \
  -H "x-knoxcall-key: tk_abc..."
```

### Approach 2: Dynamic Secret Selection

Use KnoxCall's dynamic secret selection:

```json theme={"dark"}
{
  "Authorization": "Bearer {{secret:oauth-{user_id}}}"
}
```

KnoxCall will replace `{user_id}` with the value from request context.

## OAuth2 with Refresh Token Rotation

Some providers (like Google) rotate refresh tokens:

```text theme={"dark"}
Initial Authorization:
  access_token: ya29.a0...
  refresh_token: 1//0gU...
  expires_in: 3600

First Refresh:
  access_token: ya29.a0... (new)
  refresh_token: 1//0hV... (new, old one invalidated!)
  expires_in: 3600
```

**KnoxCall handles this automatically:**

* Saves new refresh token
* Invalidates old refresh token
* No manual intervention needed

## Scopes & Permissions

Different scopes for different use cases:

### Google Drive (Read-Only)

```text theme={"dark"}
https://www.googleapis.com/auth/drive.readonly
```

### Google Drive (Full Access)

```text theme={"dark"}
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
```

### Gmail (Send Email)

```text theme={"dark"}
https://www.googleapis.com/auth/gmail.send
```

### Microsoft Graph (Calendar)

```text theme={"dark"}
Calendars.Read
Calendars.ReadWrite
```

<Tip>
  Request minimum scopes needed. Users are more likely to grant limited permissions.
</Tip>

## Testing OAuth2 Routes

After setting up OAuth2:

```bash theme={"dark"}
curl https://a1b2c3d4.acme.knoxcall.com/drive/v3/files \
  -H "x-knoxcall-route: google-drive" \
  -H "x-knoxcall-key: tk_abc123..."
```

You should receive a successful response with your Google Drive files.

## Monitoring OAuth2 Tokens

### Token Health Dashboard

Monitor your OAuth2 tokens:

* **Last refreshed**: When was the token last refreshed
* **Expires at**: When will the token expire
* **Refresh attempts**: How many times has refresh been attempted
* **Status**: Active, Expiring Soon, Revoked, Failed

### Alerts

Set up alerts for OAuth2 issues:

1. Navigate to **Alerts** → **Add Alert**
2. Type: **OAuth2 Token Issues**
3. Configure:

```text theme={"dark"}
Alert when:
- Token refresh fails 3 times
- Token expires in < 24 hours without refresh
- Token is revoked by user

Notification channels:
- Email to: admin@company.com
- Slack channel: #oauth-alerts
```

## Best Practices

### 1. Use Separate Secrets Per Environment

```text theme={"dark"}
Production:
  Secret: google-oauth-prod

Staging:
  Secret: google-oauth-staging

Development:
  Secret: google-oauth-dev
```

### 2. Request Minimal Scopes

Only request permissions you actually need:

❌ **Bad:**

```text theme={"dark"}
https://www.googleapis.com/auth/drive (full access)
```

✅ **Good:**

```text theme={"dark"}
https://www.googleapis.com/auth/drive.readonly
```

### 3. Monitor Token Health

Set up monitoring:

* Alert on refresh failures
* Alert on token expiration
* Monitor refresh success rate

### 4. Handle Revocation Gracefully

When tokens are revoked:

* Show clear error message to users
* Provide reauthorization link
* Don't expose technical details

### 5. Test Token Refresh

Manually trigger refresh to test:

1. Go to secret details
2. Click **Force Refresh**
3. Check logs for success

## Troubleshooting

### "Invalid refresh token" errors

**Causes:**

* User revoked access
* Refresh token expired (rare)
* OAuth app was deleted

**Fix:**

* Reauthorize the secret
* Check OAuth app is still active
* Verify redirect URI matches

### Token refresh fails silently

**Check:**

* Alert configuration
* Error logs in KnoxCall
* OAuth provider's API status

### Concurrent request issues

**Solution:**
KnoxCall handles this automatically with request queuing. If you see issues, contact support.

### Wrong scope errors

```http theme={"dark"}
HTTP/1.1 403 Forbidden
{
  "error": "insufficient_scope"
}
```

**Fix:**

1. Edit OAuth2 secret
2. Add required scopes
3. Reauthorize

## Next Steps

<CardGroup cols={2}>
  <Card title="Secret Management" icon="key" href="/essentials/secrets/secrets-overview">
    Learn about managing secrets
  </Card>

  <Card title="Request Signing" icon="file-signature" href="/security/request-signing">
    Add signature verification
  </Card>

  <Card title="Advanced Configuration" icon="sliders" href="/advanced/advanced-route-configuration">
    Advanced route configuration
  </Card>

  <Card title="Monitoring" icon="chart-line" href="/monitoring/analytics">
    Monitor API usage and errors
  </Card>
</CardGroup>

***

<CardGroup cols={2}>
  <Card title="📊 Statistics" icon="chart-line">
    * **Level**: intermediate
    * **Time**: 20 minutes
  </Card>

  <Card title="🏷️ Tags" icon="tags">
    `oauth2`, `authentication`, `tokens`, `google`, `microsoft`
  </Card>
</CardGroup>
