rabbitmq-server icon indicating copy to clipboard operation
rabbitmq-server copied to clipboard

Support Rich Authorization Request OAuth2 specification

Open MarcialRosales opened this issue 3 years ago • 4 comments

Proposed Changes

Rich Authorization Request specification is an extension to the OAuth2 specification. It is still a draft but it has been stable for a good while. This specification moves away from the concept of scopes and instead proposes a new JWT token field called authorization_details which consists of a list of permissions where each permission is meant for one type of resource server and it defines a list of locations and a list of actions allowed on those locations. Here is an example of a JWT token using this specification:

{
    ... ,
  "authorization_details": [
     {
      "type":"rabbitmq-endpoint", 
      "locations": [
          "cluster:rabbitmq/vhost:finance"
      ],
      "actions": [ "read", "write", "configure", "tag:administrator" ]
    }
  ]

}

A RabbitMQ server/cluster is configured with a resource_server_id which uniquely identifies it. And in this new PR we are introducing a new setting called resource_server_type which is used as a permissions' discriminator. In other words, RabbitMq will only look into those permissions which are tagged with a type which matches the value configured in resource_server_type . In the example above, resource_server_id would be rabbitmq and resource_server_type would be rabbitmq-endpoint.

The specification does not make any recommendations on the exact format of the values in the locations field. The format will be defined by the resource server the location is targeting. More on that, this PR suggests the following location's structure : cluster:<resource_server_id_pattern>[/vhost:<vhostpattern>][/queue:<queue_name_pattern>|/exchange:<exchange_name_pattern][/routing-key:<routing_key_pattern>]. Any string separated by / which does not conform to <key>:<value> is ignored. For instance, if your locations start with a prefix, e.g. vrn/cluster:rabbitmq, the vrn pattern part is ignored.

Although it is not strictly speaking part of the Rich Authorization Request specification, we are including into this PR the ability to disable the validation of the aud field. Thru a new setting called verify_aud we can disable it. By default, it is enabled.

Types of Changes

What types of changes does your code introduce to this project?

  • [ ] Bug fix (non-breaking change which fixes issue #NNNN)
  • [x ] New feature (non-breaking change which adds functionality)
  • [x] Breaking change (fix or feature that would cause an observable behavior change in existing systems)
  • [ ] Documentation improvements (corrections, new content, etc)
  • [ ] Cosmetic change (whitespace, formatting, etc)
  • [ ] Build system and/or CI

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask on the mailing list. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • [ ] I have read the CONTRIBUTING.md document
  • [ ] I have signed the CA (see https://cla.pivotal.io/sign/rabbitmq)
  • [x] I have added tests that prove my fix is effective or that my feature works
  • [x] All tests pass locally with my changes
  • [ ] If relevant, I have added necessary documentation to https://github.com/rabbitmq/rabbitmq-website
  • [ ] If relevant, I have added this change to the first version(s) in release-notes that I expect to introduce it

Further Comments

This PR will be validated by stakeholders who requested it before being reviewed and merged/released.

MarcialRosales avatar Jul 15 '22 11:07 MarcialRosales

@MarcialRosales Why do we need tag in actions (example: tag:administrator)? there is a possibility that identity providers can reserve ":" for some specific use cases. Why can't we consider administrator as admin without "tag"?

{ "authorization_details": [ { "type" : "rabbitmq",
"locations": ["cluster:finance/vhost:primary-*"], "actions": [ "read", "write", "configure" ] }, { "type" : "rabbitmq", "locations": ["cluster:finance", "cluster:inventory" ], "actions": ["tag:administrator" ] } ] }

srinivasbanoth1988 avatar Aug 05 '22 15:08 srinivasbanoth1988

Because that's how management plug-in roles have been since 2010.

We cannot avoid potential tag name conflicts, the idea is that RabbitMQ tokens/scopes are not reused by arbitrary apps.

michaelklishin avatar Aug 05 '22 19:08 michaelklishin

It appears this issue with the colon on the user-tag's actions is a blocker because the identity provider does not tolerate colons on the action's values. To overcome this issue there are a few alternatives.

  1. very simple - Drop the prefix tag: from the action mane, e,g. administrator or management. There should not be any clash with other resource servers because every authorization entry within authorization_details is for just one resource type.
  2. rather complex - Configure rabbitmq with action_aliases similar to scope_aliases. This rather complex alternative not only allows us to map a user-defined action name to a rabbitmq action name, e.g. admin -> tag:administrator but also map one user-defined action to many rabbitmq¡'s actions:
{action_aliases, #{
               <<"FullAccess">>      => [<<"tag:administrator">>, <<"configure">>, <<"write">>, <<"read">> ],

Although this latter alternative is more flexible I would rather stick to the simpler one.

MarcialRosales avatar Aug 09 '22 12:08 MarcialRosales

@MarcialRosales both seem OK to me but we can try dropping the prefix since the set of tags used by the management plugin is known ahead of time.

We can also support a different character for separator, e.g. tag=management

michaelklishin avatar Aug 09 '22 14:08 michaelklishin