Importing or Connecting an External CA¶
This guide covers two approaches for using an existing Puppet or OpenVox CA with the operator:
- CA Import -- copy existing CA data into the operator-managed PVC (one-time migration)
- External CA -- point the operator at a running CA outside the cluster (ongoing delegation)
Option A: CA Import (One-Time Migration)¶
If you have an existing CA and want the operator to manage it going forward, you can import the CA data into the operator's PVC.
Prerequisites¶
- An existing Puppet/OpenVox CA with
ca_crt.pem,ca_key.pem, andca_crl.pem - The operator installed in the cluster
Steps¶
-
Create the
CertificateAuthorityresource as usual (withoutspec.external): -
Wait for the PVC to be created, then copy your CA data into it:
# Find the PVC kubectl get pvc -l openvox.voxpupuli.org/certificate-authority=production-ca # Create a temporary pod to copy data kubectl run ca-import --image=busybox --restart=Never \ --overrides='{ "spec": { "containers": [{ "name": "ca-import", "image": "busybox", "command": ["sleep", "3600"], "volumeMounts": [{ "name": "ca-data", "mountPath": "/ca" }] }], "volumes": [{ "name": "ca-data", "persistentVolumeClaim": { "claimName": "production-ca-data" } }] } }' # Copy CA files kubectl cp ca_crt.pem ca-import:/ca/ca_crt.pem kubectl cp ca_key.pem ca-import:/ca/ca_key.pem kubectl cp ca_crl.pem ca-import:/ca/ca_crl.pem # Clean up kubectl delete pod ca-import -
The CA setup Job will detect existing data and skip regeneration. The operator will create the corresponding Secrets and transition to
Ready.
Option B: External CA (Ongoing Delegation)¶
If you have a Puppet/OpenVox CA running outside the cluster and want to keep using it, configure spec.external on the CertificateAuthority resource. The operator will delegate CSR signing and CRL fetching to the external CA URL.
Prerequisites¶
- A running Puppet/OpenVox CA accessible from the cluster (e.g.
https://puppet-ca.example.com:8140) - The CA's public certificate (
ca_crt.pem) - (Optional) A client certificate and key for mTLS authentication
Steps¶
-
Create Secrets with the CA certificate and optional client credentials:
# CA certificate for TLS verification kubectl create secret generic external-ca-cert \ --from-file=ca_crt.pem=/path/to/ca_crt.pem # (Optional) Client certificate for mTLS kubectl create secret generic external-ca-tls \ --from-file=tls.crt=/path/to/client.pem \ --from-file=tls.key=/path/to/client-key.pem -
Create the
CertificateAuthorityresource withspec.external: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 tlsSecretRef: external-ca-tls -
The operator will:
- Skip PVC creation and CA setup Job
- Validate the referenced Secrets
- Set the CA phase to
External - Periodically fetch the CRL from the external CA
- Route CSR signing requests to the external CA
External CA Fields¶
| Field | Required | Description |
|---|---|---|
url |
Yes | Base URL of the external CA (e.g. https://puppet-ca.example.com:8140) |
caSecretRef |
No | Secret name containing ca_crt.pem for TLS verification |
tlsSecretRef |
No | Secret name containing tls.crt and tls.key for mTLS client auth |
insecureSkipVerify |
No | Skip TLS verification (not recommended for production) |
Notes¶
spec.externaland customspec.storageare mutually exclusive. External CAs do not need local storage.- The
Certificatecontroller accepts bothReadyandExternalphases as "CA is available", so existingCertificateresources work without changes. - The operator does not manage the external CA's lifecycle (upgrades, backups, etc.). You are responsible for maintaining it.
- CRL refresh still works with external CAs -- the operator fetches the CRL via the Puppet CA HTTP API and stores it in a local Secret.
For the full field reference, see ExternalCASpec.
Using Another openvox-stack as External CA¶
In a multi-cluster or multi-namespace setup you can run one openvox-stack as the primary CA and point secondary stacks at it using spec.external. This avoids duplicate CA key material and keeps a single source of truth for certificate signing.
Steps¶
-
In the primary stack's namespace, export the CA certificate from its Secret:
-
Create the CA certificate Secret in the secondary namespace:
-
Determine the primary CA's Service URL. If the primary stack runs in the same cluster, use the internal ClusterIP Service:
# Format: https://<ca-name>-internal.<namespace>.svc:8140 # Example: https://production-ca-internal.primary.svc:8140If the primary stack runs in a different cluster, expose it via LoadBalancer, Ingress, or VPN and use that URL instead.
-
Create the secondary
CertificateAuthorityresource:apiVersion: openvox.voxpupuli.org/v1alpha1 kind: CertificateAuthority metadata: name: secondary-ca namespace: secondary spec: allowSubjectAltNames: true allowAuthorizationExtensions: true enableInfraCRL: true crlRefreshInterval: 5m external: url: https://production-ca-internal.primary.svc:8140 caSecretRef: primary-ca-cert -
The secondary stack will now delegate all CSR signing and CRL fetching to the primary CA.
Using an Existing Puppet CA as External CA¶
If you already run a traditional Puppet CA (on a VM or bare-metal server) and want to manage Puppet agents via the operator without migrating the CA, you can point the operator at the existing CA.
Prerequisites¶
- The Puppet CA server is accessible from the Kubernetes cluster (e.g.
https://puppet-ca.example.com:8140) - You have access to the CA certificate file (typically
/etc/puppetlabs/puppet/ssl/certs/ca.pemon the Puppet CA server) - (Optional) A signed client certificate and key for mTLS if the CA requires client authentication
Steps¶
-
Copy the CA certificate from the Puppet CA server:
-
Create the Kubernetes Secrets:
# CA certificate for TLS verification kubectl create secret generic puppet-ca-cert \ --from-file=ca_crt.pem=ca_crt.pem # (Optional) Client certificate for mTLS # Use a signed certificate from the existing Puppet CA kubectl create secret generic puppet-ca-tls \ --from-file=tls.crt=/path/to/client.pem \ --from-file=tls.key=/path/to/client-key.pem -
Create the
CertificateAuthorityresource:apiVersion: openvox.voxpupuli.org/v1alpha1 kind: CertificateAuthority metadata: name: puppet-ca spec: allowSubjectAltNames: true allowAuthorizationExtensions: true enableInfraCRL: true crlRefreshInterval: 5m external: url: https://puppet-ca.example.com:8140 caSecretRef: puppet-ca-cert tlsSecretRef: puppet-ca-tls -
Verify the CA transitions to
Externalphase: