Trusted Upstream Browser Auth
Use trusted upstream auth when MindRoom API and browser routes sit behind a deployment-owned access layer that has already authenticated the human. This mode is disabled by default. Do not enable it unless the reverse proxy or identity gateway strips client-supplied copies of the trusted headers and injects verified values itself. Header-only mode is a compatibility option for deployments where MindRoom is only reachable through that trusted gateway. Prefer strict JWT mode when the gateway can provide a signed upstream assertion.
Why It Exists
Agent-issued OAuth links are normal browser links such as /api/oauth/google_drive/authorize?connect_token=....
The connect token records the Matrix requester that triggered the missing-credentials tool result.
In a hosted multi-user private-agent deployment, the browser opening that link must authenticate as the same requester.
The standalone MINDROOM_OWNER_USER_ID setting maps every dashboard request to one Matrix user, so it is only appropriate for single-owner deployments.
It is not a hosted multi-user identity solution.
Environment
Configure the header names that your access layer owns:
MINDROOM_TRUSTED_UPSTREAM_AUTH_ENABLED=true
MINDROOM_TRUSTED_UPSTREAM_USER_ID_HEADER=X-MindRoom-User-Id
MINDROOM_TRUSTED_UPSTREAM_EMAIL_HEADER=X-MindRoom-User-Email
MINDROOM_TRUSTED_UPSTREAM_MATRIX_USER_ID_HEADER=X-MindRoom-Matrix-User-Id
MINDROOM_TRUSTED_UPSTREAM_EMAIL_TO_MATRIX_USER_ID_TEMPLATE='@{localpart}:example.org'
MINDROOM_TRUSTED_UPSTREAM_USER_ID_HEADER is required when trusted upstream auth is enabled.
The user ID value must be stable for the authenticated browser user.
MINDROOM_TRUSTED_UPSTREAM_EMAIL_HEADER is optional unless header-only auth uses MINDROOM_TRUSTED_UPSTREAM_EMAIL_TO_MATRIX_USER_ID_TEMPLATE.
When the email-to-Matrix template is set without strict JWT mode, MINDROOM_TRUSTED_UPSTREAM_EMAIL_HEADER is required because MindRoom derives the Matrix localpart from that trusted email value.
When present, the email value is stored in request.scope["auth_user"]["email"].
MINDROOM_TRUSTED_UPSTREAM_MATRIX_USER_ID_HEADER is optional for shared dashboard access.
For private user and user_agent OAuth flows, the trusted identity must resolve to the requester identity used by Matrix-backed tool execution.
Prefer MINDROOM_TRUSTED_UPSTREAM_MATRIX_USER_ID_HEADER when your access layer can supply a real Matrix ID.
When the access layer only supplies email, set MINDROOM_TRUSTED_UPSTREAM_EMAIL_TO_MATRIX_USER_ID_TEMPLATE to derive the Matrix ID from the trusted email localpart.
For example, the template @{localpart}:example.org maps alice@example.com to @alice:example.org.
The template must contain exactly one {localpart} placeholder.
Derived Matrix IDs must pass MindRoom's Matrix user ID parser.
Strict JWT Mode
Strict mode requires each trusted-upstream request to carry both the configured identity headers and a signed JWT from the upstream gateway. Enable it when the gateway publishes a JWKS endpoint and issues short-lived assertions for authenticated browser requests. In strict mode, spoofing the trusted identity header alone is not enough because MindRoom verifies the JWT signature, expiry, issuer, audience, and configured email claim before accepting the request.
MINDROOM_TRUSTED_UPSTREAM_REQUIRE_JWT=true
MINDROOM_TRUSTED_UPSTREAM_JWT_HEADER=X-Trusted-Jwt
MINDROOM_TRUSTED_UPSTREAM_JWKS_URL=https://gateway.example.com/.well-known/jwks.json
MINDROOM_TRUSTED_UPSTREAM_JWT_AUDIENCE=mindroom-dashboard
MINDROOM_TRUSTED_UPSTREAM_JWT_ISSUER=https://gateway.example.com
MINDROOM_TRUSTED_UPSTREAM_JWT_EMAIL_CLAIM=email
MINDROOM_TRUSTED_UPSTREAM_JWT_USER_ID_CLAIM=sub
MINDROOM_TRUSTED_UPSTREAM_JWT_MATRIX_USER_ID_CLAIM=matrix_user_id
MINDROOM_TRUSTED_UPSTREAM_REQUIRE_JWT is disabled by default to preserve existing header-only deployments.
When it is set to true, MINDROOM_TRUSTED_UPSTREAM_JWT_HEADER, MINDROOM_TRUSTED_UPSTREAM_JWKS_URL, MINDROOM_TRUSTED_UPSTREAM_JWT_AUDIENCE, and MINDROOM_TRUSTED_UPSTREAM_JWT_ISSUER are required.
MINDROOM_TRUSTED_UPSTREAM_JWT_EMAIL_CLAIM defaults to email.
Set MINDROOM_TRUSTED_UPSTREAM_JWT_USER_ID_CLAIM when the trusted user ID header contains a stable ID that is distinct from the email address.
Set MINDROOM_TRUSTED_UPSTREAM_JWT_MATRIX_USER_ID_CLAIM when the trusted Matrix user ID header contains a Matrix identity that should be accepted in strict mode.
MindRoom caches the JWKS response briefly and refreshes it automatically so key rotation can take effect without fetching keys on every request.
If the JWT is missing, expired, signed by an unknown key, issued by the wrong issuer, meant for the wrong audience, missing a configured identity claim, or inconsistent with a configured trusted identity header, MindRoom returns 401.
When MINDROOM_TRUSTED_UPSTREAM_JWT_USER_ID_CLAIM is set, the trusted user ID header must match that verified JWT claim.
When MINDROOM_TRUSTED_UPSTREAM_JWT_USER_ID_CLAIM is not set, the trusted user ID header must match the verified email claim because no separate signed user ID is available.
When a trusted email header is configured, that email value must match MINDROOM_TRUSTED_UPSTREAM_JWT_EMAIL_CLAIM.
When MINDROOM_TRUSTED_UPSTREAM_JWT_MATRIX_USER_ID_CLAIM is set, MINDROOM_TRUSTED_UPSTREAM_MATRIX_USER_ID_HEADER must match that verified JWT claim.
When no Matrix user ID claim is configured, strict mode only accepts a Matrix identity derived from the verified email via MINDROOM_TRUSTED_UPSTREAM_EMAIL_TO_MATRIX_USER_ID_TEMPLATE.
That derivation can use the verified JWT email claim even when MINDROOM_TRUSTED_UPSTREAM_EMAIL_HEADER is not configured.
When no Matrix user ID claim or email-to-Matrix template is configured, strict mode rejects MINDROOM_TRUSTED_UPSTREAM_MATRIX_USER_ID_HEADER because that header is not backed by a signed identity.
Instance Chart
For the hosted instance chart, configure the equivalent values:
trustedUpstreamAuth:
enabled: "true"
userIdHeader: X-MindRoom-User-Id
emailHeader: X-MindRoom-User-Email
matrixUserIdHeader: X-MindRoom-Matrix-User-Id
emailToMatrixUserIdTemplate: "@{localpart}:example.org"
requireJwt: "true"
jwtHeader: X-Trusted-Jwt
jwksUrl: https://gateway.example.com/.well-known/jwks.json
jwtAudience: mindroom-dashboard
jwtIssuer: https://gateway.example.com
jwtEmailClaim: email
jwtUserIdClaim: sub
jwtMatrixUserIdClaim: matrix_user_id
The chart renders these values as the MINDROOM_TRUSTED_UPSTREAM_* runtime environment variables.
The instance chart fails rendering when trustedUpstreamAuth.emailToMatrixUserIdTemplate is set without trustedUpstreamAuth.emailHeader.
The instance chart also fails rendering when trustedUpstreamAuth.requireJwt is true without jwtHeader, jwksUrl, jwtAudience, or jwtIssuer.
The template value must contain exactly one {localpart} placeholder.
When using the platform provisioner, configure the platform chart with matching provisioner values:
provisioner:
trustedUpstreamAuth:
enabled: "true"
userIdHeader: X-MindRoom-User-Id
emailHeader: X-MindRoom-User-Email
matrixUserIdHeader: X-MindRoom-Matrix-User-Id
emailToMatrixUserIdTemplate: "@{localpart}:example.org"
requireJwt: "true"
jwtHeader: X-Trusted-Jwt
jwksUrl: https://gateway.example.com/.well-known/jwks.json
jwtAudience: mindroom-dashboard
jwtIssuer: https://gateway.example.com
jwtEmailClaim: email
jwtUserIdClaim: sub
jwtMatrixUserIdClaim: matrix_user_id
The platform chart renders these as INSTANCE_TRUSTED_UPSTREAM_* variables on the provisioner deployment.
The platform chart fails rendering when provisioner.trustedUpstreamAuth.emailToMatrixUserIdTemplate is set without provisioner.trustedUpstreamAuth.emailHeader.
The platform chart also fails rendering when provisioner.trustedUpstreamAuth.requireJwt is true without jwtHeader, jwksUrl, jwtAudience, or jwtIssuer.
Security Boundary
Trusted upstream auth is provider-neutral.
A reverse proxy, ingress controller, OAuth2 proxy, or another gateway can provide the headers as long as MindRoom only receives gateway-verified values.
Never expose a MindRoom instance with this mode enabled directly to browsers or the public internet.
In header-only mode, every network path to MindRoom must remove any client-provided copies of the trusted headers before adding authenticated values.
In strict JWT mode, the same header-stripping requirement still applies, and MindRoom additionally validates the signed assertion.
If the configured trusted user ID header is missing, MindRoom returns 401.
If strict JWT mode is enabled and the configured JWT header is missing or invalid, MindRoom returns 401.
If a trusted browser identity does not map to the Matrix requester stored in an OAuth connect token, MindRoom returns 403.
Existing Supabase platform auth and standalone API-key auth remain available when trusted upstream auth is not enabled.