Skip to content

Latest commit

 

History

1,013 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

cmp-issuer

GitHub Release GitHub Stars Last Commit Maintenance License Tests E2E Tests Supply chain OpenSSF Scorecard

cmp-issuer is a vendor-neutral cert-manager external issuer for Certificate Management Protocol (CMP) servers.

Point a cert-manager Certificate at a CMPIssuer and the certificate is enrolled over CMPv2 with the resulting certificate written to the usual TLS Secret.

CMP message protection is mandatory. HTTP and HTTPS are both supported.

Initial enrollment uses P10CR. A renewal re-enrolls with P10CR by default or uses certificate-authenticated KUR with CRMF proof of possession when the CMP profile requires a true key update.

This repository is under active initial development. The API group is served at v1alpha1 and may change.

Contents

Prerequisites

Install

demo is the namespace your certificates are issued into. Substitute your own.

kubectl create namespace demo

helm repo add cmp-issuer https://misiektoja.github.io/cmp-issuer/charts
helm repo update
helm install cmp-issuer cmp-issuer/cmp-issuer \
  --namespace cmp-issuer-system \
  --create-namespace \
  --set 'credentialNamespaces={demo}'

That installs the CRDs, the controller and the permission cert-manager needs before it will approve requests for this issuer type. credentialNamespaces lets the controller read the issuer credentials in demo and nowhere else, so name every namespace your issuers live in.

A packaged chart, a self-contained installer manifest and an air-gapped bundle are attached to every release. Those paths, and the settings this quick start leaves at their defaults, are in Installation.

Issue your first certificate

The short version is below. Getting started explains each step, shows the expected output and lists what to check when something does not work.

Store the credential your CMP administrator gave you and the CA certificate that signs the server's CMP responses:

kubectl create secret generic cmp-credentials --namespace demo \
  --from-literal=reference='<reference>' \
  --from-literal=secret='<shared-secret>'

kubectl create secret generic cmp-trust --namespace demo \
  --from-file=ca.crt=/path/to/cmp-ca.crt

Create the issuer:

kubectl apply -f - <<'EOF'
apiVersion: certmanager.misiektoja.github.io/v1alpha1
kind: CMPIssuer
metadata:
  name: demo-issuer
  namespace: demo
spec:
  endpoint:
    url: http://cmp.example.com:8080/pkix/
  protocol:
    version: 2
    initialEnrollment: P10CR
    renewal: P10CR
    recipient: CN=Example CA,O=Example
    confirmation: Explicit
  protection:
    type: PasswordBasedMac
    passwordBasedMac:
      secretRef:
        name: cmp-credentials
  cmpTrust:
    caSecretRef:
      name: cmp-trust
      key: ca.crt
EOF

kubectl get cmpissuers -n demo
NAME          READY
demo-issuer   True

renewal decides what a cert-manager renewal sends. It defaults to another P10CR enrollment. Set it to KUR when the CMP profile requires a true key update, as described in Renewal with P10CR or KUR.

Request a certificate:

kubectl apply -f - <<'EOF'
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: demo-tls
  namespace: demo
spec:
  secretName: demo-tls
  commonName: workload.example.com
  privateKey:
    algorithm: RSA
    size: 2048
  issuerRef:
    name: demo-issuer
    kind: CMPIssuer
    group: certmanager.misiektoja.github.io
EOF

kubectl get certificate demo-tls -n demo
NAME       READY   SECRET     AGE
demo-tls   True    demo-tls   12s

How it works

Enrollment. cert-manager creates the private key and the PKCS #10 request. The controller picks up the approved CertificateRequest, sends the request to your CMP server in a protected P10CR and hands the issued chain back to cert-manager. initialEnrollment accepts only P10CR for now.

Renewal. A renewal sends another P10CR unless you set spec.protocol.renewal to KUR. KUR authenticates the request using the current valid certificate and proves possession of the key that cert-manager requested. This meets the expectations of CMP profiles requiring a true key update. Renewals can go to their own CMP alias with spec.endpoint.renewalUrl.

Slow or queued requests. When the CA cannot issue right away it answers waiting and the issuer polls until the certificate arrives. Every transaction is recorded in a CMPTransaction before the first message goes out, so a controller restart resumes that transaction instead of enrolling a second time. Follow them with kubectl get cmptransactions -A.

Private keys and secrets. P10CR never reads workload private keys. KUR reads only the current and staged keys of the certificate being renewed, after checking the controlling cert-manager Certificate, its owner UID, revision, issuer reference and Secret ownership. The controller reads Secrets only in the namespaces you name at install time. TLS trust and CMP response trust are configured separately and every response must come from the authority set as recipient.

CMP server differences. spec.protocol.validationProfile defaults to Interoperable, which tolerates the deviations real CMP servers show. It accepts certReqId -1 or 0 in a P10CR response, echoes the received value back in certConf and treats KUP caPubs as untrusted chain candidates rather than trust anchors. Choose RFC9483 for the strict checks or pin a single behavior you already know, such as spec.protocol.p10crResponseCertReqId.

Logs and metrics. Each completed enrollment writes one Issued certificate log line with the subject, serial, validity and issuing CA. Prometheus metrics count enrollments, durations and classified failures per issuer, with renewals kept separate from first enrollments. See Metrics.

Built on cert-manager's own library. Approval, denial, retry classification, Ready conditions and Events come from issuer-lib, maintained by the cert-manager project and pinned to an exact version. See ADR 0002.

Real-world interoperability. cmp-issuer is tested against real PKI and CMP server implementations to verify that it works beyond synthetic test environments. This includes interoperability testing with EJBCA and Nokia NCM, with results and known compatibility details published in Tested PKIs.

Documentation

Full documentation is at misiektoja.github.io/cmp-issuer.

Support

SUPPORT.md directs usage questions, bug reports, feature requests and security reports. Check the documentation and gather the sanitized version, resource status and controller log before posting.

License

Original cmp-issuer code is licensed under Apache-2.0. Dependencies retain their own licenses. See THIRD_PARTY_NOTICES.md.

About

Kubernetes cert-manager external issuer for Certificate Management Protocol (CMP) servers

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages