# Debug and Troubleshooting

This comprehensive guide helps you debug and troubleshoot Oten IDP integration issues systematically.

## 🔍 Debugging Methodology

### Step 1: Identify the Problem Area

**OAuth Flow Stages:**

1. **JAR Creation** - Creating and signing JWT authorization request
2. **Authorization** - Redirecting user to Oten IDP
3. **Callback** - Handling authorization response
4. **Token Exchange** - Converting authorization code to tokens
5. **API Calls** - Using access tokens for API requests

### Step 2: Gather Information

Before troubleshooting, collect:

* Error messages (exact text and error codes)
* HTTP status codes
* Request/response headers
* Timestamps
* Environment (development/production)
* Client configuration

### Step 3: Use Debugging Tools

## 🛠️ Debugging Tools

### 1. JAR Token Decoder

Use this to inspect your JAR tokens:

```javascript
// Decode JAR without verification (for debugging only)
function debugJAR(jarToken) {
  try {
    const decoded = jwt.decode(jarToken, { complete: true });

    console.log('=== JAR DEBUG INFO ===');
    console.log('Header:', JSON.stringify(decoded.header, null, 2));
    console.log('Payload:', JSON.stringify(decoded.payload, null, 2));

    // Check required claims
    const required = ['iss', 'aud', 'iat', 'exp', 'jti', 'client_id', 'redirect_uri', 'response_type'];
    const missing = required.filter(claim => !decoded.payload[claim]);

    if (missing.length > 0) {
      console.log('❌ Missing required claims:', missing);
    } else {
      console.log('✅ All required claims present');
    }

    // Check expiration
    const now = Math.floor(Date.now() / 1000);
    if (decoded.payload.exp < now) {
      console.log('❌ Token expired');
    } else {
      console.log('✅ Token not expired');
    }

    // Check audience
    if (decoded.payload.aud !== 'https://account.oten.com' &&
        decoded.payload.aud !== 'https://account.sbx.oten.dev') {
      console.log('❌ Invalid audience');
    } else {
      console.log('✅ Valid audience');
    }

  } catch (error) {
    console.log('❌ Failed to decode JAR:', error.message);
  }
}

// Usage
debugJAR(yourJARToken);
```

### 2. Environment Checker

Verify your environment configuration:

```javascript
function checkEnvironment() {
  console.log('=== ENVIRONMENT CHECK ===');

  const required = [
    'OTEN_CLIENT_ID',
    'OTEN_REDIRECT_URI'
  ];

  const optional = [
    'OTEN_CLIENT_SECRET',
    'OTEN_PRIVATE_KEY_PATH',
    'OTEN_KEY_ID',
    'OTEN_ENV'
  ];

  console.log('Required variables:');
  required.forEach(key => {
    const value = process.env[key];
    console.log(`  ${key}: ${value ? '✅ Set' : '❌ Missing'}`);
  });

  console.log('Optional variables:');
  optional.forEach(key => {
    const value = process.env[key];
    console.log(`  ${key}: ${value ? '✅ Set' : '⚠️ Not set'}`);
  });

  // Check redirect URI format
  const redirectUri = process.env.OTEN_REDIRECT_URI;
  if (redirectUri) {
    if (redirectUri.startsWith('https://') || redirectUri.startsWith('http://localhost')) {
      console.log('✅ Redirect URI format valid');
    } else {
      console.log('❌ Redirect URI must use HTTPS (or http://localhost for development)');
    }
  }
}
```

### 3. Quick Connectivity Test

Test basic connectivity to Oten IDP:

```bash
# Test basic connectivity
curl -I https://account.oten.com

# Test discovery endpoint
curl https://account.oten.com/.well-known/openid_configuration

# Test JWKS endpoint
curl https://account.oten.com/.well-known/jwks.json
```

## Step-by-Step Troubleshooting

### Problem: "Cannot connect to Oten IDP"

**Symptoms:**

* Network timeouts
* Connection refused errors
* DNS resolution failures

**Solutions:**

1. **Check network connectivity:**

```bash
# Test basic connectivity
ping account.oten.com

# Test HTTPS connectivity
curl -I https://account.oten.com
```

2. **Verify firewall settings:**

* Ensure outbound HTTPS (port 443) is allowed
* Check corporate firewall/proxy settings
* Verify no SSL/TLS inspection is interfering

3. **Check DNS resolution:**

```bash
nslookup account.oten.com
```

### Problem: "JAR signature verification failed"

**Symptoms:**

* Error code: `invalid_request_object`
* Authorization request rejected

**Solutions:**

1. **For HS256 issues:**

```javascript
// Verify client secret
console.log('Client secret length:', process.env.OTEN_CLIENT_SECRET?.length);

// Test JAR creation
const testPayload = { test: 'data', iat: Math.floor(Date.now() / 1000) };
try {
  const testJWT = jwt.sign(testPayload, process.env.OTEN_CLIENT_SECRET, { algorithm: 'HS256' });
  console.log('✅ JWT signing works');

  // Verify locally
  const verified = jwt.verify(testJWT, process.env.OTEN_CLIENT_SECRET, { algorithm: 'HS256' });
  console.log('✅ JWT verification works');
} catch (error) {
  console.log('❌ JWT signing/verification failed:', error.message);
}
```

2. **For EdDSA issues:**

```javascript
// Check private key format
const fs = require('fs');
try {
  const privateKey = fs.readFileSync(process.env.OTEN_PRIVATE_KEY_PATH, 'utf8');
  console.log('✅ Private key file readable');

  if (privateKey.includes('BEGIN PRIVATE KEY')) {
    console.log('✅ Private key format appears correct');
  } else {
    console.log('⚠️ Private key format may be incorrect');
  }
} catch (error) {
  console.log('❌ Cannot read private key file:', error.message);
}

// Verify Key ID is set
if (process.env.OTEN_KEY_ID) {
  console.log('✅ Key ID is set:', process.env.OTEN_KEY_ID);
} else {
  console.log('❌ Key ID is not set');
}
```

### Problem: "Token exchange fails"

**Symptoms:**

* Error code: `invalid_grant`
* Authorization code rejected

**Solutions:**

1. **Check authorization code:**

```javascript
app.get('/callback', (req, res) => {
  const { code, state, error } = req.query;

  console.log('Authorization code length:', code?.length);
  console.log('State matches:', state === storedState);

  if (!code) {
    console.log('❌ No authorization code received');
    return;
  }

  if (code.length < 10) {
    console.log('❌ Authorization code seems too short');
    return;
  }

  console.log('✅ Authorization code appears valid');
});
```

2. **Verify PKCE parameters:**

```javascript
// Ensure code_verifier matches code_challenge
const storedVerifier = session.codeVerifier;
const challengeFromVerifier = crypto
  .createHash('sha256')
  .update(storedVerifier)
  .digest('base64url');

console.log('Stored verifier:', storedVerifier);
console.log('Challenge from verifier:', challengeFromVerifier);
console.log('Original challenge:', session.codeChallenge);
console.log('Challenges match:', challengeFromVerifier === session.codeChallenge);
```

3. **Check redirect URI:**

```javascript
// Ensure redirect URI exactly matches registration
const configuredURI = process.env.OTEN_REDIRECT_URI;
const requestURI = req.get('host') + req.originalUrl.split('?')[0];

console.log('Configured redirect URI:', configuredURI);
console.log('Actual request URI:', requestURI);
console.log('URIs match:', configuredURI.includes(requestURI));
```

## Troubleshooting Checklist

### Before Contacting Support

Complete this checklist before reaching out for help:

**Environment Setup:**

* [ ] Client ID is correct and registered
* [ ] Redirect URI matches exactly (including protocol, domain, port, path)
* [ ] Environment variables are set correctly
* [ ] Network connectivity to Oten IDP is working

**JAR Implementation:**

* [ ] JAR contains all required JWT claims (iss, aud, iat, exp, jti)
* [ ] JAR contains all OAuth parameters (client\_id, redirect\_uri, response\_type, etc.)
* [ ] JAR is signed with correct algorithm (HS256 or EdDSA)
* [ ] JAR expiration is set appropriately (≤ 5 minutes)
* [ ] For EdDSA: Key ID matches registered public key

**OAuth Flow:**

* [ ] Authorization URL contains only client\_id and request parameters
* [ ] PKCE code\_verifier and code\_challenge are generated correctly
* [ ] State parameter is used and verified
* [ ] Authorization code is used only once
* [ ] Token exchange includes all required parameters

**Error Information Collected:**

* [ ] Exact error message and error code
* [ ] HTTP status code
* [ ] Request/response headers
* [ ] Timestamp of the error
* [ ] Steps to reproduce the issue

## 🆘 Getting Help

If you've completed the troubleshooting checklist and still need help:

### Contact Support

**Technical Support**: <support@oten.dev>

### Include This Information

When contacting support, please include:

1. **Environment details:**
   * Development or production
   * Programming language and version
   * Library versions used
2. **Error information:**
   * Complete error message
   * Error code and HTTP status
   * Timestamp of the error
3. **Configuration (sanitized):**
   * Client ID (safe to share)
   * Redirect URI
   * Scopes requested
   * JAR signing method used
4. **Code samples:**
   * JAR creation code (remove secrets)
   * Authorization URL generation
   * Token exchange implementation
5. **Debugging output:**
   * JAR token structure (decoded)
   * Network request/response logs
   * Environment check results

### What NOT to Share

**Never share these in support requests:**

* Client secrets
* Private keys
* Access tokens
* Refresh tokens
* User credentials

## 🔗 Related Documentation

* [Common Errors](broken://pages/ChQqcK8cqX9LLgyQtBJT) - Specific error codes and solutions
* [JAR Complete Implementation Guide](broken://pages/TTsI7h4QqrFoRyKuF1Di) - JAR implementation examples
* [API Reference](broken://pages/rBfeuN3JiwHAXoU2ybbc) - Complete API documentation
* [Configuration Reference](broken://pages/XsyPoCRDPUpz0vcP6KkD) - Endpoints and settings


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://oten.gitbook.io/identity-support/integration/prerequisites/support-and-troubleshoot/debug-and-troubleshooting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
