ADR-0004: Combine JWT & Basic AuthΒΆ
- Status: Accepted
- Date: 2025-02-01
- Deciders: Core Engineering Team
ContextΒΆ
The gateway needs to support two types of clients:
- Browser-based users using the Admin UI
- Headless clients such as scripts, services, and tools
These use cases require different authentication workflows:
- Browsers prefer form-based login and session cookies.
- Automation prefers stateless, token-based access.
The current config exposes both:
BASIC_AUTH_USERandBASIC_AUTH_PASSWORDJWT_SECRET_KEY,JWT_EXPIRY_SECONDS, and cookie settings
DecisionΒΆ
We will combine both authentication modes as follows:
- Basic Auth secures access to
/admin. Upon success, a short-lived JWT cookie is issued. - JWT Bearer token (via header or cookie) is required for all API, WebSocket, and SSE requests.
- Tokens are signed using the shared
JWT_SECRET_KEYand include standard claims (sub, exp, scopes). - When
AUTH_REQUIRED=false, the gateway allows unauthenticated access (dev only).
ConsequencesΒΆ
- β Developers can log in once via browser and obtain an authenticated session.
- β Scripts can use a generated JWT directly, with no credential storage.
- β Tokens must be signed, rotated, and verified securely (TLS required).
- π JWTs expire and must be refreshed periodically by clients.
Alternatives ConsideredΒΆ
| Option | Why Not |
|---|---|
| JWT only | CLI tools need a pre-acquired token; not friendly for interactive login. |
| Basic only | Password sent on every request; cannot easily revoke or expire credentials. |
| OAuth2 / OpenID Connect | Too complex for self-hosted setups; requires external identity provider. |
| mTLS client auth | Secure but heavy; not usable in browsers or simple HTTP clients. |
StatusΒΆ
This combined authentication mechanism is implemented and enabled by default in the gateway.
Update: Asymmetric JWT Algorithm SupportΒΆ
- Date: 2025-01-13
- Status: Extended
- Enhancement By: Core Engineering Team
Enhancement OverviewΒΆ
JWT authentication has been extended to support both symmetric (HMAC) and asymmetric (RSA/ECDSA) algorithms, significantly expanding the gateway's authentication capabilities for enterprise and distributed environments.
Supported AlgorithmsΒΆ
| Category | Algorithms | Use Case | Key Management |
|---|---|---|---|
| HMAC (Symmetric) | HS256, HS384, HS512 | Single-service, simple deployments | Shared secret (JWT_SECRET_KEY) |
| RSA (Asymmetric) | RS256, RS384, RS512 | Multi-service, enterprise | Public/private key pair |
| ECDSA (Asymmetric) | ES256, ES384, ES512 | High-performance, modern crypto | Public/private key pair |
ConfigurationΒΆ
Symmetric (HMAC) - Default:
Asymmetric (RSA/ECDSA) - New:
JWT_ALGORITHM=RS256
JWT_PUBLIC_KEY_PATH=jwt/public.pem
JWT_PRIVATE_KEY_PATH=jwt/private.pem
JWT_AUDIENCE_VERIFICATION=true
JWT_ISSUER_VERIFICATION=true
Benefits of Asymmetric SupportΒΆ
β Enhanced Security
- Private key never leaves the signing service
- Public key can be safely distributed for verification
- Eliminates shared secret management challenges
β Scalability & Federation
- Multiple services can verify tokens independently
- No need to distribute signing secrets
- Supports microservices and distributed architectures
β Enterprise Compliance
- Meets enterprise security standards (SOC2, ISO 27001)
- Supports Hardware Security Module (HSM) integration
- Enables proper key lifecycle management
β Future-Proof Architecture
- Foundation for advanced features like key rotation
- Compatible with industry-standard JWT libraries
- Supports Dynamic Client Registration scenarios
Implementation NotesΒΆ
- Backward Compatibility: All existing HMAC configurations continue to work unchanged
- Runtime Configuration: Algorithm and keys are validated at startup
- Error Handling: Clear error messages for misconfigured keys or missing files
- Performance: Minimal overhead for asymmetric operations in typical workloads
Security ConsiderationsΒΆ
- Key Storage: Private keys must be secured and never committed to version control
- Key Rotation: Implement regular key rotation procedures for asymmetric keys
- Algorithm Selection: Choose algorithm based on security requirements and performance needs
- Audience Verification: Can be disabled for Dynamic Client Registration (DCR) scenarios
Update: MCP Endpoint Authentication ConfigurationΒΆ
- Date: 2025-01-16
- Status: Extended
- Enhancement By: Core Engineering Team
Enhancement OverviewΒΆ
A new MCP_REQUIRE_AUTH configuration option provides fine-grained control over authentication requirements for MCP protocol endpoints (/mcp/*), independent of the global AUTH_REQUIRED setting.
ConfigurationΒΆ
| Setting | Default | Description |
|---|---|---|
MCP_REQUIRE_AUTH | false | When true, all /mcp requests must include a valid Bearer token. When false, unauthenticated requests are allowed but can only access public tools, resources, and prompts. |
Behavior MatrixΒΆ
AUTH_REQUIRED | MCP_REQUIRE_AUTH | REST API | MCP Endpoints |
|---|---|---|---|
true | false (default) | Auth required | Public-only access without token |
true | true | Auth required | Auth required |
false | false | No auth | Public-only access without token |
false | true | No auth | Auth required |
Use CasesΒΆ
Default (MCP_REQUIRE_AUTH=false):
- Suitable for public MCP services offering public tools
- Unauthenticated clients can discover and invoke public tools only
- Team-scoped and private tools require authentication
Strict Mode (MCP_REQUIRE_AUTH=true):
- Recommended for multi-tenant deployments
- All MCP clients must authenticate before any operation
- Prevents anonymous enumeration of available tools
Security ConsiderationsΒΆ
- When
MCP_REQUIRE_AUTH=false, unauthenticated requests receive an empty team list (teams=[]), restricting access tovisibility=publicitems only - Private and team-scoped tools, resources, and prompts are never exposed to unauthenticated users
- The service layer enforces access control regardless of this setting
Configuration DependenciesΒΆ
Full MCP access control (visibility + team scoping + membership validation) requires:
MCP_CLIENT_AUTH_ENABLED=true(default) - enables JWT authentication for MCP endpoints- Valid Bearer tokens with
teamsclaim for team-scoped access - Team membership validation runs on each request (60s cache TTL)
When MCP_CLIENT_AUTH_ENABLED=false:
- Access control relies on
MCP_REQUIRE_AUTH+ tool/resource visibility only - Team membership validation is skipped (no JWT to extract teams from)
- Use
TRUST_PROXY_AUTH=truewith a reverse proxy for user identification
Update: API Basic Authentication Disabled by DefaultΒΆ
- Date: 2026-01-28
- Status: Extended
- Enhancement By: Core Engineering Team
Security Enhancement OverviewΒΆ
Basic authentication for API endpoints is now disabled by default to improve security posture. This change follows security best practices by preferring JWT tokens for programmatic API access.
ConfigurationΒΆ
| Setting | Default | Description |
|---|---|---|
API_ALLOW_BASIC_AUTH | false | Enable Basic auth for API endpoints (/api/metrics/*). Disabled by default for security. |
DOCS_ALLOW_BASIC_AUTH | false | Enable Basic auth for documentation endpoints (/docs, /redoc). Independent of API setting. |
Behavior ChangesΒΆ
| Component | Before | After |
|---|---|---|
| Admin UI | Basic auth (broken - validated but not passed to routes) | Email/password authentication (PLATFORM_ADMIN_EMAIL/PASSWORD) |
| API Endpoints | Basic auth allowed | Basic auth disabled by default. Set API_ALLOW_BASIC_AUTH=true to enable. |
| Documentation | Basic auth configurable | Unchanged - controlled by DOCS_ALLOW_BASIC_AUTH |
| CLI Tools | Basic auth fallback | Only uses Basic auth if API_ALLOW_BASIC_AUTH=true |
Migration GuideΒΆ
For API access:
# Recommended: Use JWT tokens
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
--username admin@example.com --exp 10080 --secret $JWT_SECRET_KEY)
# If Basic auth is required (development only):
export API_ALLOW_BASIC_AUTH=true
For Admin UI:
# Use email/password authentication
PLATFORM_ADMIN_EMAIL=admin@example.com
PLATFORM_ADMIN_PASSWORD=your-secure-password
Security RationaleΒΆ
- JWT tokens are more secure: They have expiration, can be revoked, and don't transmit passwords on every request
- Basic auth sends credentials on every request: Higher risk of credential exposure
- Separation of concerns: Admin UI authentication is now clearly separate from API authentication
- Defense in depth: Disabled by default reduces attack surface