Skip to content

Harden RBAC and reduce over-privileged access in ztvp-certificates#158

Open
p-rog wants to merge 1 commit into
validatedpatterns:mainfrom
p-rog:security-patches
Open

Harden RBAC and reduce over-privileged access in ztvp-certificates#158
p-rog wants to merge 1 commit into
validatedpatterns:mainfrom
p-rog:security-patches

Conversation

@p-rog

@p-rog p-rog commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

The ztvp-certificates chart grants its CA extraction ServiceAccount significantly broader permissions than it needs. This PR applies the principle of least privilege across four areas:

  • Namespace-scoped secrets/configmaps access — the ca-reader ClusterRole previously granted cluster-wide secrets:[get,list] and configmaps:[get,list]. Replaced with namespace-scoped Role + RoleBinding pairs limited to the 4 namespaces the Job actually reads from: openshift-ingress-operator, openshift-ingress, openshift-config, openshift-config-managed.

  • Read-only proxy access with declarative management — the SA previously had proxies:[get,patch] to imperatively patch proxy/cluster.spec.trustedCA. Reduced to proxies:[get] with resourceNames:[cluster]. The trustedCA configuration is now managed declaratively via a new ArgoCD-synced template (proxy-trustedca.yaml) using ServerSideApply, leveraging ArgoCD's cluster-admin privileges instead of granting patch access to the Job SA.

  • Namespace-scoped rollout restart — the rollout ClusterRoleBinding (allowing workload restarts in any namespace) is replaced with per-namespace RoleBinding(s) driven by a new .Values.rollout.namespaces list. The extraction script was also aligned to iterate rollout.namespaces instead of distribution.targetNamespaces, ensuring RBAC permissions and script behavior stay in sync.

  • Redact sensitive credentials from ACS Job logs — the create-auth-provider Job previously logged the full OIDC configuration JSON including the plaintext client_secret. Replaced with jq-based redaction that masks the secret value before printing. Falls back gracefully if jq is unavailable.

Changes

File Change
charts/ztvp-certificates/templates/rbac.yaml Replace cluster-wide secrets/configmaps rules with namespace-scoped Roles; reduce proxy verbs to read-only; replace rollout ClusterRoleBinding with per-namespace RoleBindings
charts/ztvp-certificates/templates/proxy-trustedca.yaml New — declarative Proxy resource managed by ArgoCD (sync-wave 24, ServerSideApply)
charts/ztvp-certificates/files/extract-certificates.sh.tpl Remove oc patch proxy/cluster calls; align rollout iteration to rollout.namespaces
charts/ztvp-certificates/values.yaml Add rollout.namespaces list (default: [qtodo])
overrides/values-ztvp-certificates.yaml Add rollout.namespaces: [qtodo]
charts/acs-central/templates/jobs/create-auth-provider.yaml Redact client_secret from OIDC debug output

Test plan

Verified on an OCP 4.21 cluster with a full ZTVP pattern deployment:

  • Helm template renders correctly for all modified charts
  • All 14 ArgoCD applications Synced/Healthy after deployment
  • SA can read secrets/configmaps only in the 4 permitted namespaces; denied in kube-system, openshift-monitoring, vault, stackrox, keycloak-system, qtodo
  • SA cannot list secrets cluster-wide
  • SA can restart workloads only in qtodo namespace; denied in openshift-monitoring, openshift-apiserver, kube-system, stackrox, vault
  • SA has read-only proxy access (get allowed, patch denied); proxy/cluster.spec.trustedCA.name correctly set to ztvp-proxy-ca by ArgoCD
  • CA extraction Job completes successfully; CA bundle ConfigMap created (21KB)
  • ACS Job logs show "OIDC Configuration JSON (client_secret redacted):" with no plaintext secret

Made with Cursor

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant