Skip to content

OSAC-953: Update AuthConfig to use organization groups#666

Open
CrystalChun wants to merge 1 commit into
osac-project:mainfrom
CrystalChun:groups-authz
Open

OSAC-953: Update AuthConfig to use organization groups#666
CrystalChun wants to merge 1 commit into
osac-project:mainfrom
CrystalChun:groups-authz

Conversation

@CrystalChun

@CrystalChun CrystalChun commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Description

Determine if a user can get/update/delete a project based on the organization group they're part of.

Testing

  • Ran integration test
    • Logged in as admin on CLI and created organization test-org, added user ben, assigned ben tenant-admin role
    • Logged in as ben on CLI and created project, verify able to see project
    • Logged in as charles on CLI and verify not able to see project
    • Deleted project successfully

Assisted-by: Claude Code noreply@anthropic.com

/cc @jhernand

Summary by CodeRabbit

Release Notes

  • New Features

    • Added tenant-scoped authorization rules for Project operations with granular role-based access control.
    • Enhanced JWT organization claim support to accept multiple formats (array and object structures).
  • Improvements

    • Streamlined authentication claim processing by consolidating organization claim handling.
    • Maintained backwards compatibility with group-based tenant fallback for legacy JWT identities.

@openshift-ci-robot

openshift-ci-robot commented Jun 9, 2026

Copy link
Copy Markdown

@CrystalChun: This pull request references OSAC-953 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the sub-task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Description

Determine if a user can get/update/delete a project based on the organization group they're part of.

Testing

  • Ran integration test
    • Logged in as admin on CLI and created organization test-org, added user ben, assigned ben tenant-admin role
    • Logged in as ben on CLI and created project, verify able to see project
    • Logged in as charles on CLI and verify not able to see project
    • Deleted project successfully

Assisted-by: Claude Code noreply@anthropic.com

/cc @jhernand

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR updates OPA authorization policy to derive tenant identity exclusively from JWT organization claims (supporting both array and object formats), introduces a normalized subject_org_groups helper mapping tenants to their group memberships, and adds tenant-scoped gRPC authorization rules for Projects/* methods. Keycloak realm mappers are updated to emit the organization claim, and integration tests verify the new claim shapes.

Changes

gRPC Authorization Policy: Organization-Based Tenant & Project Rules

Layer / File(s) Summary
JWT tenant derivation from organization claim
charts/service/templates/grpc-server/authconfig.yaml, manifests/base/grpc-server/authconfig.yaml
subject_tenants now derives exclusively from input.auth.identity.organization (supporting both array and object formats); removed prior fallback to organizations claim; retains backward-compatible fallback to JWT groups when organization is absent.
Normalized org-groups helper
charts/service/templates/grpc-server/authconfig.yaml, manifests/base/grpc-server/authconfig.yaml
Introduced subject_org_groups that maps tenants to objects containing groups. For Keycloak-style organization objects, uses directly; for array-format organization, synthesizes per-tenant mappings using top-level JWT groups claim.
Project-scoped gRPC allow rules
charts/service/templates/grpc-server/authconfig.yaml, manifests/base/grpc-server/authconfig.yaml
⚠️ Security impact: New authorization rules gate Projects/Create to tenant admins, Projects/List to clients with permissions, and Projects/Get/Projects/Update/Projects/Delete to JWT-authenticated callers with tenant-scoped viewer or manager group membership derived from subject_org_groups and request context tenant/project name. Violation: Deny.
Keycloak organization claim mappers
it/charts/keycloak/files/realm.json
Updated organization protocol mapper configuration (removed jsonType.label); added new organization-groups protocol mapper to emit organization group claims into id.token, access.token, and userinfo.token contexts.
Test organization claim shape parsing
it/it_organization_lifecycle_test.go
Updated JWT payload parsing to accept organization claim in both array (org-name strings) and object (keyed by org name) formats; extracts org names from either representation and verifies expected organization membership.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • omer-vishlitzky
  • tzumainn
  • jhernand

🔐 Authorization Fortified
Tenants now claim their organization fame,
Projects guarded by per-tenant group name,
Helm and manifests sing the same refrain,
Keycloak mappers emit the domain chain. ⛓️


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
No-Hardcoded-Secrets ❌ Error it/charts/keycloak/files/realm.json contains hardcoded key material: privateKey base64 length 1588 (and certificate length 900). Move privateKey/certificate out of realm.json (use Kubernetes/Keycloak Secrets or templating at deploy time) and keep only non-secret realm config in the PR.
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly references the JIRA ticket (OSAC-953) and accurately summarizes the main change: updating AuthConfig to use organization groups for authorization.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Weak-Crypto ✅ Passed PASS (Low risk): PR updates OPA/JWT authorization; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or crypto/non-constant-time comparisons found in changed-file diff.
No-Injection-Vectors ✅ Passed Scanned the PR’s authconfig.yaml, manifests authconfig, realm.json, and lifecycle test for eval(/exec(/pickle.loads(/yaml.load(/shell=True/os.system/dangerouslySetInnerHTML; none found.
Container-Privileges ✅ Passed PASS: No manifests enable privileged/hostPID/hostNetwork/hostIPC/SYS_ADMIN; allowPrivilegeEscalation is false and runAsNonRoot is true (low risk impact).
No-Sensitive-Data-In-Logs ✅ Passed Reviewed the PR’s changed authconfig YAMLs, Keycloak realm config, and Go test; no log/print statements that would expose passwords/tokens/PII were found.
Ai-Attribution ✅ Passed Local git history for this PR includes “Assisted-by: Claude Code noreply@anthropic.com” and shows no “Co-Authored-By” trailers (low provenance/attribution risk).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@charts/service/templates/grpc-server/authconfig.yaml`:
- Around line 282-295: The current authorization rule inside the allow if block
applies the same group check to Get/Update/Delete and therefore denies read-only
viewers; modify the policy by splitting the rule into two checks: one allow
branch that permits grpc_method == "/osac.public.v1.Projects/Get" when
input.auth.identity.authnMethod == "jwt" and some group in
subject_org_groups[tenant].groups where group == sprintf("/%s/viewers", [name])
or group == sprintf("/%s/managers", [name]); and a second allow branch that
permits grpc_method in
{"/osac.public.v1.Projects/Update","/osac.public.v1.Projects/Delete"} only when
the same jwt check and some group in subject_org_groups[tenant].groups where
group == sprintf("/%s/managers", [name]); retain use of tenant :=
input.context.context_extensions.tenant and name :=
input.context.context_extensions.name in both branches.
- Around line 104-108: The current rule assigns subject_tenants = subject_groups
when input.auth.identity.authnMethod == "jwt" and organization is missing, which
incorrectly treats project group paths as tenants; update the logic so that when
authnMethod is "jwt" and input.auth.identity.organization is absent,
subject_tenants remains empty (do not assign subject_groups). Concretely, remove
or guard the branch that sets subject_tenants from subject_groups for JWTs
without organization, relying solely on input.auth.identity.organization as the
authoritative tenant source and leaving subject_tenants unset in that case.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 99d70ea3-613b-4bd1-95d3-1a70fbb81c66

📥 Commits

Reviewing files that changed from the base of the PR and between 8e8f231 and 20ea641.

📒 Files selected for processing (1)
  • charts/service/templates/grpc-server/authconfig.yaml

Comment thread charts/service/templates/grpc-server/authconfig.yaml Outdated
Comment thread charts/service/templates/grpc-server/authconfig.yaml Outdated
@CrystalChun CrystalChun force-pushed the groups-authz branch 2 times, most recently from 5b0c673 to 41f59c9 Compare June 10, 2026 00:35

@jhernand jhernand left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to update the authconfig.yaml file in the manifests directory as well.

@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: CrystalChun
Once this PR has been reviewed and has the lgtm label, please ask for approval from jhernand. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@CrystalChun

Copy link
Copy Markdown
Contributor Author

You need to update the authconfig.yaml file in the manifests directory as well.

Thank you! Updated that one as well

@CrystalChun CrystalChun force-pushed the groups-authz branch 2 times, most recently from 3b6cd8b to 930964d Compare June 10, 2026 18:15

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@charts/service/templates/grpc-server/authconfig.yaml`:
- Around line 271-301: Add an allow rule for the Projects/List gRPC method:
create a new allow-if block checking grpc_method ==
"/osac.public.v1.Projects/List", extract tenant :=
input.context.context_extensions.tenant, require input.auth.identity.authnMethod
== "jwt", and verify some group in subject_org_groups[tenant].groups (or narrow
to viewers/managers if you prefer filtering at the app layer); this mirrors the
Get/Update rules and ensures JWT-authenticated tenant members can call
Projects/List while the server can perform any result-level filtering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 3f312678-7c68-4944-b608-71f503969b9d

📥 Commits

Reviewing files that changed from the base of the PR and between 20ea641 and 930964d.

📒 Files selected for processing (2)
  • charts/service/templates/grpc-server/authconfig.yaml
  • manifests/base/grpc-server/authconfig.yaml

Comment thread charts/service/templates/grpc-server/authconfig.yaml
@CrystalChun CrystalChun force-pushed the groups-authz branch 5 times, most recently from ad5b834 to 14bff45 Compare June 10, 2026 21:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@it/charts/keycloak/files/realm.json`:
- Around line 836-846: The realm config sets protocolMapper
"oidc-organization-group-membership-mapper" (id "org-group-membership-001") but
the chart defaults images.keycloak to 26.3 and realm.json declares
keycloakVersion 26.3.5, which is <26.6.0 where that mapper is guaranteed; update
the deployment to a compatible Keycloak version (bump values.images.keycloak
default and chart/appVersion to >=26.6.0 and align realm.json keycloakVersion)
or alternatively gate/remove the protocolMapper
"oidc-organization-group-membership-mapper" (org-group-membership-001) for older
versions and provide a fallback mapper implementation so org-scoped JWT
membership continues to be emitted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 3a58f4ce-ff1b-4fd9-a490-e39d1ef78a29

📥 Commits

Reviewing files that changed from the base of the PR and between 930964d and 14bff45.

📒 Files selected for processing (3)
  • charts/service/templates/grpc-server/authconfig.yaml
  • it/charts/keycloak/files/realm.json
  • manifests/base/grpc-server/authconfig.yaml

Comment thread it/charts/keycloak/files/realm.json Outdated
@CrystalChun CrystalChun force-pushed the groups-authz branch 8 times, most recently from d747d86 to bd603a9 Compare June 11, 2026 03:01
@CrystalChun CrystalChun force-pushed the groups-authz branch 8 times, most recently from 4db781b to a8791a2 Compare June 11, 2026 21:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
charts/service/templates/grpc-server/authconfig.yaml (1)

94-95: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Major authorization risk: JWT fallback still classifies raw groups as tenants.

Line 94 says JWT callers without organization should have an empty tenant list, but Line 111 overrides that by assigning subject_tenants = subject_groups. Impact: project ACL-style groups (for example /<project>/managers) can be propagated as tenant identifiers (including in x-subject.tenants), weakening tenant-boundary guarantees in downstream authorization/filtering.

🔧 Suggested fix
-          # Fallback to groups for JWT users without organization claim (backwards compatibility)
-          subject_tenants = subject_groups if {
-            input.auth.identity.authnMethod == "jwt"
-            not input.auth.identity.organization
-          }

Based on learnings: in this repo’s grpc-server Helm auth config, JWT tenant resolution should use the singular auth.identity.organization claim as authoritative and must not fall back to JWT groups.

Also applies to: 110-114

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@charts/service/templates/grpc-server/authconfig.yaml` around lines 94 - 95,
The template currently falls back to using JWT groups as tenants (assigning
subject_tenants = subject_groups), which allows project ACL groups to be treated
as tenant identifiers; change the tenant-resolution logic so subject_tenants is
populated only from the singular claim auth.identity.organization (e.g. set
subject_tenants to that claim when present, otherwise to an empty list) and
remove the unconditional fallback to subject_groups; if service accounts must
use groups as tenants, make that conditional (only set subject_tenants =
subject_groups when a service-account claim like auth.identity.type ==
"service_account" or a dedicated service_account boolean is present), and ensure
x-subject.tenants is emitted only from subject_tenants.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@charts/service/templates/grpc-server/authconfig.yaml`:
- Around line 94-95: The template currently falls back to using JWT groups as
tenants (assigning subject_tenants = subject_groups), which allows project ACL
groups to be treated as tenant identifiers; change the tenant-resolution logic
so subject_tenants is populated only from the singular claim
auth.identity.organization (e.g. set subject_tenants to that claim when present,
otherwise to an empty list) and remove the unconditional fallback to
subject_groups; if service accounts must use groups as tenants, make that
conditional (only set subject_tenants = subject_groups when a service-account
claim like auth.identity.type == "service_account" or a dedicated
service_account boolean is present), and ensure x-subject.tenants is emitted
only from subject_tenants.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: cc871161-2ed4-457c-bf2e-2ac474efcd55

📥 Commits

Reviewing files that changed from the base of the PR and between 42eae89 and a8791a2.

📒 Files selected for processing (4)
  • charts/service/templates/grpc-server/authconfig.yaml
  • it/charts/keycloak/files/realm.json
  • it/it_organization_lifecycle_test.go
  • manifests/base/grpc-server/authconfig.yaml
💤 Files with no reviewable changes (3)
  • it/it_organization_lifecycle_test.go
  • manifests/base/grpc-server/authconfig.yaml
  • it/charts/keycloak/files/realm.json

Determine if a user can get/update/delete a project based
on the organization group they're part of.

Assisted-by: Claude Code <noreply@anthropic.com>
@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown

@CrystalChun: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-vmaas 7dd0887 link true /test e2e-vmaas

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants