# Schwab OAuth 2.0 Compliance Documentation

This document outlines how the n8n-nodes-schwab package complies with Schwab's OAuth 2.0 security requirements.

## Schwab OAuth 2.0 Requirements

Schwab requires all API integrations to use OAuth 2.0 with the following specifications:

### ✅ OAuth 2.0 Framework Compliance

**Requirement**: Use OAuth 2.0 authorization framework over HTTPS
- **Implementation**: ✅ Extends n8n's `oAuth2Api` base credential type
- **Standard**: Adheres to IETF RFC 6749 (OAuth 2.0) and RFC 6750 (Bearer Token)
- **Protocol**: All communication over HTTPS

### ✅ Three-Legged OAuth Workflow

**Requirement**: Implement Three-Legged OAuth workflow for user consent
- **Implementation**: ✅ Configured with `authorizationCode` grant type
- **Flow**:
  1. User clicks "Connect" in n8n
  2. Redirected to Schwab's Login Micro Site (LMS)
  3. User logs in and grants consent (CAG process)
  4. User redirected back to n8n with authorization code
  5. n8n exchanges code for access token automatically

### ✅ App Registration Elements

#### Client ID & Client Secret
**Requirement**: Unique App credentials for OAuth authorization
- **Implementation**: ✅ Stored in n8n credentials as:
  - `clientId` (inherited from oAuth2Api) - Your Schwab App Key
  - `clientSecret` (inherited from oAuth2Api) - Your Schwab App Secret
  - `appKey` (custom field) - Duplicate of Client ID for ThirdPartyId header
- **Security**: ✅ Client Secret stored encrypted by n8n, never exposed in logs or UI

#### Callback URL (redirect_uri)
**Requirement**: HTTPS callback URL with 255 character limit
- **Implementation**: ✅ Automatically managed by n8n
- **URL Format**: `https://your-n8n-instance.com/rest/oauth2-credential/callback`
- **User Action Required**: Register this URL in Schwab Developer Portal
- **HTTPS**: ✅ Required for production n8n instances

#### Display Name
**Requirement**: App display name shown during CAG
- **Implementation**: ✅ "Schwab OAuth2 API" shown in n8n credential setup
- **User Configuration**: Set in Schwab Developer Portal when creating app

### ✅ Token Management

#### Access Token
**Requirement**: Use Access Token to access Protected Resources (Bearer token)
- **Implementation**: ✅ Automatic token management via n8n's oAuth2Api
- **Usage**: ✅ Sent in Authorization header as `Bearer {access_token}`
- **Lifetime**: Typically 30 minutes (Schwab default)
- **Storage**: ✅ Encrypted in n8n credential storage

#### Refresh Token
**Requirement**: Renew access via Refresh Token
- **Implementation**: ✅ Automatic refresh via n8n's oAuth2Api
- **Behavior**: n8n automatically refreshes expired tokens before API calls
- **Lifetime**: 90 days (Schwab default)
- **Storage**: ✅ Encrypted in n8n credential storage

### ✅ Authorization & Token URLs

**Requirement**: Correct Schwab OAuth endpoints
- **Authorization URL**: ✅ `https://api.schwabapi.com/v1/oauth/authorize`
- **Access Token URL**: ✅ `https://api.schwabapi.com/v1/oauth/token`
- **Implementation**: Hard-coded in credentials as hidden fields

### ✅ Scope Management

**Requirement**: Request appropriate OAuth scopes
- **Implementation**: ✅ Default scope: `readonly`
- **Available Scopes**:
  - `readonly` - Read account and market data
  - `trade` - Place and manage trades
  - `readonly trade` - Both permissions
- **Configuration**: Currently fixed to `readonly` (can be modified in credentials)

### ✅ ThirdPartyId Header

**Requirement**: Include App Key in ThirdPartyId header (Schwab-specific)
- **Implementation**: ✅ Added in v0.2.6
- **Header**: `ThirdPartyId: {App Key / Client ID}`
- **Usage**: Automatically included in all API requests
- **Source**: Uses `appKey` field from credentials

## OAuth Flow Diagram

```
┌─────────────┐
│    User     │
└──────┬──────┘
       │ 1. Click "Connect" in n8n
       ▼
┌─────────────────────┐
│  n8n (User-Agent)   │
└──────┬──────────────┘
       │ 2. Redirect to Schwab with Client ID
       ▼
┌──────────────────────────────┐
│  Schwab Authorization Server │
│  (Login Micro Site - LMS)    │
└──────┬───────────────────────┘
       │ 3. User logs in
       │ 4. User grants consent (CAG)
       │ 5. Select accounts to link
       │
       │ 6. Redirect to callback with auth code
       ▼
┌─────────────────────┐
│  n8n (User-Agent)   │
└──────┬──────────────┘
       │ 7. Exchange auth code for tokens
       │    (Client ID + Client Secret)
       ▼
┌──────────────────────────────┐
│  Schwab Authorization Server │
└──────┬───────────────────────┘
       │ 8. Return Access Token + Refresh Token
       ▼
┌─────────────────────┐
│  n8n Token Storage  │ (Encrypted)
└──────┬──────────────┘
       │
       │ 9. API Calls with Bearer Token + ThirdPartyId
       ▼
┌──────────────────────┐
│  Schwab API Server   │
│  (Resource Server)   │
└──────────────────────┘
```

## Security Best Practices

### ✅ Implemented by n8n-nodes-schwab

1. **HTTPS Only**: All OAuth communication over HTTPS ✅
2. **Encrypted Storage**: Client Secret and tokens encrypted at rest ✅
3. **Automatic Token Refresh**: Prevents token expiration issues ✅
4. **Bearer Token Authentication**: Tokens sent in Authorization header ✅
5. **No Credential Exposure**: Credentials never logged or exposed in UI ✅

### ⚠️ User Responsibilities

1. **HTTPS n8n Instance**: Production n8n must use HTTPS (required by Schwab)
2. **Secure Client Secret**: Never commit or share Client Secret
3. **Callback URL Registration**: Must register n8n's OAuth callback URL in Schwab portal
4. **App Approval**: Schwab app must be approved and promoted to Production
5. **Scope Selection**: Request only necessary scopes (principle of least privilege)

## Environment Requirements

### Development (Sandbox)
- Schwab app in Sandbox environment
- n8n instance accessible via HTTPS
- Test data only

### Production
- Schwab app approved and promoted to Production
- n8n instance with valid SSL certificate
- Production Schwab account
- Real account data

## Compliance Checklist

Before using this node in production:

- [ ] Schwab Developer Portal account created
- [ ] App created and approved in Schwab portal
- [ ] App Key (Client ID) obtained
- [ ] App Secret (Client Secret) obtained
- [ ] Callback URL registered in Schwab app (n8n OAuth callback URL)
- [ ] n8n instance uses HTTPS
- [ ] Schwab OAuth2 API credentials created in n8n
- [ ] OAuth connection tested (click "Connect" and authorize)
- [ ] Access token obtained successfully
- [ ] API calls work without authentication errors

## OAuth 2.0 Standards Compliance

This implementation complies with:

- ✅ **RFC 6749**: The OAuth 2.0 Authorization Framework
  - Authorization Code Grant Type (Section 4.1)
  - Token Endpoint (Section 3.2)
  - Access Token Response (Section 5.1)
  
- ✅ **RFC 6750**: The OAuth 2.0 Bearer Token Usage
  - Authorization Header (Section 2.1)
  - Bearer Token Format

## Version History

### v0.2.6
- Added `appKey` field to credentials for ThirdPartyId header
- Fixed ThirdPartyId header implementation
- Enhanced OAuth compliance documentation

### v0.2.5
- Added ThirdPartyId header to API requests
- Fixed 500 Internal Server Error

### v0.2.0
- Migrated to native n8n OAuth2 implementation
- Automatic token refresh
- Extends oAuth2Api base credential

## Support & Resources

- **Schwab Developer Portal**: https://developer.schwab.com/
- **OAuth 2.0 Specification**: https://tools.ietf.org/html/rfc6749
- **Bearer Token Spec**: https://tools.ietf.org/html/rfc6750
- **n8n OAuth Documentation**: https://docs.n8n.io/integrations/builtin/credentials/
- **GitHub Issues**: Report issues on project repository

## Conclusion

✅ **This implementation fully complies with Schwab's OAuth 2.0 requirements**, including:
- Three-Legged OAuth workflow
- Authorization Code grant type
- Bearer token authentication
- Automatic token refresh
- Required ThirdPartyId header
- HTTPS communication
- Secure credential storage

Users must ensure their n8n instance uses HTTPS and properly register their callback URL in the Schwab Developer Portal.
