API Authentication

Auth0 JWT authentication, user tokens, service tokens for CI/CD, and hub-to-registry service communication.

MCP Hub uses multiple authentication mechanisms depending on the context: Auth0 for user authentication, bearer tokens for API access, and service tokens for inter-service communication.

Authentication Overview

ContextMechanismToken Type
Web dashboard loginAuth0 OAuth2/OIDCSession cookie
Public API (unauthenticated)NoneRate-limited by IP
Authenticated APIBearer tokenUser JWT or service token
CI/CD pipelinesBearer tokenService token
Hub-to-registry communicationBearer tokenService JWT

Auth0 Integration

MCP Hub delegates all user authentication to Auth0, a third-party identity provider. This means MCP Hub never stores or handles user passwords directly.

How Login Works

  1. The user clicks Log In on the MCP Hub dashboard.
  2. MCP Hub redirects the user to Auth0’s Universal Login page.
  3. The user authenticates with one of the configured providers:
    • Google OAuth: Sign in with Google account.
    • GitHub OAuth: Sign in with GitHub account (provides access to repository metadata).
    • GitLab OAuth: Sign in with GitLab account.
    • Email/Password: Traditional email and password (managed by Auth0).
  4. Auth0 redirects back to MCP Hub’s callback URL with an authorization code.
  5. MCP Hub exchanges the code for tokens (ID token, access token, refresh token).
  6. A session is created and the user is logged in.

Auth0 Configuration

MCP Hub requires the following Auth0 environment variables:

AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_CALLBACK_URL=http://localhost:8080/auth/callback
AUTH0_AUDIENCE=https://api.mcp-hub.info
SESSION_SECRET=your-random-32-byte-secret

The callback URL must exactly match one of the Allowed Callback URLs configured in your Auth0 application settings. For production, this should be your domain with HTTPS (e.g., https://mcp-hub.info/auth/callback).

Social Connections

MCP Hub supports the following social login providers through Auth0:

  • Google: Requires Google Cloud OAuth credentials configured in Auth0.
  • GitHub: Requires a GitHub OAuth App. Provides access to public repository metadata for MCP ingestion.
  • GitLab: Requires a GitLab OAuth application.

Each social connection is configured in the Auth0 dashboard under Authentication > Social. The requested scopes are email and profile.

API Token Authentication

Bearer Token Format

Authenticated API requests include the token in the Authorization header:

Authorization: Bearer <token>

User Tokens

User tokens are obtained through the Auth0 login flow. They are JWT tokens signed by Auth0 and validated by MCP Hub using Auth0’s public keys (JWKS).

User tokens contain:

  • Subject (sub): The Auth0 user identifier.
  • Email: The user’s email address.
  • Scopes: Permissions based on the user’s plan and roles.
  • Expiration: Token expiry time (managed by Auth0).

Rate Limits by Authentication

AuthenticationRate Limit
Anonymous (no token)15 requests/minute
Free plan30 requests/minute
PRO plan300 requests/minute
EnterpriseCustom (up to 5000 requests/minute)

Rate limit headers are included in all API responses:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1704067200

When the rate limit is exceeded, the API returns HTTP 429 with an error message.

Service Tokens

Service tokens are API tokens created by organization Admins and Owners for automated access. They are designed for CI/CD pipelines, scripts, and integrations that need to interact with the MCP Hub API without user login.

Creating a Service Token

POST /api/v1/orgs/{orgId}/tokens
{
  "name": "GitHub Actions CI Token",
  "description": "Token for evaluating MCPs in CI/CD pipeline",
  "scopes": ["read:org:acme", "ci:org:acme"],
  "expires_in_days": 365
}

The response includes the full token value, which is shown only once:

{
  "id": "token-uuid",
  "name": "GitHub Actions CI Token",
  "token": "mcp_tk_abc123def456...",
  "token_prefix": "mcp_tk_a",
  "scopes": ["read:org:acme", "ci:org:acme"],
  "expires_at": "2027-02-10T12:00:00Z"
}

Store the token securely. It cannot be retrieved after creation. Only the token prefix (first 8 characters) is stored for identification purposes.

Token Scopes

Service tokens use scope-based authorization:

ScopeDescription
read:publicRead public MCPs and their metadata
read:org:<orgId>Read MCPs within a specific organization
ci:org:<orgId>Use the CI/CD evaluate endpoint for an organization
admin:org:<orgId>Full organization access (use with caution)

Token Security

  • Hash storage: Only the SHA-256 hash of the token is stored in the database. The raw token is never persisted.
  • Prefix identification: The first 8 characters of the token are stored as token_prefix for identification in listings and logs.
  • Expiration: Tokens have an expiration date. Expired tokens are automatically rejected.
  • Revocation: Tokens can be revoked at any time by organization Admins and Owners. Revocation is immediate.
  • Usage tracking: The last_used_at timestamp is updated on each API call, allowing administrators to identify unused tokens.

Revoking a Token

DELETE /api/v1/orgs/{orgId}/tokens/{tokenId}

Or set the revoked_at timestamp. Revocation is immediate and irreversible – a new token must be created if access is needed again.

Hub-to-Registry Service Token

MCP Hub communicates with mcp-registry to publish certified artifacts. This server-to-server communication uses a dedicated service JWT token.

Configuration

REGISTRY_URL=http://localhost:8081
REGISTRY_SERVICE_TOKEN=your-service-jwt-token

The REGISTRY_SERVICE_TOKEN is a pre-shared JWT that grants MCP Hub the admin:publish scope on the registry. It is used exclusively for publishing operations (uploading manifests and bundles to the registry).

Security Requirements

  • The service token must never be logged or exposed in API responses.
  • It should be rotated periodically as part of operational security.
  • The registry validates the token on every publish request.
  • Communication between hub and registry should use HTTPS in production.

Machine-to-Machine Authentication

For automated systems that need to obtain tokens without user interaction, Auth0 supports the client credentials grant:

curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/oauth/token' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'grant_type=client_credentials' \
  --data 'client_id=YOUR_M2M_CLIENT_ID' \
  --data 'client_secret=YOUR_M2M_CLIENT_SECRET' \
  --data 'audience=https://api.mcp-hub.info'

This requires creating a Machine-to-Machine application in Auth0 and authorizing it for the MCP Hub API.

Token Validation Flow

When MCP Hub receives an API request with a Bearer token:

  1. Parse token: Extract the token from the Authorization header.
  2. Identify token type: Check if it is a user JWT (from Auth0) or a service token (prefix mcp_tk_).
  3. Validate:
    • User JWT: Verify signature against Auth0 JWKS, check expiration, extract claims.
    • Service token: Hash the token, look up the hash in the database, verify it is not expired or revoked.
  4. Load context: Fetch the user record, organization memberships, and platform role.
  5. Check permissions: Verify the token’s scopes are sufficient for the requested operation.
  6. Apply rate limits: Check and update rate limit counters based on the user’s plan.

Troubleshooting

“Callback URL mismatch”

The AUTH0_CALLBACK_URL in your .env file must exactly match one of the URLs configured in Auth0’s Allowed Callback URLs. Check for trailing slashes and protocol mismatches (http vs https).

“Invalid state parameter”

This CSRF protection error typically occurs when:

  • The session cookie was not saved (check cookie settings).
  • Multiple browser tabs caused a state mismatch.
  • The session expired before the callback was received.

“Token expired”

Service tokens have explicit expiration dates. Create a new token with a longer lifetime or implement token rotation in your CI/CD pipeline.

“Forbidden” on API calls

Verify that the token has the required scopes for the endpoint being called. Check the endpoint documentation for the required scope.