Skip to content

feat(auth): configure Cryostat to hook in to OpenShift RBAC for fine-grained permissions - #337

Open
andrewazores wants to merge 2 commits into
cryostatio:mainfrom
andrewazores:fine-grained-permissions
Open

andrewazores wants to merge 2 commits into
cryostatio:mainfrom
andrewazores:fine-grained-permissions

Conversation

@andrewazores

@andrewazores andrewazores commented Aug 11, 2026

Copy link
Copy Markdown
Member

Related to cryostatio/cryostat#1733
Depends on cryostatio/cryostat#1734
See cryostatio/cryostat-operator#1428

Configures the Cryostat container for OPENSHIFT RBAC mode (ie perform additional fine-grained access control checks - see linked Cryostat issue and PR) when OpenShift SSO integration is enabled and Basic auth is not enabled, or BASIC RBAC mode (ie assume proxy has authenticated and authorized user, just enforce that the incoming request is being received from the proxy) when auth proxy Basic/htpasswd mode is enabled, or else allow the default PERMISSIVE RBAC mode (ie accept all requests).

The openshift-oauth-proxy Access Review/Token Review is dropped from create pods/exec to simply get pods, which is a much lower bar - however, Cryostat itself will expect users to have create pods/exec permissions, so in the default configuration the effective permissions required of a user do not change. Users can customize Cryostat's RBAC permissions using the Helm chart's extra env vars configuration to selectively map Cryostat API resources to different k8s RBAC roles as needed.

How to manually test:

  1. Check out and build this PR and linked Cryostat PR (feat(auth): OpenShift RBAC fine-grained permissions cryostat#1734), or use quay.io/andrewazores/cryostat:4.3.0-fine-grained-permissions-5 as the core image.
  2. As cluster admin, create namespaces (projects) cryostat and apps1.
  3. Deploy Cryostat using this Helm chart into the cryostat namespace with OpenShift OAuth proxy enabled:
    helm install cryostat ./charts/cryostat -n cryostat \
      --set core.route.enabled=true \
      --set core.discovery.kubernetes.enabled=true \
      --set core.discovery.kubernetes.namespaces='{apps1}' \
      --set core.image.repository=quay.io/andrewazores/cryostat \
      --set core.image.tag=4.3.0-fine-grained-permissions-5 \
      --set authentication.openshift.enabled=true
    
  4. Log in to the Cryostat UI and ensure normal functionality for a cluster admin user (kubeadmin). Assuming crc here, log out from the admin account (or use an incognito/private browsing window) and log in as the developer user. The developer should have no access to Cryostat.
  5. As admin, oc adm policy add-role-to-user -n cryostat view developer to grant the developer read access to the Cryostat installation namespace. The developer should now be able to log in to Cryostat, but should not be able to actually do anything as they are only passing the basic auth proxy access check but failing all fine-grained RBAC checks.
  6. Uninstall and reinstall the Helm release to add RBAC permission mappings via core.config.extra.envVars:
    helm uninstall cryostat && \
    helm install cryostat ./charts/cryostat -n cryostat \
      --set core.route.enabled=true \
      --set core.discovery.kubernetes.enabled=true \
      --set core.discovery.kubernetes.namespaces='{apps1}' \
      --set core.image.repository=quay.io/andrewazores/cryostat \
      --set core.image.tag=4.3.0-fine-grained-permissions-6 \
      --set authentication.openshift.enabled=true \
      --set-json 'core.config.extra.envVars=[
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ACTIVERECORDINGS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ACTIVERECORDINGS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ACTIVERECORDINGS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ARCHIVEDRECORDINGS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ARCHIVEDRECORDINGS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ARCHIVEDRECORDINGS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ASYNCPROFILER_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ASYNCPROFILER_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__ASYNCPROFILER_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__AUTOMATEDRULES_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__AUTOMATEDRULES_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__AUTOMATEDRULES_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__CREDENTIALS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__CREDENTIALS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__CREDENTIALS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__DISCOVERYNODES_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__DISCOVERYNODES_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__DISCOVERYPLUGINS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__DISCOVERYPLUGINS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__DISCOVERYPLUGINS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__EVENTTEMPLATES_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__EVENTTEMPLATES_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__EVENTTEMPLATES_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__EVENTTYPES_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__HEAPDUMPS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__HEAPDUMPS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__HEAPDUMPS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__MATCHEXPRESSIONS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__PROBES_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__PROBES_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__PROBES_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__PROBETEMPLATES_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__PROBETEMPLATES_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__PROBETEMPLATES_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__RECORDINGMETADATA_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__RECORDINGMETADATA_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__REPORTS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__REPORTS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__TARGETS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__TARGETS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__TARGETS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__THREADDUMPS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__THREADDUMPS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__THREADDUMPS_WRITE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__UNIFIEDLOGS_DELETE_","value":"pods/exec:create"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__UNIFIEDLOGS_READ_","value":"pods:get"},
        {"name":"CRYOSTAT_SECURITY_RBAC_PERMISSIONS__UNIFIEDLOGS_WRITE_","value":"pods/exec:create"}
      ]'
    
    This should grant the developer user readonly permissions within the Cryostat API. The developer user account should now be able to ex. view active recordings, view archives, list event templates and event types, view stored credentials. They should not be able to start new recordings, archive running recordings, add credentials, enable automated rules, etc. pods/exec:create is the default mapping so these permission mappings are redundant but included for clarity. pods:get is a lower privilege which the developer's view role grants.
  7. oc adm policy add-role-to-user -n cryostat admin developer. Cryostat caches access review decisions for 1 minute, so wait up to 1 minute after invoking this. The developer user should now be able to perform any Cryostat action.
  8. oc adm policy remove-role-from-user -n cryostat admin developer, wait another 1 minute, and the developer user should now be back to readonly privileges.

@andrewazores andrewazores added feat New feature or request safe-to-test labels Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added authentication-aware security modes for OpenShift and basic authentication.
    • Added configurable namespace-scoped or cluster-scoped OpenShift access reviews, enabled by default for namespace scope.
    • OAuth proxy now forwards access tokens only when OpenShift authentication is enabled without basic authentication.
  • Bug Fixes

    • Corrected OpenShift access-review defaults and descriptions.
    • Basic authentication now takes precedence when both methods are enabled.
  • Tests

    • Added coverage for authentication modes, namespace scoping, token forwarding, and default behavior.

Walkthrough

The chart adds namespace-scoped OpenShift RBAC configuration. It updates OAuth proxy access-review defaults and configures RBAC mode and access-token forwarding based on authentication settings. Helm tests cover the supported combinations.

Changes

OpenShift authentication configuration

Layer / File(s) Summary
Access-review defaults and schema
charts/cryostat/values.yaml, charts/cryostat/values.schema.json, charts/cryostat/README.md
The chart adds namespace-scoped RBAC configuration, enabled by default. The subresource default is empty, and the verb default is get. The descriptions identify the correct fields.
Authentication-dependent runtime settings
charts/cryostat/templates/cryostat_deployment.yaml, charts/cryostat/templates/_openshiftOauthProxy.tpl
The deployment sets CRYOSTAT_SECURITY_RBAC_MODE to OPENSHIFT or BASIC. OpenShift authentication can also set CRYOSTAT_SECURITY_RBAC_NAMESPACE from the pod namespace. The OAuth proxy passes access tokens when basic authentication is disabled.
Runtime configuration validation
charts/cryostat/tests/cryostat_deployment_test.yaml
Tests cover RBAC mode selection, namespace injection, and access-token forwarding for OpenShift, basic, combined, and disabled authentication configurations.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: aptmac

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed The description references related, dependent, and operator pull requests that match the RBAC changes.
Out of Scope Changes check ✅ Passed All listed changes support RBAC mode selection, OAuth proxy permissions, namespace scoping, documentation, or tests.
Title check ✅ Passed The title clearly describes configuring Cryostat authentication for fine-grained OpenShift RBAC.
Description check ✅ Passed The description accurately explains the RBAC modes, permission changes, related issues, and manual validation steps.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@andrewazores
andrewazores marked this pull request as ready for review August 11, 2026 20:57
@andrewazores
andrewazores requested a review from a team as a code owner August 11, 2026 20:57

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
charts/cryostat/templates/cryostat_deployment.yaml (1)

189-201: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Align the chart with an application version that supports these RBAC variables.

The default quay.io/cryostat/cryostat:4.3.0-snapshot image has no Cryostat implementation for these variables. They cannot select PERMISSIVE or cluster-wide access reviews. Update the application image and contract together, then test the deployed behavior.

🤖 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/cryostat/templates/cryostat_deployment.yaml` around lines 189 - 201,
The chart’s RBAC environment variables require an application image version that
implements their contract. Update the default Cryostat image reference to a
compatible version, ensure the RBAC mode and namespace-scoping values in the
deployment template match that application’s supported behavior, and verify the
rendered/deployed chart supports permissive and cluster-wide access-review
configurations.
🧹 Nitpick comments (1)
charts/cryostat/tests/cryostat_deployment_test.yaml (1)

1560-1577: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add coverage for the changed access-review defaults.

These tests cover access-token forwarding only. Add an OpenShift case that verifies the rendered proxy arguments use resource=pods, an empty subresource, and verb=get, and do not use the old create pods/exec combination.

🤖 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/cryostat/tests/cryostat_deployment_test.yaml` around lines 1560 -
1577, Add a test alongside the existing OpenShift auth-proxy cases that enables
OpenShift authentication and asserts the rendered cryostat-authproxy arguments
use resource=pods, an empty subresource, and verb=get, while confirming the old
create pods/exec combination is absent.
🤖 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.

Outside diff comments:
In `@charts/cryostat/templates/cryostat_deployment.yaml`:
- Around line 189-201: The chart’s RBAC environment variables require an
application image version that implements their contract. Update the default
Cryostat image reference to a compatible version, ensure the RBAC mode and
namespace-scoping values in the deployment template match that application’s
supported behavior, and verify the rendered/deployed chart supports permissive
and cluster-wide access-review configurations.

---

Nitpick comments:
In `@charts/cryostat/tests/cryostat_deployment_test.yaml`:
- Around line 1560-1577: Add a test alongside the existing OpenShift auth-proxy
cases that enables OpenShift authentication and asserts the rendered
cryostat-authproxy arguments use resource=pods, an empty subresource, and
verb=get, while confirming the old create pods/exec combination is absent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 8a2bb271-0ca3-4dfd-9055-dfba7ac57702

📥 Commits

Reviewing files that changed from the base of the PR and between e59d4ad and 4bbd943.

📒 Files selected for processing (5)
  • charts/cryostat/README.md
  • charts/cryostat/templates/cryostat_deployment.yaml
  • charts/cryostat/tests/cryostat_deployment_test.yaml
  • charts/cryostat/values.schema.json
  • charts/cryostat/values.yaml

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant