Authentication mechanisms
Albus supports four mechanisms for authenticating requests from the Albus platform to your hosted MCP servers:
The default example below provides the complete agent configuration and run
request. Each alternative shows a diff against the default MCP server entry;
apply only the diff for the mechanism your server requires.
1. Albus identity JWT (default)
Use the default mechanism to authenticate Albus without provisioning a shared secret or registering Albus as a client with your identity provider. A server entry with noauth field defaults to
"auth": {"type": "albus_identity_jwt"}: every request to the server
includes the header Authorization: Bearer <token>, where <token> is an
identity token minted by Albus for your organization and the declared server
URL.
Authenticate the CLI or SDK with ALBUS_API_KEY as described in
Authentication. Replace the example MCP
URL with your server’s Streamable HTTP endpoint.
Discovery is available at
<issuer>/.well-known/openid-configuration.
Identity token claims
Identity token claims
The identity token is an ES256 JWT with exactly the following six claims:
The issuer serves the standard discovery documents, public and cached for one
hour:
<issuer>/.well-known/openid-configuration<issuer>/.well-known/jwks.json
Verify with Next.js on Vercel: mcp-handler and jose
Verify with Next.js on Vercel: mcp-handler and jose
withMcpAuth from mcp-handler calls your verifier function with the bearer
token and answers 401 when the verifier function returns undefined.
Verify the token with jose:app/api/mcp/route.ts
jwtVerify checks the signature against the JWKS and validates the exp,
iss, and aud claims. Tool handlers read the session id and invocation id
from ctx.http?.authInfo.extra.Verify with Go: coreos/go-oidc
Verify with Go: coreos/go-oidc
oidc.NewProvider reads the discovery document from the issuer; the
ClientID field of oidc.Config is the expected audience.Multiple organizations and key rotation
Multiple organizations and key rotation
If your server is used by more than one Albus organization, keep an allowlist
of the issuers you trust and configure a verifier for each issuer. Select the
verifier by the token’s
iss claim only when the iss value is in the
allowlist. Never fetch a JWKS from an issuer you did not configure: whoever
controls the iss value would then control the signing key.Signing keys rotate by kid. Configure the verifier to select the key by
kid and refetch the JWKS when a token contains an unknown kid. New keys
are published before use; old keys remain published until tokens signed with
the old keys have expired. Do not pin a key or cache the JWKS beyond the
response’s cache headers.2. OAuth 2.0 client credentials
If your server already requires tokens from Auth0, Okta, WorkOS, or another OAuth 2.0 provider, useoauth2_client_credentials to keep the server’s
existing verification. Albus calls token_url with the client credentials
when the run starts and sends the returned access token as
Authorization: Bearer <access-token>.
Store the client secret as an Albus secret first (client_id may be a secret
reference or a literal):
Albus obtains the access token once, at launch, and does not refresh the access
token during the run. The access token must be valid for at least 10 minutes or
the launch fails. If the access token expires during a long run, every
401
from the server appears in the audit log as mcp_auth_rejected and as a tool
error visible to the model.
3. Static bearer token
Usebearer when your server accepts a fixed access token and does not need
an identity provider exchange. Albus resolves the secret at launch and sends
Authorization: Bearer <secret> on every MCP request.
Store the token without the Bearer prefix:
auth.token must be a secret reference; a raw token is rejected.
4. Custom headers
Useheaders when your server requires an API key in a custom header,
another authorization scheme, or a token the caller obtains before the run.
Header values can be secret references or literals.
For an X-API-Key header, store the key as a secret:
Authorization combine with any auth mode. An
Authorization entry in headers (in any casing) disables the default
identity token and is sent verbatim, so the value must be the complete header
value, scheme included (Bearer <token> or token <token>). A request with
both an explicit auth block and a headers.Authorization entry is rejected
with 400.
Caller-minted tokens
If your application already holds credentials for the server’s identity provider, mint a short-lived access token before callingrun_session and
pass the access token as a literal headers.Authorization value. Your server
keeps trusting the same provider, and the provider credentials stay with your
application.
With the minted access token in MCP_ACCESS_TOKEN, apply this change to the
default example before submitting the run. The CLI command uses jq to add
the header to the complete agent configuration.
"<literal>", so a token minted per run does not create a new revision, and a
retry with the same idempotency key and a freshly minted token re-attaches to
the original run.
Vercel Deployment Protection
Store the deployment bypass secret with Albus and use the headerx-vercel-protection-bypass with a value such as
albus.sh/secrets/acme-vercel-bypass. The bypass header lets the request
reach your handler; the handler still verifies the identity token to
authorize the request. Leave auth at its default to use both checks.
For 401 responses recorded as mcp_auth_rejected, check the issuer and
audience, the complete Authorization value, and the token’s expiry. See
Troubleshooting.