API Authentication
6 min read
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
| Context | Mechanism | Token Type |
|---|---|---|
| Web dashboard login | Auth0 OAuth2/OIDC | Session cookie |
| Public API (unauthenticated) | None | Rate-limited by IP |
| Authenticated API | Bearer token | User JWT or service token |
| CI/CD pipelines | Bearer token | Service token |
| Hub-to-registry communication | Bearer token | Service 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
- The user clicks Log In on the MCP Hub dashboard.
- MCP Hub redirects the user to Auth0’s Universal Login page.
- 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).
- Auth0 redirects back to MCP Hub’s callback URL with an authorization code.
- MCP Hub exchanges the code for tokens (ID token, access token, refresh token).
- 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
| Authentication | Rate Limit |
|---|---|
| Anonymous (no token) | 15 requests/minute |
| Free plan | 30 requests/minute |
| PRO plan | 300 requests/minute |
| Enterprise | Custom (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:
| Scope | Description |
|---|---|
read:public | Read 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_prefixfor 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_attimestamp 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:
- Parse token: Extract the token from the Authorization header.
- Identify token type: Check if it is a user JWT (from Auth0) or a service token (prefix
mcp_tk_). - 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.
- Load context: Fetch the user record, organization memberships, and platform role.
- Check permissions: Verify the token’s scopes are sufficient for the requested operation.
- 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.