Credentials operator
The credentials operator provisions just-in-time credentials for workloads running on Kubernetes. These credentials come in the form of Kubernetes Secrets (mTLS certificates, database username + passwords), or AWS IAM roles.
Deploying the credentials operator
To deploy the operator, use the Helm chart.
To deploy with Otterize Cloud as the certificate provider, we recommend you follow the instructions in Otterize Cloud. To deploy with cert-manager as the certificate provider, you must also configure the Issuer name and whether it should look for a ClusterIssuer or an Issuer (namespace-scoped).
Provisioning AWS IAM roles using the credentials operator
The credentials operator is controlled using annotations placed on pods. To have it provision an AWS IAM role, you must specify the pod annotation credentials-operator.otterize.com/create-aws-role
, with the value being true
. Once you do so, the credentials operator will provision an AWS IAM role, and automatically bind it with the Kubernetes ServiceAccount of the pod by setting the EKS role ARN annotation on the ServiceAccount and the appropriate Trust Relationship on the AWS IAM role.
Provisioning mTLS certificates using the credentials operator
The credentials operator is controlled using annotations placed on pods. To have it provision certificates and place them in Secrets, you must specify the pod annotation credentials-operator.otterize.com/tls-secret-name
, with the value being the name of the secret. Once you do so, the credentials operator will provision a certificate for the pod, using Otterize Cloud, cert-manager or SPIRE, depending how you've deployed it.
Provisioning database username + password using the credentials operator
The credentials operator is controlled using annotations placed on pods. To have it provision database username + password and place them in Secrets, you must specify the pod annotation credentials-operator.otterize.com/user-password-secret-name
, with the value being the name of the secret. Once you do so, the credentials operator will provision a username and password for the pod.
Secrets are automatically rotated (defaults to every 8 hours). This value can be controlled using the databaseSecretRotationInterval
key in the credentials operator values.yaml
.
If you want pods to be restarted automatically after secret rotation, set the annotation credentials-operator.otterize.com/restart-on-secret-rotation
on the pod (no matter the value).
How does the credentials operator provision certificates?
The credentials operator performs two steps in order to issue certificates.
Step 1: SPIRE entry registration
This step only happens if the operator is configured to use SPIRE for certificate generation. Once the operator resolves the service name for a pod, it labels the pod so that SPIRE can find it, and registers an entry with the SPIRE server for that label.
Step 2: Certificate generation
The operator consults the annotation credentials-operator.otterize.com/tls-secret-name
. If that annotation exists, the operator creates a secret named after the value of the label. That secret contains X.509 credentials within, provided by cert-manager, Otterize Cloud or SPIRE, depending on how the credentials operator is configured.
cert-manager
The operator creates a cert-manager Certificate
resource, which will create a Kubernetes Secret with the name specified by the value of the annotation credentials-operator.otterize.com/tls-secret-name
. The common name and DNS names in the certificate are values that represent the identity of the service, as resolved by the service identity resolution algorithm, i.e. servicename.namespace
.
The operator will use a ClusterIssuer
or an Issuer
to create the Certificate resource, which it expects to find in the same namespace as the Pod
with the annotation. The Issuer
is configured at deploy time, using the Helm chart.
In the event that the default approver controller in cert-manager
is disabled, the credentials operator can auto-approve its own CertificateRequests
. Enable this capability by configuring the Helm chart autoApprove
flag.
Otterize Cloud
The operator requests certificates from Otterize Cloud, which internally manages them in Hashicorp Vault. The certificates are then placed within a Kubernetes Secret named with the value of the annotation credentials-operator.otterize.com/tls-secret-name
.
SPIRE
Once the operator has registered the pod with SPIRE, which happens automatically for a pod that has the credentials-operator.otterize.com/tls-secret-name
annotation upon pod startup. The credentials operator then acquires the SVID and certificates for the CA chain and places them within a Kubernetes Secret. The SVID and DNS names in the certificate is the identity of the service, as resolved by the service identity resolution algorithm, i.e. servicename.namespace
.
SPIRE workload registrar
When deployed with a SPIRE server, the operator registers every pod with the SPIRE server (even those without annotations). Alongside the credentials operator, you could use SPIRE agents and the SPIRE SDK to work with the same SPIRE server. To learn more, check out the documentation for SPIRE. Note that to use the credentials operator, you do not need to work directly with SPIRE or SPIRE agents, and can do everything completely using annotations and Kubernetes Secrets.
Pod annotations
Annotation | Description | Default |
---|---|---|
credentials-operator.otterize.com/tls-secret-name | If set, the operator will create a secret with this name with mTLS credentials for this pod. | N/A |
credentials-operator.otterize.com/dns-names | If set, overrides the list of subject alternative names in the certificate. Should include the hostname of Kubernetes services that will be used to access this pod. | N/A |
credentials-operator.otterize.com/cert-ttl | Override for the expiration time for the certificate in seconds. | If deployed with the bundled SPIRE server, 1 day (86400). |
credentials-operator.otterize.com/cert-type | Type of the credential bundle - pem or jks . | pem |
credentials-operator.otterize.com/cert-file-name | Certificate key name in the secret. When mounted, this is the filename for the certificate (when using SPIRE it's the SVID file). Only used when cert-type is pem . Not supported when certificateProvider is cert-manager . | cert.pem |
credentials-operator.otterize.com/ca-file-name | Bundle (certificate chain bundle) key name in the secret. When mounted, this is the filename for the certificate chain. Only used when cert-type is pem . Not supported when certificateProvider is cert-manager . | ca.pem |
credentials-operator.otterize.com/key-file-name | Private key key name in the secret. When mounted, this is the filename for the private key. Only used when cert-type is pem . Not supported when certificateProvider is cert-manager . | key.pem |
credentials-operator.otterize.com/keystore-file-name | Keystore key name in the secret. When mounted, this is the filename for the keystore. Only used when cert-type is jks . Not supported when certificateProvider is cert-manager . | keystore.jks |
credentials-operator.otterize.com/truststore-file-name | Truststore key name in the secret. When mounted, this is the filename for the truststore. Only used when cert-type is jks . Not supported when certificateProvider is cert-manager . | truststore.jks |
credentials-operator.otterize.com/jks-password | Password for the JKS truststore and keystore. Only used when cert-type is jks . | password |
credentials-operator.otterize.com/restart-pod-on-certificate-renewal | A pod with this annotation (no matter the value) will be restarted after certificate renewal, along with any replicas. Should be ideally set through the pod owner's template spec so it will persist between restarts. | N/A |
credentials-operator.otterize.com/user-password-secret-name | If set, the operator will create a secret with this name containing user-password credentials for this pod. | N/A |
credentials-operator.otterize.com/restart-on-secret-rotation | A pod with this annotation (no matter the value) will be restarted after user-password secret rotation, along with any replicas. Should be ideally set through the pod owner's template spec so it will persist between restarts. | |
intents.otterize.com/service-name | Used for service identity resolution. |