Skip to content

JWT Token Vending Service for MCP Gateway

The JWT Token Vending Service provides a user-friendly mechanism for generating personal access tokens without the use of an external IdP that can be used for programmatic access to MCP servers. This service bridges the gap between human authentication (web UI sessions) and machine authentication (JWT tokens), enabling users to create tokens with scoped permissions for automation, scripting, and agent access.

The Challenge with Token Management in Enterprise MCP Deployments

In enterprise scenarios, users often need to provide programmatic access to MCP servers for various automation tasks, CI/CD pipelines, and AI agents. Traditional approaches present several challenges:

  • Manual Token Management: Requiring users to manually generate M2M credentials through AWS Cognito or other IdPs creates friction and security risks
  • Scope Complexity: Users need to understand complex scope configurations and may accidentally grant excessive permissions
  • Token Lifecycle: No centralized way to manage token expiration, renewal, or revocation
  • Audit Trail: Difficulty tracking which tokens were generated by whom and for what purpose

A Solution with Integrated Token Vending

The JWT Token Vending Service provides an enterprise-ready solution that integrates directly with the existing MCP Gateway authentication infrastructure, allowing users to generate scoped JWT tokens through a familiar web interface.

Here is an architecture diagram showing how the token vending service integrates with the existing system:

graph TB
    %% Users and Token Generation Flow
    subgraph UserFlow["User Token Generation Flow"]
        direction TB
        User[User<br/>Web UI Session]
        TokenUI[Token Generation<br/>Web Interface]
        User -->|Authenticated Session| TokenUI
    end

    %% Core Infrastructure
    subgraph Infrastructure["MCP Gateway & Registry Infrastructure"]
        direction TB
        Nginx["Nginx<br/>Reverse Proxy"]
        AuthServer["Auth Server<br/>(Enhanced with Token Vending)"]
        Registry["Registry<br/>Web UI + Token Generation"]
        RegistryMCP["Registry<br/>MCP Server"]
    end

    %% Generated Token Usage
    subgraph TokenUsage["Token Usage"]
        direction TB
        Agent[AI Agent<br/>with Generated Token]
        Script[Automation Script<br/>with Generated Token]
        Pipeline[CI/CD Pipeline<br/>with Generated Token]
    end

    %% Identity Provider
    IdP[Identity Provider<br/>Amazon Cognito]

    %% MCP Server Farm
    subgraph MCPFarm["MCP Server Farm"]
        direction TB
        MCP1[MCP Server 1<br/>CurrentTime]
        MCP2[MCP Server 2<br/>FinInfo]
        MCP3[MCP Server 3<br/>Custom]
        MCPn[MCP Server n<br/>...]
    end

    %% Token Generation Flow
    TokenUI -->|POST /api/tokens/generate<br/>with user context| Registry
    Registry -->|POST /internal/tokens<br/>with user scopes| AuthServer
    AuthServer -->|Self-signed JWT<br/>with HMAC-SHA256| Registry
    Registry -->|Display token<br/>to user| TokenUI

    %% Token Usage Flow
    Agent -->|MCP requests<br/>with Bearer token| Nginx
    Script -->|API calls<br/>with Bearer token| Nginx
    Pipeline -->|Automated access<br/>with Bearer token| Nginx

    %% Internal routing and validation
    Nginx -->|Route /mcpgw/*<br/>Auth validation| AuthServer
    Nginx -->|Route /mcpgw/*<br/>Tool discovery| RegistryMCP
    Nginx -->|Route /tokens<br/>Token UI| Registry
    Nginx -->|Route /server1/*<br/>Proxy to MCP servers| MCP1
    Nginx -->|Route /server2/*<br/>Proxy to MCP servers| MCP2
    Nginx -->|Route /serverN/*<br/>Proxy to MCP servers| MCP3
    Nginx -->|Route /serverN/*<br/>Proxy to MCP servers| MCPn

    %% Auth flows
    IdP -.->|User session validation<br/>Group/scope mapping| AuthServer
    AuthServer -.->|Self-signed JWT validation<br/>Scope enforcement| AuthServer

    %% Styling
    classDef userStyle fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
    classDef tokenStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef agentStyle fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef idpStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef nginxStyle fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    classDef authStyle fill:#ffebee,stroke:#c62828,stroke-width:2px
    classDef registryStyle fill:#fff8e1,stroke:#f57f17,stroke-width:2px
    classDef mcpStyle fill:#e3f2fd,stroke:#1976d2,stroke-width:2px

    class UserFlow userStyle
    class User userStyle
    class TokenUI tokenStyle
    class TokenUsage agentStyle
    class Agent,Script,Pipeline agentStyle
    class IdP idpStyle
    class Nginx nginxStyle
    class AuthServer authStyle
    class Registry,RegistryMCP registryStyle
    class MCP1,MCP2,MCP3,MCPn mcpStyle

Architecture Components for Token Vending

The JWT Token Vending Service extends the existing MCP Gateway infrastructure with new capabilities:

Enhanced Registry Web UI

  • Token Generation Interface: User-friendly form for creating JWT tokens with custom scopes and expiration
  • Scope Validation: Real-time validation ensuring requested scopes are subset of user's current permissions
  • Token Display: Secure, one-time display of generated tokens with copy functionality and usage instructions

Enhanced Auth Server

  • Internal Token Endpoint: New /internal/tokens endpoint for generating self-signed JWT tokens
  • Scope Validation Logic: Ensures generated tokens cannot exceed user's current permissions
  • Rate Limiting: Prevents token generation abuse with configurable limits per user
  • Self-Signed JWT Support: Validates both Cognito tokens and internally generated tokens

Token Security Features

  • HMAC-SHA256 Signing: Uses shared secret key for token signing and validation
  • Scope Inheritance: Generated tokens can have same or fewer permissions than user's current scopes
  • Configurable Expiration: Token lifetime from 1-24 hours with 8-hour default
  • Unique Token IDs: Each token has a unique identifier for potential tracking and revocation

At a high-level the token generation and usage flow works as follows:

sequenceDiagram
    participant User
    participant Browser
    participant Registry as Registry<br/>Web UI
    participant AuthServer as Auth Server
    participant Agent
    participant Gateway as Gateway<br/>(Nginx)
    participant MCP as MCP Server

    %% Token Generation Flow
    Note over User,AuthServer: Token Generation Flow
    User->>Browser: Navigate to /tokens
    Browser->>Registry: GET /tokens with session cookie
    Registry->>Registry: Validate user session + extract scopes
    Registry->>Browser: Token generation form

    User->>Browser: Configure token (scopes, expiration, description)
    Browser->>Registry: POST /api/tokens/generate
    Registry->>Registry: Validate requested scopes ⊆ user scopes
    Registry->>AuthServer: POST /internal/tokens with user context

    AuthServer->>AuthServer: Rate limit check (10/hour/user)
    AuthServer->>AuthServer: Generate JWT with HMAC-SHA256
    AuthServer->>Registry: Return signed JWT token
    Registry->>Browser: Display token with copy functionality
    Browser->>User: Show token + usage instructions

    %% Token Usage Flow
    Note over Agent,MCP: Token Usage Flow
    User->>Agent: Provide generated JWT token
    Agent->>Gateway: MCP request with Bearer token
    Gateway->>AuthServer: Validate token + extract scopes

    alt Self-Signed Token
        AuthServer->>AuthServer: Detect issuer: "mcp-auth-server"
        AuthServer->>AuthServer: Validate HMAC-SHA256 signature
        AuthServer->>AuthServer: Extract scopes + enforce access
    else Cognito Token (Fallback)
        AuthServer->>AuthServer: Standard Cognito validation
    end

    alt Sufficient Permissions
        AuthServer->>Gateway: 200 OK + allowed scopes
        Gateway->>MCP: Forward MCP request
        MCP->>Gateway: MCP response
        Gateway->>Agent: MCP response
    else Insufficient Permissions
        AuthServer->>Gateway: 403 Access Denied
        Gateway->>Agent: 403 Access Denied
    end
  1. A User authenticates to the Registry web UI using their existing session (derived from Cognito OAuth or M2M flow) which contains their current scopes and permissions.

  2. The User navigates to the token generation interface at /tokens and configures their desired token parameters including optional custom scopes (must be subset of current scopes), expiration time (1-24 hours), and description.

  3. The Registry validates the user's session, ensures requested scopes are a subset of the user's current permissions, and calls the Auth Server's internal token generation endpoint with the user context and token parameters.

  4. The Auth Server performs security checks (rate limiting, scope validation, expiration limits) and generates a self-signed JWT token using HMAC-SHA256 with the shared secret key. The token contains standard JWT claims plus MCP-specific metadata.

  5. The Registry displays the generated token to the user with copy functionality, usage instructions, and security warnings. The token is shown only once for security.

  6. The User saves the token securely and provides it to their Agent or automation script for programmatic access to MCP servers.

  7. When the Agent makes MCP requests, it includes the generated JWT token in the Authorization header. The Gateway forwards the request to the Auth Server for validation.

  8. The Auth Server detects self-signed tokens by the issuer claim, validates the HMAC-SHA256 signature using the shared secret, and enforces scope-based access control using the same logic as Cognito tokens.

  9. If the token is valid and the requested operation is within the token's scope, the Gateway forwards the request to the appropriate MCP Server. Otherwise, it returns a 403 Access Denied response.

The above implementation provides a seamless way for users to generate programmatic access tokens without requiring direct interaction with the Identity Provider, while maintaining the same security guarantees and scope enforcement as the existing authentication system.

Agent Integration

The JWT Token Vending Service integrates seamlessly with existing agent authentication patterns through enhanced command-line support:

Enhanced Agent Command Line Interface

The agent now supports direct JWT token usage through a new --jwt-token parameter:

# Method 1: Direct token usage
python agent.py \
  --jwt-token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  --message "What is the current time in New York?"

# Method 2: Environment variable
export JWT_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
python agent.py --jwt-token "$JWT_TOKEN" --message "List available servers"

# Method 3: Token from file
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." > ~/.mcp/jwt_token
python agent.py --jwt-token "$(cat ~/.mcp/jwt_token)" --message "Help me analyze data"

Token Storage Best Practices

Secure Storage Options

# Option 1: Encrypted environment file
echo "JWT_TOKEN=your_token_here" | gpg --encrypt > ~/.mcp/token.gpg

# Option 2: System keyring (macOS)
security add-generic-password -a "$USER" -s "mcp-jwt-token" -w "your_token_here"

# Option 3: Secure file with restricted permissions
echo "your_token_here" > ~/.mcp/jwt_token
chmod 600 ~/.mcp/jwt_token

CI/CD Integration

# GitHub Actions example
name: MCP Agent Workflow
on: [push]
jobs:
  run-agent:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run MCP Agent
        env:
          JWT_TOKEN: ${{ secrets.MCP_JWT_TOKEN }}
        run: |
          python agent.py --jwt-token "$JWT_TOKEN" --message "Deploy analysis"

Security Features and Considerations

Token Security Implementation

Rate Limiting

  • Per-User Limits: Maximum 10 tokens per user per hour
  • Sliding Window: Uses hourly time slots for rate calculation
  • Memory-Based: Simple in-memory counter with automatic cleanup
  • Configurable: Limits adjustable via environment variables

Scope Inheritance and Validation

  • Subset Validation: Generated tokens cannot exceed user's current permissions
  • Real-Time Validation: Scope checks performed at generation time
  • Default Behavior: Empty scope request defaults to user's full scope set
  • JSON Validation: Custom scope uploads validated for proper JSON format

Token Lifecycle Management

  • Configurable Expiration: 1-24 hour range with 8-hour default
  • No Refresh: Tokens cannot be refreshed, must be regenerated
  • Unique Identifiers: Each token has a unique jti claim for tracking
  • Self-Contained: All authorization data embedded in token

Cryptographic Implementation

HMAC-SHA256 Signing

# Token generation process
payload = {
    "iss": "mcp-auth-server",
    "aud": "mcp-registry", 
    "sub": username,
    "scope": " ".join(requested_scopes),
    "exp": current_time + (expires_in_hours * 3600),
    "iat": current_time,
    "jti": str(uuid.uuid4()),
    "token_use": "access",
    "client_id": "user-generated",
    "token_type": "user_generated"
}

# Sign with shared secret
access_token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')

Token Validation Process

# Validation with issuer detection
try:
    # Quick check for self-signed tokens
    unverified_claims = jwt.decode(token, options={"verify_signature": False})
    if unverified_claims.get('iss') == 'mcp-auth-server':
        # Validate self-signed token
        claims = jwt.decode(token, SECRET_KEY, algorithms=['HS256'], 
                          issuer='mcp-auth-server', audience='mcp-registry')
        scopes = claims.get('scope', '').split()
        return {'valid': True, 'scopes': scopes, 'method': 'self_signed'}
    else:
        # Fall back to Cognito validation
        return validate_cognito_token(token)
except jwt.InvalidTokenError:
    return {'valid': False, 'error': 'Invalid token'}

Security Best Practices

For Users

  1. Minimal Scopes: Generate tokens with only required permissions
  2. Short Expiration: Use shortest practical token lifetime
  3. Secure Storage: Store tokens in encrypted or protected locations
  4. Regular Rotation: Regenerate tokens periodically
  5. Monitor Usage: Track token usage in application logs

For Administrators

  1. Audit Logging: Monitor token generation patterns and frequency
  2. Scope Configuration: Regularly review and update scope definitions
  3. Rate Limit Tuning: Adjust rate limits based on usage patterns
  4. Key Management: Protect the shared SECRET_KEY used for signing
  5. Access Reviews: Periodically review user permissions and group memberships

Threat Model and Mitigations

Token Theft

  • Risk: Stolen tokens provide unauthorized access
  • Mitigation: Short expiration times, scope limitations, audit logging

Scope Escalation

  • Risk: Users attempt to generate tokens with excessive permissions
  • Mitigation: Strict subset validation, real-time scope checking

Rate Limit Bypass

  • Risk: Automated token generation for abuse
  • Mitigation: Per-user rate limiting, monitoring, account lockout policies

Replay Attacks

  • Risk: Intercepted tokens used maliciously
  • Mitigation: HTTPS enforcement, short token lifetimes, unique token IDs

Implementation Configuration

Environment Variables

# Token generation settings
MAX_TOKEN_LIFETIME_HOURS=24          # Maximum token lifetime
DEFAULT_TOKEN_LIFETIME_HOURS=8       # Default token lifetime
MAX_TOKENS_PER_USER_PER_HOUR=10     # Rate limiting

# JWT settings
JWT_ISSUER="mcp-auth-server"         # Token issuer
JWT_AUDIENCE="mcp-registry"          # Token audience
SECRET_KEY="your-shared-secret"      # HMAC signing key (must be shared)

Scope Configuration

Generated tokens inherit scope validation from the existing scopes.yml configuration:

# Example scope allowing read access to time servers
mcp-servers-time/read:
  - server: "currenttime"
    methods: ["initialize", "tools/list", "tools/call"]
    tools: ["current_time_by_timezone", "current_time_utc"]

# Example scope for financial data access  
mcp-servers-finance/read:
  - server: "fininfo"
    methods: ["initialize", "tools/list", "tools/call"]
    tools: ["get_stock_price", "get_market_data"]

# Admin scope with full access
mcp-registry-admin:
  - server: "*"
    methods: ["*"]
    tools: ["*"]

User Interface Configuration

The token generation interface provides:

Token Configuration Options

  • Description: Optional human-readable token description
  • Expiration: Dropdown with 1, 8, and 24-hour options
  • Scope Method: Radio buttons for "Use current scopes" or "Custom JSON"
  • Custom Scopes: JSON textarea for advanced users

User Experience Features

  • Current Permissions Display: Shows user's active scopes as badges
  • Real-time Validation: Client-side validation of JSON scope format
  • Copy Functionality: Multiple copy methods with fallbacks for different browsers
  • Usage Instructions: Clear examples of how to use the generated token
  • Security Warnings: Prominent warnings about token storage and sharing

By implementing the JWT Token Vending Service, organizations can provide their users with a secure, user-friendly way to generate programmatic access tokens while maintaining enterprise-grade security controls and comprehensive audit capabilities. The service seamlessly integrates with existing MCP Gateway infrastructure and provides a foundation for advanced token management features.