Configure RabbitMQ with OAuth2.0

Securing RabbitMQ with OAuth 2.0 Authentication using Auth0.com

Posted by Alfus Jaganathan on Wednesday, March 27, 2024

Background

If you are looking into configuring a RabbitMQ server or cluster with OAuth 2.0 authentication, this article will provide you with a solid starting point and key insights. Throughout this discussion, I’ve chosen to use Auth0 as the OAuth 2.0 provider. Nonetheless, the principles and steps outlined here are applicable to any OAuth 2.0 providers.

Understanding OAuth 2.0

Before diving deeper into the configuration process, it’s crucial to grasp the foundational concepts of the OAuth 2.0 protocol and understand how it operates. OAuth 2.0 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. It works by allowing the issuance of tokens to third-party clients by an authorization server, with the approval of the resource owner. The client then uses the token to access the protected resources hosted by the resource server.

OAuth 2.0 in RabbitMQ Authentication and Authorization

RabbitMQ leverages OAuth 2.0 for both authentication and authorization, allowing for a more secure and flexible management of permissions. In the context of RabbitMQ:

  • Authentication involves verifying the identity of a user or service attempting to connect to RabbitMQ. With OAuth 2.0, RabbitMQ can authenticate users based on tokens rather than traditional username/password methods. This is particularly useful for microservices architectures and cloud-native applications, where managing credentials can be cumbersome and less secure.

  • Authorization is about determining what authenticated users are allowed to do. In RabbitMQ, this translates to what queues and exchanges a user can access, and the actions they can perform (e.g., read, write). OAuth 2.0 tokens can carry claims (or scopes) that define these permissions explicitly. RabbitMQ can then interpret these claims to grant or deny access to its resources accordingly.

Integrating OAuth 2.0 with RabbitMQ

To integrate OAuth 2.0 authentication and authorization with RabbitMQ, you will need to:

  1. Setup an OAuth 2.0 Provider: Configure an OAuth 2.0 provider such as Auth0. This involves creating a tenant, defining API access permissions (scopes), and registering your RabbitMQ server as a client.

  2. Configure RabbitMQ to Use OAuth 2.0: Adjust RabbitMQ configuration to accept OAuth 2.0 tokens. This typically involves installing and configuring a plugin that understands how to validate and interpret these tokens.

  3. Obtain Tokens: Clients need to obtain OAuth 2.0 tokens from the configured provider. These tokens must include the necessary scopes for the actions the client intends to perform on RabbitMQ.

  4. Connect to RabbitMQ with Tokens: Instead of using traditional credentials, clients authenticate to RabbitMQ using the obtained OAuth 2.0 tokens. RabbitMQ validates these tokens with the OAuth 2.0 provider to ensure they are valid and checks the token’s claims to determine what actions the client is authorized to perform.

This setup enhances the security and flexibility of RabbitMQ by leveraging the robust OAuth 2.0 protocol for authentication and authorization. It streamlines the management of permissions, especially in dynamic and complex environments, making it a highly recommended approach for modern application architectures.

Getting Started

Prerequisites

Note: RabbitMQ can be installed through various methods. The configurations should be applicable without issues, provided they are correctly implemented in the rabbitmq.conf file or specified as environment variables.

Setup an OAuth 2.0 Provider (Auth0)

I closely followed the Auth0 Example from RabbitMQ’s official documentation to configure the OAuth 2.0 provider, focusing specifically on several key areas:

Creating RabbitMQ API: This step involves setting up RabbitMQ to interface with Auth0, defining the scopes and permissions that will be managed through OAuth 2.0. More details can be found here: Creating RabbitMQ API.

Configuring Permissions in RabbitMQ API: This section explains how to configure permissions within the RabbitMQ API, which is essential for managing access and actions within RabbitMQ. Further information is available at: Configuring permissions in RabbitMQ API.

Creating an OAuth Client for the Management UI: Necessary for integrating RabbitMQ’s Management UI with OAuth 2.0, this step allows users to log in via Auth0. The procedure is described here: Creating an OAuth client for the Management UI.

Creating an Application: This involves setting up an application in Auth0 to be used by RabbitMQ for authentication and authorization. Detailed instructions can be found at: Creating an Application.

Creating a New User and Granting Permissions: The final step includes creating users within Auth0 and assigning the necessary permissions for interacting with RabbitMQ. More information is available at: Creating a new user and granting permissions.

Obtaining and using Signing Key: Signing key is an important step in securing RabbitMQ with OAuth 2.0, as it ensures that the tokens used for authentication and authorization are valid and come from a trusted source. This process involves several steps, from obtaining the signing key from Auth0 to configuring RabbitMQ to use this key.

Note: You can obtain a signing key from any OAuth 2.0 provider that uses JSON Web Tokens (JWTs) for access tokens. Typically you can obtain it from a JWKS Endpoint or through a manual process, referring the provider specific configuration.

Following the above steps, as outlined in the RabbitMQ documentation, is crucial for integrating OAuth 2.0 with RabbitMQ, for a successful configuration authentication and authorization mechanism.

Configure RabbitMQ to Use OAuth 2.0

After obtaining the signing key, you need to configure RabbitMQ to use this key for verifying JWTs. Here, RabbitMQ’s configuration is updated via the cluster operator as below. Update the existing cluster configuration to include:

Plugin: Add rabbitmq_auth_backend_oauth2 to the additionalPlugins list.

Management Plugin Configuration: Add management UI client application OAuth details management.oauth_client_id, management.oauth_client_secret, management.oauth_provider_url, and management.oauth_scopes into additionalConfig.

Auth Backends: Add rabbit_auth_backend_oauth2 as an auth_backend into additionalConfig. This configuration specifies OAuth 2.0 as an authentication option.

Backend Configuration: Include resource_server_id and resource_server_type in additionalConfig, setting both values to rabbitmq. Other configurations like preferred_username_claims, extra_scopes_source, jwks_url, default_key, and signing_keys can be added to the advancedConfig section.

Combining all these, the configuration YAML must be updated as shown below. Replace each of the placeholders [place-holder] with the correct values.

Note: I am omitting the existing configuration items for better clarity of changes specific to OAuth 2.0 configuration.

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
  name: rabbitmq
  namespace: rabbitmq-clusters
spec:
  rabbitmq:
    additionalPlugins:
      - rabbitmq_auth_backend_oauth2
    additionalConfig: |
      auth_backends.1 = rabbit_auth_backend_oauth2
      auth_backends.2 = internal
      auth_oauth2.resource_server_id = rabbitmq
      auth_oauth2.resource_server_type = rabbitmq
      management.oauth_client_id = [your-client-id]
      management.oauth_client_secret = [your-client-secret]
      management.oauth_provider_url = https://[your-auth0-domain].us.auth0.com/
      management.oauth_scopes = "openid profile rabbitmq.*"      
    advancedConfig: |
      [
          {rabbitmq_auth_backend_oauth2, [
            {preferred_username_claims, [<<"user_name">>,<<"email">>,<<"name">>]},
            {extra_scopes_source, <<"permissions">>},
            {key_config, [
            {jwks_url, <<"https://[your-auth0-domain].us.auth0.com/.well-known/jwks.json">>},
            {default_key, <<"[your-auth0-default-key]">>},
            {signing_keys, #{
              <<"[your-auth0-default-key]">> => {pem, <<"[your-public-key]">>}
              }}
            ]}
          ]} 
        ].       

Once the above configuration details are appended to your original cluster configuration, re-deploy RabbitmqCluster. This command will redeploy the cluster pods. After the deployment is successful, you should be able to log into the management UI using OAuth 2.0. Similarly, if you have a client created and configured for an AMQP client, you can use the credentials to connect, authenticate and authorize against the RabbitMQ server. Refer Java AMQP client - OAuth2.0 for details.

For advanced authentication and authorization configuration, refer to the official documentation - oauth2 examples.

Hope you had fun coding!


comments powered by Disqus