Skip to content

Threat model

Assets

The controller handles CMP shared secrets, issuer bootstrap private keys, bootstrap certificates, CMP trust anchors, TLS trust anchors, PKCS #10 CSRs and issued certificate chains. P10CR must not handle workload private keys. IR temporarily handles the requested workload private key and KUR the current and requested workload private keys, each after authenticating their cert-manager ownership chain.

Trust boundaries

Kubernetes RBAC protects issuer configuration and credential Secrets. A CMPIssuer may read only credential Secrets in its own namespace. A CMPClusterIssuer resolves credential Secrets only in the controller-configured cluster resource namespace.

CMP response trust is independent from TLS server trust. CMP PKIProtection is mandatory on every request and response. HTTPS provides confidentiality and transport authentication in addition to message protection. HTTP intentionally provides no transport confidentiality.

cert-manager approval is a network boundary. Unapproved or denied CertificateRequests must cause no CMP request.

Primary threats and controls

Threat Control
Credential exfiltration Least-privilege Secret RBAC, no secret values in logs or Events and no credentials in command arguments
Workload key exfiltration P10CR never follows private-key Secret annotations. IR and KUR verify the controlling Certificate name and UID, revision, issuer reference, next-key status, staged Secret owner and label plus CSR key equality before reading a key. KUR also verifies the current Secret and its cert-manager provenance
Annotation-selected arbitrary Secret read Treat cert-manager.io/private-key-secret-name only as one value in an authenticated cert-manager ownership chain and reject before a Secret read when that chain is absent or inconsistent
KUR authorized with the wrong certificate Require the current certificate and key to match, require current validity and digital-signature Key Usage when present then preserve the subject and SAN set in the CRMF template. A current Secret without cert-manager provenance for the Certificate is refused and never triggers a renewal fallback
IR or KUR requested-key substitution Match the staged private key to the signed CSR and use that key for CRMF proof of possession
IR for a hand-written or renewed request Allow IR for revision one of a cert-manager Certificate with no earlier revision in its status. Allow it for a later revision only when the issuer enables renewalFallback, the revision immediately follows Certificate.status.revision and the controller found the current certificate missing or expired before the first send or the recorded transaction carries that reason. No other request can direct the controller to a staged key
Renewal fallback forced by deleting the current Secret The fallback is off unless the issuer enables it. It needs Secret delete permission in the workload namespace or an expired certificate. Creating a Certificate for the issuer already yields an initial enrollment under the same issuer credentials, so the fallback adds no capability. A Secret written by another tool fails the provenance check and never falls back
Ambiguous IR or KUR send followed by another operation Persist the operation before the first send and never change it afterwards. A renewal fallback is decided before that send. Retry only the same operation under the recorded transaction identifier
Forged CMP response Require the configured protection mechanism then validate transaction ID, nonces, response body and signer trust before accepting a certificate
Certificate substitution Verify the issued leaf public key matches the signed CSR public key and validate the chain against CMP trust
Impersonation by another authority under the same anchor Require every response to name the authority configured as spec.protocol.recipient. Trust anchors establish that a responder is trusted, not which responder answered, so under a shared root any subordinate CA would otherwise satisfy protection verification. The comparison ignores attribute order. A response without a sender name is rejected because it cannot be bound to the configured authority
P10CR response identifier ambiguity Accept only the standards value -1 or the observed legacy value 0, echo the received value in certConf and allow an issuer to pin one value
Unverifiable confirmation response Verify against configured anchors, response signer certificates or the retained transaction signer when a server omits extraCerts from pkiConf. Configured response certificates remain subject to chain validation. The signer must match the sender and invalid protection is rejected
Unbounded wait for a delayed confirmation Record the validated chain before certConf is sent, then poll for a delayed pkiConf from that recorded state under the configured transaction deadline and poll ceiling, rather than holding a reconcile open or discarding an issued certificate
Redirect or header state injection Disable HTTP redirects and derive transaction state only from authenticated CMP DER
Resource exhaustion Bound response size, timeouts, polling, transaction duration and request concurrency
Duplicate enrollment after a restart Record the transaction identifier plus issuer and credential configuration identity in a CMPTransaction before the first message is sent, resume only that bound transaction on the next reconcile and return the recorded chain when the certificate was already issued
Forged or altered transaction state Resume a CMPTransaction only when it carries the CSR digest, operation, configuration digest and issuer identity the controller recorded and validate its recorded chain against the current CMP trust anchors before it is confirmed or returned, so write access to the resource cannot substitute a certificate for a request
Removal of transaction state belonging to another request Condition every delete of a CMPTransaction on the UID that was read, so a record deleted and recreated under the same name keeps the state of the request that created it
Ambiguous timeout on an unanswered enrollment Pin the transaction identifier before the message reaches the network and retry under it. Both tested servers refuse the repeat under an authenticated error, Nokia NCM 26.7 with transactionIdInUse and EJBCA CE 9.3.7 with badRequest, and neither issues a second certificate. The request fails permanently and cert-manager enrolls again under a new transaction identifier
Credential or workload key rotation mid-transaction Record each credential Secret UID and resourceVersion plus each IR or KUR workload Secret UID and key-material digest before the first message, then stop an unfinished transaction before more CMP traffic when any identity changes. The workload digest covers the consumed keys only, so a metadata-only write by another controller does not stop the transaction
Cross-namespace Secret reference Secret references contain names and keys only. Namespace selection is fixed by issuer scope
Malformed ASN.1 Fail closed, fuzz parsers and keep the parser behind project-owned interfaces

IR and KUR private-key boundary

The requested key proves possession in IR and KUR. The issuer credentials protect IR. The existing certificate key protects KUR. With rotationPolicy: Always the two KUR keys are distinct Secrets. With Never they can contain the same private key. The annotation cert-manager.io/private-key-secret-name is never sufficient authorization by itself.

The manager has cluster-wide get permission for cert-manager Certificates because it must resolve the controlling owner. It has no list, watch or mutation permission for Certificates. Secret access remains bound per namespace through RoleBindings. A cluster issuer needs that binding in each workload namespace that selects IR or KUR.

Residual risks

The CMP library and adapter share a maintainer, so both can make the same specification mistake. ADR 0001 records the dependency boundary and independent validation requirements. CMP interoperability also depends on each server's profile, algorithms, endpoint and authentication policy.