Skip to main content

RabbitMQ Keycloak OAuth2 401

Symptom

Use this guide when the RabbitMQ Management UI redirects to Keycloak successfully, but RabbitMQ returns 401 Unauthorized immediately after login, often on /api/whoami.

Historical signals from this failure mode included:

  • the browser reached the Keycloak login page normally
  • the redirect back to RabbitMQ succeeded
  • the first authenticated Management API request returned 401
  • RabbitMQ logs showed misleading fallback messages such as user 'rabbitmq' - invalid credentials

Current Repo Drift To Know First

The current repo still proves the Keycloak side of the integration:

  • lumie-infra/security/keycloak/common-values.yaml defines the public rabbitmq client
  • the same file defines the rabbitmq-admin client scope
  • that scope now includes an oidc-audience-mapper for rabbitmq

The current repo does not prove that RabbitMQ still enables the OAuth2 backend in Git. The inspected RabbitMQ manifests under lumie-infra/platform/rabbitmq/ currently show only auth_backends.1 = internal in the rendered additionalConfig, and no checked-in auth_oauth2.* settings were found.

That means this page remains a valid troubleshooting guide for the historical 401, but if you are debugging it now you must first verify whether OAuth2 is still enabled in the live broker or in a config path outside the current repo tree.

Likely Causes

Two independent failures produced the same 401:

  1. The Keycloak access token was missing aud: rabbitmq, so RabbitMQ rejected the token at the audience-check stage.
  2. RabbitMQ could not fetch or validate the JWKS endpoint because Erlang TLS rejected the wildcard certificate match for auth.lumie-edu.com.

The important lesson is that one 401 did not imply one root cause. Fixing the audience mapper alone still left the TLS failure in place.

Diagnostic Path

Decode the access token first

Inspect the Keycloak access token and confirm the audience claim includes rabbitmq. The current repo's fixed Keycloak scope expresses this in lumie-infra/security/keycloak/common-values.yaml.

Representative shape:

{
"aud": "rabbitmq",
"azp": "rabbitmq",
"preferred_username": "bluemayne"
}

If azp is present but aud is missing, the token can still look superficially correct while failing RabbitMQ audience verification.

Search RabbitMQ logs for TLS failures, not only OAuth keywords

The original JWKS failure surfaced as Erlang TLS log lines such as:

  • bad_cert
  • hostname_check_failed
  • ssl_handshake
  • Handshake Failure

If you grep only for oauth or whoami, you can miss the actual broker-side verification failure.

Confirm whether the broker still has OAuth2 enabled at all

Because the current repo no longer shows checked-in auth_oauth2.* settings, verify the live broker config before assuming this page is the right fix path. If the live config is internal-auth only, a 401 after Keycloak redirect may be coming from an entirely different access path.

Fix

  1. Keep the Keycloak rabbitmq-admin scope configured with an audience mapper for rabbitmq, which is the current state of lumie-infra/security/keycloak/common-values.yaml.
  2. If RabbitMQ OAuth2 is still enabled in the live broker, configure its HTTPS JWKS client to accept the wildcard hostname match required for auth.lumie-edu.com.

Representative shape:

auth_oauth2.resource_server_id = rabbitmq
auth_oauth2.issuer = https://auth.lumie-edu.com/realms/infra
auth_oauth2.https.hostname_verification = wildcard
  1. Re-test /api/whoami with a valid bearer token only after both the audience claim and the TLS path are confirmed.

Prevention

  • Treat RabbitMQ OAuth2 401s as potentially multi-cause during first-time SSO rollout.
  • When debugging Erlang-based services, search TLS logs separately from application-level OAuth logs.
  • Do not assume a wildcard certificate behaves the same across Go, Java, Python, and Erlang TLS stacks.
  • Keep the Keycloak client-scope contract explicit. For RabbitMQ, azp alone is not enough; aud must include the resource server identifier.

Verification

cd Lumie
rg -n "rabbitmq-admin|oidc-audience-mapper|included.custom.audience|clientId\": \"rabbitmq\"" \
lumie-infra/security/keycloak/common-values.yaml
rg -n "auth_oauth2|rabbitmq_auth_backend_oauth2|hostname_verification" \
lumie-infra/platform/rabbitmq

Success means the Keycloak audience mapper is still declared in Git, and the second command tells you whether the RabbitMQ OAuth2 broker settings are still repo-visible or must be verified directly from the live deployment.

Source Incident Detail

The April 11, 2026 source incident records the RabbitMQ-specific part of the Keycloak SSO rollout. A 401 from RabbitMQ management UI was not one bug. It was a chain of OAuth2 claim, audience, TLS, and broker-setting mismatches.

DetailValue
Affected componentRabbitMQ management OAuth2 login
Identity providerKeycloak infra realm
Main symptomlogin returned 401 even when Keycloak authentication appeared successful
Durable fix directionexplicit RabbitMQ audience and a dedicated authorization claim
Important trapRabbitMQ/Erlang TLS and OAuth logs need separate inspection

The source record's most reusable root causes were:

CauseWhy it produced 401
missing aud for RabbitMQthe broker did not see itself as an intended token audience
relying only on azpauthorized party is not the same as resource-server audience
trying to overload scopeKeycloak reconstructs final OAuth scope late in token creation
wildcard TLS behaviorErlang TLS verification did not match assumptions from other clients
incomplete broker config visibilitysome settings had to be checked in the live deployment, not only Git

When reproducing, keep the token itself as evidence. Decode aud, azp, scope, and any custom claim before changing broker config.