Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

KEYCLOAK-16488 Add AuthZ settings to client CRD Redux #333

Merged
merged 1 commit into from
Apr 8, 2021

Conversation

trevorloranger
Copy link

@trevorloranger trevorloranger commented Mar 24, 2021

JIRA ID

Additional Information

  • Adds authorizationSettings field to the KeycloakClient CRD.
    • This approach fixes the issue which surfaced in the previous pull request by using v1.JSON to eliminate the cycles which occur within the ResourceServerRepresentation data type. See diagram below for the links removed. Also, here is the issue tracking support for recursion in CRD validation schemas. Inspired by a fix applied to a similar problem encountered in the Prometheus Operator project.
    • What impact does this have on users who specify authorizationSettings in their CRs? Not much as the "type erased" fields can be specified as usual within the YAML, minus schema validation by k8s. It has more of an impact on any Go code needing to consume this data - which is unlikely within the Operator and will happily be serialized to JSON again when it is sent forward to the Keycloak Admin REST API.
  • Added a gate to prevent delete client role event on the auto-generated uma_protection role which is created behind the scenes by Keycloak when authorizationSettings are present during client create.
    • Why? The Keycloak Operator would otherwise delete this role behind the scenes on the next reconciliation loop, unbeknownst to the user, which would be unexpected and undesirable behavior. Moreover, until the discussed sync options are available the only alternative to this approach is to require users wanting to specify authorizationSettings in their CRs to explicitly add uma_protection to Spec.Roles. I feel this approach requires less hand holding and is less error prone but I'm open for ideas/suggestions!
    • This was due to role functionality which was merged since my previous pull request was reverted.
                      ┌──────────────────────┐
        ┌─────────────┤KeycloakResourceServer├─────────────┐
        │             └──────────┬───────────┘             │
        │                        │                         │
        ▼                        ▼                         ▼
┌────────────────┐        ┌─────────────┐         ┌──────────────┐
│KeycloakResource│◄───────┤KeycloakScope├────────►│KeycloakPolicy│
└─────────────┬──┘        └─────────────┘         └──┬─────┬─────┘
        ▲     │              ▲       ▲               │     │
        │     └────REMOVE────┘       └────REMOVE─────┘     │
        │                                                  │
        └──────────────────────────────────────────────────┘

Verification Steps

Client CRD with authorizationSettings
apiVersion: keycloak.org/v1alpha1
kind: KeycloakClient
metadata:
  name: client-with-authz
  labels:
    app: sso
spec:
  realmSelector:
    matchLabels:
      app: sso
  client:
    clientId: client-with-authz
    serviceAccountsEnabled: true
    authorizationServicesEnabled: true
    authorizationSettings:
      allowRemoteResourceManagement: true
      policyEnforcementMode: ENFORCING
      resources:
      - name: Audio Resource
        uri: "/audio"
        type: urn:client-with-authz:resources:audio
        scopes:
        - name: audio:listen
      - name: Image Resource
        uri: "/image"
        type: urn:client-with-authz:resources:image
        scopes:
        - name: image:create
        - name: image:read
        - name: image:delete
      policies:
      - name: Role Policy
        description: A policy that is role based
        type: role
        logic: POSITIVE
        config:
          roles: '[{"id":"client-with-authz/uma_protection","required":true}]'
      - name: Aggregate Policy
        description: Aggregate Policy Description
        type: aggregate
        logic: POSITIVE
        decisionStrategy: AFFIRMATIVE
        config:
          applyPolicies: '["Role Policy","Deny Policy"]'
      - name: Audio Permission
        description: An audio permission description
        type: resource
        logic: POSITIVE
        decisionStrategy: AFFIRMATIVE
        config:
          defaultResourceType: urn:client-with-authz:resources:audio
          default: 'true'
          applyPolicies: '["Time Policy"]'
          scopes: '["audio:listen"]'
      - name: Image Permission
        description: An image permission description
        type: scope
        logic: POSITIVE
        decisionStrategy: UNANIMOUS
        config:
          applyPolicies: '["Deny Policy"]'
          scopes: '["image:delete"]'
      - name: Deny Policy
        description: A policy that is JS based
        type: js
        config:
          code: "$evaluation.deny();"
      - name: Time Policy
        description: A policy that grants access between 3 and 5 PM
        type: time
        logic: POSITIVE
        config:
          hour: '15'
          hourEnd: '17'
      scopes:
      - name: audio:listen
      - name: image:create
      - name: image:read
      - name: image:delete
  1. Create a new file client-with-authz.yaml at deploy/examples/client with the expanded contents of the above CRD
  2. Run kubectl create -f deploy/examples/client/client-with-authz.yaml -n <namespace>
  3. Verify authorization settings within Keycloak Admin Console UI

Checklist:

@trevorloranger
Copy link
Author

@slaskawi here is the fix for the authorizationSettings PR I submitted previously. Thank you for your patience!

@slaskawi
Copy link
Contributor

Before diving in, @pedroigor - would you mind to have a quick look into this from the UMA perspective?

@trevorloranger
Copy link
Author

@pedroigor - do you think you'll have time to review my PR this week? Let me know if you have any further questions. Thank you!

@slaskawi
Copy link
Contributor

This LGTM. @pedroigor Last chance :)

@pedroigor
Copy link

@slaskawi @trevorloranger Sorry for the delay. LGTM.

However, having a 1:1 mapping between the CRDs and the authz model exposes a bit of complexity. We should be able to think about something that could make life easier when defining permissions for resources using some commonly used policies such as roles, groups, etc.

Nothing that we could not improve later.

@Kampe
Copy link
Contributor

Kampe commented Apr 7, 2021

Can we get an example of how to use these, the yaml examples are very dated now...

@trevorloranger
Copy link
Author

Can we get an example of how to use these, the yaml examples are very dated now...

Hi, I have provided an example of a client with authorization settings in the "Verification Steps" I wrote above. I could include this example to deploy/examples/client in this PR but I don't want to hold this up from being merged. I'll let @slaskawi advise.

@slaskawi slaskawi self-assigned this Apr 8, 2021
@slaskawi slaskawi merged commit 0c760d3 into keycloak:master Apr 8, 2021
@slaskawi
Copy link
Contributor

slaskawi commented Apr 8, 2021

Integrated, thanks @trevorloranger !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants