-
Notifications
You must be signed in to change notification settings - Fork 102
Description
Hello there, I'm new to trust-manager and see this as a valuable tool to facilitate synchronizing CA trust bundles for Kubernetes.
This may be a duplicate of #761
Currently, we are leveraging CA trust bundles in Kubernetes secrets and referencing the secrets in our custom issuers to establish secure, trusted connections with remote resources.
Looking over the trust-manager documentation, I have configured trust-manager with a Bundle CRD, but the synchronization does not happen unless I have a RBAC policy that provides trust-manager read access to all namespaces, not just the namespaces I'm targeting. Is this expected behavior, or am I missing a specification field somewhere?
Here's a script to reproduce:
# install cert-manager
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.19.2 \
--set crds.enabled=true
# create a namespace for custom issuer
kubectl create namespace issuer-playground
# install trust-manager
helm install trust-manager oci://quay.io/jetstack/charts/trust-manager \
--namespace cert-manager \
--set secretTargets.enabled=true \
--create-namespace \
--wait
# create a Kubernetes secret for the trusted CA chain
kubectl create secret generic enterprise-root-ca \
--from-file=ca.crt=trusted-chain.pem \
--namespace=cert-manager \
--dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f - <<EOF
apiVersion: trust.cert-manager.io/v1alpha1
kind: Bundle
metadata:
name: issuer-ca-bundle
spec:
sources:
- useDefaultCAs: false
- secret:
name: "enterprise-root-ca"
key: "ca.crt"
target:
secret:
key: "ca.crt"
namespaceSelector:
matchLabels:
issuer-ca-bundle: "enabled"
EOF
# label the namespace to allow issuer-ca-bundle to write secrets to it
kubectl label namespace issuer-playground issuer-ca-bundle=enabledWhen trust-manager runs, I see the following error:
time=2026-01-16T00:56:43.353Z level=ERROR msg="Failed to watch" logger=controller-runtime/cache/UnhandledError err="failed to list *v1.PartialObjectMetadata: secrets is forbidden: User \"system:serviceaccount:cert-manager:trust-manager\" cannot list resource \"secrets\" in API group \"\" at the cluster scope" reflector=k8s.io/client-go@v0.34.3/tools/cache/reflector.go:290 type=*v1.PartialObjectMetadata
The error is pretty explicit -- trust-manager does not have the ability to list secrets at the cluster scope. The only way I see to fix this issue is create RBAC policies that grant secret read at the cluster level and permission to write secrets at the namespace level.
# create ClusterRole allowing trust-manager to read secrets at the cluster level
kubectl apply -f - <<EOF
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: trust-manager-read
labels:
app.kubernetes.io/name: trust-manager
rules:
- apiGroups: ["trust.cert-manager.io"]
resources: ["bundles"]
verbs: ["get", "list", "watch"]
- apiGroups: ["trust.cert-manager.io"]
resources: ["bundles/status"]
verbs: ["patch", "update"]
- apiGroups: [""]
resources: ["secrets", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: trust-manager-read
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: trust-manager-read
subjects:
- kind: ServiceAccount
name: trust-manager
namespace: cert-manager
EOF
# create a Role for the issuer-playground namespace allowing trust-manager to write to secrets
kubectl apply -f - <<EOF
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: trust-manager-write
namespace: issuer-playground # change to your namespace
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: trust-manager-write
namespace: issuer-playground # change to your namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: trust-manager-write
subjects:
- kind: ServiceAccount
name: trust-manager
namespace: cert-manager
EOFNow, after applying that RBAC rule, I'm able to sync my secret successfully to the issuer-playground namespace.
Is it necessary that trust-manager needs to have read access to secrets cluster-wide? Or am I applying the incorrect specification to the bundle? I can see the need to list namespaces to determine the labels, but it doesn't make sense why it needs cluster-level access to read secrets.