DocsSecurityAuthentication

Authentication Methods

Implement secure authentication with OAuth2, multi-factor authentication, and session management for AI applications.

Authentication Methods

OAuth2 + PKCE

Secure authorization flow

  • PKCE code challenge
  • State parameter validation
  • Token refresh rotation

Multi-Factor Auth

Additional security layer

  • TOTP authenticator apps
  • SMS verification
  • WebAuthn/FIDO2

API Key Auth

Programmatic access

  • Scoped permissions
  • Rate limiting
  • Key rotation

Session Management

Secure session handling

  • JWT-based sessions
  • Timeout management
  • Secure cookies

Authentication Configuration

auth.config.yaml
# MCPCodex Authentication Configuration
# auth.config.yaml

authentication:
  # Primary Authentication Provider
  primary:
    provider: "oauth2"
    issuer: "https://auth.mcpcodex.com"
    client_id: "mcpcodex-client"
    scopes: ["openid", "profile", "email", "mcpcodex:api"]
    
    # PKCE (Proof Key for Code Exchange)
    pkce:
      enabled: true
      code_challenge_method: "S256"
    
    # Token Configuration
    tokens:
      access_token:
        lifetime: 900  # 15 minutes
        algorithm: "RS256"
        issuer: "mcpcodex.com"
        audience: "mcpcodex-api"
      
      refresh_token:
        lifetime: 86400  # 24 hours
        rotation: true
        max_reuse: 0
      
      id_token:
        lifetime: 3600  # 1 hour
        claims: ["sub", "email", "name", "roles"]

  # Multi-Factor Authentication
  mfa:
    enabled: true
    required_for_roles: ["admin", "developer"]
    grace_period: 3600  # 1 hour
    
    providers:
      totp:
        enabled: true
        issuer: "MCPCodex"
        digits: 6
        period: 30
        algorithm: "SHA1"
      
      sms:
        enabled: true
        provider: "twilio"
        template: "Your MCPCodex code: {code}"
      
      email:
        enabled: true
        provider: "sendgrid"
        template: "mfa-code"
      
      webauthn:
        enabled: true
        rp_id: "mcpcodex.com"
        rp_name: "MCPCodex"
        user_verification: "required"

  # Session Management
  session:
    provider: "jwt"
    cookie_name: "mcpcodex_session"
    
    security:
      secure: true
      http_only: true
      same_site: "strict"
      path: "/"
      domain: ".mcpcodex.com"
    
    timeouts:
      idle: 3600     # 1 hour
      absolute: 28800  # 8 hours
      remember_me: 2592000  # 30 days

  # Password Policy
  password:
    min_length: 12
    max_length: 128
    require_uppercase: true
    require_lowercase: true
    require_numbers: true
    require_symbols: true
    
    complexity:
      min_score: 3  # zxcvbn score
      dictionary_check: true
      common_patterns: false
    
    history:
      prevent_reuse: 12
      expiry_days: 90
    
    lockout:
      max_attempts: 5
      lockout_duration: 900  # 15 minutes
      progressive_delay: true

  # API Key Authentication
  api_keys:
    enabled: true
    prefix: "mcp_"
    length: 32
    
    scopes:
      - "read:models"
      - "write:models" 
      - "read:contexts"
      - "write:contexts"
      - "admin:users"
    
    rotation:
      auto_rotate: false
      rotation_period: 90  # days
      warning_period: 14   # days
    
    rate_limiting:
      requests_per_minute: 100
      burst_size: 20

Authentication Service

auth.service.ts
// MCPCodex Authentication Implementation
// auth.service.ts

import { OAuth2Client } from '@mcpcodex/oauth2';
import { MFAProvider } from '@mcpcodex/mfa';
import { SessionManager } from '@mcpcodex/session';

export class AuthenticationService {
  private oauth2: OAuth2Client;
  private mfa: MFAProvider;
  private sessionManager: SessionManager;

  constructor() {
    this.oauth2 = new OAuth2Client({
      issuer: process.env.AUTH_ISSUER,
      clientId: process.env.AUTH_CLIENT_ID,
      clientSecret: process.env.AUTH_CLIENT_SECRET,
      redirectUri: process.env.AUTH_REDIRECT_URI,
      pkce: true
    });

    this.mfa = new MFAProvider({
      totp: { enabled: true },
      sms: { provider: 'twilio' },
      webauthn: { enabled: true }
    });

    this.sessionManager = new SessionManager({
      secret: process.env.SESSION_SECRET,
      cookieName: 'mcpcodex_session',
      secure: true,
      httpOnly: true,
      sameSite: 'strict'
    });
  }

  // OAuth2 + PKCE Authentication Flow
  async initiateAuth(redirectUri?: string): Promise<string> {
    const { codeVerifier, codeChallenge } = this.oauth2.generatePKCE();
    
    // Store code verifier in session
    await this.sessionManager.set('code_verifier', codeVerifier);
    
    return this.oauth2.getAuthorizationUrl({
      codeChallenge,
      codeChallengeMethod: 'S256',
      state: this.generateState(),
      redirectUri
    });
  }

  async completeAuth(code: string, state: string): Promise<AuthResult> {
    // Validate state
    const expectedState = await this.sessionManager.get('expected_state');
    if (state !== expectedState) {
      throw new Error('Invalid state parameter');
    }

    // Exchange code for tokens
    const codeVerifier = await this.sessionManager.get('code_verifier');
    const tokens = await this.oauth2.exchangeCodeForTokens({
      code,
      codeVerifier
    });

    // Validate tokens
    const userInfo = await this.oauth2.getUserInfo(tokens.accessToken);
    
    // Check if MFA is required
    if (await this.mfa.isRequired(userInfo.sub)) {
      return {
        requiresMFA: true,
        mfaToken: await this.mfa.generateMFAToken(userInfo.sub),
        user: userInfo
      };
    }

    // Create session
    const session = await this.sessionManager.create({
      userId: userInfo.sub,
      email: userInfo.email,
      roles: userInfo.roles,
      tokens
    });

    return {
      success: true,
      session,
      user: userInfo
    };
  }

  // Multi-Factor Authentication
  async verifyMFA(mfaToken: string, code: string, method: MFAMethod): Promise<AuthResult> {
    const isValid = await this.mfa.verify(mfaToken, code, method);
    
    if (!isValid) {
      throw new Error('Invalid MFA code');
    }

    // Get user info from MFA token
    const userInfo = await this.mfa.getUserFromToken(mfaToken);
    
    // Create session
    const session = await this.sessionManager.create({
      userId: userInfo.sub,
      email: userInfo.email,
      roles: userInfo.roles,
      mfaVerified: true
    });

    return {
      success: true,
      session,
      user: userInfo
    };
  }

  // API Key Authentication
  async authenticateApiKey(apiKey: string): Promise<ApiKeyResult> {
    const keyData = await this.validateApiKey(apiKey);
    
    if (!keyData) {
      throw new Error('Invalid API key');
    }

    // Check rate limits
    await this.checkRateLimit(keyData.keyId);
    
    // Update last used timestamp
    await this.updateApiKeyUsage(keyData.keyId);

    return {
      userId: keyData.userId,
      scopes: keyData.scopes,
      rateLimit: keyData.rateLimit
    };
  }

  // Session Validation
  async validateSession(sessionToken: string): Promise<SessionInfo> {
    const session = await this.sessionManager.validate(sessionToken);
    
    if (!session) {
      throw new Error('Invalid session');
    }

    // Check if session has expired
    if (session.expiresAt < Date.now()) {
      await this.sessionManager.destroy(sessionToken);
      throw new Error('Session expired');
    }

    // Check if tokens need refresh
    if (session.tokens && this.shouldRefreshToken(session.tokens)) {
      session.tokens = await this.refreshTokens(session.tokens);
      await this.sessionManager.update(sessionToken, { tokens: session.tokens });
    }

    return session;
  }

  // Logout and Session Management
  async logout(sessionToken: string): Promise<void> {
    const session = await this.sessionManager.get(sessionToken);
    
    if (session && session.tokens) {
      // Revoke tokens at OAuth2 provider
      await this.oauth2.revokeTokens(session.tokens);
    }

    // Destroy session
    await this.sessionManager.destroy(sessionToken);
  }

  private async shouldRefreshToken(tokens: TokenSet): Promise<boolean> {
    const expiryBuffer = 300; // 5 minutes
    return tokens.accessToken.expiresAt < (Date.now() + expiryBuffer);
  }

  private async refreshTokens(tokens: TokenSet): Promise<TokenSet> {
    return await this.oauth2.refreshTokens(tokens.refreshToken);
  }

  private generateState(): string {
    return crypto.randomBytes(32).toString('hex');
  }
}

// Types
interface AuthResult {
  success?: boolean;
  requiresMFA?: boolean;
  mfaToken?: string;
  session?: SessionInfo;
  user?: UserInfo;
}

interface ApiKeyResult {
  userId: string;
  scopes: string[];
  rateLimit: RateLimitInfo;
}

Essential Commands

Setup OAuth2

Configure OAuth2 authentication.

mcpcodex auth setup oauth2

Enable MFA

Setup multi-factor authentication.

mcpcodex auth mfa enable

Generate API Key

Create API keys for programmatic access.

mcpcodex auth apikey create

Validate Session

Verify session validity and tokens.

mcpcodex auth validate

Next Steps

Authenticate Securely

Implement robust authentication with OAuth2, MFA, and secure session management.