Skip to content

Commit ced1004

Browse files
committed
Tokenize Credential Request
Signed-off-by: desmax74 <mdessi@redhat.com>
1 parent bc72c15 commit ced1004

29 files changed

Lines changed: 1506 additions & 13 deletions

CLAUDE.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,86 @@ The TrustedProfileAnalyzer CR spec uses `x-kubernetes-preserve-unknown-fields: t
158158
- `metrics.enabled`: Enable metrics collection
159159
- `tracing.enabled`: Enable distributed tracing
160160

161+
## Cloud Credential Operator (CCO) Integration
162+
163+
The operator supports OpenShift Cloud Credential Operator integration for automatic cloud credential provisioning. CCO eliminates the need to manually create and manage S3 access keys by delegating credential lifecycle to the platform.
164+
165+
### Enabling CCO
166+
167+
Set `cloudProvider` in the CR spec. This is the master toggle — when absent, no CCO resources are created and credentials must be supplied manually via `storage.accessKey`/`storage.secretKey`.
168+
169+
```yaml
170+
spec:
171+
cloudProvider: aws # "aws" or "gcp"
172+
ccoMode: mint # optional: "default", "mint", "passthrough", or "manual"
173+
cloudCredentials:
174+
aws:
175+
statementEntries:
176+
- effect: Allow
177+
action: ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"]
178+
resource: "*"
179+
```
180+
181+
When `cloudProvider` is set:
182+
- A `CredentialsRequest` resource is created in the `openshift-cloud-credential-operator` namespace
183+
- CCO provisions a Secret named `<release-name>-cloud-creds` in the deployment namespace
184+
- `storage.accessKey` and `storage.secretKey` become **optional** (auto-populated from the CCO secret)
185+
186+
### Disabling CCO
187+
188+
Remove or leave `cloudProvider` unset in the CR spec. When unset:
189+
- No `CredentialsRequest` is created
190+
- No CCO volumes or environment variables are injected into pods
191+
- S3 credentials must be provided explicitly via `storage.accessKey` and `storage.secretKey`
192+
193+
### CCO Modes
194+
195+
| Mode | `ccoMode` value | Description |
196+
|------|----------------|-------------|
197+
| **Default** | `default` | CCO auto-determines provisioning method. |
198+
| **Mint** | `mint` | CCO creates new IAM credentials with least-privilege permissions from `statementEntries`. |
199+
| **Passthrough** | `passthrough` | CCO copies cluster admin credentials to the target namespace. |
200+
| **Manual** | `manual` | Credentials pre-provisioned via `ccoctl` tool (STS/WIF). Requires `stsIAMRoleARN` for AWS. |
201+
202+
### Manual Mode (STS)
203+
204+
Manual mode uses short-lived token-based authentication instead of static access keys. It requires additional configuration:
205+
206+
```yaml
207+
spec:
208+
cloudProvider: aws
209+
ccoMode: manual
210+
cloudCredentials:
211+
aws:
212+
statementEntries:
213+
- effect: Allow
214+
action: ["s3:*"]
215+
resource: "*"
216+
stsIAMRoleARN: "arn:aws:iam::123456789012:role/trustify-s3-role"
217+
```
218+
219+
When manual mode is active, the operator automatically:
220+
- Mounts a projected ServiceAccount token at `/var/run/secrets/openshift/serviceaccount`
221+
- Mounts the CCO credentials secret at `/var/run/secrets/cloud`
222+
- Sets `AWS_SHARED_CREDENTIALS_FILE`, `AWS_WEB_IDENTITY_TOKEN_FILE`, and `AWS_ROLE_ARN` environment variables
223+
- Omits `TRUSTD_S3_ACCESS_KEY` / `TRUSTD_S3_SECRET_KEY` (the AWS SDK uses STS instead)
224+
225+
### Key Files
226+
227+
| File | Purpose |
228+
|------|---------|
229+
| `helm-charts/.../templates/credentialrequest.yaml` | CredentialsRequest template (conditional on `cloudProvider`) |
230+
| `helm-charts/.../templates/helpers/_cco.tpl` | Helper templates for manual mode volumes/mounts/env vars |
231+
| `helm-charts/.../templates/helpers/_storage.tpl` | S3 env vars — branches on CCO vs manual credentials |
232+
| `config/rbac/clusterrole.yaml` | ClusterRole granting access to `credentialsrequests` API |
233+
| `config/rbac/clusterrolebinding_cco.yaml` | Binds the CCO ClusterRole to the operator ServiceAccount |
234+
| `test/fixtures/aws_cco_*.yaml` | Example CRs for each CCO mode |
235+
| `test/e2e/cco_helm_rendering_test.go` | E2E tests for CCO template rendering |
236+
237+
### RBAC
238+
239+
The operator requires a ClusterRole with permissions on `cloudcredential.openshift.io/credentialsrequests` (create, delete, get, list, patch, update, watch). This is configured in `config/rbac/clusterrole.yaml` and bound via `config/rbac/clusterrolebinding_cco.yaml`.
240+
161241
## Linting
162242

163243
The project uses golangci-lint with configuration in `.golangci.yml`. Enabled linters include:

Dockerfile.rhtpa-operator.rh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ LABEL features.operators.openshift.io/proxy-aware="false"
5151
LABEL features.operators.openshift.io/cnf="false"
5252
LABEL features.operators.openshift.io/csi="false"
5353
LABEL features.operators.openshift.io/tls-profiles="false"
54-
LABEL features.operators.openshift.io/token-auth-aws="false"
54+
LABEL features.operators.openshift.io/token-auth-aws="true"
5555
LABEL features.operators.openshift.io/token-auth-azure="false"
5656
LABEL features.operators.openshift.io/token-auth-gcp="false"
5757

bundle.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ LABEL features.operators.openshift.io/proxy-aware="false"
2323
LABEL features.operators.openshift.io/cnf="false"
2424
LABEL features.operators.openshift.io/csi="false"
2525
LABEL features.operators.openshift.io/tls-profiles="false"
26-
LABEL features.operators.openshift.io/token-auth-aws="false"
26+
LABEL features.operators.openshift.io/token-auth-aws="true"
2727
LABEL features.operators.openshift.io/token-auth-azure="false"
2828
LABEL features.operators.openshift.io/token-auth-gcp="false"
2929
# Core bundle labels.

bundle/manifests/rhtpa-operator.clusterserviceversion.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ metadata:
103103
features.operators.openshift.io/fips-compliant: "false"
104104
features.operators.openshift.io/proxy-aware: "false"
105105
features.operators.openshift.io/tls-profiles: "false"
106-
features.operators.openshift.io/token-auth-aws: "false"
106+
features.operators.openshift.io/token-auth-aws: "true"
107107
features.operators.openshift.io/token-auth-azure: "false"
108108
features.operators.openshift.io/token-auth-gcp: "false"
109109
operators.openshift.io/valid-subscription: '["Red Hat Trusted Profile Analyzer"]'

bundle/metadata/annotations.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ annotations:
2222
features.operators.openshift.io/cnf: "false"
2323
features.operators.openshift.io/csi: "false"
2424
features.operators.openshift.io/tls-profiles: "false"
25-
features.operators.openshift.io/token-auth-aws: "false"
25+
features.operators.openshift.io/token-auth-aws: "true"
2626
features.operators.openshift.io/token-auth-azure: "false"
2727
features.operators.openshift.io/token-auth-gcp: "false"

config/manifests/bases/rhtpa-operator.clusterserviceversion.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ metadata:
1111
features.operators.openshift.io/fips-compliant: "false"
1212
features.operators.openshift.io/proxy-aware: "false"
1313
features.operators.openshift.io/tls-profiles: "false"
14-
features.operators.openshift.io/token-auth-aws: "false"
14+
features.operators.openshift.io/token-auth-aws: "true"
1515
features.operators.openshift.io/token-auth-azure: "false"
1616
features.operators.openshift.io/token-auth-gcp: "false"
1717
operators.openshift.io/valid-subscription: '["Red Hat Trusted Profile Analyzer"]'

config/rbac/clusterrole.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: ClusterRole
3+
metadata:
4+
name: cco-credentialsrequest-access
5+
rules:
6+
- apiGroups: ["cloudcredential.openshift.io"]
7+
resources: ["credentialsrequests"]
8+
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: ClusterRoleBinding
3+
metadata:
4+
labels:
5+
app.kubernetes.io/name: rhtpa-operator
6+
app.kubernetes.io/managed-by: kustomize
7+
name: cco-credentialsrequest-rolebinding
8+
roleRef:
9+
apiGroup: rbac.authorization.k8s.io
10+
kind: ClusterRole
11+
name: cco-credentialsrequest-access
12+
subjects:
13+
- kind: ServiceAccount
14+
name: rhtpa-operator-controller-manager
15+
namespace: placeholder

config/rbac/kustomization.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ resources:
1515
- rolebinding_job.yaml
1616
- role_cluster_ingress.yaml
1717
- role_cluster_ingress_binding.yaml
18+
- clusterrole.yaml
19+
- clusterrolebinding_cco.yaml
1820
# The following RBAC configurations are used to protect
1921
# the metrics endpoint with authn/authz. These configurations
2022
# ensure that only authorized users and service accounts

devel/cco/credentialRequest.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: cloudcredential.openshift.io/v1
2+
kind: CredentialsRequest
3+
metadata:
4+
name: my-operator-credentials
5+
namespace: openshift-cloud-credential-operator
6+
spec:
7+
secretRef:
8+
name: my-cloud-creds
9+
namespace: my-operator-namespace
10+
providerSpec:
11+
apiVersion: cloudcredential.openshift.io/v1
12+
kind: AWSProviderSpec # AWS
13+
statementEntries:
14+
- effect: Allow
15+
action:
16+
- "s3:GetObject"
17+
- "s3:PutObject"
18+
- "s3:DeleteObject"
19+
- "s3:ListBucket"
20+
- "s3:GetBucketLocation"
21+
- "s3:ListBucketMultipartUploads"
22+
- "s3:AbortMultipartUpload"
23+
- "s3:ListMultipartUploadParts"
24+
resource: "*"

0 commit comments

Comments
 (0)