rabbitmq-oauth2-tutorial icon indicating copy to clipboard operation
rabbitmq-oauth2-tutorial copied to clipboard

Access to vhost '/' refused.

Open apostolides opened this issue 9 months ago • 17 comments

Hello and good evening.

I am following the suggested documentation for using Keycloak with rabbitmq. However I always get the following access denied error:

(530) "NOT_ALLOWED - access to vhost '/' refused for user '05c4b0ae-9c07-4ab6-b3a1-c1e9e5e36759'"

I believe the keycloak scopes (even though they are present in the JWT) are not visible on rabbit as seen here.

rabbitmq-1  | 2025-02-21 13:59:04.992226+00:00 [debug] <0.699.0> Computing username from client's JWT token: [<<"05c4b0ae-9c07-4ab6-b3a1-c1e9e5e36759">>] -> 05c4b0ae-9c07-4ab6-b3a1-c1e9e5e36759
rabbitmq-1  | 2025-02-21 13:59:04.992305+00:00 [debug] <0.699.0> User '05c4b0ae-9c07-4ab6-b3a1-c1e9e5e36759' authenticated successfully by backend rabbit_auth_backend_oauth2
rabbitmq-1  | 2025-02-21 13:59:04.994004+00:00 [debug] <0.699.0> Matching virtual host '/' against the following scopes:
rabbitmq-1  | 2025-02-21 13:59:04.994058+00:00 [error] <0.699.0> Error on AMQP connection <0.699.0> (192.168.48.1:39816 -> 192.168.48.2:5672, user: '05c4b0ae-9c07-4ab6-b3a1-c1e9e5e36759', state: opening):        
rabbitmq-1  | 2025-02-21 13:59:04.994058+00:00 [error] <0.699.0> access to vhost '/' refused for user '05c4b0ae-9c07-4ab6-b3a1-c1e9e5e36759'

Decoded token field (after authenticating with keycloak) looks like:

  "scope": "email rabbitmq.read:*/* rabbitmq.configure:*/* rabbitmq.write:*/* profile",

I am using files from this example.

What am I missing?

Thanks in advance!

Reproduction steps

  1. Import Keycloak realm settings
  2. Modify resource_server_id to include appropriate aud claim (works since I can authenticate)
  3. Run RabbitMQ with docker (tried latest image and also 4.0.2-management as seen on examples)
  4. Run provided Pika client. ...

Expected behavior

Client should be able to access vhost.

Additional context

No response

apostolides avatar Feb 21 '25 14:02 apostolides

Hi @apostolides , sorry for the late reply. I have just followed the steps in the example keycloak (main branch) and it all works. Here is the successful log from RabbitMQ.

2025-04-10 08:11:38.742855+00:00 [debug] <0.886.0> ResourceServers: #{}
2025-04-10 08:11:38.742877+00:00 [debug] <0.886.0> ResourceServersIds: []
2025-04-10 08:11:38.742938+00:00 [debug] <0.886.0> OAuth 2 JWT: resolved resource_server_id: <<"rabbitmq">> oauth_provider_id: root
2025-04-10 08:11:38.743056+00:00 [debug] <0.886.0> OAuth 2 JWT: signing_key_id : '<<"Gnl2ZlbRh3rAr6Wymc988_5cY7T5GuePd5dpJlXDJUk">>'
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0> OAuth 2 JWT: signing key found: 'json', '#{<<"alg">> => <<"RS256">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"e">> => <<"AQAB">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"kid">> =>
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                                <<"Gnl2ZlbRh3rAr6Wymc988_5cY7T5GuePd5dpJlXDJUk">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"kty">> => <<"RSA">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"n">> =>
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                                <<"2dP-vRn-Kj-S_oGd49kq6-CKNAduCC1raLfTH7B3qjmZYm45yDl-XmgK9CNmHXkho9qvmhdksdzDVsdeDlhKIdcIWadhqDzdtn1hj_22iUwrhH0bd475hlKcsiZ-oy_sdgGgAzvmmTQmdMqEXqV2B9q9KFBmo4Ahh_6-d4wM1rH9kxl0RvMAKLe-daoIHIjok8hCO4cKQQEw_ErBe4SF2cr3wQwCfF1qVu4eAVNVfxfy_uEvG3Q7x005P3TcK-QcYgJxav3lictSi5dyWLgGQAvkknWitpRK8KVLypEj5WKej6CF8nq30utn15FQg0JkHoqzwiCqqeen8GIPteI7Vw">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"use">> => <<"sig">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"x5c">> =>
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                                [<<"MIICmDCCAYACCQC7YJWOo6LVaDANBgkqhkiG9w0BAQsFADAOMQwwCgYDVQQDDANqd3QwHhcNMjIwNTA2MTQzNjQ5WhcNMjIwNjA1MTQzNjQ5WjAOMQwwCgYDVQQDDANqd3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ0/69Gf4qP5L+gZ3j2Srr4Io0B24ILWtot9MfsHeqOZlibjnIOX5eaAr0I2YdeSGj2q+aF2Sx3MNWx14OWEoh1whZp2GoPN22fWGP/baJTCuEfRt3jvmGUpyyJn6jL+x2AaADO+aZNCZ0yoRepXYH2r0oUGajgCGH/r53jAzWsf2TGXRG8wAot751qggciOiTyEI7hwpBATD8SsF7hIXZyvfBDAJ8XWpW7h4BU1V/F/L+4S8bdDvHTTk/dNwr5BxiAnFq/eWJy1KLl3JYuAZAC+SSdaK2lErwpUvKkSPlYp6PoIXyerfS62fXkVCDQmQeirPCIKqp56fwYg+14jtXAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACJlWtWnQqepYiFCijVgy/eM5KL0rFZOZ6HNefoJTrYY1QYZrWxRz3M4u9JpUy4fBvGHxElBElcr3fXLXDytH9EwMJm1E5x3o3qkQyWdXYGW6ZF58dklcJTdejOxEO373qpywVwbCFGiuIt7s5v4v+r2HOg3D4elb2bqxmRim04xIkVZufKo+h6a8dBb5JEU3UaxyGDBR0IdyjhyBo1+HhH+RqZsxQhQ7DhlIGWUYZNCu13fb1GNSMiNqspKnMpFdQ4Bfpsb7vOeEK+aqJjCKcYbuGa6BiwBjbKYyEF5r01Tob50dcVPfIGOqO0lQ3IsV31n9LSoAAtaVqioPK1rvDo=">>],
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"x5t">> =>
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                                <<"bP4amLmJLd-wDJ8cl_b2Ucw6U14">>,
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                            <<"x5t#S256">> =>
2025-04-10 08:11:38.743104+00:00 [debug] <0.886.0>                                                <<"iS5v-gxo8zOviP0XHQcB9u9RwOjz9U9o_e054bk_KU8">>}'
2025-04-10 08:11:38.745090+00:00 [debug] <0.886.0> ResourceServers: #{}
2025-04-10 08:11:38.745118+00:00 [debug] <0.886.0> ResourceServersIds: []
2025-04-10 08:11:38.745172+00:00 [debug] <0.886.0> Computing username from client's JWT token: [<<"50b38464-440c-48d2-880d-050a7d28f7b0">>] -> 50b38464-440c-48d2-880d-050a7d28f7b0
2025-04-10 08:11:38.745230+00:00 [debug] <0.886.0> User '50b38464-440c-48d2-880d-050a7d28f7b0' authenticated successfully by backend rabbit_auth_backend_oauth2
2025-04-10 08:11:38.746718+00:00 [debug] <0.886.0> Matching virtual host '/' against the following scopes: read:*/*,write:*/*,configure:*/*
2025-04-10 08:11:38.747087+00:00 [info] <0.886.0> connection 172.18.0.1:55390 -> 172.18.0.3:5672: user '50b38464-440c-48d2-880d-050a7d28f7b0' authenticated and granted access to vhost '/'

MarcialRosales avatar Apr 10 '25 08:04 MarcialRosales

I would like to continue this thread and report a similar problem, but using azure provider and the access denied error only occurs when I try to retrieve messages, it seems to me that the administrator tag in the rabbit profile is being ignored:

Return from the authentication api:

{"error":"not_authorised","reason":"Access refused."}

The JWT follows this format:

{
"aud": "xxxxxxxxxx-xxxxx-9d73-7e5a34de6cf1",
"iss": "https://sts.windows.net/858c1424-15c5-4788-bc86-9ef4bdcee2f7/",
"iat": 1744559994,
"nbf": 1744559994,
"exp": 1744565265,
"acr": "1", 
"aio": "dsad12exxxxxxxxxxxxxxxxxxxQG5pgTLpNOeaIQCz8scW+5WiLnl77/sJsSz5GpunIaU9OngiY7DuRHccLLtGWMR",
 "amr": [
 "pwd",
 "mfa"
 ],
 "appid": "xxxxxxxxxxxx-xxxxx-48f0-9d73-xxxxxxxxx",
 "appidacr": "1",
 "family_name": "xxxxx",
 "given_name": "Renato",
 "ipaddr": "xxxx:xxx:xxxxx:xx:xx:xxxx:xx:xx",
 "name": "Renato de Souza",
 "oid": "xxxxxxxxx-2d19-483c-85a1-xxxxxxx",
 "onprem_sid": "S-1-5-21-xxxxxxxxxxxx07146231-1581001300-27402",
 "rh": "1.ASDQWxxxxxxxxxxxxxxxx8hp70vc7i97dxR132DASPBInXN-WjTebPFRAZsGAA.",
 "roles": [
 "xxxxxxxxx-dsds-xxxx-9d73-xaadsdas.tag:administrator"
 ],
 "scp": "email profile User.Read",
 "sid": "xxxxxxxxxxxxxxxxx49-98499ed1a05f",
 "sub": "xxxxxxxxxxxxxgjDV2_wxxxxxHEbGgipM",
 "tid": "xxxxxxxxxx-15c5-4788-xxxxxx-9ef4bdcee2f7",
 "unique_name": "[email protected]",
 "upn": "[email protected]",
 "uti": "xxxxxxxxxxxxxxxxxxx",
 "see": "1.0"
}

Log error rabbit: Example create queue in other vhost:

2025-04-13 16:50:06.101210+00:00 [warning] <0.2662.0> Declare queue error: configure access to queue 'teste123' in vhost 'meu-vhost' refused for user 'zmAcvRqHKuaxhQ6s3kCWgjDV2_wubp49XrEHEbGgipM'

Steps to reproduce:

Environment: Kubernetes Rabbit version: docker.io/bitnami/rabbitmq:3.12.14-debian-12-r7

Role Azure Portal:

xxx-38a1-xxxx-9d73-7e5a34de6cf1.tag:administrator

rabbit.config:

## OIDC Configuration
    auth_backends.1 = rabbit_auth_backend_oauth2
   auth_backends.2 = rabbit_auth_backend_internal

   management.oauth_enabled = true
   management.oauth_client_id = CLIENT_ID
   management.oauth_client_secret = SECRET_ID
   management.oauth_provider_url = https://login.microsoftonline.com/TENANT_ID

   auth_oauth2.resource_server_id = CLIENT_ID
   auth_oauth2.additional_scopes_key = roles
   auth_oauth2.jwks_url = https://login.microsoftonline.com/TENANT_ID/discovery/keys?appid=CLIENT_ID

Expected behavior Azure user must be able to retrieve messages in queues.

renatovieiradesouza avatar Apr 13 '25 16:04 renatovieiradesouza

hi @renatovieiradesouza , in RabbitMQ , the user scopes tag:administrator, tag:management, tag:monitoring and tag:policymaker are meant for the management ui only. If your user , be administrator or not, wants to read from, write to, or declare a resource such as a queue or an exchange, it must have the appropriate scope/permissions. you are missing read permission on the vhost and queue you want to read from. Check out https://www.rabbitmq.com/docs/oauth2#step5 and https://www.rabbitmq.com/docs/oauth2#scope-translation

However, you gave me an idea to update the tutorial for azure/entra to test a messaging application like PerfTest. This is what the keycloak tutorial does. To run a PerfTest against azure, i need to update the instructions here to add read and write in addition to configure.

MarcialRosales avatar Apr 14 '25 05:04 MarcialRosales

hi @renatovieiradesouza , in RabbitMQ , the user scopes tag:administrator, tag:management, tag:monitoring and tag:policymaker are meant for the management ui only. If your user , be administrator or not, wants to read from, write to, or declare a resource such as a queue or an exchange, it must have the appropriate scope/permissions. you are missing read permission on the vhost and queue you want to read from. Check out https://www.rabbitmq.com/docs/oauth2#step5 and https://www.rabbitmq.com/docs/oauth2#scope-translation

However, you gave me an idea to update the tutorial for azure/entra to test a messaging application like PerfTest. This is what the keycloak tutorial does. To run a PerfTest against azure, i need to update the instructions here to add read and write in addition to configure.

I found this documentation and I was able to understand that permission is missing, but what structure would the Azure profile configuration be?

This:

xxxx-38a1-48f0-9d73-xxxx.tag:write

That's what confused me, or should I adjust the scope configuration in my rabbit configuration file:

auth_oauth2.scope_aliases.admin = rabbitmq.tag:administrator rabbitmq.read:*/

I tried the setting, but rabbit doesn't recognize the configuration, what would be the correct one for azure?

auth_oauth2.scope_prefix = api://
 auth_oauth2.additional_scopes_key = extra_scope
 auth_oauth2.scope_aliases.admin = xxxx-38a1-48f0-xxxx-xxxxx.tag:administrator rabbitmq.read:*/

my complete config:

auth_backends.1 = rabbit_auth_backend_oauth2
auth_backends.2 = rabbit_auth_backend_internal

management.oauth_enabled = true
management.oauth_client_id = CLIENT_ID
management.oauth_client_secret = SECRET_ID
management.oauth_provider_url = https://login.microsoftonline.com/TENANT_ID

auth_oauth2.resource_server_id = CLIENT_ID
auth_oauth2.additional_scopes_key = roles
auth_oauth2.jwks_url = https://login.microsoftonline.com/TENANT_ID/discovery/keys?appid=CLIENT_ID
auth_oauth2.scope_prefix = api://
auth_oauth2.additional_scopes_key = extra_scope
auth_oauth2.scope_aliases.admin = CLIENT_ID.tag:administrator rabbitmq.read:*/

renatovieiradesouza avatar Apr 14 '25 12:04 renatovieiradesouza

if you followed the whole azure/entra tutorial, there is a section where it creates a role to grant the configure scope .. see how the scope is named Application_ID.configure:*/* . THen you grant that azure role to the user and by doing that you are essentially giving the user the scope associated to the role. So, in your case would be <CLIENT_ID>.read:*/*. and maybe also <CLIENT_ID>.write:*/*. You do not need to do any mapping (a.k.a scope aliases) because you can create a role in azure that matches what rabbitmq expects.

MarcialRosales avatar Apr 14 '25 15:04 MarcialRosales

Mind you that if you are using topic exchange, you have to use a slightly longer scope format. see https://www.rabbitmq.com/docs/oauth2#topic-exchange-scopes

MarcialRosales avatar Apr 14 '25 15:04 MarcialRosales

if you followed the whole azure/entra tutorial, there is a section where it creates a role to grant the configure scope .. see how the scope is named Application_ID.configure:*/* . THen you grant that azure role to the user and by doing that you are essentially giving the user the scope associated to the role. So, in your case would be <CLIENT_ID>.read:*/*. and maybe also <CLIENT_ID>.write:*/*. You do not need to do any mapping (a.k.a scope aliases) because you can create a role in azure that matches what rabbitmq expects.

I did exactly that, but I can't log in with this configuration, only with xxx.tag:administrator is it possible to log in.

None of these options mapped to the azure roles work:

CLIENT_ID.configure:*/*
CLIENT_ID.read:*/*
CLIENT_ID.write:*/*

Role working Azure:

CLIENT_ID.tag:administrator

JWT being built:

"iss": "https://sts.windows.net/858c1424-15c5-4788-bc86-9ef4bdcee2f7/",
"iat": 1744645877,
"nbf": 1744645877,
"exp": 1744649874,
"acr": "1",
"aio": "Axxxxxxxxxj8PCVFsdV+IGoSgprrq46Dyp+HC8OmN7AKkq/NSIDq4LT8guvSdL7ystjvNvcHI/ur/DUv",
 "amr": [
 "pwd",
 "mfa"
 ],
 "appid": "CLIENT_ID",
 "appidacr": "1",
 "family_name": "de Souza",
 "given_name": "Renato",
 "ipaddr": "2804:868:d057:e632:8c42:8de4:e7af:8a4",
 "name": "Renato de Souza",
 "oid": "XXXX-XXX-483c-85a1-XXXX",
 "onprem_sid": "S-1-5-21-XXXX-507146231-XXXX-27402",
 "rh": "1.XXXXX-WjTebPFRAZsGAA.",
 "roles": [
 "CLIENT_ID.configure:*/*"
 ],
 "scp": "email profile User.Read",
 "sid": "XXXX-XXX-fdab-XXX-877f8afc04bf",
 "sub": "XXXXXXX",
 "tid": "TENANT_ID",
 "unique_name": "[email protected]",
 "upn":  "[email protected]",
 "uti": "csFDSF3243FDSDfsd",
 "see": "1.0"
}

we tried to configure the two roles:

"roles": [
"CLIENT_ID.tag:administrator,CLIENT_ID.configure:*/*"
],

But they are not organized as items in the jwt, as the example in the doc shows:

Image

documentation In Azure I can't associate two roles to a user.

rsouzabossabox avatar Apr 14 '25 16:04 rsouzabossabox

But you have it already .. you have already create a role with the value CLIENT_ID.configure:*/*. Why you cannot create another role where you replace configure for read and another one for write? And grant your user those two new roles?

MarcialRosales avatar Apr 14 '25 18:04 MarcialRosales

Azure does not allow adding more than one role to the user.

Image

rsouzabossabox avatar Apr 14 '25 19:04 rsouzabossabox

Ok, if you are limited to just one role, what you can do is define a role with whatever format you like e.g. "super-rabbitmq-user", and define a scope alias in RabbitMQ. Take into account that only 4.1 onwards allows you to configure scope aliases in .conf style. In earlier versions you have to use the old .config style (https://www.rabbitmq.com/docs/oauth2-examples#using-scope-aliases). You would define a scope aliases of "super-rabbitmq-user" or whatever you choose, mapped to whatever scopes you want to grant it, e.g. administrator scope, configure/read/write scope across any vhost and resource name..

MarcialRosales avatar Apr 14 '25 19:04 MarcialRosales

Ok, if you are limited to just one role, what you can do is define a role with whatever format you like e.g. "super-rabbitmq-user", and define a scope alias in RabbitMQ. Take into account that only 4.1 onwards allows you to configure scope aliases in .conf style. In earlier versions you have to use the old .config style (https://www.rabbitmq.com/docs/oauth2-examples#using-scope-aliases). You would define a scope aliases of "super-rabbitmq-user" or whatever you choose, mapped to whatever scopes you want to grant it, e.g. administrator scope, configure/read/write scope across any vhost and resource name..

Please, can you tell me where I can find the scope documentation for versions prior to 4?

I am currently using kubernetes and the rabbit version is:

docker.io/bitnami/rabbitmq:3.12.14-debian-12-r7

I did not find how to configure this scope with erlang in the configuration file, thanks for the collaboration.

My configuration, but not working:

advanced.config: |-
[ {rabbitmq_auth_backend_oauth2, [ {extra_scopes_source, <<"roles">>}, {scope_aliases, #{ <<"CLIENT_ID.tag:administrator">> => [ <<"CLIENT_ID.read:/">> ], <<"CLIENT_ID.configure:/">> => [ <<"CLIENT_ID.configure:/">> ] }} ]} ].

Other attempts:

apiVersion: v1
data:
  rabbitmq.conf: |-
    ## OIDC Configuration
    auth_backends.1 = rabbit_auth_backend_oauth2
    auth_backends.2 = rabbit_auth_backend_internal    

    management.oauth_enabled = true
    management.oauth_client_id = CLIENT_ID
    management.oauth_client_secret = SECRET
    management.oauth_provider_url = https://login.microsoftonline.com/TENANT

    auth_oauth2.resource_server_id = CLIENT_ID
    auth_oauth2.additional_scopes_key = roles
    auth_oauth2.scope_aliases.admin = CLIENT_ID.tag:administrator CLIENT_ID.read:*/*

    auth_oauth2.jwks_url = https://login.microsoftonline.com/TENANT/discovery/keys?appid=CLIENT_ID
  advanced.config: |-    
    [
      {rabbitmq_auth_backend_oauth2, [
        {extra_scopes_source, <<"admin">>},
        {scope_aliases, #{
          <<"CLIENT_ID.tag:administrator">> => [
            <<"CLIENT_ID.read:*/*">>
          ]
        }}
      ]}
    ].  
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/instance: rabbitmq
    app.kubernetes.io/name: rabbitmq
  name: rabbitmq-config
  namespace: messaging

Role azure with value: admin

Image

Results without erlang and with scope_aliases:

2025-04-15 00:08:15.602167+00:00 [error] <0.136.0> You've tried to set auth_oauth2.scope_aliases.admin, but there is no setting with that name.
2025-04-15 00:08:15.616770+00:00 [error] <0.136.0>   Did you mean one of these?
2025-04-15 00:08:15.746526+00:00 [error] <0.136.0>     auth_oauth2.scope_prefix
2025-04-15 00:08:15.746619+00:00 [error] <0.136.0>     auth_oauth2.default_key
2025-04-15 00:08:15.746686+00:00 [error] <0.136.0>     auth_oauth2.https.cacertfile
2025-04-15 00:08:15.747986+00:00 [error] <0.136.0> Error preparing configuration in phase transform_datatypes:
2025-04-15 00:08:15.748072+00:00 [error] <0.136.0>   - Conf file attempted to set unknown variable: auth_oauth2.scope_aliases.admin
BOOT FAILED

Results with erlang:

401

JWT

"iss": "https://sts.windows.net/TEANTNT_ID/",
"iat": 1744675759,
"nbf": 1744675759,
"exp": 1744680768,
"acr": "1",
"aio": "AWQAm/8ZAxxxxxxai8LfiPNKkt8GS9Nc7G1xQtmpMKncZSeo5TynnIyST9GVYJHTWfNvReWa58e9EzY+n0Yol6b31aujeXnZ89UCI6jpzRGs7YHNGSbpDdc",
"amr": [
  "pwd",
  "mfa"
],
"appid": "XXXXXXXXXXXXXXXXXX",
"appidacr": "1",
"family_name": "XXXXa",
"given_name": "Renato",
"ipaddr": "2804:868:d057:e632:8c42:8de4:e7af:8a4",
"name": "Renato XXXXa",
"oid": "cxxxxx2d19-483c-85a1-d3689eeac3db",
"onprem_sid": "S-1-5-21-2030126595-507146231-1581001300-27402",
"rh": "1.AQYxxxxxvc7i97dxRkihOPBInXN-WjTebPFRAZsGAA.",
"roles": [
  "admin"
],
"scp": "email profile User.Read",
"sid": "xxxx3602-520897045b6c",
"sub": "zmAxxxxxx3kCWgjDV2_wubp49XrEHEbGgipM",
"tid": "TEANTNT_ID",
"unique_name": "[email protected]",
"upn": "[email protected]",
"uti": "hNLAJdxxxxsL9PM7AA",
"ver": "1.0"
}

Diagnostics Rabbit:

rabbitmq-diagnostics environment

setting scope_aliases doesn't seem to have any effect in rabbit

[{accept,[]},
 {amqp10_common,[]},
 {amqp_client,
     [{prefer_ipv6,false},{ssl_options,[]},{writer_gc_threshold,1000000000}]},
 {asn1,[]},
 {aten,
     [{detection_threshold,0.99},
      {heartbeat_interval,100},
      {poll_interval,5000},
      {scaling_factor,1.5}]},
 {base64url,[]},
 {compiler,[]},
 {cowboy,[]},
 {cowlib,[]},
 {credentials_obfuscation,[{enabled,true}]},
 {crypto,[{fips_mode,false},{rand_cache_size,896}]},
 {cuttlefish,[]},
 {eldap,[]},
 {enough,[]},
 {gen_batch_server,[]},
 {inets,[]},
 {jose,[{crypto_fallback,true}]},
 {kernel,
     [{connect_all,true},
      {inet_default_connect_options,[{nodelay,true}]},
      {inet_dist_listen_max,25672},
      {inet_dist_listen_min,25672},
      {logger,
          [{handler,default,logger_std_h,
               #{config => #{type => standard_io},
                 formatter =>
                     {logger_formatter,
                         #{single_line => false,legacy_header => true}}}}]},
      {logger_level,notice},
      {logger_sasl_compatible,false},
      {net_tickintensity,4},
      {net_ticktime,60},
      {prevent_overlapping_partitions,false},
      {shell_docs_ansi,auto},
      {shell_history_drop,[]},
      {shutdown_func,{rabbit_prelaunch,shutdown_func}}]},
 {mnesia,
     [{dir,
          "/bitnami/rabbitmq/mnesia/[email protected]"},
      {dump_log_time_threshold,90000},
      {dump_log_write_threshold,5000}]},
 {observer_cli,
     [{plugins,
          [#{module => rabbit_observer_cli_classic_queues,title => "Classic",
             shortcut => "CQ",sort_column => 4},
           #{module => rabbit_observer_cli_quorum_queues,title => "Quorum",
             shortcut => "QQ",sort_column => 4}]},
      {scheduler_usage,disable}]},
 {os_mon,
     [{start_cpu_sup,false},
      {start_disksup,false},
      {start_memsup,false},
      {start_os_sup,false}]},
 {osiris,
     [{data_dir,
          "/bitnami/rabbitmq/mnesia/[email protected]/stream"},
      {max_segment_size_chunks,256000},
      {port_range,{6000,6500}},
      {replica_forced_gc_default_interval,4999},
      {replication_transport,tcp}]},
 {prometheus,[]},
 {public_key,[]},
 {ra,[{data_dir,
          "/bitnami/rabbitmq/mnesia/[email protected]/quorum"},
      {wal_max_batch_size,4096},
      {wal_max_size_bytes,536870912}]},
 {rabbit,
     [{auth_backends,
          [rabbit_auth_backend_oauth2,rabbit_auth_backend_internal]},
      {auth_mechanisms,['PLAIN','AMQPLAIN']},
      {autocluster,
          [{peer_discovery_backend,rabbit_peer_discovery_classic_config}]},
      {autoheal_state_transition_timeout,60000},
      {background_gc_enabled,false},
      {background_gc_target_interval,60000},
      {backing_queue_module,rabbit_priority_queue},
      {channel_max,2047},
      {channel_operation_timeout,15000},
      {channel_tick_interval,60000},
      {cluster_formation,
          [{node_cleanup,
               [{cleanup_interval,10},{cleanup_only_log_warning,true}]},
           {peer_discovery_k8s,
               [{k8s_host,"kubernetes.default.svc.cluster.local"}]}]},
      {cluster_keepalive_interval,10000},
      {cluster_nodes,{[],disc}},
      {cluster_partition_handling,autoheal},
      {collect_statistics,fine},
      {collect_statistics_interval,5000},
      {config_entry_decoder,[{passphrase,undefined}]},
      {consumer_timeout,1800000},
      {credentials_obfuscation_fallback_secret,<<"nocookie">>},
      {credit_flow_default_credit,{400,200}},
      {data_dir,
          "/bitnami/rabbitmq/mnesia/[email protected]"},
      {dead_letter_worker_consumer_prefetch,32},
      {dead_letter_worker_publisher_confirm_timeout,180000},
      {default_consumer_prefetch,{false,0}},
      {default_permissions,[<<".*">>,<<".*">>,<<".*">>]},
      {default_user,<<"admin">>},
      {default_user_tags,[administrator]},
      {default_vhost,<<"/">>},
      {delegate_count,16},
      {disk_free_limit,50000000},
      {disk_monitor_failure_retries,10},
      {disk_monitor_failure_retry_interval,120000},
      {enabled_plugins_file,
          "/opt/bitnami/rabbitmq/etc/rabbitmq/enabled_plugins"},
      {feature_flags_file,
          "/bitnami/rabbitmq/mnesia/rabbit@rabbitmq-0.rabbitmq-headless.messaging.svc.cluster.local-feature_flags"},
      {fhc_read_buffering,false},
      {fhc_write_buffering,true},
      {frame_max,131072},
      {halt_on_upgrade_failure,true},
      {handshake_timeout,10000},
      {heartbeat,60},
      {log,
          [{categories,
               [{default,[{compress_on_rotate,false}]},
                {ra,[{compress_on_rotate,false}]},
                {upgrade,[{compress_on_rotate,false}]},
                {federation,[{compress_on_rotate,false}]},
                {queue,[{compress_on_rotate,false}]},
                {mirroring,[{compress_on_rotate,false}]},
                {channel,[{compress_on_rotate,false}]},
                {connection,[{compress_on_rotate,false}]}]},
           {file,
               [{compress,false},
                {formatter,
                    {rabbit_logger_text_fmt,
                        #{single_line => false,use_colors => false,
                          prefix_format => [time," [",level,"] ",pid," "],
                          level_format => lc,
                          time_format => {rfc3339,32,[]},
                          color_esc_seqs => #{},
                          line_format => [msg]}}}]},
           {console,
               [{stdio,stdout},
                {formatter,
                    {rabbit_logger_text_fmt,
                        #{single_line => false,use_colors => true,
                          prefix_format => [time," [",level,"] ",pid," "],
                          level_format => lc,
                          time_format => {rfc3339,32,[]},
                          color_esc_seqs =>
                              #{error => "\e[38;5;160m",info => [],
                                warning => "\e[38;5;214m",
                                debug => "\e[38;5;246m",
                                notice => "\e[38;5;87m",
                                emergency => "\e[1;37m\e[48;5;196m",
                                alert => "\e[1;37m\e[48;5;93m",
                                critical => "\e[1;37m\e[48;5;20m"},
                          line_format => [msg]}}}]},
           {exchange,
               [{formatter,
                    {rabbit_logger_text_fmt,
                        #{single_line => false,use_colors => false,
                          prefix_format => [time," [",level,"] ",pid," "],
                          level_format => lc,
                          time_format => {rfc3339,32,[]},
                          color_esc_seqs => #{},
                          line_format => [msg]}}}]},
           {journald,
               [{fields,
                    [{"SYSLOG_IDENTIFIER","rabbitmq-server"},
                     syslog_timestamp,syslog_pid,priority,
                     {"ERL_PID",pid},
                     {"CODE_FILE",file},
                     {"CODE_LINE",line},
                     {"CODE_MFA",mfa}]}]},
           {syslog,
               [{formatter,
                    {rabbit_logger_text_fmt,
                        #{single_line => false,use_colors => false,
                          prefix_format => [],level_format => lc,
                          time_format => {rfc3339,32,[]},
                          color_esc_seqs => #{},
                          line_format => [msg]}}}]}]},
      {loopback_users,[]},
      {max_message_size,134217728},
      {memory_monitor_interval,2500},
      {mirroring_flow_control,true},
      {mirroring_sync_batch_size,4096},
      {mnesia_table_loading_retry_limit,10},
      {mnesia_table_loading_retry_timeout,30000},
      {msg_store_credit_disc_bound,{4000,800}},
      {msg_store_file_size_limit,16777216},
      {msg_store_index_module,rabbit_msg_store_ets_index},
      {msg_store_io_batch_size,4096},
      {msg_store_shutdown_timeout,600000},
      {num_ssl_acceptors,10},
      {num_tcp_acceptors,10},
      {password_hashing_module,rabbit_password_hashing_sha256},
      {plugins_dir,"/opt/bitnami/rabbitmq/plugins"},
      {plugins_expand_dir,
          "/bitnami/rabbitmq/mnesia/rabbit@rabbitmq-0.rabbitmq-headless.messaging.svc.cluster.local-plugins-expand"},
      {proxy_protocol,false},
      {queue_explicit_gc_run_operation_threshold,1000},
      {queue_index_embed_msgs_below,4096},
      {queue_index_max_journal_entries,32768},
      {queue_master_locator,<<"min-masters">>},
      {quorum_cluster_size,3},
      {quorum_commands_soft_limit,32},
      {ranch_connection_max,infinity},
      {release_series_eol_date,{2024,2,21}},
      {reverse_dns_lookups,false},
      {server_properties,[]},
      {ssl_allow_poodle_attack,false},
      {ssl_apps,[asn1,crypto,public_key,ssl]},
      {ssl_cert_login_from,distinguished_name},
      {ssl_handshake_timeout,5000},
      {ssl_listeners,[]},
      {ssl_options,[]},
      {stream_messages_soft_limit,256},
      {tcp_listen_options,
          [{backlog,128},
           {nodelay,true},
           {linger,{true,0}},
           {exit_on_close,false}]},
      {tcp_listeners,[{"auto",5672}]},
      {trace_vhosts,[]},
      {track_auth_attempt_source,false},
      {tracking_execution_timeout,15000},
      {vhost_restart_strategy,continue},
      {vm_memory_calculation_strategy,rss},
      {vm_memory_high_watermark,0.4},
      {vm_memory_high_watermark_paging_ratio,0.5},
      {writer_gc_threshold,1000000000}]},
 {rabbit_common,[]},
 {rabbitmq_auth_backend_ldap,
     [{anon_auth,false},
      {dn_lookup_attribute,none},
      {dn_lookup_base,none},
      {dn_lookup_bind,as_user},
      {group_lookup_base,none},
      {idle_timeout,300000},
      {log,false},
      {other_bind,as_user},
      {pool_size,64},
      {port,389},
      {resource_access_query,{constant,true}},
      {servers,undefined},
      {ssl_options,[]},
      {tag_queries,[{administrator,{constant,false}}]},
      {timeout,infinity},
      {topic_access_query,{constant,true}},
      {use_ssl,false},
      {use_starttls,false},
      {user_bind_pattern,none},
      {user_dn_pattern,"${username}"},
      {vhost_access_query,{constant,true}}]},
 {rabbitmq_auth_backend_oauth2,
     [{extra_scopes_source,<<"roles">>},
      {key_config,
          [{jwks_url,
               "https://login.microsoftonline.com/TENANT_ID/discovery/keys?appid=CLIENT_ID"}]},
      {resource_server_id,<<"CLIENT_ID">>}]},
 {rabbitmq_management,
     [{content_security_policy,
          "script-src 'self' 'unsafe-eval' 'unsafe-inline'; object-src 'self'"},
      {cors_allow_origins,[]},
      {cors_max_age,1800},
      {http_log_dir,none},
      {load_definitions,none},
      {management_db_cache_multiplier,5},
      {max_http_body_size,10000000},
      {oauth_client_id,"CLIENT_ID"},
      {oauth_client_secret,"KWD8Q~aRRm2DDOGW.Ic8P3rUNMDuusw8YFA0qaKI"},
      {oauth_enabled,true},
      {oauth_provider_url,
          "https://login.microsoftonline.com/TENANT_ID"},
      {process_stats_gc_timeout,300000},
      {stats_event_max_backlog,250}]},
 {rabbitmq_management_agent,
     [{rates_mode,basic},
      {sample_retention_policies,
          [{global,[{605,5},{3660,60},{29400,600},{86400,1800}]},
           {basic,[{605,5},{3600,60}]},
           {detailed,[{605,5}]}]}]},
 {rabbitmq_prelaunch,[]},
 {rabbitmq_prometheus,
     [{return_per_object_metrics,false},
      {ssl_config,[]},
      {tcp_config,[{port,15692}]}]},
 {rabbitmq_web_dispatch,[]},
 {ranch,[]},
 {recon,[]},
 {redbug,[]},
 {runtime_tools,[{ttb_autostart_module,ttb_autostart}]},
 {sasl,[{errlog_type,error}]},
 {seshat,[]},
 {ssl,[]},
 {stdlib,[]},
 {stdout_formatter,[]},
 {syntax_tools,[]},
 {sysmon_handler,
     [{busy_dist_port,true},
      {busy_port,false},
      {gc_ms_limit,0},
      {heap_word_limit,0},
      {port_limit,100},
      {process_limit,100},
      {schedule_ms_limit,0}]},
 {systemd,
     [{auto_formatter,true},
      {logger,
          [{handler,systemd_journal,systemd_journal_h,
               #{formatter => {logger_formatter,#{template => [msg]}}}}]},
      {unset_env,true},
      {watchdog_scale,2}]},
 {thoas,[]},
 {tools,[{file_util_search_methods,[{[],[]},{"ebin","esrc"},{"ebin","src"}]}]},
 {xmerl,[]}]

rsouzabossabox avatar Apr 14 '25 21:04 rsouzabossabox

Hi @renatovieiradesouza you have to replace CLIENT_ID/Application_ID with your actual client_id/application_id in your azure env. you cannot put literally CLIENT_ID. That is why i am previous comment (https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/issues/44#issuecomment-2802105254) I put it around < >. I recommend you upgrade to 4.0.

To choose the docs' version you go to the top right corner of any docs page, and choose the version. Currently you can choose from next which means future 4.1, 4.0 (the default), 3.13 and 3.12.

I will make it clearer in the docs that Application_ID or CLIENT_ID are keywords you have to replace with the actual value. For instance, this is wrong auth_oauth2.resource_server_id = CLIENT_ID . Take a look at this example https://github.com/rabbitmq/rabbitmq-oauth2-tutorial/blob/main/conf/entra/rabbitmq.conf.tmpl#L9C1-L9C58

You can see that it is not putting literally CLIENT_ID but instead auth_oauth2.resource_server_id = {Application(client) ID} . And the file extension is rabbitmq.conf.tmpl .. it is a template, it is meant to be edited and replace {Application(client) ID} with your actual value.

MarcialRosales avatar Apr 15 '25 04:04 MarcialRosales

Can you upgrade to a newer version? I just found out that you are on 3.12... If not, you should be ok with 3.12. But many things have changed since 3.12. For instance scope aliases can be configured in .conf format.

MarcialRosales avatar Apr 15 '25 06:04 MarcialRosales

This CLIENT_ID is an example, I am changing it to real values, today my SSO is working correctly. I only have a problem setting the two roles, because Azure does not allow adding the two roles to a user or group.

I just wanted to understand how I can set the roles through .conf, because I still don't understand.

Look at my file as it is:

the values ​​are not real, but it is already like that.

 rabbitmq.conf: |-
 ## OIDC Configuration
 auth_backends.1 = rabbit_auth_backend_oauth2
 auth_backends.2 = rabbit_auth_backend_internal

 management.oauth_enabled = true
 management.oauth_client_id = 123123q1bw-43q1-65y7-6q32-7q88w5s4w
 management.oauth_client_secret = KWD8Q~aRRm2DDOGW.dasd^1asdd12sff23413
 management.oauth_provider_url = https://login.microsoftonline.com/978c9687-15c5-9965-bc86-9qq6bdcee2f7
 management.oauth_scopes = openid profile api://123123q1bw-43q1-65y7-6q32-7q88w5s4w/rabbitmq

 auth_oauth2.resource_server_id = 484671b7-43q1-48f0-6q32-7q88w5s4w
 auth_oauth2.additional_scopes_key = roles
 auth_oauth2.jwks_url = https://login.microsoftonline.com/978c9687-15c5-9965-bc86-9qq6bdcee2f7/discovery/keys?appid=484671b7-38a1-48f0-6q32-7q88w5s4w

Recap.

I need help or some document that demonstrates how I can set the necessary roles via conf, because in Azure it is not possible to follow the documentation steps to use the two configured roles.

Image

bitnami rabbit version 4.1 is not available, the official 4.1 image does not run on kubernetes natively

I attempted use new version: image: docker.io/bitnami/rabbitmq:4.0.1 but not working scope configuration:

auth_oauth2.scope_aliases.superadmin = 698457b7-43a1-45f0-6d73-7e8a27de6cf1.tag:administrator 698457b7-43a1-45f0-6d73-7e8a27de6cf1.configure:*/*

rabbitmq 10:53:24.97 INFO  ==> ** RabbitMQ setup finished! **
rabbitmq 10:53:24.99 INFO  ==> ** Starting RabbitMQ **
2025-04-17 10:53:27.035400+00:00 [error] <0.156.0> You've tried to set auth_oauth2.scope_aliases.superadmin, but there is no setting with that name.
2025-04-17 10:53:27.061129+00:00 [error] <0.156.0>   Did you mean one of these?
2025-04-17 10:53:27.284765+00:00 [error] <0.156.0>     auth_oauth2.scope_prefix
2025-04-17 10:53:27.284921+00:00 [error] <0.156.0>     auth_oauth2.issuer
2025-04-17 10:53:27.285034+00:00 [error] <0.156.0>     auth_oauth2.end_session_endpoint
2025-04-17 10:53:27.286772+00:00 [error] <0.156.0> Error preparing configuration in phase transform_datatypes:
2025-04-17 10:53:27.286831+00:00 [error] <0.156.0>   - Conf file attempted to set unknown variable: auth_oauth2.scope_aliases.superadmin
BOOT FAILED
2025-04-17 10:53:27.290606+00:00 [error] <0.156.0>
2025-04-17 10:53:27.290606+00:00 [error] <0.156.0> BOOT FAILED
2025-04-17 10:53:27.290606+00:00 [error] <0.156.0> ===========
2025-04-17 10:53:27.290606+00:00 [error] <0.156.0> Error during startup: {error,failed_to_prepare_configuration}
2025-04-17 10:53:27.290606+00:00 [error] <0.156.0>
===========
Error during startup: {error,failed_to_prepare_configuration}

I attempted with latest version:

config:
auth_oauth2.scope_aliases.1.alias = api://as78747-874w-8qq4-9d73-478q4a57e4:superadmin
auth_oauth2.scope_aliases.1.scope = as78747-874w-8qq4-9d73-478q4a57e4.tag:administrator as78747-874w-8qq4-9d73-478q4a57e4.configure:*/*    

error:
2025-04-17 11:03:17.378216+00:00 [error] <0.153.0> You've tried to set auth_oauth2.scope_aliases.1.alias, but there is no setting with that name.
2025-04-17 11:03:17.414462+00:00 [error] <0.153.0>   Did you mean one of these?
2025-04-17 11:03:17.709252+00:00 [error] <0.153.0>     auth_oauth2.scope_prefix
2025-04-17 11:03:17.709370+00:00 [error] <0.153.0>     auth_oauth2.https.cacertfile
2025-04-17 11:03:17.709489+00:00 [error] <0.153.0>     auth_oauth2.https.verify
2025-04-17 11:03:17.710506+00:00 [error] <0.153.0> You've tried to set auth_oauth2.scope_aliases.1.scope, but there is no setting with that name.
2025-04-17 11:03:17.710590+00:00 [error] <0.153.0>   Did you mean one of these?
2025-04-17 11:03:18.043221+00:00 [error] <0.153.0>     auth_oauth2.scope_prefix
2025-04-17 11:03:18.043333+00:00 [error] <0.153.0>     auth_oauth2.https.cacertfile
2025-04-17 11:03:18.043387+00:00 [error] <0.153.0>     auth_oauth2.resource_server_type
2025-04-17 11:03:18.044690+00:00 [error] <0.153.0> Error preparing configuration in phase transform_datatypes:
2025-04-17 11:03:18.044776+00:00 [error] <0.153.0>   - Conf file attempted to set unknown variable: auth_oauth2.scope_aliases.1.scope
2025-04-17 11:03:18.044861+00:00 [error] <0.153.0>   - Conf file attempted to set unknown variable: auth_oauth2.scope_aliases.1.alias

In Official Docker Hub not available 4.1 version:

  • https://hub.docker.com/r/bitnami/rabbitmq/tags

The documentation to 4.1 version

Image

rsouzabossabox avatar Apr 16 '25 21:04 rsouzabossabox

The solution to this scenario of Azure's limitation on adding more than one role to a user is solved by using Azure groups.

The view of groups will look strange, but you can simply add the group for each permission you want.

Imagine that you need these permissions:

CLIENT_ID.tag:administrator
CLIENT_ID.read:*/*
CLIENT_ID.write:*/*

You will add the group 3 times and associate each role with them.

This will load the roles into your JWT.

It is important to ensure group permissions and no longer user permissions in the API permissions.

rsouzabossabox avatar Apr 21 '25 23:04 rsouzabossabox

Great you got solved it.

The scope_aliases mapping only exist in 4.1 in .conf. To use scope_aliases in 4.0 you have to use .config.

Will you push a PR to the Entra/Azure tutorial with your findings?

Have you found out this section https://www.rabbitmq.com/docs/oauth2#discovery-endpoint-params of the docs? If you set up issuer plus the discovery endpoint parameters you do not need to set management.oauth_provider_url or auth_oauth2.jwks_url . This feature was added for vendors like Azure/Entra.

MarcialRosales avatar Apr 22 '25 07:04 MarcialRosales

Great you got solved it.

The scope_aliases mapping only exist in 4.1 in .conf. To use scope_aliases in 4.0 you have to use .config.

Will you push a PR to the Entra/Azure tutorial with your findings?

Have you found out this section https://www.rabbitmq.com/docs/oauth2#discovery-endpoint-params of the docs? If you set up issuer plus the discovery endpoint parameters you do not need to set management.oauth_provider_url or auth_oauth2.jwks_url . This feature was added for vendors like Azure/Entra.

Thanks for the help. I will send the PR.

rsouzabossabox avatar Apr 22 '25 17:04 rsouzabossabox