kafka-ui icon indicating copy to clipboard operation
kafka-ui copied to clipboard

RBAC Regex fails using Azure OAuth Roles

Open mriley-mbgp opened this issue 8 months ago • 6 comments

Issue submitter TODO list

  • [x] I've looked up my issue in FAQ
  • [x] I've searched for an already existing issues here
  • [x] I've tried running main-labeled docker image and the issue still persists there
  • [x] I'm running a supported version of the application which is listed here

Describe the bug (actual behavior)

After upgrading to Kafbat 1.2.0 via Helm Chart 1.4.12, it is expected that we have support for using regex to identify subjects for roles when configuring RBAC permissions. We use Microsoft Entra ID as a generic OAuth2 Provider, with custom-params configured to set the roles-field to roles, which allows us to utilise App Roles within EntraID to assign our users to the subjects Kafbat is configured to read.

Our redacted OAuth configuration is this:

type: OAUTH2
oauth2:
  client:
    azure:
      clientId: <redacted>
      clientSecret: <redacted>
      scope: openid
      client-name: azure
      provider: azure
      issuer-uri: <redacted>
      jwk-set-uri: <redacted>
      user-name-attribute: email
      custom-params:
        type: oauth 
        roles-field: roles 

Our RBAC is configured like this:

rbac:
    roles:
      - name: "readonly-global"
        clusters:
          - dev
        subjects:
          - provider: oauth
            type: role
            value: ".*-ADMIN"
            isRegex: true
        permissions:
          - resource: clusterconfig
            actions: [ "view" ]
          - resource: topic
            value: ".*"
            actions: 
              - VIEW
          - resource: consumer
            value: ".*"
            actions: [ view ]
          - resource: schema
            value: ".*"
            actions: [ view ]
          - resource: connect
            value: ".*"
            actions: [ view ]
          - resource: acl
            actions: [ view ]
      - name: "readdelete-testrole"
        clusters:
          - dev
        subjects:
          - provider: oauth
            type: role
            value: "dev.engsoft.user"
        permissions:
          - resource: topic
            value: mgp.engsoft\..*
            actions: 
            - MESSAGES_READ
            - MESSAGES_DELETE

Within Azure, I have two roles assigned: dev.engsoft.user via a group assignment and KAFBAT-ADMIN via direct assignment. Both groups are present in the token sent to Kafbat, which can be seen in the logs, however, Kafbat does not respect the regex assignment of .*-ADMIN and only assigns roles that exactly match, regardless of the isRegex field value.

Here are logs of this with the above configuration:

2025-03-25 16:30:04,457 TRACE [reactor-http-epoll-9] i.k.u.s.r.e.OauthAuthorityExtractor: Extracting OAuth2 user authorities
2025-03-25 16:30:04,458 DEBUG [reactor-http-epoll-9] i.k.u.s.r.e.OauthAuthorityExtractor: Principal name is: [<redacted email>]
2025-03-25 16:30:04,459 DEBUG [reactor-http-epoll-9] i.k.u.s.r.e.OauthAuthorityExtractor: Matched roles by username: []
2025-03-25 16:30:04,459 TRACE [reactor-http-epoll-9] i.k.u.s.r.e.OauthAuthorityExtractor: The field is either a set or a list, returning as is
2025-03-25 16:30:04,459 DEBUG [reactor-http-epoll-9] i.k.u.s.r.e.OauthAuthorityExtractor: Token's groups: [KAFBAT-ADMIN,dev.engsoft.user]
2025-03-25 16:30:04,459 DEBUG [reactor-http-epoll-9] i.k.u.s.r.e.OauthAuthorityExtractor: Matched group roles: [readdelete-testrole]

Setting the subject to the following shows the permission successfully assigns:

 subjects:
- provider: oauth
  type: role
  value: "KAFBAT-ADMIN"
  isRegex: true
2025-03-25 16:56:18,855 TRACE [reactor-http-epoll-8] i.k.u.s.r.e.OauthAuthorityExtractor: Extracting OAuth2 user authorities
2025-03-25 16:56:18,855 DEBUG [reactor-http-epoll-8] i.k.u.s.r.e.OauthAuthorityExtractor: Principal name is: [<redacted email>]
2025-03-25 16:56:18,856 DEBUG [reactor-http-epoll-8] i.k.u.s.r.e.OauthAuthorityExtractor: Matched roles by username: []
2025-03-25 16:56:18,856 TRACE [reactor-http-epoll-8] i.k.u.s.r.e.OauthAuthorityExtractor: The field is either a set or a list, returning as is
2025-03-25 16:56:18,856 DEBUG [reactor-http-epoll-8] i.k.u.s.r.e.OauthAuthorityExtractor: Token's groups: [KAFBAT-ADMIN,dev.engsoft.user]
2025-03-25 16:56:18,857 DEBUG [reactor-http-epoll-8] i.k.u.s.r.e.OauthAuthorityExtractor: Matched group roles: [readonly-global, readdelete-testrole]

It appears that the configuration of isRegex is ignored entirely. For the record, the regex we use for topic naming permissions within these roles all work as expected, which points directly to the implementation of Subject regex parsing.

Expected behavior

It is expected that for a regex, Kafbat matches any roles that succeed against that regex to the group. The above .*-ADMIN example is taken directly from the documentation - in reality, we want it to match an even simpler regex of .* so we can assign any role a set of global default permissions.

Your installation details

We're running:

  • App version v1.2.0 3074abc
  • Helm chart version 1.4.12
yamlApplicationConfig:
    kafka:
      internalTopicPrefix: _ui_
      clusters:
        - name: dev
          bootstrapServers: dev-kafka-bootstrap.dev-kafka.svc.cluster.local:9092
          schemaRegistry: http://conf-schema-registry:8081
          readonly: false
          properties:
            security:
              protocol: SASL_PLAINTEXT
            sasl:
              mechanism: PLAIN
              jaas:
                config: org.apache.kafka.common.security.plain.PlainLoginModule required username="<redacted>" password="<redacted>" ;
    auth:
      type: OAUTH2
      oauth2:
        client:
          azure:
            clientId: <redacted>
            clientSecret: <redacted>
            scope: openid
            client-name: azure
            provider: azure
            issuer-uri: <redacted>
            jwk-set-uri: <redacted>
            user-name-attribute: email
            custom-params:
              type: oauth
              roles-field: roles
    logging:
      level:
        root: info # trace,debug, info, warn, error. default: info
        io.kafbat.ui.service.rbac: TRACE
    rbac:
      roles:
        - name: "readonly-global"
          clusters:
            - dev
          subjects:
            - provider: oauth
              type: role
              value: "KAFBAT-ADMIN"
              isRegex: true
          permissions:
            - resource: clusterconfig
              actions: [ "view" ]
            - resource: topic
              value: ".*"
              actions: 
                - VIEW
            - resource: consumer
              value: ".*"
              actions: [ view ]
            - resource: schema
              value: ".*"
              actions: [ view ]
            - resource: connect
              value: ".*"
              actions: [ view ]
            - resource: acl
              actions: [ view ]
        - name: "readdelete-testrole"
          clusters:
            - dev
          subjects:
            - provider: oauth
              type: role
              value: "dev.engsoft.user"
          permissions:
            - resource: topic
              value: mgp.engsoft\..*
              actions: 
              - MESSAGES_READ
              - MESSAGES_DELETE

Steps to reproduce

Deploy Kafbat via chart with the above configuration and correct setup in EntraID and the result is reproducible.

Screenshots

No response

Logs

Image

Additional context

This was discussed in the community Discord. We tried the suggestion of changing isRegex to isIsRegex but this didn't work.

mriley-mbgp avatar Mar 25 '25 17:03 mriley-mbgp

Hi mriley-mbgp! 👋

Welcome, and thank you for opening your first issue in the repo!

Please wait for triaging by our maintainers.

As development is carried out in our spare time, you can support us by sponsoring our activities or even funding the development of specific issues. Sponsorship link

If you plan to raise a PR for this issue, please take a look at our contributing guide.

github-actions[bot] avatar Mar 25 '25 17:03 github-actions[bot]

@mriley-mbgp I tried using regex instead of isRegex and it worked.

rahulrg09 avatar Apr 11 '25 22:04 rahulrg09

@rahulrg09 Thanks for that, this appears to be the case for me as well - it is now working as intended when using regex. I guess this issue now comes down to whether the documentation should be updated to match this behaviour, or understanding why the intended isRegex isn't working.

mriley-mbgp avatar Apr 14 '25 15:04 mriley-mbgp

doesn't work due to jackson/lombok shenanigans, will fix soon

Haarolean avatar May 13 '25 20:05 Haarolean

hey @mriley-mbgp I am also trying to setup RBAC with Azure Entra groups/roles. I have below groups and app roles assigned -

Entra Group App role
Kafka-Admin Admin
Kafka-Developer Developer

Below is my rbac config -

auth:
  type: OAUTH2
  oauth2:
    client:
      azure:
        clientId: "REDACTED"
        clientSecret: "REDACTED"
        scope: openid
        client-name: azure
        provider: azure
        redirect-uri: https://kafka-ui.dev.com/login/oauth2/code/azure
        authorization-grant-type: authorization_code
        issuer-uri: "https://login.microsoftonline.com/REDACTED/v2.0"
        jwk-set-uri: "https://login.microsoftonline.com/REDACTED/discovery/v2.0/keys"
        user-name-attribute: email
        custom-params:
          type: oauth
          roles-field: roles
rbac:
  roles:
    - name: "admins"
      clusters:
        - kafka-dev
      subjects:
        - provider: oauth
          type: role
          value: "Admin"
      permissions:
        - resource: applicationconfig
          actions: all

        - resource: clusterconfig
          actions: all

        - resource: topic
          value: ".*"
          actions: all

        - resource: consumer
          value: ".*"
          actions: all

        - resource: schema
          value: ".*"
          actions: all

        - resource: connect
          value: ".*"
          actions: all

        - resource: ksql
          actions: all

        - resource: acl
          actions: [ view ]

    - name: "developer"
      clusters:
        - kafka-dev
      subjects:
        - provider: oauth
          type: role
          value: "Developer"
      permissions:
        - resource: clusterconfig
          actions: [ "view" ]

        - resource: topic
          value: ".*"
          actions:
            - VIEW
            - MESSAGES_READ
            - ANALYSIS_VIEW

        - resource: consumer
          value: ".*"
          actions: [ view ]

        - resource: schema
          value: ".*"
          actions: [ view ]

        - resource: connect
          value: ".*"
          actions: [ view ]

        - resource: acl
          actions: [ view ]

When I did sso login, I am not able to list see any clusters. Logs -

[30m2025-09-03 07:42:01,663[0;39m [39mDEBUG[0;39m [[34mreactor-http-epoll-1[0;39m] [33mo.s.s.w.s.c.WebSessionServerSecurityContextRepository[0;39m: Found SecurityContext 'SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=RbacOidcUser[user=Name: [[email protected]], Granted Authorities: [[OIDC_USER, SCOPE_User.Read, SCOPE_email, SCOPE_openid, SCOPE_profile]], User Attributes: [{sub=lFcwFgffchEDQczSYwApfHLM56upNMkr5ZPsj8aQsPA, ver=2.0, iss=https://login.microsoftonline.com/95b666d1-9a75-49ab-95a3-dadkgjadk/v2.0, groups=[b72409db-c62a-4945-b935-e56a677f59f6], uti=4bvtTQqfKkK49gZQltWIAA, given_name=Parvez, nonce=nBP-Mq1Kwez0q2LYdh2G0XmTAbLz7uH-5RWK_Bgiqlk, picture=https://graph.microsoft.com/v1.0/me/photo/$value, tid=95b666d1-9a75-49ab-95a3-8969fbcdc08c, aud=[00fee5d4-96d7-4d74-a9f1-11384875e390], nbf=Wed Sep 03 07:37:00 UTC 2025, rh=1.ARwA0Wa2lXWaq0mVo4lp-83AjNTl_gDXlnRNqfEROEh145DOAKkcAA., name=Parvez Kazi, exp=2025-09-03T08:42:00Z, family_name=Kazi, iat=2025-09-03T07:37:00Z, [email protected]}], groups=[]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[OIDC_USER, SCOPE_User.Read, SCOPE_email, SCOPE_openid, SCOPE_profile]]]' in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@3d975415'

...
 Principal [[email protected]] doesn't have any roles, nothing to do

groups=[b72409db-c62a-4945-b935-e56a677f59f6] from above logs is the group object ID of Admin group. Is there any thing to do from Entra App side for these roles to be in token ?

pkazi avatar Sep 03 '25 08:09 pkazi

hey @mriley-mbgp I am also trying to setup RBAC with Azure Entra groups/roles. I have below groups and app roles assigned -

Entra Group App role Kafka-Admin Admin Kafka-Developer Developer Below is my rbac config -

auth:
  type: OAUTH2
  oauth2:
    client:
      azure:
        clientId: "REDACTED"
        clientSecret: "REDACTED"
        scope: openid
        client-name: azure
        provider: azure
        redirect-uri: https://kafka-ui.dev.com/login/oauth2/code/azure
        authorization-grant-type: authorization_code
        issuer-uri: "https://login.microsoftonline.com/REDACTED/v2.0"
        jwk-set-uri: "https://login.microsoftonline.com/REDACTED/discovery/v2.0/keys"
        user-name-attribute: email
        custom-params:
          type: oauth
          roles-field: roles
rbac:
  roles:
    - name: "admins"
      clusters:
        - kafka-dev
      subjects:
        - provider: oauth
          type: role
          value: "Admin"
      permissions:
        - resource: applicationconfig
          actions: all

        - resource: clusterconfig
          actions: all

        - resource: topic
          value: ".*"
          actions: all

        - resource: consumer
          value: ".*"
          actions: all

        - resource: schema
          value: ".*"
          actions: all

        - resource: connect
          value: ".*"
          actions: all

        - resource: ksql
          actions: all

        - resource: acl
          actions: [ view ]

    - name: "developer"
      clusters:
        - kafka-dev
      subjects:
        - provider: oauth
          type: role
          value: "Developer"
      permissions:
        - resource: clusterconfig
          actions: [ "view" ]

        - resource: topic
          value: ".*"
          actions:
            - VIEW
            - MESSAGES_READ
            - ANALYSIS_VIEW

        - resource: consumer
          value: ".*"
          actions: [ view ]

        - resource: schema
          value: ".*"
          actions: [ view ]

        - resource: connect
          value: ".*"
          actions: [ view ]

        - resource: acl
          actions: [ view ]

When I did sso login, I am not able to list see any clusters. Logs -

[30m2025-09-03 07:42:01,663�[0;39m �[39mDEBUG�[0;39m [�[34mreactor-http-epoll-1�[0;39m] �[33mo.s.s.w.s.c.WebSessionServerSecurityContextRepository�[0;39m: Found SecurityContext 'SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=RbacOidcUser[user=Name: [[email protected]], Granted Authorities: [[OIDC_USER, SCOPE_User.Read, SCOPE_email, SCOPE_openid, SCOPE_profile]], User Attributes: [{sub=lFcwFgffchEDQczSYwApfHLM56upNMkr5ZPsj8aQsPA, ver=2.0, iss=https://login.microsoftonline.com/95b666d1-9a75-49ab-95a3-dadkgjadk/v2.0, groups=[b72409db-c62a-4945-b935-e56a677f59f6], uti=4bvtTQqfKkK49gZQltWIAA, given_name=Parvez, nonce=nBP-Mq1Kwez0q2LYdh2G0XmTAbLz7uH-5RWK_Bgiqlk, picture=https://graph.microsoft.com/v1.0/me/photo/$value, tid=95b666d1-9a75-49ab-95a3-8969fbcdc08c, aud=[00fee5d4-96d7-4d74-a9f1-11384875e390], nbf=Wed Sep 03 07:37:00 UTC 2025, rh=1.ARwA0Wa2lXWaq0mVo4lp-83AjNTl_gDXlnRNqfEROEh145DOAKkcAA., name=Parvez Kazi, exp=2025-09-03T08:42:00Z, family_name=Kazi, iat=2025-09-03T07:37:00Z, [email protected]}], groups=[]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[OIDC_USER, SCOPE_User.Read, SCOPE_email, SCOPE_openid, SCOPE_profile]]]' in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@3d975415'

...
 Principal [[email protected]] doesn't have any roles, nothing to do

groups=[b72409db-c62a-4945-b935-e56a677f59f6] from above logs is the group object ID of Admin group. Is there any thing to do from Entra App side for these roles to be in token ?

My issue sorted, as our IT team had missed to put value field for each appRole, those were empty. After adding specific values, RBAC worked based on Azure entra app roles

pkazi avatar Sep 03 '25 15:09 pkazi