Skip to content

PROJQUAY-11657: feat(operator): implement STS/CCO credential flow for unmanaged S3 storage - #1273

Draft
jbpratt wants to merge 1 commit into
quay:masterfrom
jbpratt:PROJQUAY-5850
Draft

PROJQUAY-11657: feat(operator): implement STS/CCO credential flow for unmanaged S3 storage#1273
jbpratt wants to merge 1 commit into
quay:masterfrom
jbpratt:PROJQUAY-5850

Conversation

@jbpratt

@jbpratt jbpratt commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Implement end-to-end CCO CredentialRequest integration so quay-app pods on STS-enabled OpenShift clusters (ROSA, OSD) can authenticate to AWS S3 without static credentials when ObjectStorage is managed: false
  • Operator reads ROLEARN from its environment at startup, detects STS-capable clusters, creates a CredentialRequest via server-side apply, and once provisioned mounts the CCO Secret into the quay-app container with AWS_SHARED_CREDENTIALS_FILE
  • Gracefully falls back when ROLEARN is absent — zero behavior change for existing installations
  • Requeues silently while CCO provisions credentials; blocks rollout only for real errors (misconfigured STS, static credential conflicts)

Changes

Area File(s) What
Startup main.go Read ROLEARN env once, store on reconciler struct
Context pkg/context/context.go 5 STS fields on QuayRegistryContext
API apis/quay/v1/quayregistry_types.go 2 new ConditionReason constants
Detection controllers/quay/features.go checkSTSCapability() — 5-step detection chain using meta.IsNoMatchError for graceful fallback on non-OpenShift clusters
Reconciler controllers/quay/quayregistry_controller.go RBAC markers, STS detection call, checkSTSCredentialConflict() (standalone), ensureCredentialRequest() with correct RawExtension providerSpec and typed OwnerReferences
Middleware pkg/middleware/middleware.go Volume/mount/env injection scoped to quay-app container only
CSV bundle/manifests/quay-operator.clusterserviceversion.yaml token-auth-aws: "true", clusterPermissions, bound-sa-token projected volume
RBAC config/rbac/role.yaml Regenerated — infrastructures, cloudcredentials, credentialsrequests
E2E test/chainsaw/sts_cco/ Chainsaw test scaffold for ROSA + test-e2e-sts Makefile target

Test plan

  • make fmt && make vet — clean
  • make manifests — RBAC regenerated
  • make test — all unit tests pass (STS detection matrix, credential conflict, middleware injection)
  • make test-e2e-kind — regression (no ROLEARN, STS path never fires)
  • make test-e2e-sts — ROSA cluster with STS enabled (requires ROLEARN + STS_S3_BUCKET)

🤖 Generated with Claude Code

@openshift-ci

openshift-ci Bot commented Jun 2, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Enterprise

Run ID: 0d577611-cc11-4c5b-b4cf-574f8d268f69

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code

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

@codecov-commenter

codecov-commenter commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 46.11399% with 104 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.49%. Comparing base (42f98d5) to head (72e56a5).
⚠️ Report is 36 commits behind head on master.

Files with missing lines Patch % Lines
controllers/quay/quayregistry_controller.go 17.39% 95 Missing ⚠️
controllers/quay/features.go 87.03% 7 Missing ⚠️
main.go 0.00% 1 Missing ⚠️
pkg/middleware/middleware.go 95.65% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1273      +/-   ##
==========================================
- Coverage   62.28%   61.49%   -0.79%     
==========================================
  Files          25       25              
  Lines        3762     3955     +193     
==========================================
+ Hits         2343     2432      +89     
- Misses       1419     1523     +104     
Flag Coverage Δ
unit-tests 61.49% <46.11%> (-0.79%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
apis/quay/v1/quayregistry_types.go 38.79% <ø> (ø)
pkg/context/context.go 0.00% <ø> (ø)
main.go 0.00% <0.00%> (ø)
pkg/middleware/middleware.go 65.02% <95.65%> (+3.20%) ⬆️
controllers/quay/features.go 67.66% <87.03%> (+2.73%) ⬆️
controllers/quay/quayregistry_controller.go 34.12% <17.39%> (-2.05%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…orage (PROJQUAY-11657)

Enable quay-app pods on STS-enabled OpenShift clusters (ROSA, OSD) to
authenticate to AWS S3 via short-lived tokens instead of static credentials
when ObjectStorage is unmanaged. The operator reads ROLEARN from its
environment at startup, detects STS-capable clusters (AWS platform, CCO
mode, CRD availability), creates a CredentialRequest via server-side apply,
and once provisioned, mounts the CCO Secret into the quay-app container
with AWS_SHARED_CREDENTIALS_FILE set. When the CredentialRequest is
pending, the reconciler requeues silently. Rollout is blocked with
actionable conditions only for real errors: misconfigured STS or static
credential conflicts.

Key changes:
- STS cluster detection via Infrastructure, CloudCredential, and
  CredentialsRequest APIs using meta.IsNoMatchError for graceful fallback
- CredentialRequest lifecycle via standalone SSA with correct
  RawExtension providerSpec and typed OwnerReferences
- Volume/env injection scoped to the quay-app container only
- CSV: token-auth-aws annotation, clusterPermissions, bound-sa-token volume
- RBAC for infrastructures, cloudcredentials, credentialsrequests
- Chainsaw e2e test scaffold for ROSA (test-e2e-sts target)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jbpratt jbpratt changed the title feat(operator): implement STS/CCO credential flow for unmanaged S3 storage (PROJQUAY-11657) PROJQUAY-11657: feat(operator): implement STS/CCO credential flow for unmanaged S3 storage Jun 4, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

@jbpratt: This pull request references [Jira Issue PROJQUAY-11657](https://redhat.atlassian.net/browse/PROJQUAY-11657), which is invalid:

  • expected the story to target the "quay-v3.18.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

Details

In response to this:

Summary

  • Implement end-to-end CCO CredentialRequest integration so quay-app pods on STS-enabled OpenShift clusters (ROSA, OSD) can authenticate to AWS S3 without static credentials when ObjectStorage is managed: false
  • Operator reads ROLEARN from its environment at startup, detects STS-capable clusters, creates a CredentialRequest via server-side apply, and once provisioned mounts the CCO Secret into the quay-app container with AWS_SHARED_CREDENTIALS_FILE
  • Gracefully falls back when ROLEARN is absent — zero behavior change for existing installations
  • Requeues silently while CCO provisions credentials; blocks rollout only for real errors (misconfigured STS, static credential conflicts)

Changes

Area File(s) What
Startup main.go Read ROLEARN env once, store on reconciler struct
Context pkg/context/context.go 5 STS fields on QuayRegistryContext
API apis/quay/v1/quayregistry_types.go 2 new ConditionReason constants
Detection controllers/quay/features.go checkSTSCapability() — 5-step detection chain using meta.IsNoMatchError for graceful fallback on non-OpenShift clusters
Reconciler controllers/quay/quayregistry_controller.go RBAC markers, STS detection call, checkSTSCredentialConflict() (standalone), ensureCredentialRequest() with correct RawExtension providerSpec and typed OwnerReferences
Middleware pkg/middleware/middleware.go Volume/mount/env injection scoped to quay-app container only
CSV bundle/manifests/quay-operator.clusterserviceversion.yaml token-auth-aws: "true", clusterPermissions, bound-sa-token projected volume
RBAC config/rbac/role.yaml Regenerated — infrastructures, cloudcredentials, credentialsrequests
E2E test/chainsaw/sts_cco/ Chainsaw test scaffold for ROSA + test-e2e-sts Makefile target

Test plan

  • make fmt && make vet — clean
  • make manifests — RBAC regenerated
  • make test — all unit tests pass (STS detection matrix, credential conflict, middleware injection)
  • make test-e2e-kind — regression (no ROLEARN, STS path never fires)
  • make test-e2e-sts — ROSA cluster with STS enabled (requires ROLEARN + STS_S3_BUCKET)

🤖 Generated with Claude Code

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.

@jbpratt

jbpratt commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

This is a test

@openshift-ci

openshift-ci Bot commented Jun 18, 2026

Copy link
Copy Markdown

PR needs rebase.

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.

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

Development

Successfully merging this pull request may close these issues.

3 participants