Merge pull request #2847 from Infisical/daniel/k8s-dynamic-secrets

feat(k8-operator): dynamic secrets
This commit is contained in:
Maidul Islam
2025-01-09 12:45:30 -05:00
committed by GitHub
42 changed files with 3584 additions and 927 deletions

View File

@@ -0,0 +1,437 @@
---
sidebarTitle: "InfisicalDynamicSecret CRD"
title: "InfisicalDynamicSecret CRD"
description: "Learn how to generate dynamic secret leases in Infisical and sync them to your Kubernetes cluster."
---
## Overview
The **InfisicalDynamicSecret** CRD allows you to easily create and manage dynamic secret leases in Infisical and automatically sync them to your Kubernetes cluster as native **Kubernetes Secret** resources.
This means any Pod, Deployment, or other Kubernetes resource can make use of dynamic secrets from Infisical just like any other K8s secret.
This CRD offers the following features:
- **Generate a dynamic secret lease** in Infisical and track its lifecycle.
- **Write** the dynamic secret from Infisical to your cluster as native Kubernetes secret.
- **Automatically rotate** the dyanmic secret value before it expires to make sure your cluster always has valid credentials.
- **Optionally trigger redeployments** of any workloads that consume the secret if you enable auto-reload.
### Prerequisites
- The operator is installed on to your Kubernetes cluster
- You have already configured a dynamic secret in Infisical
## Configure Dynamic Secret CRD
The example below shows a sample **InfisicalDynamicSecret** CRD that creates a dynamic secret lease in Infisical, and syncs the lease to your Kubernetes cluster.
```yaml dynamic-secret-crd.yaml
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalDynamicSecret
metadata:
name: infisicaldynamicsecret
spec:
hostAPI: https://app.infisical.com/api # Optional, defaults to https://app.infisical.com/api
dynamicSecret:
secretName: <dynamic-secret-name>
projectId: <project-id>
secretsPath: <path/to/dynamic-secret> # Root directory is /
environmentSlug: <env-slug>
# Lease revocation policy defines what should happen to leases created by the operator if the CRD is deleted.
# If set to "Revoke", leases will be revoked when the InfisicalDynamicSecret CRD is deleted.
leaseRevocationPolicy: Revoke
# Lease TTL defines how long the lease should last for the dynamic secret.
# This value must be less than 1 day, and if a max TTL is defined on the dynamic secret, it must be below the max TTL.
leaseTTL: 1m
# A reference to the secret that the dynamic secret lease should be stored in.
# If the secret doesn't exist, it will automatically be created.
managedSecretReference:
secretName: <secret-name>
secretNamespace: default # Must be the same namespace as the InfisicalDynamicSecret CRD.
creationPolicy: Orphan
# Only have one authentication method defined or you are likely to run into authentication issues.
# Remove all except one authentication method.
authentication:
awsIamAuth:
identityId: <machine-identity-id>
azureAuth:
identityId: <machine-identity-id>
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
gcpIdTokenAuth:
identityId: <machine-identity-id>
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
universalAuth:
credentialsRef:
secretName: <secret-name> # universal-auth-credentials
secretNamespace: <secret-namespace> # default
```
Apply the InfisicalDynamicSecret CRD to your cluster.
```bash
kubectl apply -f dynamic-secret-crd.yaml
```
After applying the InfisicalDynamicSecret CRD, you should notice that the dynamic secret lease has been created in Infisical and synced to your Kubernetes cluster. You can verify that the lease has been created by doing:
```bash
kubectl get secret <managed-secret-name> -o yaml
```
After getting the secret, you should should see that the secret has data that contains the lease credentials.
```yaml
apiVersion: v1
data:
DB_PASSWORD: VHhETjZ4c2xsTXpOSWdPYW5LLlRyNEc2alVKYml6WiQjQS0tNTdodyREM3ZLZWtYSi4hTkdyS0F+TVFsLU9CSA==
DB_USERNAME: cHg4Z0dJTUVBcHdtTW1aYnV3ZWRsekJRRll6cW4wFEE=
kind: Secret
# .....
```
### InfisicalDynamicSecret CRD properties
<Accordion title="hostAPI">
If you are fetching secrets from a self-hosted instance of Infisical set the value of `hostAPI` to
` https://your-self-hosted-instace.com/api`
When `hostAPI` is not defined the operator fetches secrets from Infisical Cloud.
<Accordion title="Advanced use case">
If you have installed your Infisical instance within the same cluster as the Infisical operator, you can optionally access the Infisical backend's service directly without having to route through the public internet.
To achieve this, use the following address for the hostAPI field:
``` bash
http://<backend-svc-name>.<namespace>.svc.cluster.local:4000/api
```
Make sure to replace `<backend-svc-name>` and `<namespace>` with the appropriate values for your backend service and namespace.
</Accordion>
</Accordion>
<Accordion title="leaseTTL">
The `leaseTTL` is a string-formatted duration that defines the time the lease should last for the dynamic secret.
The format of the field is `[duration][unit]` where `duration` is a number and `unit` is a string representing the unit of time.
The following units are supported:
- `s` for seconds (must be at least 5 seconds)
- `m` for minutes
- `h` for hours
- `d` for days
<Note>
The lease duration at most be 1 day (24 hours). And the TTL must be less than the max TTL defined on the dynamic secret.
</Note>
</Accordion>
<Accordion title="managedSecretReference">
The `managedSecretReference` field is used to define the Kubernetes secret where the dynamic secret lease should be stored. The required fields are `secretName` and `secretNamespace`.
```yaml
spec:
managedSecretReference:
secretName: <secret-name>
secretNamespace: default
```
<Accordion title="managedSecretReference.secretName">
The name of the Kubernetes secret where the dynamic secret lease should be stored.
</Accordion>
<Accordion title="managedSecretReference.secretNamespace">
The namespace of the Kubernetes secret where the dynamic secret lease should be stored.
</Accordion>
<Accordion title="managedSecretReference.creationPolicy">
Creation polices allow you to control whether or not owner references should be added to the managed Kubernetes secret that is generated by the Infisical operator.
This is useful for tools such as ArgoCD, where every resource requires an owner reference; otherwise, it will be pruned automatically.
#### Available options
- `Orphan` (default)
- `Owner`
<Tip>
When creation policy is set to `Owner`, the `InfisicalSecret` CRD must be in
the same namespace as where the managed kubernetes secret.
</Tip>
This field is optional.
</Accordion>
<Accordion title="managedSecretReference.secretType">
Override the default Opaque type for managed secrets with this field. Useful for creating kubernetes.io/dockerconfigjson secrets.
This field is optional.
</Accordion>
</Accordion>
<Accordion title="leaseRevocationPolicy">
The field is optional and will default to `None` if not defined.
The lease revocation policy defines what the operator should do with the leases created by the operator, when the InfisicalDynamicSecret CRD is deleted.
Valid values are `None` and `Revoke`.
Behavior of each policy:
- `None`: The operator will not override existing secrets in Infisical. If a secret with the same key already exists, the operator will skip pushing that secret, and the secret will not be managed by the operator.
- `Revoke`: The operator will revoke the leases created by the operator when the InfisicalDynamicSecret CRD is deleted.
```yaml
spec:
leaseRevocationPolicy: Revoke
```
</Accordion>
<Accordion title="dynamicSecret">
The `dynamicSecret` field is used to specify which dynamic secret to create leases for. The required fields are `secretName`, `projectId`, `secretsPath`, and `environmentSlug`.
```yaml
spec:
dynamicSecret:
secretName: <dynamic-secret-name>
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secrets-path>
```
<Accordion title="dynamicSecret.secretName">
The name of the dynamic secret.
</Accordion>
<Accordion title="dynamicSecret.projectId">
The project ID of where the dynamic secret is stored in Infisical.
</Accordion>
<Accordion title="dynamicSecret.environmentSlug">
The environment slug of where the dynamic secret is stored in Infisical.
</Accordion>
<Accordion title="dynamicSecret.secretsPath">
The path of where the dynamic secret is stored in Infisical. The root path is `/`.
</Accordion>
</Accordion>
<Accordion title="authentication">
The `authentication` field dictates which authentication method to use when pushing secrets to Infisical.
The available authentication methods are `universalAuth`, `kubernetesAuth`, `awsIamAuth`, `azureAuth`, `gcpIdTokenAuth`, and `gcpIamAuth`.
<Accordion title="universalAuth">
The universal authentication method is one of the easiest ways to get started with Infisical. Universal Auth works anywhere and is not tied to any specific cloud provider.
[Read more about Universal Auth](/documentation/platform/identities/universal-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `credentialsRef`: The name and namespace of the Kubernetes secret that stores the service token.
- `credentialsRef.secretName`: The name of the Kubernetes secret.
- `credentialsRef.secretNamespace`: The namespace of the Kubernetes secret.
Example:
```yaml
# infisical-push-secret.yaml
spec:
universalAuth:
credentialsRef:
secretName: <secret-name>
secretNamespace: <secret-namespace>
```
```yaml
# machine-identity-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
name: universal-auth-credentials
type: Opaque
stringData:
clientId: <machine-identity-client-id>
clientSecret: <machine-identity-client-secret>
```
</Accordion>
<Accordion title="kubernetesAuth">
The Kubernetes machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within a Kubernetes environment.
[Read more about Kubernetes Auth](/documentation/platform/identities/kubernetes-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `serviceAccountRef`: The name and namespace of the service account that will be used to authenticate with Infisical.
- `serviceAccountRef.name`: The name of the service account.
- `serviceAccountRef.namespace`: The namespace of the service account.
Example:
```yaml
spec:
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
```
</Accordion>
<Accordion title="awsIamAuth">
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
authentication:
awsIamAuth:
identityId: <machine-identity-id>
```
</Accordion>
<Accordion title="azureAuth">
The AWS IAM machine identity authentication method is used to authenticate with Infisical. Azure Auth can only be used from within an Azure environment.
[Read more about Azure Auth](/documentation/platform/identities/azure-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
authentication:
azureAuth:
identityId: <machine-identity-id>
```
</Accordion>
<Accordion title="gcpIamAuth">
The GCP IAM machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used both within and outside GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `serviceAccountKeyFilePath`: The path to the GCP service account key file.
Example:
```yaml
spec:
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
```
</Accordion>
<Accordion title="gcpIdTokenAuth">
The GCP ID Token machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
gcpIdTokenAuth:
identityId: <machine-identity-id>
```
</Accordion>
</Accordion>
<Accordion title="tls">
This block defines the TLS settings to use for connecting to the Infisical
instance.
Fields:
<Accordion title="caRef">
This block defines the reference to the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
Valid fields:
- `secretName`: The name of the Kubernetes secret containing the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
- `secretNamespace`: The namespace of the Kubernetes secret containing the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
- `key`: The name of the key in the Kubernetes secret which contains the value of the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
Example:
```yaml
tls:
caRef:
secretName: custom-ca-certificate
secretNamespace: default
key: ca.crt
```
</Accordion>
</Accordion>
### Applying the InfisicalDynamicSecret CRD to your cluster
Once you have configured the `InfisicalDynamicSecret` CRD with the required fields, you can apply it to your cluster. After applying, you should notice that a lease has been created in Infisical and synced to your Kubernetes cluster.
```bash
kubectl apply -f dynamic-secret-crd.yaml
```
## Auto redeployment
Deployments referring to Kubernetes secrets containing Infisical dynamic secrets don't automatically reload when the dynamic secret lease expires. This means your deployment may use expired dynamic secrets unless manually redeployed.
To address this, we've added functionality to automatically redeploy your deployment when the associated Kubernetes secret containing your Infisical dynamic secret updates.
#### Enabling auto redeploy
To enable auto redeployment you simply have to add the following annotation to the deployment that consumes a managed secret
```yaml
secrets.infisical.com/auto-reload: "true"
```
<Accordion title="Deployment example with auto redeploy enabled">
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
annotations:
secrets.infisical.com/auto-reload: "true" # <- redeployment annotation
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
envFrom:
- secretRef:
name: managed-secret # The name of your managed secret, the same that you're using in your InfisicalDynamicSecret CRD (spec.managedSecretReference.secretName)
ports:
- containerPort: 80
```
</Accordion>
<Info>
#### How it works
When the lease changes, the operator will check to see which deployments are using the operator-managed Kubernetes secret that received the update.
Then, for each deployment that has this annotation present, a rolling update will be triggered. A redeployment won't happen if the lease is renewed, only if it's recreated.
</Info>

View File

@@ -0,0 +1,400 @@
---
sidebarTitle: "InfisicalPushSecret CRD"
title: "Using the InfisicalPushSecret CRD"
description: "Learn how to use the InfisicalPushSecret CRD to push and manage secrets in Infisical."
---
## Push Secrets to Infisical
### Example usage
Below is a sample InfisicalPushSecret CRD that pushes secrets defined in a Kubernetes secret to Infisical.
After filling out the fields in the InfisicalPushSecret CRD, you can apply it directly to your cluster.
Before applying the InfisicalPushSecret CRD, you need to create a Kubernetes secret containing the secrets you want to push to Infisical. An example can be seen below the InfisicalPushSecret CRD.
```yaml infisical-push-secret.yaml
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalPushSecret
metadata:
name: infisical-push-secret-demo
spec:
resyncInterval: 1m
hostAPI: https://app.infisical.com/api
# Optional, defaults to no replacement.
updatePolicy: Replace # If set to replace, existing secrets inside Infisical will be replaced by the value of the PushSecret on sync.
# Optional, defaults to no deletion.
deletionPolicy: Delete # If set to delete, the secret(s) inside Infisical managed by the operator, will be deleted if the InfisicalPushSecret CRD is deleted.
destination:
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secret-path>
push:
secret:
secretName: push-secret-demo # Secret CRD
secretNamespace: default
# Only have one authentication method defined or you are likely to run into authentication issues.
# Remove all except one authentication method.
authentication:
awsIamAuth:
identityId: <machine-identity-id>
azureAuth:
identityId: <machine-identity-id>
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
gcpIdTokenAuth:
identityId: <machine-identity-id>
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
universalAuth:
credentialsRef:
secretName: <secret-name> # universal-auth-credentials
secretNamespace: <secret-namespace> # default
```
```yaml source-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: push-secret-demo
namespace: default
stringData: # can also be "data", but needs to be base64 encoded
API_KEY: some-api-key
DATABASE_URL: postgres://127.0.0.1:5432
ENCRYPTION_KEY: fabcc12-a22-facbaa4-11aa568aab
```
```bash
kubectl apply -f source-secret.yaml
```
After applying the soruce-secret.yaml file, you are ready to apply the InfisicalPushSecret CRD.
```bash
kubectl apply -f infisical-push-secret.yaml
```
After applying the InfisicalPushSecret CRD, you should notice that the secrets you have defined in your source-secret.yaml file have been pushed to your specified destination in Infisical.
### InfisicalPushSecret CRD properties
<Accordion title="hostAPI">
If you are fetching secrets from a self-hosted instance of Infisical set the value of `hostAPI` to
` https://your-self-hosted-instace.com/api`
When `hostAPI` is not defined the operator fetches secrets from Infisical Cloud.
<Accordion title="Advanced use case">
If you have installed your Infisical instance within the same cluster as the Infisical operator, you can optionally access the Infisical backend's service directly without having to route through the public internet.
To achieve this, use the following address for the hostAPI field:
``` bash
http://<backend-svc-name>.<namespace>.svc.cluster.local:4000/api
```
Make sure to replace `<backend-svc-name>` and `<namespace>` with the appropriate values for your backend service and namespace.
</Accordion>
</Accordion>
<Accordion title="resyncInterval">
The `resyncInterval` is a string-formatted duration that defines the time between each resync.
The format of the field is `[duration][unit]` where `duration` is a number and `unit` is a string representing the unit of time.
The following units are supported:
- `s` for seconds (must be at least 5 seconds)
- `m` for minutes
- `h` for hours
- `d` for days
- `w` for weeks
The default value is `1m` (1 minute).
Valid intervals examples:
```yaml
resyncInterval: 5s # 10 seconds
resyncInterval: 10s # 10 seconds
resyncInterval: 5m # 5 minutes
resyncInterval: 1h # 1 hour
resyncInterval: 1d # 1 day
```
</Accordion>
<Accordion title="updatePolicy">
The field is optional and will default to `None` if not defined.
The update policy defines how the operator should handle conflicting secrets when pushing secrets to Infisical.
Valid values are `None` and `Replace`.
Behavior of each policy:
- `None`: The operator will not override existing secrets in Infisical. If a secret with the same key already exists, the operator will skip pushing that secret, and the secret will not be managed by the operator.
- `Replace`: The operator will replace existing secrets in Infisical with the new secrets. If a secret with the same key already exists, the operator will update the secret with the new value.
```yaml
spec:
updatePolicy: Replace
```
</Accordion>
<Accordion title="deletionPolicy">
This field is optional and will default to `None` if not defined.
The deletion policy defines what the operator should do in case the InfisicalPushSecret CRD is deleted.
Valid values are `None` and `Delete`.
Behavior of each policy:
- `None`: The operator will not delete the secrets in Infisical when the InfisicalPushSecret CRD is deleted.
- `Delete`: The operator will delete the secrets in Infisical that are managed by the operator when the InfisicalPushSecret CRD is deleted.
```yaml
spec:
deletionPolicy: Delete
```
</Accordion>
<Accordion title="destination">
The `destination` field is used to specify where you want to create the secrets in Infisical. The required fields are `projectId`, `environmentSlug`, and `secretsPath`.
```yaml
spec:
destination:
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secrets-path>
```
<Accordion title="destination.projectId">
The project ID where you want to create the secrets in Infisical.
</Accordion>
<Accordion title="destination.environmentSlug">
The environment slug where you want to create the secrets in Infisical.
</Accordion>
<Accordion title="destination.secretsPath">
The path where you want to create the secrets in Infisical. The root path is `/`.
</Accordion>
</Accordion>
<Accordion title="push">
The `push` field is used to define what you want to push to Infisical. Currently the operator only supports pushing Kubernetes secrets to Infisical. An example of the `push` field is shown below.
<Accordion title="secret">
The `secret` field is used to define the Kubernetes secret you want to push to Infisical. The required fields are `secretName` and `secretNamespace`.
Example usage of the `push.secret` field:
```yaml infisical-push-secret.yaml
push:
secret:
secretName: push-secret-demo
secretNamespace: default
```
```yaml push-secret-demo.yaml
apiVersion: v1
kind: Secret
metadata:
name: push-secret-demo
namespace: default
# Pass in the secrets you wish to push to Infisical
stringData:
API_KEY: some-api-key
DATABASE_URL: postgres://127.0.0.1:5432
ENCRYPTION_KEY: fabcc12-a22-facbaa4-11aa568aab
```
</Accordion>
</Accordion>
<Accordion title="authentication">
The `authentication` field dictates which authentication method to use when pushing secrets to Infisical.
The available authentication methods are `universalAuth`, `kubernetesAuth`, `awsIamAuth`, `azureAuth`, `gcpIdTokenAuth`, and `gcpIamAuth`.
<Accordion title="universalAuth">
The universal authentication method is one of the easiest ways to get started with Infisical. Universal Auth works anywhere and is not tied to any specific cloud provider.
[Read more about Universal Auth](/documentation/platform/identities/universal-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `credentialsRef`: The name and namespace of the Kubernetes secret that stores the service token.
- `credentialsRef.secretName`: The name of the Kubernetes secret.
- `credentialsRef.secretNamespace`: The namespace of the Kubernetes secret.
Example:
```yaml
# infisical-push-secret.yaml
spec:
universalAuth:
credentialsRef:
secretName: <secret-name>
secretNamespace: <secret-namespace>
```
```yaml
# machine-identity-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
name: universal-auth-credentials
type: Opaque
stringData:
clientId: <machine-identity-client-id>
clientSecret: <machine-identity-client-secret>
```
</Accordion>
<Accordion title="kubernetesAuth">
The Kubernetes machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within a Kubernetes environment.
[Read more about Kubernetes Auth](/documentation/platform/identities/kubernetes-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `serviceAccountRef`: The name and namespace of the service account that will be used to authenticate with Infisical.
- `serviceAccountRef.name`: The name of the service account.
- `serviceAccountRef.namespace`: The namespace of the service account.
Example:
```yaml
spec:
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
```
</Accordion>
<Accordion title="awsIamAuth">
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
authentication:
awsIamAuth:
identityId: <machine-identity-id>
```
</Accordion>
<Accordion title="azureAuth">
The AWS IAM machine identity authentication method is used to authenticate with Infisical. Azure Auth can only be used from within an Azure environment.
[Read more about Azure Auth](/documentation/platform/identities/azure-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
authentication:
azureAuth:
identityId: <machine-identity-id>
```
</Accordion>
<Accordion title="gcpIamAuth">
The GCP IAM machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used both within and outside GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `serviceAccountKeyFilePath`: The path to the GCP service account key file.
Example:
```yaml
spec:
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
```
</Accordion>
<Accordion title="gcpIdTokenAuth">
The GCP ID Token machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
gcpIdTokenAuth:
identityId: <machine-identity-id>
```
</Accordion>
</Accordion>
<Accordion title="tls">
This block defines the TLS settings to use for connecting to the Infisical
instance.
Fields:
<Accordion title="caRef">
This block defines the reference to the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
Valid fields:
- `secretName`: The name of the Kubernetes secret containing the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
- `secretNamespace`: The namespace of the Kubernetes secret containing the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
- `key`: The name of the key in the Kubernetes secret which contains the value of the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
Example:
```yaml
tls:
caRef:
secretName: custom-ca-certificate
secretNamespace: default
key: ca.crt
```
</Accordion>
</Accordion>
### Applying the InfisicalPushSecret CRD to your cluster
Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster.
After applying, you should notice that the secrets have been pushed to Infisical.
```bash
kubectl apply -f source-push-secret.yaml # The secret that you're referencing in the InfisicalPushSecret CRD push.secret field
kubectl apply -f example-infisical-push-secret-crd.yaml # The InfisicalPushSecret CRD itself
```

View File

@@ -1,109 +1,9 @@
---
title: "Kubernetes Operator"
description: "How to use Infisical to inject secrets into Kubernetes clusters."
sidebarTitle: "InfisicalSecret CRD"
title: "InfisicalSecret CRD"
description: "Learn how to use the InfisicalSecret CRD to fetch secrets from Infisical and store them as native Kubernetes secret resource"
---
![title](../../images/k8-diagram.png)
The Infisical Secrets Operator is a Kubernetes controller that retrieves secrets from Infisical and stores them in a designated cluster.
It uses an `InfisicalSecret` resource to specify authentication and storage methods.
The operator continuously updates secrets and can also reload dependent deployments automatically.
<Note>
If you are already using the External Secrets operator, you can view the
integration documentation for it
[here](https://external-secrets.io/latest/provider/infisical/).
</Note>
## Install Operator
The operator can be install via [Helm](https://helm.sh) or [kubectl](https://github.com/kubernetes/kubectl)
<Tabs>
<Tab title="Helm (recommended)">
**Install the latest Infisical Helm repository**
```bash
helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
helm repo update
```
**Install the Helm chart**
To select a specific version, view the application versions [here](https://hub.docker.com/r/infisical/kubernetes-operator/tags) and chart versions [here](https://cloudsmith.io/~infisical/repos/helm-charts/packages/detail/helm/secrets-operator/#versions)
```bash
helm install --generate-name infisical-helm-charts/secrets-operator
```
```bash
# Example installing app version v0.2.0 and chart version 0.1.4
helm install --generate-name infisical-helm-charts/secrets-operator --version=0.1.4 --set controllerManager.manager.image.tag=v0.2.0
```
**Namespace-scoped Installation**
The operator can be configured to watch and manage secrets in a specific namespace instead of having cluster-wide access. This is useful for:
- **Enhanced Security**: Limit the operator's permissions to only specific namespaces instead of cluster-wide access
- **Multi-tenant Clusters**: Run separate operator instances for different teams or applications
- **Resource Isolation**: Ensure operators in different namespaces don't interfere with each other
- **Development & Testing**: Run development and production operators side by side in isolated namespaces
**Note**: For multiple namespace-scoped installations, only the first installation should install CRDs. Subsequent installations should set `installCRDs: false` to avoid conflicts.
```bash
# First namespace installation (with CRDs)
helm install operator-namespace1 infisical-helm-charts/secrets-operator \
--namespace first-namespace \
--set scopedNamespace=first-namespace \
--set scopedRBAC=true
# Subsequent namespace installations
helm install operator-namespace2 infisical-helm-charts/secrets-operator \
--namespace another-namespace \
--set scopedNamespace=another-namespace \
--set scopedRBAC=true \
--set installCRDs=false
```
When scoped to a namespace, the operator will:
- Only watch InfisicalSecrets in the specified namespace
- Only create/update Kubernetes secrets in that namespace
- Only access deployments in that namespace
The default configuration gives cluster-wide access:
```yaml
installCRDs: true # Install CRDs (set to false for additional namespace installations)
scopedNamespace: "" # Empty for cluster-wide access
scopedRBAC: false # Cluster-wide permissions
```
If you want to install operators in multiple namespaces simultaneously:
- Make sure to set `installCRDs: false` for all but one of the installations to avoid conflicts, as CRDs are cluster-wide resources.
- Use unique release names for each installation (e.g., operator-namespace1, operator-namespace2).
</Tab>
<Tab title="Kubectl">
For production deployments, it is highly recommended to set the version of the Kubernetes operator manually instead of pointing to the latest version.
Doing so will help you avoid accidental updates to the newest release which may introduce unintended breaking changes. View all application versions [here](https://hub.docker.com/r/infisical/kubernetes-operator/tags).
The command below will install the most recent version of the Kubernetes operator.
However, to set the version manually, download the manifest and set the image tag version of `infisical/kubernetes-operator` according to your desired version.
Once you apply the manifest, the operator will be installed in `infisical-operator-system` namespace.
```
kubectl apply -f https://raw.githubusercontent.com/Infisical/infisical/main/k8-operator/kubectl-install/install-secrets-operator.yaml
```
</Tab>
</Tabs>
## Sync Infisical Secrets to your cluster
Once you have installed the operator to your cluster, you'll need to create a `InfisicalSecret` custom resource definition (CRD).
```yaml example-infisical-secret-crd.yaml
@@ -789,48 +689,6 @@ This is useful for tools such as ArgoCD, where every resource requires an owner
</Accordion>
### Propagating labels & annotations
The operator will transfer all labels & annotations present on the `InfisicalSecret` CRD to the managed Kubernetes secret to be created.
Thus, if a specific label is required on the resulting secret, it can be applied as demonstrated in the following example:
<Accordion title="Example propagation">
```yaml
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: infisicalsecret-sample
labels:
label-to-be-passed-to-managed-secret: sample-value
annotations:
example.com/annotation-to-be-passed-to-managed-secret: "sample-value"
spec:
..
authentication:
...
managedSecretReference:
...
```
This would result in the following managed secret to be created:
```yaml
apiVersion: v1
data: ...
kind: Secret
metadata:
annotations:
example.com/annotation-to-be-passed-to-managed-secret: sample-value
secrets.infisical.com/version: W/"3f1-ZyOSsrCLGSkAhhCkY2USPu2ivRw"
labels:
label-to-be-passed-to-managed-secret: sample-value
name: managed-token
namespace: default
type: Opaque
```
</Accordion>
### Apply the InfisicalSecret CRD to your cluster
Once you have configured the InfisicalSecret CRD with the required fields, you can apply it to your cluster.
@@ -854,7 +712,7 @@ kubectl get secrets -n <namespace of managed secret>
1 minutes.
</Info>
### Using managed secret in your deployment
## Using managed secret in your deployment
Incorporating the managed secret created by the operator into your deployment can be achieved through several methods.
Here, we will highlight three of the most common ways to utilize it. Learn more about Kubernetes secrets [here](https://kubernetes.io/docs/concepts/configuration/secret/)
@@ -996,25 +854,6 @@ spec:
</Accordion>
### Connecting to instances with private/self-signed certificate
To connect to Infisical instances behind a private/self-signed certificate, you can configure the TLS settings in the `InfisicalSecret` CRD
to point to a CA certificate stored in a Kubernetes secret resource.
```yaml
---
spec:
hostAPI: https://app.infisical.com/api
resyncInterval: 10
tls:
caRef:
secretName: custom-ca-certificate
secretNamespace: default
key: ca.crt
authentication:
---
```
The definition file of the Kubernetes secret for the CA certificate can be structured like the following:
```yaml
@@ -1081,503 +920,44 @@ spec:
Then, for each deployment that has this annotation present, a rolling update will be triggered.
</Info>
## Push Secrets to Infisical
## Propagating labels & annotations
The operator will transfer all labels & annotations present on the `InfisicalSecret` CRD to the managed Kubernetes secret to be created.
Thus, if a specific label is required on the resulting secret, it can be applied as demonstrated in the following example:
### Example usage
Below is a sample InfisicalPushSecret CRD that pushes secrets defined in a Kubernetes secret to Infisical.
After filling out the fields in the InfisicalPushSecret CRD, you can apply it directly to your cluster.
Before applying the InfisicalPushSecret CRD, you need to create a Kubernetes secret containing the secrets you want to push to Infisical. An example can be seen below the InfisicalPushSecret CRD.
```bash
kubectl apply -f source-secret.yaml
```
After applying the soruce-secret.yaml file, you are ready to apply the InfisicalPushSecret CRD.
```bash
kubectl apply -f infisical-push-secret.yaml
```
After applying the InfisicalPushSecret CRD, you should notice that the secrets you have defined in your source-secret.yaml file have been pushed to your specified destination in Infisical.
```yaml infisical-push-secret.yaml
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalPushSecret
metadata:
name: infisical-push-secret-demo
spec:
resyncInterval: 1m
hostAPI: https://app.infisical.com/api
# Optional, defaults to no replacement.
updatePolicy: Replace # If set to replace, existing secrets inside Infisical will be replaced by the value of the PushSecret on sync.
# Optional, defaults to no deletion.
deletionPolicy: Delete # If set to delete, the secret(s) inside Infisical managed by the operator, will be deleted if the InfisicalPushSecret CRD is deleted.
destination:
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secret-path>
push:
secret:
secretName: push-secret-demo # Secret CRD
secretNamespace: default
# Only have one authentication method defined or you are likely to run into authentication issues.
# Remove all except one authentication method.
authentication:
awsIamAuth:
identityId: <machine-identity-id>
azureAuth:
identityId: <machine-identity-id>
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
gcpIdTokenAuth:
identityId: <machine-identity-id>
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
universalAuth:
credentialsRef:
secretName: <secret-name> # universal-auth-credentials
secretNamespace: <secret-namespace> # default
```
```yaml source-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: push-secret-demo
namespace: default
stringData: # can also be "data", but needs to be base64 encoded
API_KEY: some-api-key
DATABASE_URL: postgres://127.0.0.1:5432
ENCRYPTION_KEY: fabcc12-a22-facbaa4-11aa568aab
```
### InfisicalPushSecret CRD properties
<Accordion title="hostAPI">
If you are fetching secrets from a self-hosted instance of Infisical set the value of `hostAPI` to
` https://your-self-hosted-instace.com/api`
When `hostAPI` is not defined the operator fetches secrets from Infisical Cloud.
<Accordion title="Advanced use case">
If you have installed your Infisical instance within the same cluster as the Infisical operator, you can optionally access the Infisical backend's service directly without having to route through the public internet.
To achieve this, use the following address for the hostAPI field:
``` bash
http://<backend-svc-name>.<namespace>.svc.cluster.local:4000/api
```
Make sure to replace `<backend-svc-name>` and `<namespace>` with the appropriate values for your backend service and namespace.
</Accordion>
</Accordion>
<Accordion title="resyncInterval">
The `resyncInterval` is a string-formatted duration that defines the time between each resync.
The format of the field is `[duration][unit]` where `duration` is a number and `unit` is a string representing the unit of time.
The following units are supported:
- `s` for seconds (must be at least 5 seconds)
- `m` for minutes
- `h` for hours
- `d` for days
- `w` for weeks
The default value is `1m` (1 minute).
Valid intervals examples:
```yaml
resyncInterval: 5s # 10 seconds
resyncInterval: 10s # 10 seconds
resyncInterval: 5m # 5 minutes
resyncInterval: 1h # 1 hour
resyncInterval: 1d # 1 day
```
</Accordion>
<Accordion title="updatePolicy">
The field is optional and will default to `None` if not defined.
The update policy defines how the operator should handle conflicting secrets when pushing secrets to Infisical.
Valid values are `None` and `Replace`.
Behavior of each policy:
- `None`: The operator will not override existing secrets in Infisical. If a secret with the same key already exists, the operator will skip pushing that secret, and the secret will not be managed by the operator.
- `Replace`: The operator will replace existing secrets in Infisical with the new secrets. If a secret with the same key already exists, the operator will update the secret with the new value.
```yaml
spec:
updatePolicy: Replace
```
</Accordion>
<Accordion title="deletionPolicy">
This field is optional and will default to `None` if not defined.
The deletion policy defines what the operator should do in case the InfisicalPushSecret CRD is deleted.
Valid values are `None` and `Delete`.
Behavior of each policy:
- `None`: The operator will not delete the secrets in Infisical when the InfisicalPushSecret CRD is deleted.
- `Delete`: The operator will delete the secrets in Infisical that are managed by the operator when the InfisicalPushSecret CRD is deleted.
```yaml
spec:
deletionPolicy: Delete
```
</Accordion>
<Accordion title="destination">
The `destination` field is used to specify where you want to create the secrets in Infisical. The required fields are `projectId`, `environmentSlug`, and `secretsPath`.
```yaml
spec:
destination:
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secrets-path>
```
<Accordion title="destination.projectId">
The project ID where you want to create the secrets in Infisical.
</Accordion>
<Accordion title="destination.environmentSlug">
The environment slug where you want to create the secrets in Infisical.
</Accordion>
<Accordion title="destination.secretsPath">
The path where you want to create the secrets in Infisical. The root path is `/`.
</Accordion>
</Accordion>
<Accordion title="push">
The `push` field is used to define what you want to push to Infisical. Currently the operator only supports pushing Kubernetes secrets to Infisical. An example of the `push` field is shown below.
<Accordion title="secret">
The `secret` field is used to define the Kubernetes secret you want to push to Infisical. The required fields are `secretName` and `secretNamespace`.
Example usage of the `push.secret` field:
```yaml infisical-push-secret.yaml
push:
secret:
secretName: push-secret-demo
secretNamespace: default
```
```yaml push-secret-demo.yaml
apiVersion: v1
kind: Secret
metadata:
name: push-secret-demo
namespace: default
# Pass in the secrets you wish to push to Infisical
stringData:
API_KEY: some-api-key
DATABASE_URL: postgres://127.0.0.1:5432
ENCRYPTION_KEY: fabcc12-a22-facbaa4-11aa568aab
```
</Accordion>
</Accordion>
<Accordion title="authentication">
The `authentication` field dictates which authentication method to use when pushing secrets to Infisical.
The available authentication methods are `universalAuth`, `kubernetesAuth`, `awsIamAuth`, `azureAuth`, `gcpIdTokenAuth`, and `gcpIamAuth`.
<Accordion title="universalAuth">
The universal authentication method is one of the easiest ways to get started with Infisical. Universal Auth works anywhere and is not tied to any specific cloud provider.
[Read more about Universal Auth](/documentation/platform/identities/universal-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `credentialsRef`: The name and namespace of the Kubernetes secret that stores the service token.
- `credentialsRef.secretName`: The name of the Kubernetes secret.
- `credentialsRef.secretNamespace`: The namespace of the Kubernetes secret.
Example:
```yaml
# infisical-push-secret.yaml
spec:
universalAuth:
credentialsRef:
secretName: <secret-name>
secretNamespace: <secret-namespace>
```
```yaml
# machine-identity-credentials.yaml
apiVersion: v1
kind: Secret
metadata:
name: universal-auth-credentials
type: Opaque
stringData:
clientId: <machine-identity-client-id>
clientSecret: <machine-identity-client-secret>
```
</Accordion>
<Accordion title="kubernetesAuth">
The Kubernetes machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within a Kubernetes environment.
[Read more about Kubernetes Auth](/documentation/platform/identities/kubernetes-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `serviceAccountRef`: The name and namespace of the service account that will be used to authenticate with Infisical.
- `serviceAccountRef.name`: The name of the service account.
- `serviceAccountRef.namespace`: The namespace of the service account.
Example:
```yaml
spec:
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
```
</Accordion>
<Accordion title="awsIamAuth">
The AWS IAM machine identity authentication method is used to authenticate with Infisical.
[Read more about AWS IAM Auth](/documentation/platform/identities/aws-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
authentication:
awsIamAuth:
identityId: <machine-identity-id>
```
</Accordion>
<Accordion title="azureAuth">
The AWS IAM machine identity authentication method is used to authenticate with Infisical. Azure Auth can only be used from within an Azure environment.
[Read more about Azure Auth](/documentation/platform/identities/azure-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
authentication:
azureAuth:
identityId: <machine-identity-id>
```
</Accordion>
<Accordion title="gcpIamAuth">
The GCP IAM machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used both within and outside GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
- `serviceAccountKeyFilePath`: The path to the GCP service account key file.
Example:
```yaml
spec:
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
```
</Accordion>
<Accordion title="gcpIdTokenAuth">
The GCP ID Token machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Example:
```yaml
spec:
gcpIdTokenAuth:
identityId: <machine-identity-id>
```
</Accordion>
</Accordion>
<Accordion title="tls">
This block defines the TLS settings to use for connecting to the Infisical
instance.
Fields:
<Accordion title="caRef">
This block defines the reference to the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
Valid fields:
- `secretName`: The name of the Kubernetes secret containing the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
- `secretNamespace`: The namespace of the Kubernetes secret containing the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
- `key`: The name of the key in the Kubernetes secret which contains the value of the CA certificate to use for connecting to the Infisical instance with SSL/TLS.
Example:
```yaml
tls:
caRef:
secretName: custom-ca-certificate
secretNamespace: default
key: ca.crt
```
</Accordion>
</Accordion>
### Applying the InfisicalPushSecret CRD to your cluster
Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster.
After applying, you should notice that the secrets have been pushed to Infisical.
```bash
kubectl apply -f source-push-secret.yaml # The secret that you're referencing in the InfisicalPushSecret CRD push.secret field
kubectl apply -f example-infisical-push-secret-crd.yaml # The InfisicalPushSecret CRD itself
```
### Connecting to instances with private/self-signed certificate
To connect to Infisical instances behind a private/self-signed certificate, you can configure the TLS settings in the `InfisicalPushSecret` CRD
to point to a CA certificate stored in a Kubernetes secret resource.
<Accordion title="Example propagation">
```yaml
apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
name: infisicalsecret-sample
labels:
label-to-be-passed-to-managed-secret: sample-value
annotations:
example.com/annotation-to-be-passed-to-managed-secret: "sample-value"
spec:
hostAPI: https://app.infisical.com/api
resyncInterval: 30s
tls:
caRef:
secretName: custom-ca-certificate
secretNamespace: default
key: ca.crt
..
authentication:
# ...
...
managedSecretReference:
...
```
## Global configuration
To configure global settings that will apply to all instances of `InfisicalSecret`, you can define these configurations in a Kubernetes ConfigMap.
For example, you can configure all `InfisicalSecret` instances to fetch secrets from a single backend API without specifying the `hostAPI` parameter for each instance.
### Available global properties
| Property | Description | Default value |
| -------- | --------------------------------------------------------------------------------- | ----------------------------- |
| hostAPI | If `hostAPI` in `InfisicalSecret` instance is left empty, this value will be used | https://app.infisical.com/api |
### Applying global configurations
All global configurations must reside in a Kubernetes ConfigMap named `infisical-config` in the namespace `infisical-operator-system`.
To apply global configuration to the operator, copy the following yaml into `infisical-config.yaml` file.
```yaml infisical-config.yaml
apiVersion: v1
kind: Namespace
metadata:
name: infisical-operator-system
---
apiVersion: v1
kind: ConfigMap
metadata:
name: infisical-config
namespace: infisical-operator-system
data:
hostAPI: https://example.com/api # <-- global hostAPI
```
Then apply this change via kubectl by running the following
```bash
kubectl apply -f infisical-config.yaml
```
## Troubleshoot operator
If the operator is unable to fetch secrets from the API, it will not affect the managed Kubernetes secret.
It will continue attempting to reconnect to the API indefinitely.
The InfisicalSecret resource uses the `status.conditions` field to report its current state and any errors encountered.
This would result in the following managed secret to be created:
```yaml
$ kubectl get infisicalSecrets
NAME AGE
infisicalsecret-sample 12s
$ kubectl describe infisicalSecret infisicalsecret-sample
...
Spec:
...
Status:
Conditions:
Last Transition Time: 2022-12-18T04:29:09Z
Message: Infisical controller has located the Infisical token in provided Kubernetes secret
Reason: OK
Status: True
Type: secrets.infisical.com/LoadedInfisicalToken
Last Transition Time: 2022-12-18T04:29:10Z
Message: Failed to update secret because: 400 Bad Request
Reason: Error
Status: False
Type: secrets.infisical.com/ReadyToSyncSecrets
Events: <none>
apiVersion: v1
data: ...
kind: Secret
metadata:
annotations:
example.com/annotation-to-be-passed-to-managed-secret: sample-value
secrets.infisical.com/version: W/"3f1-ZyOSsrCLGSkAhhCkY2USPu2ivRw"
labels:
label-to-be-passed-to-managed-secret: sample-value
name: managed-token
namespace: default
type: Opaque
```
## Uninstall Operator
The managed secret created by the operator will not be deleted when the operator is uninstalled.
<Tabs>
<Tab title="Helm">
Install Infisical Helm repository
```bash
helm uninstall <release name>
```
</Tab>
<Tab title="Kubectl">
```
kubectl delete -f https://raw.githubusercontent.com/Infisical/infisical/main/k8-operator/kubectl-install/install-secrets-operator.yaml
```
</Tab>
</Tabs>
## Useful Articles
- [Managing secrets in OpenShift with Infisical](https://xphyr.net/post/infisical_ocp/)
</Accordion>

View File

@@ -0,0 +1,195 @@
---
title: "Kubernetes Operator"
sidebarTitle: "Overview"
description: "How to use Infisical to inject, push, and manage secrets within Kubernetes clusters"
---
The Infisical Operator is a collection of Kubernetes controllers that streamline how secrets are managed between Infisical and your Kubernetes cluster.
It provides multiple Custom Resource Definitions (CRDs) which enable you to:
- **Sync** secrets from Infisical into Kubernetes (`InfisicalSecret`).
- **Push** new secrets from Kubernetes to Infisical (`InfisicalPushSecret`).
- **Manage** dynamic secrets and automatically create time-bound leases (`InfisicalDynamicSecret`).
When these CRDs are configured, the Infisical Operator will continuously monitors for changes and performs necessary updates to keep your Kubernetes secrets up to date.
It can also automatically reload dependent Deployments resources whenever relevant secrets are updated.
<Note>
If you are already using the External Secrets operator, you can view the
integration documentation for it
[here](https://external-secrets.io/latest/provider/infisical/).
</Note>
## Install
The operator can be install via [Helm](https://helm.sh). Helm is a package manager for Kubernetes that allows you to define, install, and upgrade Kubernetes applications.
**Install the latest Helm repository**
```bash
helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
```
```bash
helm repo update
```
The operator can be installed either cluster-wide or restricted to a specific namespace.
If you require stronger isolation and stricter access controls, a namespace-scoped installation may make more sense.
<Tabs>
<Tab title="Cluster Wide Installation">
```bash
helm install --generate-name infisical-helm-charts/secrets-operator
```
</Tab>
<Tab title="Namespace Scoped Installation">
The operator can be configured to watch and manage secrets in a specific namespace instead of having cluster-wide access. This is useful for:
- **Enhanced Security**: Limit the operator's permissions to only specific namespaces instead of cluster-wide access
- **Multi-tenant Clusters**: Run separate operator instances for different teams or applications
- **Resource Isolation**: Ensure operators in different namespaces don't interfere with each other
- **Development & Testing**: Run development and production operators side by side in isolated namespaces
**Note**: For multiple namespace-scoped installations, only the first installation should install CRDs. Subsequent installations should set `installCRDs: false` to avoid conflicts.
```bash
# First namespace installation (with CRDs)
helm install operator-namespace1 infisical-helm-charts/secrets-operator \
--namespace first-namespace \
--set scopedNamespace=first-namespace \
--set scopedRBAC=true
# Subsequent namespace installations
helm install operator-namespace2 infisical-helm-charts/secrets-operator \
--namespace another-namespace \
--set scopedNamespace=another-namespace \
--set scopedRBAC=true \
--set installCRDs=false
```
When scoped to a namespace, the operator will:
- Only watch InfisicalSecrets in the specified namespace
- Only create/update Kubernetes secrets in that namespace
- Only access deployments in that namespace
The default configuration gives cluster-wide access:
```yaml
installCRDs: true # Install CRDs (set to false for additional namespace installations)
scopedNamespace: "" # Empty for cluster-wide access
scopedRBAC: false # Cluster-wide permissions
```
If you want to install operators in multiple namespaces simultaneously:
- Make sure to set `installCRDs: false` for all but one of the installations to avoid conflicts, as CRDs are cluster-wide resources.
- Use unique release names for each installation (e.g., operator-namespace1, operator-namespace2).
</Tab>
</Tabs>
## Custom Resource Definitions
Currently the operator supports the following CRD's. We are constantly expanding the functionality of the operator, and this list will be updated as new CRD's are added.
1. [InfisicalSecret](/integrations/platforms/kubernetes/infisical-secret-crd): Sync secrets from Infisical to a Kubernetes secret.
2. [InfisicalPushSecret](/integrations/platforms/kubernetes/infisical-push-secret-crd): Push secrets from a Kubernetes secret to Infisical.
3. [InfisicalDynamicSecret](/integrations/platforms/kubernetes/infisical-dynamic-secret-crd): Sync dynamic secrets and create leases automatically in Kubernetes.
## General Configuration
### Private/self-signed certificate
To connect to Infisical instances behind a private/self-signed certificate, you can configure the TLS settings in the CRD
to point to a CA certificate stored in a Kubernetes secret resource.
```yaml
---
spec:
hostAPI: https://app.infisical.com/api
tls:
caRef:
secretName: custom-ca-certificate
secretNamespace: default
key: ca.crt
---
```
## Global configuration
To configure global settings that will apply to all instances of `InfisicalSecret`, you can define these configurations in a Kubernetes ConfigMap.
For example, you can configure all `InfisicalSecret` instances to fetch secrets from a single backend API without specifying the `hostAPI` parameter for each instance.
### Available global properties
| Property | Description | Default value |
| -------- | --------------------------------------------------------------------------------- | ----------------------------- |
| hostAPI | If `hostAPI` in `InfisicalSecret` instance is left empty, this value will be used | https://app.infisical.com/api |
### Applying global configurations
All global configurations must reside in a Kubernetes ConfigMap named `infisical-config` in the namespace `infisical-operator-system`.
To apply global configuration to the operator, copy the following yaml into `infisical-config.yaml` file.
```yaml infisical-config.yaml
apiVersion: v1
kind: Namespace
metadata:
name: infisical-operator-system
---
apiVersion: v1
kind: ConfigMap
metadata:
name: infisical-config
namespace: infisical-operator-system
data:
hostAPI: https://example.com/api # <-- global hostAPI
```
Then apply this change via kubectl by running the following
```bash
kubectl apply -f infisical-config.yaml
```
## Troubleshoot operator
If the operator is unable to fetch secrets from the API, it will not affect the managed Kubernetes secret.
It will continue attempting to reconnect to the API indefinitely.
The InfisicalSecret resource uses the `status.conditions` field to report its current state and any errors encountered.
```yaml
$ kubectl get infisicalSecrets
NAME AGE
infisicalsecret-sample 12s
$ kubectl describe infisicalSecret infisicalsecret-sample
...
Spec:
...
Status:
Conditions:
Last Transition Time: 2022-12-18T04:29:09Z
Message: Infisical controller has located the Infisical token in provided Kubernetes secret
Reason: OK
Status: True
Type: secrets.infisical.com/LoadedInfisicalToken
Last Transition Time: 2022-12-18T04:29:10Z
Message: Failed to update secret because: 400 Bad Request
Reason: Error
Status: False
Type: secrets.infisical.com/ReadyToSyncSecrets
Events: <none>
```
## Uninstall Operator
The managed secret created by the operator will not be deleted when the operator is uninstalled.
<Tabs>
<Tab title="Helm">
Install Infisical Helm repository
```bash
helm uninstall <release name>
```
</Tab>
</Tabs>

View File

@@ -349,7 +349,15 @@
{
"group": "Container orchestrators",
"pages": [
"integrations/platforms/kubernetes",
{
"group": "Kubernetes",
"pages": [
"integrations/platforms/kubernetes/overview",
"integrations/platforms/kubernetes/infisical-secret-crd",
"integrations/platforms/kubernetes/infisical-push-secret-crd",
"integrations/platforms/kubernetes/infisical-dynamic-secret-crd"
]
},
"integrations/platforms/kubernetes-csi",
"integrations/platforms/docker-swarm-with-agent",
"integrations/platforms/ecs-with-agent"