Back to Infisical

Kubernetes Operator

docs/integrations/platforms/kubernetes/overview.mdx

0.160.916.4 KB
Original Source

import KubernetesOperatorTemplating from "/snippets/kubernetes-operator-v1beta1-templating.mdx";

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.
  • Push new secrets from Kubernetes to Infisical.
  • Manage dynamic secrets and automatically create time-bound leases.

When these CRDs are configured, the Infisical Operator will continuously monitor for changes and perform necessary updates to keep your Kubernetes secrets up to date. It can also automatically reload dependent Deployment resources whenever relevant secrets are updated.

<Info> The operator supports two CRD API versions: **v1beta1** and **v1alpha1**. Use **v1beta1** for new installations; **v1alpha1** is legacy and will be deprecated soon. </Info> <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> <Tabs> <Tab title="Supported Kubernetes versions"> The following [Kubernetes minor releases](https://kubernetes.io/releases/) are currently supported. The latest operator version is tested against each Kubernetes version. It may work with other versions of Kubernetes, but those are not officially supported.
- 1.33
- 1.32
- 1.31
- 1.30
- 1.29
</Tab> <Tab title="Supported Kubernetes distributions"> The Infisical Kubernetes Operator has been tested successfully in the following hosted Kubernetes environments:
- Amazon Elastic Kubernetes Service (EKS)
- Google Kubernetes Engine (GKE)
- Microsoft Azure Kubernetes Service (AKS)
- Oracle Container Engine for Kubernetes (OKE)
- Red Hat OpenShift

It may work in other Kubernetes distributions, but those are not officially supported. Please report any issues [here](https://github.com/Infisical/infisical/issues).
</Tab> </Tabs>

Install

The operator can be installed via Helm. 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"> When installing the operator cluster-wide, the operator will watch and manage CRDs across all namespaces in the cluster. This is the default installation method and the quickest way to get started with using the operator. Cluster-wide installations are useful for: - **Simplified Management**: A single operator instance manages secrets across all namespaces - **Centralized Operations**: One deployment to monitor, update, and maintain - **Cross-Namespace Flexibility**: Easily manage secrets for applications spanning multiple namespaces - **Quick Setup**: Works out of the box with no additional RBAC configuration required
```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 as CRDs are cluster-wide resources.
</Note>

### Single Namespace
```bash
# First namespace installation (with CRDs)
helm install operator-namespaced infisical-helm-charts/secrets-operator \
  --namespace single-namespace \
  --set scopedNamespaces=single-namespace \
  --set scopedRBAC=true
```

<Accordion title="Using values.yaml file">
```yaml values-operator1.yaml
  scopedNamespaces: single-namespace
  scopedRBAC: true
  installCRDs: true
```
</Accordion>


### Multiple Namespaces
```bash
 helm install operator-1 infisical-helm-charts/secrets-operator \
  --namespace ns1 \
  --set scopedNamespaces=ns1 \
  --set scopedRBAC=true \
  --set installCRDs=true # Only install CRDs once in the cluster (default is true)

helm install operator-namespace2 infisical-helm-charts/secrets-operator \
  --namespace ns2 \
  --set scopedNamespaces=ns2 \
  --set scopedRBAC=true \
  --set installCRDs=false # Do not install CRDs in subsequent namespace installations
```

<Accordion title="Using values.yaml file">
```yaml values-operator1.yaml
  scopedNamespaces: ns1
  scopedRBAC: true
  installCRDs: false
```

```yaml values-operator2.yaml
  scopedNamespaces: ns2
  scopedRBAC: true
  installCRDs: false
```
</Accordion>


### Multiple namespaces with one operator installation
```bash
  helm install operator infisical-helm-charts/secrets-operator \
  --namespace operator-namespace \
  --set "scopedNamespaces={ns1,ns2,ns3}" \
  --set scopedRBAC=true
```
<Accordion title="Using values.yaml file">
```yaml values.yaml
  scopedNamespaces:
    - ns1
    - ns2
    - ns3
  scopedRBAC: true
```

</Accordion>
</Tab> </Tabs>

Using your own service account

By default a service account is created for the operator based on the operator release name. You can bring your own service account by setting controllerManager.serviceAccount.create to false and setting controllerManager.serviceAccount.name to the name of the service account you want to use in your values.yaml file.

Example values.yaml file:

yaml
controllerManager:
  serviceAccount:
    create: false
    name: my-service-account
# other values...
<Note> Please note that if you set `controllerManager.serviceAccount.create` to `false`, the service account needs to already exist in the namespace you are installing the operator in. </Note> <Tip> Custom service accounts are supported in chart version `0.10.11` and above. Please upgrade your helm chart to `0.10.11` or above before attempting to use custom service accounts. </Tip>

Custom Resource Definitions

<Tabs> <Tab title="v1beta1 (Recommended)"> The v1beta1 API separates authentication and connection configuration into their own reusable CRDs, making it easier to manage credentials across multiple secret resources.
| CRD | Description |
| --- | ----------- |
| [InfisicalConnection](/integrations/platforms/kubernetes/infisical-connection-crd) | Defines how to connect to an Infisical instance (host, TLS). Referenced by other CRDs. |
| [InfisicalAuth](/integrations/platforms/kubernetes/infisical-auth-crd) | Defines authentication credentials for a machine identity. Referenced by other CRDs. |
| [InfisicalStaticSecret](/integrations/platforms/kubernetes/infisical-static-secret-crd) | Sync secrets from Infisical to a Kubernetes secret. Replaces `InfisicalSecret`. |
</Tab> <Tab title="v1alpha1"> <Warning> The v1alpha1 CRDs are legacy and are planned for deprecation. </Warning>
| CRD | Status | Description |
| --- | ------ | ----------- |
| [InfisicalSecret](/integrations/platforms/kubernetes/infisical-secret-crd) | Deprecated | Sync secrets from Infisical to a Kubernetes secret. Use [InfisicalStaticSecret](/integrations/platforms/kubernetes/infisical-static-secret-crd) (v1beta1) instead. See [migration guide](#migrating-from-v1alpha1-to-v1beta1). |
| [InfisicalPushSecret](/integrations/platforms/kubernetes/infisical-push-secret-crd) | Active | Push secrets from a Kubernetes secret to Infisical. |
| [InfisicalDynamicSecret](/integrations/platforms/kubernetes/infisical-dynamic-secret-crd) | Active | Sync dynamic secrets and create leases automatically in Kubernetes. |
</Tab> </Tabs>

Metrics and Prometheus

The operator exposes Prometheus metrics on /metrics for monitoring reconciliation performance, errors, and resource utilization.

Configuration

Enable the ServiceMonitor during installation. This will create a prometheus ServiceMonitor resource in the same namespace as the operator.

yaml
telemetry:
  serviceMonitor:
    enabled: true
    # ... other telemetry configuration (optional) ...
<AccordionGroup> <Accordion title="telemetry.serviceMonitor.enabled" query="telemetry.serviceMonitor.enabled"> Enable ServiceMonitor for Prometheus Operator. Defaults to `false`. </Accordion> <Accordion title="telemetry.serviceMonitor.selectors" query="telemetry.serviceMonitor.selectors"> Additional labels for ServiceMonitor. Defaults to `{}`. </Accordion> <Accordion title="telemetry.serviceMonitor.scheme" query="telemetry.serviceMonitor.scheme"> Scheme to use for the ServiceMonitor. Defaults to `https`. </Accordion> <Accordion title="telemetry.serviceMonitor.port" query="telemetry.serviceMonitor.port"> Port to use for the ServiceMonitor. Defaults to `https`. </Accordion> <Accordion title="telemetry.serviceMonitor.path" query="telemetry.serviceMonitor.path"> Path to use for the ServiceMonitor. Defaults to `/metrics`. </Accordion> <Accordion title="telemetry.serviceMonitor.interval" query="telemetry.serviceMonitor.interval"> Scrape interval. Defaults to `30s`. </Accordion> <Accordion title="telemetry.serviceMonitor.scrapeTimeout" query="telemetry.serviceMonitor.scrapeTimeout"> Scrape timeout. Defaults to `10s`. </Accordion> <Accordion title="telemetry.serviceMonitor.bearerTokenFile" query="telemetry.serviceMonitor.bearerTokenFile"> Bearer token file. Defaults to `/var/run/secrets/kubernetes.io/serviceaccount/token`. </Accordion> </AccordionGroup>
yaml
telemetry:
  serviceMonitor:
    enabled: true

    selectors: {}
    scheme: https
    port: https
    path: /metrics
    bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    interval: 30s
    scrapeTimeout: 10s

Available Metrics

The operator exposes standard controller-runtime metrics. For a complete list of available metrics, see the Kubebuilder metrics reference.

Key metrics to monitor:

  • controller_runtime_reconcile_total - Reconciliation count
  • controller_runtime_reconcile_errors_total - Error count
  • controller_runtime_reconcile_time_seconds - Reconciliation duration

v1beta1 controllers: InfisicalStaticSecret, InfisicalAuth, InfisicalConnection

v1alpha1 controllers: InfisicalSecret, InfisicalPushSecret, InfisicalDynamicSecret

Example Prometheus Setup

<Steps> <Step title="Install Prometheus Operator"> ```bash helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace
```
</Step> <Step title="Install Operator with Metrics Enabled"> ```bash helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
helm install infisical-secrets-operator infisical-helm-charts/secrets-operator \
  --set telemetry.serviceMonitor.enabled=true
```
</Step> <Step title="Verify ServiceMonitor"> ```bash kubectl get servicemonitor ```
Check that the ServiceMonitor appears in your operator's namespace.
</Step> <Step title="Access Prometheus"> ```bash kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090 ```
Open [http://localhost:9090/targets](http://localhost:9090/targets) and verify the operator target shows **UP**.
</Step> </Steps>

Example Queries

promql
# Total reconciliations
controller_runtime_reconcile_total

# P99 latency
histogram_quantile(0.99, rate(controller_runtime_reconcile_time_seconds_bucket[5m]))

# Memory usage (MB)
process_resident_memory_bytes / 1024 / 1024

General Configuration

Private/self-signed certificate

To connect to Infisical instances behind a private/self-signed certificate, you can configure TLS settings to point to a CA certificate stored in a Kubernetes secret resource.

<Tabs> <Tab title="v1beta1 (Recommended)"> In v1beta1, TLS is configured on the [InfisicalConnection](/integrations/platforms/kubernetes/infisical-connection-crd) resource:
```yaml
apiVersion: secrets.infisical.com/v1beta1
kind: InfisicalConnection
metadata:
  name: my-infisical-connection
spec:
  address: https://infisical.mydomain.com
  tls:
    caCertificate:
      name: secret-containing-ca-certificate
      namespace: default
      key: ca.crt
```

All CRDs that reference this `InfisicalConnection` will automatically use the configured TLS settings.
</Tab> <Tab title="v1alpha1"> In v1alpha1, TLS is configured inline on each CRD:
```yaml
spec:
  hostAPI: https://app.infisical.com/api
  tls:
    caRef:
      secretName: custom-ca-certificate
      secretNamespace: default
      key: ca.crt
```
</Tab> </Tabs> <KubernetesOperatorTemplating />

Migrating from v1alpha1 to v1beta1

<Info> This migration guide applies to `InfisicalSecret` only. `InfisicalPushSecret` and `InfisicalDynamicSecret` do not have v1beta1 replacements yet and should continue to be used as-is. </Info>

The v1beta1 API introduces a cleaner separation of concerns. Instead of defining authentication and connection details inline in each secret CRD, you now create dedicated InfisicalConnection and InfisicalAuth resources that can be shared across multiple secret resources.

Key changes

  • Secret resource: InfisicalSecret -> InfisicalStaticSecret

    InfisicalStaticSecret replaces the v1alpha1 InfisicalSecret CRD. Instead of defining auth and connection settings inline, it references dedicated InfisicalAuth and InfisicalConnection resources.

  • Authentication: inline authentication -> InfisicalAuth

    Authentication config is now defined in a standalone InfisicalAuth resource that can be reused across CRDs. Authenticated credentials are cached and shared by all resources referencing the same InfisicalAuth.

  • Connection: inline hostAPI / tls -> InfisicalConnection

    Connection config is now defined in a standalone InfisicalConnection resource that can be reused by auth and secret resources.

Migration steps

<Steps> <Step title="Create an InfisicalConnection resource"> Extract the `hostAPI` and `tls` settings from your existing CRD into a new `InfisicalConnection` resource. See the [InfisicalConnection CRD](/integrations/platforms/kubernetes/infisical-connection-crd) documentation for the full spec. </Step> <Step title="Create an InfisicalAuth resource"> Extract the `authentication` block from your existing CRD into a new `InfisicalAuth` resource. See the [InfisicalAuth CRD](/integrations/platforms/kubernetes/infisical-auth-crd) documentation for the full spec. </Step> <Step title="Replace InfisicalSecret with InfisicalStaticSecret"> Create a new `InfisicalStaticSecret` resource that references your `InfisicalConnection` and `InfisicalAuth` resources. See the [InfisicalStaticSecret CRD](/integrations/platforms/kubernetes/infisical-static-secret-crd) documentation for the full spec. </Step> <Step title="Delete the old v1alpha1 resource"> Once you have verified that the new v1beta1 resources are working, delete the old `InfisicalSecret` CRD instance. </Step> </Steps>

Uninstall Operator

The managed secret created by the operator will not be deleted when the operator is uninstalled.

Uninstall Infisical Helm repository

bash
  helm uninstall <release name>