certforge-issuer is a cert-manager external issuer that intercepts CertificateRequest objects and submits them to CertForge for policy evaluation, approval, and issuance. Your existing Certificate manifests work unchanged — you just point issuerRef at CertForge instead of a built-in issuer.
Prerequisites
- Kubernetes 1.24+
- cert-manager v1.14+
- A CertForge account with at least one Domain Trust Profile covering your cluster’s domains
Before you install
CertForge must be configured for the domains your workloads will request certificates for, otherwise requests will be rejected immediately withInvalidRequest.
1. Create a Domain Trust Profile covering the domain patterns your workloads use. For example, if pods will request certs for *.internal.example.com, your DTP must include that pattern. Go to Domain Trust Profiles → New in the CertForge dashboard.
2. Generate an API token — go to Settings → API Keys and create a token with the enroll and read scopes. No other scopes are required. You will supply this during installation.
Installation
Helm (recommended)
US East (default):Manual
Configure the issuer
Namespaced issuer
UseCertForgeIssuer to scope issuance to a single namespace:
Cluster-wide issuer
UseCertForgeClusterIssuer to issue certificates across all namespaces. The credentials secret must live in the certforge-system namespace:
Data residency
Your API token is scoped to a single region at account creation time. Seturl to match your org’s region — the URL and token together route every certificate request to the correct region with no cross-border data flows.
To serve multiple regions from one cluster, deploy a separate
CertForgeClusterIssuer per region with its own credentials secret:
Request a certificate
Point any cert-managerCertificate at CertForge by changing issuerRef:
CertificateRequest; the issuer controller submits the CSR to CertForge; once issued the certificate is written back as a Kubernetes Secret.
Wildcard certificates
Wildcard certificates work the same way — ensure your DTP permits wildcards for the domain:Multiple SANs
How approval works
Certificate issuance involves two separate approval steps: 1. cert-manager approval — cert-manager’s built-in approver only auto-approves requests for its own built-in issuers (ACME, CA, SelfSigned). Forcertforge-issuer, the CertificateRequest will sit with an empty APPROVED column until it is approved. The certforge-issuer controller will not submit the CSR to CertForge until this condition is set.
For production, install cert-manager-approver-policy and deploy a CertificateRequestPolicy that auto-approves requests for certforge.io issuers. CertForge already enforces domain policy via Domain Trust Profiles, so the Kubernetes-side rule just needs to unblock the approval gate:
CertForgeIssuer and CertForgeClusterIssuer (anything in the certforge.io group). For namespace-scoped or domain-scoped variants, see the sample file in the certforge-issuer repository.
For local testing, approve manually with cmctl:
- Auto-approve — the certificate is issued immediately, typically within a few seconds.
- Manual approval required — the request enters the CertForge approval queue. The controller polls until the request is approved or denied. The
Certificatestays pending until then.
Troubleshooting
If aCertificate stays pending, inspect the underlying CertificateRequest:
Check the issuer controller logs for connectivity errors:
x509: certificate signed by unknown authority:
Your self-hosted CertForge instance uses a CA the controller doesn’t trust. Add the CA certificate to your cluster’s trusted roots (e.g. via a custom CA bundle in the node’s trust store, or by configuring the certforge-issuer pod with a volume-mounted CA cert and the SSL_CERT_FILE environment variable pointing to it).
API token invalid in controller logs:
The token in the certforge-credentials secret has expired or been revoked. Generate a new one under Settings → API Keys and update the secret: