CertificateAuthority¶
A CertificateAuthority manages the CA infrastructure: a PVC for CA data, a setup Job that runs puppetserver ca setup, and Secrets for CA certificates, keys, and CRLs. A Config references the CertificateAuthority via its authorityRef field.
Example¶
apiVersion: openvox.voxpupuli.org/v1alpha1
kind: CertificateAuthority
metadata:
name: production-ca
spec:
crlRefreshInterval: 5m
storage:
size: 1Gi
Autosigning is configured via SigningPolicy resources that reference this CertificateAuthority.
Spec¶
| Field | Type | Default | Description |
|---|---|---|---|
ttl |
string | 5y |
CA certificate TTL as duration string (e.g. 5y, 365d, 8760h) |
allowSubjectAltNames |
bool | true |
Allow SANs in CSRs |
allowAuthorizationExtensions |
bool | true |
Allow authorization extensions (pp_role, pp_environment, etc.) in CSRs |
enableInfraCRL |
bool | true |
Enable infrastructure CRL for compile server revocation |
allowAutoRenewal |
bool | true |
Allow agents to automatically renew certificates before expiry |
autoRenewalCertTTL |
string | 90d |
TTL threshold for automatic certificate renewal (duration: 90d, 30d, 2160h) |
crlRefreshInterval |
string | 5m |
How often the operator refreshes the CRL Secret from the CA (Go duration: 5m, 1h, 30s) |
resources |
ResourceRequirements | requests: 200m/768Mi, limits: 1/1Gi | Compute resources for the CA setup Job |
storage |
StorageSpec | - | PVC settings for CA data |
external |
ExternalCASpec | - | External CA configuration (mutually exclusive with custom storage) |
intermediateCA |
IntermediateCASpec | - | Intermediate CA configuration |
ExternalCASpec¶
Configures an external CA running outside the cluster. When set, the operator delegates CSR signing and CRL fetching to the external CA URL instead of managing its own CA infrastructure. See the External CA guide for step-by-step setup instructions.
Mutual exclusivity
spec.external and custom spec.storage are mutually exclusive. A CEL validation rule rejects resources that set both. External CAs do not need local storage.
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Base URL of the external Puppet/OpenVox CA (e.g. https://puppet-ca.example.com:8140). Must start with http:// or https://. |
caSecretRef |
string | No | Name of a Secret containing ca_crt.pem for TLS verification of the external CA |
tlsSecretRef |
string | No | Name of a Secret containing tls.crt and tls.key for mTLS client authentication |
insecureSkipVerify |
bool | No | Skip TLS certificate verification (not recommended for production) |
Example:
apiVersion: openvox.voxpupuli.org/v1alpha1
kind: CertificateAuthority
metadata:
name: external-ca
spec:
allowSubjectAltNames: true
allowAuthorizationExtensions: true
enableInfraCRL: true
crlRefreshInterval: 5m
external:
url: https://puppet-ca.example.com:8140
caSecretRef: external-ca-cert # Secret with ca_crt.pem
tlsSecretRef: external-ca-tls # Secret with tls.crt + tls.key (optional mTLS)
insecureSkipVerify: false
IntermediateCASpec¶
Not yet implemented
Intermediate CA support is defined in the CRD schema but not yet implemented in the controller. This section documents the planned API surface.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Activate intermediate CA mode |
secretName |
string | - | Secret containing ca.pem, key.pem, crl.pem |
Status¶
| Field | Type | Description |
|---|---|---|
phase |
string | Current lifecycle phase |
caSecretName |
string | Name of the Secret containing ca_crt.pem (public CA certificate) |
serviceName |
string | Name of the internal ClusterIP Service for operator communication. Empty when spec.external is set. |
signingSecretName |
string | Name of the TLS Secret used for mTLS authentication when signing certificates via the CA HTTP API |
notAfter |
time | Expiry time of the CA certificate |
conditions |
[]Condition | CAReady |
Phases¶
| Phase | Description |
|---|---|
Pending |
CertificateAuthority created, waiting for reconciliation |
Initializing |
CA setup Job is running |
Ready |
CA Secrets created, Certificates can be signed |
External |
External CA configured (no PVC, Job, or internal Service) |
Error |
CA setup failed |
CA Secrets¶
The CA setup Job creates three separate Secrets with different security profiles:
| Secret | Contents | Mounted in Pods | Purpose |
|---|---|---|---|
{name}-ca |
ca_crt.pem |
Yes (all pods) | Public CA certificate for trust chain |
{name}-ca-key |
ca_key.pem |
No (API access only) | CA private key, never exposed to pods |
{name}-ca-crl |
ca_crl.pem, infra_crl.pem |
Yes (non-CA pods) | CRL for certificate revocation checks |
The CRL Secret is periodically refreshed by the operator (see crlRefreshInterval). Non-CA pods mount it as a directory volume (not SubPath) so kubelet auto-syncs changes without pod restarts. CA pods read the CRL directly from the CA PVC.
sequenceDiagram
participant Op as Operator
participant CA as CA Server (port 8140)
participant Sec as Secret {name}-ca-crl
participant KL as kubelet
participant Srv as Non-CA Server Pods
loop every crlRefreshInterval (default 5m)
Op->>CA: GET /puppet-ca/v1/certificate_revocation_list/ca
CA-->>Op: CRL PEM data
Op->>Sec: Update ca_crl.pem
end
Note over KL: ~60s sync period
KL->>Srv: Projected volume update
Srv->>Srv: TLS handshake uses new CRL
Internal Service¶
The CertificateAuthority controller creates a dedicated ClusterIP Service named {name}-internal for operator-internal communication (CSR signing and CRL refresh). This Service is separate from any Pool Service so that users can freely configure the Pool's Service type (ClusterIP, LoadBalancer, NodePort) without conflicting with the operator.
The internal Service FQDN ({name}-internal.{namespace}.svc) is automatically added as a SAN to the CA server certificate during setup, so TLS validation succeeds without manual configuration.
Created Resources¶
| Resource | Name | Description |
|---|---|---|
| Service | {name}-internal |
Internal ClusterIP Service for operator communication (port 8140) |
| PVC | {name}-data |
Persistent storage for CA keys and data |
| ServiceAccount | {name}-ca-setup |
Job ServiceAccount with permission to create CA Secrets |
| Role | {name}-ca-setup |
Scoped to CA Secret creation |
| RoleBinding | {name}-ca-setup |
Binds Role to ServiceAccount |
| Job | {name}-ca-setup |
Runs puppetserver ca setup, creates CA Secrets |
| Secret | {name}-ca |
Public CA certificate (ca_crt.pem) |
| Secret | {name}-ca-key |
CA private key (ca_key.pem) |
| Secret | {name}-ca-crl |
CRL data (ca_crl.pem, infra_crl.pem) -- periodically refreshed |