Authentication
The proxy handles two independent auth directions: inbound — validating tokens from MCP clients — and outbound — attaching credentials to upstream API requests.
Inbound auth
Inbound auth protects your MCP endpoint. Configure it per-group:
groups:
- name: default
endpoint: /mcp
upstreams: [kraken]
inbound_auth:
strategy: jwt
jwt:
issuer: https://auth.example.com
jwks_url: https://auth.example.com/.well-known/jwks.json
audience: mcp-anything JWT
Validates OIDC JWTs. JWKS keys are auto-rotated on expiry.
inbound_auth:
strategy: jwt
jwt:
issuer: https://auth.example.com
jwks_url: https://auth.example.com/.well-known/jwks.json
audience: my-mcp-proxy # optional, validates aud claim
algorithms: [RS256, ES256] # optional, defaults to RS256 Token introspection
Validates tokens via an OIDC introspection endpoint. Suitable for opaque tokens.
inbound_auth:
strategy: introspection
introspection:
endpoint: https://auth.example.com/oauth/introspect
client_id: ${INTROSPECTION_CLIENT_ID}
client_secret: ${INTROSPECTION_CLIENT_SECRET} API key
Validates a static key from a request header.
inbound_auth:
strategy: apikey
apikey:
header: X-API-Key
value: ${API_KEY} Lua
Custom validation logic in a Lua script. Receives the request headers and must return a boolean.
inbound_auth:
strategy: lua
lua:
source: scripts/validate_token.lua -- scripts/validate_token.lua
local token = headers["Authorization"]
if not token then return false end
-- custom validation logic
return token:sub(1, 7) == "Bearer " and #token > 20 JavaScript (Sobek)
Custom validation logic in a sandboxed ECMAScript runtime (Grafana Sobek). Receives the request headers as a plain object and must return a boolean.
inbound_auth:
strategy: js
js:
source: scripts/validate_token.js // scripts/validate_token.js
const token = headers["Authorization"] ?? "";
if (!token.startsWith("Bearer ")) return false;
// custom HMAC or structural check
return token.length > 20; None
inbound_auth:
strategy: none No authentication. Use this for development or for public endpoints.
Outbound auth
Outbound auth injects credentials into requests the proxy makes to upstream APIs. Configure it per-upstream:
upstreams:
- name: myapi
type: http
tool_prefix: api
base_url: https://api.example.com
openapi:
source: https://api.example.com/openapi.yaml
outbound_auth:
strategy: oauth2_client_credentials
oauth2_client_credentials:
token_url: https://auth.example.com/oauth/token
client_id: ${CLIENT_ID}
client_secret: ${CLIENT_SECRET}
scopes: [read:data, write:data] Bearer token
Injects a static Bearer token from an environment variable.
outbound_auth:
strategy: bearer
bearer:
token: ${API_TOKEN} OAuth2 Client Credentials
Performs the OAuth2 CC flow and caches the token until it expires, then refreshes automatically.
outbound_auth:
strategy: oauth2_client_credentials
oauth2_client_credentials:
token_url: https://auth.example.com/oauth/token
client_id: ${CLIENT_ID}
client_secret: ${CLIENT_SECRET}
scopes: [read, write] API key
Injects an API key as a header or query parameter.
outbound_auth:
strategy: api_key
api_key:
header: X-API-Key # or use: query: api_key
value: ${UPSTREAM_KEY} Lua
Custom token acquisition — useful for non-standard auth schemes.
outbound_auth:
strategy: lua
lua:
source: scripts/get_token.lua JavaScript (Sobek)
Token acquisition in a sandboxed ECMAScript runtime. The script must return a string that is used as the Authorization header value.
outbound_auth:
strategy: js
js:
source: scripts/get_token.js // scripts/get_token.js
const resp = ctx.fetch("https://auth.example.com/token", {
method: "POST",
body: JSON.stringify({ client_id: ctx.env.CLIENT_ID, client_secret: ctx.env.CLIENT_SECRET }),
headers: { "Content-Type": "application/json" },
});
return "Bearer " + resp.json().access_token; Per-operation bypass
Set x-mcp-auth-required: false on an operation via an overlay to skip outbound auth for that operation. Useful for public endpoints within an otherwise authenticated upstream.
- target: "$.paths[\"/public/status\"].get"
update:
x-mcp-auth-required: false Secret references
All config fields that reference secrets use ${ENV_VAR} syntax. The proxy expands these at startup from the process environment. Secret values are never logged.
See also
- Tool Groups — per-group inbound auth configuration
- OpenAPI Overlays — per-operation auth bypass