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

# Authentication

> Learn how to authenticate with the Aries API using OAuth2 and manage access tokens in JavaScript/TypeScript

## Overview

The Aries API uses **OAuth2 with Bearer tokens** (JWT format) for authentication. All API requests require a valid access token in the Authorization header.

## Authentication Flow

### 1. OAuth2 Client Credentials

First, obtain your OAuth2 credentials from the Aries platform:

* **Client ID**: Your application identifier
* **Client Secret**: Your application secret key

### 2. Initialize the SDK

```javascript theme={null}
import { AriesClient } from '@aries-exchange/sdk';

const client = new AriesClient({
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret'
});

// The SDK handles token management automatically
```

## OAuth2 Authorization Flow

### Authorization Code Flow

For applications that need user authorization:

```javascript theme={null}
import { AriesClient } from '@aries-exchange/sdk';

const client = new AriesClient({
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret'
});

// Step 1: Get authorization URL
const authUrl = await client.oauth2.getAuthorizationUrl({
  redirectUri: 'https://yourapp.com/callback',
  scope: ['read', 'trade'],
  state: 'random_state_string'
});
console.log(`Redirect user to: ${authUrl}`);

// Step 2: Exchange code for tokens
const authorizationCode = 'code_from_callback';
const tokens = await client.oauth2.exchangeCode({
  code: authorizationCode,
  redirectUri: 'https://yourapp.com/callback'
});

console.log(`Access Token: ${tokens.accessToken}`);
console.log(`Refresh Token: ${tokens.refreshToken}`);
console.log(`Expires In: ${tokens.expiresIn} seconds`);
```

### PKCE Support

For enhanced security in public clients (SPAs, mobile apps):

```javascript theme={null}
import crypto from 'crypto';

// Generate code verifier
function generateCodeVerifier() {
  return crypto.randomBytes(32)
    .toString('base64url');
}

// Generate code challenge
function generateCodeChallenge(verifier) {
  return crypto.createHash('sha256')
    .update(verifier)
    .digest('base64url');
}

// Use PKCE
const codeVerifier = generateCodeVerifier();
const codeChallenge = generateCodeChallenge(codeVerifier);

// Step 1: Authorization with PKCE
const authUrl = await client.oauth2.getAuthorizationUrl({
  redirectUri: 'https://yourapp.com/callback',
  codeChallenge,
  codeChallengeMethod: 'S256'
});

// Step 2: Exchange code with verifier
const tokens = await client.oauth2.exchangeCode({
  code: authorizationCode,
  redirectUri: 'https://yourapp.com/callback',
  codeVerifier
});
```

### MFA Verification

If MFA is enabled:

```javascript theme={null}
// Verify MFA
const mfaResult = await client.oauth2.verifyMfa({
  code: '123456',  // 6-digit MFA code
  sessionToken: authResponse.sessionToken
});

// Exchange for tokens
const tokens = await client.oauth2.exchangeCode({
  code: mfaResult.authorizationCode,
  redirectUri: 'https://yourapp.com/callback'
});
```

## Token Management

### Refreshing Access Tokens

Access tokens expire after a set period. Use refresh tokens to obtain new access tokens:

```javascript theme={null}
// Refresh the access token
const newTokens = await client.oauth2.refreshToken(tokens.refreshToken);

console.log(`New Access Token: ${newTokens.accessToken}`);
console.log(`Expires In: ${newTokens.expiresIn} seconds`);
```

### Automatic Token Refresh

The SDK automatically refreshes tokens when they expire:

```javascript theme={null}
// Configure automatic refresh
const client = new AriesClient({
  clientId: 'your_client_id',
  clientSecret: 'your_client_secret',
  refreshToken: 'your_refresh_token',
  autoRefresh: true  // Enable automatic token refresh
});

// Make API calls without worrying about token expiration
const accounts = await client.users.getUserAccounts();
```

## Using Bearer Tokens Directly

If you already have an access token:

```javascript theme={null}
import { AriesClient } from '@aries-exchange/sdk';

const client = new AriesClient({
  bearerToken: 'your_access_token'
});

// Make authenticated requests
const profile = await client.users.getUserProfile();
```

## Security Best Practices

### 1. Store Credentials Securely

Never hardcode credentials in your source code:

```javascript theme={null}
const client = new AriesClient({
  clientId: process.env.ARIES_CLIENT_ID,
  clientSecret: process.env.ARIES_CLIENT_SECRET
});
```

### 2. Use Environment Variables

Create a `.env` file (add to `.gitignore`):

```bash theme={null}
ARIES_CLIENT_ID=your_client_id
ARIES_CLIENT_SECRET=your_client_secret
ARIES_REFRESH_TOKEN=your_refresh_token
```

Load in your application:

```javascript theme={null}
import dotenv from 'dotenv';
dotenv.config();

const client = new AriesClient({
  clientId: process.env.ARIES_CLIENT_ID,
  clientSecret: process.env.ARIES_CLIENT_SECRET
});
```

### 3. Handle Token Expiration

```javascript theme={null}
import { AriesAPIError } from '@aries-exchange/sdk';

try {
  const profile = await client.users.getUserProfile();
} catch (error) {
  if (error instanceof AriesAPIError && error.statusCode === 401) {
    // Token expired, refresh it
    const tokens = await client.oauth2.refreshToken(refreshToken);
    client.bearerToken = tokens.accessToken;

    // Retry the request
    const profile = await client.users.getUserProfile();
  }
}
```

### 4. Scope Limitations

Request only the scopes you need:

```javascript theme={null}
// Minimal scopes for read-only access
const authUrl = await client.oauth2.getAuthorizationUrl({
  redirectUri: 'https://yourapp.com/callback',
  scope: ['read']  // Only read access
});

// Full trading access
const authUrl = await client.oauth2.getAuthorizationUrl({
  redirectUri: 'https://yourapp.com/callback',
  scope: ['read', 'trade', 'withdraw']  // All permissions
});
```

## OAuth2 Scopes

Available scopes:

* `read` - Read account data, positions, and orders
* `trade` - Place and cancel orders
* `withdraw` - Withdraw funds from account
* `admin` - Administrative operations

## Error Handling

```javascript theme={null}
import { AriesAPIError } from '@aries-exchange/sdk';

try {
  const profile = await client.users.getUserProfile();
} catch (error) {
  if (error instanceof AriesAPIError) {
    switch (error.statusCode) {
      case 401:
        console.error('Authentication failed: Invalid credentials');
        break;
      case 403:
        console.error('Forbidden: Insufficient permissions');
        break;
      case 429:
        const retryAfter = error.headers.get('Retry-After');
        console.error(`Rate limit exceeded. Retry after ${retryAfter} seconds`);
        break;
      default:
        console.error(`API Error: ${error.message}`);
    }
  } else {
    console.error('Unexpected error:', error);
  }
}
```

## TypeScript Support

The SDK includes full TypeScript definitions:

```typescript theme={null}
import { AriesClient, Tokens, Profile } from '@aries-exchange/sdk';

const client: AriesClient = new AriesClient({
  clientId: process.env.ARIES_CLIENT_ID!,
  clientSecret: process.env.ARIES_CLIENT_SECRET!
});

// Type-safe token exchange
const tokens: Tokens = await client.oauth2.exchangeCode({
  code: authorizationCode,
  redirectUri: 'https://yourapp.com/callback'
});

// Type-safe profile retrieval
const profile: Profile = await client.users.getUserProfile();
console.log(`Authenticated as: ${profile.email}`);
```

## Complete Example

```javascript theme={null}
import { AriesClient, AriesAPIError } from '@aries-exchange/sdk';
import dotenv from 'dotenv';

dotenv.config();

async function main() {
  // Initialize client
  const client = new AriesClient({
    clientId: process.env.ARIES_CLIENT_ID,
    clientSecret: process.env.ARIES_CLIENT_SECRET,
    autoRefresh: true
  });

  try {
    // Get user profile
    const profile = await client.users.getUserProfile();
    console.log(`Authenticated as: ${profile.email}`);

    // Get user accounts
    const accounts = await client.users.getUserAccounts();
    console.log(`Found ${accounts.length} accounts`);
  } catch (error) {
    if (error instanceof AriesAPIError) {
      if (error.statusCode === 401) {
        console.error('Authentication failed');
      } else if (error.statusCode === 403) {
        console.error('Access forbidden');
      } else {
        console.error(`API Error: ${error.message}`);
      }
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

main();
```

## Browser Usage

For browser-based applications:

```javascript theme={null}
// Import for browsers
import { AriesClient } from '@aries-exchange/sdk/browser';

// Initialize (never expose client secret in browser)
const client = new AriesClient({
  clientId: 'your_public_client_id',
  // No client secret - use PKCE instead
});

// Use OAuth2 flow with PKCE
const codeVerifier = generateCodeVerifier();
const codeChallenge = generateCodeChallenge(codeVerifier);

// Store verifier in sessionStorage
sessionStorage.setItem('code_verifier', codeVerifier);

// Redirect to authorization
window.location.href = await client.oauth2.getAuthorizationUrl({
  redirectUri: window.location.origin + '/callback',
  codeChallenge,
  codeChallengeMethod: 'S256'
});

// In callback page
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const verifier = sessionStorage.getItem('code_verifier');

const tokens = await client.oauth2.exchangeCode({
  code,
  redirectUri: window.location.origin + '/callback',
  codeVerifier: verifier
});

// Store tokens securely
sessionStorage.setItem('access_token', tokens.accessToken);
```

## Next Steps

* [Quick Start Guide](/sdks/javascript/quick-start) - Get started with basic operations
* [Users API](/sdks/javascript/users) - Manage user accounts and profiles
* [Orders API](/sdks/javascript/orders) - Place and manage trades

## Related Resources

* OAuth2 Specification: [RFC 6749](https://tools.ietf.org/html/rfc6749)
* PKCE Extension: [RFC 7636](https://tools.ietf.org/html/rfc7636)
* JWT Tokens: [RFC 7519](https://tools.ietf.org/html/rfc7519)
