cert-manager / approver-policy

approver-policy is a cert-manager approver that allows users to define policies that restrict what certificates can be requested.
https://cert-manager.io/docs/policy/approval/approver-policy/
Apache License 2.0
66 stars 23 forks source link

failed to create subjectaccessreview #300

Closed HSoulat closed 11 months ago

HSoulat commented 11 months ago

Certificate approbation doesn't work with custom approval-policy on a certificate / certificate-request in kube-system namespace but work on others namespaces

Here are the logs of approver policy pod :

On custon namespace

I1107 09:56:03.021039       1 controller.go:315] controller-manager "msg"="Reconciling" "CertificateRequest"={"name":"xxx-tls-clxs6","namespace":"xxx"} "controller"="certificaterequest" "controllerGroup"="cert-manager.io" "controllerKind"="CertificateRequest" "name"="xxx-clxs6" "namespace"="xxx" "reconcileID"="745d0fb8-2e36-4004-9297-72404aed1c87"
I1107 09:56:03.022066       1 certificaterequests.go:172] controller/certificaterequests "msg"="syncing certificaterequest" "name"="xxx-clxs6" "namespace"="xxx"
I1107 09:56:03.026323       1 certificaterequests.go:195] controller/certificaterequests "msg"="approving request" "name"="xxx-clxs6" "namespace"="xxx"
I1107 09:56:03.026393       1 conditions.go:263] Setting lastTransitionTime for CertificateRequest "" condition "Approved" to 2023-11-07 09:56:03.026386343 +0000 UTC m=+1189.231032754I1107 09:56:03.026795       1 recorder.go:104] controller-manager/events "msg"="Approved by CertificateRequestPolicy: \"ccc-policy\"" "object"={"kind":"CertificateRequest","namespace":"xxx","name":"xxx-clxs6","uid":"1e602535-53f9-4fa2-a81f-e3802b9f043a","apiVersion":"cert-manager.io/v1","resourceVersion":"23855088"} "reason"="Approved" "type"="Normal"
I1107 09:56:03.166309       1 controller.go:344] controller-manager "msg"="Reconcile successful" "CertificateRequest"={"name":"xxx-clxs6","namespace":"xxx"} "controller"="certificaterequest" "controllerGroup"="cert-manager.io" "controllerKind"="CertificateRequest" "name"="xxx-clxs6" "namespace"="xxx" "reconcileID"="745d0fb8-2e36-4004-9297-72404aed1c87"

On kube-system

I1107 10:03:19.879028       1 controller.go:315] controller-manager "msg"="Reconciling" "CertificateRequest"={"name":"yyy-tls-b7rbx","namespace":"kube-system"} "controller"="certificaterequest" "controllerGroup"="cert-manager.io" "controllerKind"="CertificateRequest" "name"="yyy-tls-b7rbx" "namespace"="kube-system" "reconcileID"="fb0c3690-106c-47fe-8db7-0d1d5b3d5894"
I1107 10:03:19.879075       1 certificaterequests.go:172] controller/certificaterequests "msg"="syncing certificaterequest" "name"="yyy-tls-b7rbx" "namespace"="kube-system"
I1107 10:03:19.879130       1 controller.go:344] controller-manager "msg"="Reconcile successful" "CertificateRequest"={"name":"yyy-tls-b7rbx","namespace":"kube-system"} "controller"="certificaterequest" "controllerGroup"="cert-manager.io" "controllerKind"="CertificateRequest" "name"="yyy-tls-b7rbx" "namespace"="kube-system" "reconcileID"="fb0c3690-106c-47fe-8db7-0d1d5b3d5894"
I1107 10:03:20.445465       1 controller.go:315] controller-manager "msg"="Reconciling" "CertificateRequest"={"name":"yyy-tls-v6z27","namespace":"kube-system"} "controller"="certificaterequest" "controllerGroup"="cert-manager.io" "controllerKind"="CertificateRequest" "name"="yyy-tls-v6z27" "namespace"="kube-system" "reconcileID"="533af2b5-72e5-448a-8aaf-581f6c8a2b1c"
I1107 10:03:20.445507       1 certificaterequests.go:172] controller/certificaterequests "msg"="syncing certificaterequest" "name"="yyy-tls-v6z27" "namespace"="kube-system"
I1107 10:03:20.449591       1 recorder.go:104] controller-manager/events "msg"="approver-policy failed to review the request and will retry" "object"={"kind":"CertificateRequest","namespace":"kube-system","name":"yyy-tls-v6z27","uid":"32d7ec7c-26d2-42e0-a9dc-813b5cb8670f","apiVersion":"cert-manager.io/v1","resourceVersion":"23857628"} "reason"="EvaluationError" "type"="Warning"
E1107 10:03:20.450255       1 controller.go:329] controller-manager "msg"="Reconciler error" "error"="failed to perform predicate on policies: failed to create subjectaccessreview: .authorization.k8s.io \"\" is invalid: spec.user: Invalid value: \"\": at least one of user or group must be specified" "CertificateRequest"={"name":"yyy-tls-v6z27","namespace":"kube-system"} "controller"="certificaterequest" "controllerGroup"="cert-manager.io" "controllerKind"="CertificateRequest" "name"="yyy-tls-v6z27" "namespace"="kube-system" "reconcileID"="533af2b5-72e5-448a-8aaf-581f6c8a2b1c"

Cert manager v1.12.2 approver policy v0.8.0

erikgb commented 11 months ago

@HSoulat Have you read the RBAC part in the docs: https://cert-manager.io/docs/policy/approval/approver-policy/#configuration?

Are you able to share some details of your CertificateRequest, Issuer (or ClusterIssuer) and CertificateRequestPolicy?

HSoulat commented 11 months ago

@erikgb, sure, I may have missed something regarding the RBAC configuration

Issuer,

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: xxx-issuer
spec:
  ca:
    secretName: ca-xxx-key-pair

Policy,

apiVersion: policy.cert-manager.io/v1alpha1
kind: CertificateRequestPolicy
metadata:
  name: xxx-policy
spec:
  allowed:
    ...
    isCA: false
    usages:
    - "server auth"
    - "client auth"
    - "key encipherment"
    - "digital signature"
    subject:
     ...
  constraints:
    ...
  selector:
    # Select all IssuerRef
    issuerRef: {}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cert-manager-policy:xxx
rules:
  - apiGroups: ["policy.cert-manager.io"]
    resources: ["certificaterequestpolicies"]
    verbs: ["use"]
    # Name of the CertificateRequestPolicies to be used.
    resourceNames: ["xxx-policy"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cert-manager-policy:xxx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cert-manager-policy:xxx
subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
  name: cert-manager
  namespace: cert-manager

Certificate.

apiVersion: cert-manager.io/v1
kind: CertificateRequest
metadata:
  annotations:
    cert-manager.io/certificate-name: xxx-tls
    cert-manager.io/certificate-revision: "1"
    cert-manager.io/private-key-secret-name: xxx-tls-w4cdm
  creationTimestamp: "2023-11-07T13:16:09Z"
  generateName: xxx-tls-
  generation: 1
  name: xxx-tls-rwn9m
  namespace: kube-system
  ownerReferences:
  - apiVersion: cert-manager.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: Certificate
    name: xxx-tls
    uid: ed749d1a-54cb-480e-a449-36bdfff232e1
  resourceVersion: "23930574"
  uid: c8808450-44f6-4655-a4db-1923bd0cac91
spec:
  duration: 2760h0m0s
  issuerRef:
    group: cert-manager.io
    kind: ClusterIssuer
    name: xxx-issuer
  request: 
    ...
  usages:
  - digital signature
  - key encipherment

I have also tested the same configuration with a selfsign issuer and I got the same behavior. The certificate requests in any namespace are approved execpted in kube-system

SgtCoDFish commented 11 months ago

Definitely looks like there's something strange going on here!

That SubjectAccessReview (SAR) is created here. It uses the username from the certficaterequest.spec but it doesn't look like there's a username in your CertificateRequest there.

Usually that should be set by the mutating webhook in cert-manager in the normal case and then checked by the cert-manager validating webhook. Are they working as expected for kube-system?

wallrj commented 11 months ago

Building on what @SgtCoDFish said; perhaps the platform admin has modified the MutatingWebhookConfiguration to avoid it being called for kube-system objects:

Check for differences between the actual mutatingwebhook configuration (kubectl get mutatingwebhookconfiguration cert-manager-webhook -o yaml) and the original cert-manager mutatingwebhookconfiguration.

jsoref commented 11 months ago

What version of K8s? Which vendor? (GKE?)

Do you have access to API server logs? (For GKE, these have been quite illuminating)

HSoulat commented 11 months ago

@wallrj you're true, AKS platform is adding the following in namespaceSelectoron MutatingWebhookConfigurationas well on ValidatingWebhookConfiguration.

namespaceSelector:
      matchExpressions:
        - key: kubernetes.azure.com/managedby
          operator: NotIn
          values:
            - aks
        - key: control-plane
          operator: NotIn
          values:
            - 'true'

kube-system namespace have both labels.

What is strange to me is that if I use the default approver in cert-manager the validation process is working.

wallrj commented 11 months ago

What is strange to me is that if I use the default approver in cert-manager the validation process is working.

That's because the default approver in cert-manager always approves CertificateRequests. It ignores the empty identity fields in those kube-system CertificateRequest resources.

In a default installation, cert-manager automatically approves all CertificateRequests and CertificateSigningRequests that use any of its built-in issuers. This is done to simplify the first-time experience of using cert-manager. -- https://cert-manager.io/docs/policy/approval/

HSoulat commented 11 months ago

Thanks for your help to understand the root cause. So using a custom approver on AKS do not permit to generate CertificateRequests on kube-system or an option is available to allow build-in/empty user ?

wallrj commented 11 months ago

Thanks for your help to understand the root cause. So using a custom approver on AKS do not permit to generate CertificateRequests on kube-system or an option is available to allow build-in/empty user ?

My advice is to treat kube-system as the property of AKS and not to attempt to create or change any resources in that namespace.

But it looks like you can disable the "Admissions Enforcer" if you choose:

wallrj commented 11 months ago

@HSoulat feel free to re-open this issue if necessary.

/close

jetstack-bot commented 11 months ago

@wallrj: Closing this issue.

In response to [this](https://github.com/cert-manager/approver-policy/issues/300#issuecomment-1824267299): >@HSoulat feel free to re-open this issue if necessary. > >/close Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.