Approver-policy-enterprise Venafi plugin
Learn how to configure the approver-policy component of TLS Protect for Kubernetes Enterprise
Venafi Approver Policy
The Enterprise version of approver-policy has a Venafi plugin which allows it to connect to a Venafi Control Plane server (VaaS/ TPP) and apply the policy settings of a particular policy folder. The approver-policy-enterprise project uses VenafiConnection CRs to configure how to connect to the Venafi Control Plane. The configuring venafi-connection documentation explains how to create these VenafiConnection CRs.
Create a CertificateRequestPolicy containing Venafi plugin configuration.
For the snippet below, we assume that the following VenafiConnection CR exist: namespace: jetstack-secure name: application-team-1-connection
apiVersion: policy.cert-manager.io/v1alpha1kind: CertificateRequestPolicymetadata:name: venafi-policy1spec:allowed:commonName:value: "*"dnsNames:values: ["*"]usages:- "signing"- "digital signature"- "server auth"plugins:venafi:values:venafiConnectionName: application-team-1-connectionzone: \VED\Policy\Teams\application-team-1selector:issuerRef: {}
After the connection defined in the VenafiConnection CR is tested without errors, the CertificateRequestPolicy can check the specified zone and becomes Ready.
$ kubectl wait --for=condition=Ready certificaterequestpolicy venafi-policy1certificaterequestpolicy.policy.cert-manager.io/tpp-policy1 condition met
If it does not become Ready, then use kubectl describe to see what is wrong. E.g.:
$ kubectl describe certificaterequestpolicy tpp-policy1...Warning NotReady 5s (x2 over 5s)policy.cert-manager.io CertificateRequestPolicy is not ready for approval evaluation: spec.plugins.tpp.values: Invalid value: "whilegetting zone configuration for policy: while creating vcert client: vcert error: your data contains problems: auth error: failed toauthenticate: can't determine valid credentials set": Retrying in 1m0s
In this example you can see that the credentials are invalid or are missing. If you edit the Secret and add the correct the credentials, they will be rechecked within 1 minute and the CertificateRequestPolicy will then become Ready.
Create an approved certificate
Once the CertificateRequestPolicy is Ready you can try creating a Certificate which is allowed by your TPP policy:
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: approved-certificatespec:commonName: hello.worlddnsNames:- "hello.world"- "example.hello.world"privateKey:algorithm: RSAsize: 4096issuerRef:name: my-issuerkind: Issuergroup: cert-manager.io
$ cmctl create certificaterequest approved-certificate --from-certificate-file cert-approve.yaml
You should see an event that says that the CertificateRequest was approved:
$ kubectl get eventsLAST SEEN TYPE REASON OBJECT MESSAGE2m2s Normal Approved certificaterequest/approved-certificate Approved by CertificateRequestPolicy: "tpp-policy1"
Create a denied certificate
Now let's modify the TPP policy to only allow certificates with the domain example.com:
Delete the certificate that we created earlier and then try again.
$ kubectl delete cr approved-certificatecmctl create certificaterequest approved-certificate --from-certificate-file cert-approve.yaml
This time you will see the CertificateRequest has been denied and there is an error event attached to the CertificateRequest explaining what went wrong:
$ kubectl describe cr approved-certificate...Events:Type Reason Age From Message---- ------ ---- ---- -------Warning Denied 41s policy.cert-manager.io No policy approved this request: [tpp-policy1: common name hello.world is not allowed in this policy: [^([\p{L}\p{N}-*]+\.)*example\.com$]]
Periodic Configuration and Connection Health Checks
As a Kubernetes platform administrator, having installed a CerticateRequestPolicy, you will want to know that approver-policy-enterprise continues to be able to connect to the Venafi API and that it continues to be able to download the Venafi policy settings. And you need to know about any problems before they affect the approval of CertificateRequest resources.
The Venafi plugin in approver-policy-enterprise periodically performs a health check which connects to the Venafi API and downloads the policy configuration. It reports errors via the CertificateRequestPolicy.Status and with structured log messages, so that you can set up your monitoring systems to either check the Ready condition in the CertificateRequestPolicy.Status, or set up alerts when errors are logged by the approver-policy-enterprise component.
You can configure the interval between health checks using the --venafi-ready-check-interval flag. The default interval is 1 hour.
If you need to reduce the frequency of Venafi API requests you can increase this interval, but this will delay your alerts and it will take longer for you to be notified if there is a problem with the connection to the Venafi API.
📖 Read more about Customizing approver-policy-enterprise using command line flags.
Troubleshooting
Configuration and Connection Validation
The Venafi plugin for approver-policy-enterprise connects to a Venafi API server and downloads policy data. If there is a failure (e.g. a connection failure, authentication error or a download failure), then CertificateRequest resources will be Denied and will not be processed by cert-manager.
You can use kubectl describe to examine the Ready condition and Event resources associated with a particular CertificateRequestPolicy. The CertificateRequestPolicy.Status is updated when ever the CertificateRequestPolicy is created or modified.
If the policy has been downloaded successfully, you will see something like:
$ kubectl describe certificaterequestpolicy application-team-1...Status:Conditions:Message: CertificateRequestPolicy is ready for approval evaluationReason: ReadyStatus: TrueType: Ready...Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Ready 42m (x12 over 19h) policy.cert-manager.io CertificateRequestPolicy is ready for approval evaluation
If the connection failed you will see something like:
$ kubectl describe certificaterequestpolicy application-team-1Status:Conditions:Message: CertificateRequestPolicy is not ready for approval evaluation: spec.plugins.venafi.values: Invalid value: "while getting zone configuration for policy: connection is not ready yet (Venafi self-test failed): error authenticating with Venafi: vcert error: server error: server unavailable: Get \"https://api.venafi.cloud/v1/useraccounts\": dial tcp: lookup api.venafi.cloud on 10.96.0.10:53: server misbehaving": Retrying in 1h0m0sReason: NotReadyStatus: FalseType: Ready...Events:Type Reason Age From Message---- ------ ---- ---- -------Warning NotReady 112s (x76 over 6m55s) policy.cert-manager.io CertificateRequestPolicy is not ready for approval evaluation: spec.plugins.venafi.values: Invalid value: "while getting zone configuration for policy: connection is not ready yet (Venafi self-test failed): error authenticating with Venafi: vcert error: server error: server unavailable: Get \"https://api.venafi.cloud/v1/useraccounts\": dial tcp: lookup api.venafi.cloud on 10.96.0.10:53: server misbehaving": Retrying in 1h0m0s
You can also check the status of the VenafiConnection resource, as follows:
$ kubectl describe -n jetstack-secure venaficonnection...Status:Conditions:Last Transition Time: 2023-03-24T09:50:46ZMessage: connection is not ready yet (Venafi self-test failed): error authenticating with Venafi: vcert error: server error: server unavailable: Get "https://api.venafi.cloud/v1/useraccounts": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
And you can check the approver-policy-enterprise logs, as follows:
$ kubectl logs -n jetstack-secure deploy/cert-manager-approver-policy cert-manager-approver-policy...E0324 09:50:46.172533 1 plugin.go:286] venafi/evaluate "msg"="Internal CertificateRequestPolicy evaluation error" "error"="while getting zone configuration for policy: connection is not ready yet (Venafi self-test failed): error authenticating with Venafi: vcert error: server error: server unavailable: Get \"https://api.venafi.cloud/v1/useraccounts\": net/http: request canceled (Client.Timeout exceeded while awaiting headers)" "UID"="2405bccb-c445-4291-a9d5-4a63dc99a5b2" "certificaterequest"={"Namespace":"application-team-1","Name":"service-1-4xwxw"} "description"="The VenafiConnection is invalid." "policy"={"Namespace":"","Name":"application-team-1"}I0324 09:50:46.176662 1 recorder.go:103] controller-manager/events "msg"="No policy approved this request: [application-team-1: Internal CertificateRequestPolicy evaluation error: 2405bccb-c445-4291-a9d5-4a63dc99a5b2]" "object"={"kind":"CertificateRequest","namespace":"application-team-1","name":"service-1-4xwxw","uid":"20d6ae73-0889-4850-8a91-331f264f3c32","apiVersion":"cert-manager.io/v1","resourceVersion":"112056"} "reason"="Denied" "type"="Warning"
As an application developer, if you create a CertificateRequest while there is a Venafi connection failure, you may see that your CertificateRequest is denied and an associated generic Warning Event:
$ kubectl describe cr -n application-team-1 service-1-4xwxw...Events:Type Reason Age From Message---- ------ ---- ---- -------...Warning Denied 7m11s policy.cert-manager.io No policy approved this request: [application-team-1: Internal CertificateRequestPolicy evaluation error: 2405bccb-c445-4291-a9d5-4a63dc99a5b2]
The warning message deliberately omits the specific details of the error, because the details may reveal sensitive infrastructure details. Instead, the message contains a UUID which can be shared with the platform administrator, so that they can diagnose the problem by looking up that UUID in the logs.