> ## Documentation Index
> Fetch the complete documentation index at: https://infisical.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes Operator Helm chart

> Deploy the Infisical Kubernetes Operator using the official Helm chart.

The Infisical Kubernetes Operator automates secret management between Infisical and your Kubernetes cluster. It syncs secrets from Infisical into Kubernetes, pushes secrets from Kubernetes to Infisical, and manages dynamic secrets with time-bound leases.

For usage details, CRD reference, and examples, see the [Kubernetes Operator documentation](https://infisical.com/docs/integrations/platforms/kubernetes/overview).

## Installation

**1. Add the Helm repository**

```bash theme={"dark"}
helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
helm repo update
```

**2. Install the chart**

Install the operator cluster-wide or namespace-scoped.

> [accordion] Choosing cluster-wide or namespace-scoped
>
> The installation mode decides whether a resource in one namespace can use credentials from another namespace:
>
> | Mode | Cross-namespace references | Use when |
> | - | - | - |
> | Cluster-wide (default) | Allowed. The cluster is the trust boundary. | You trust everyone who can create operator resources, such as a platform team that manages authentication from one namespace. |
> | Namespace-scoped | Blocked. Kubernetes rejects the operator's requests to other namespaces. | Teams share a cluster and each team owns a namespace. Install one operator per team namespace. |

> [tab] Cluster-wide (default)
>
> The operator will watch and manage CRDs across all namespaces in the cluster. This is the default and quickest way to get started.
>
> ```bash theme={"dark"}
> helm install --generate-name infisical-helm-charts/secrets-operator
> ```

> [tab] Namespace-scoped
>
> Limit the operator's permissions to only specific namespaces instead of cluster-wide access. Useful for multi-tenant clusters or environments requiring strict resource isolation.
>
> Before you install, check these settings:
>
> * Set `scopedRBAC=true` (if you set only `scopedNamespaces`, the operator still gets a ClusterRole and watches every namespace)
> * Set `installCRDs=true` only on the first install (CRDs are cluster-wide resources, so later installs must set `installCRDs=false`)
>
> **Single namespace:**
>
> ```bash theme={"dark"}
> helm install operator-namespaced infisical-helm-charts/secrets-operator \
>   --namespace single-namespace \
>   --set scopedNamespaces=single-namespace \
>   --set scopedRBAC=true
> ```
>
> > [accordion] Using values.yaml file
> >
> > ```yaml values.yaml theme={"dark"}
> >   scopedNamespaces: single-namespace
> >   scopedRBAC: true
> >   installCRDs: true
> > ```
>
> **Multiple namespaces (separate operators):**
>
> ```bash theme={"dark"}
> 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] Using values.yaml file
> >
> > ```yaml values-operator1.yaml theme={"dark"}
> >   scopedNamespaces: ns1
> >   scopedRBAC: true
> >   installCRDs: true
> > ```
> >
> > ```yaml values-operator2.yaml theme={"dark"}
> >   scopedNamespaces: ns2
> >   scopedRBAC: true
> >   installCRDs: false
> > ```
>
> **Multiple namespaces (single operator):**
>
> With one operator for several namespaces, a resource in any of those namespaces can reference a service account, `InfisicalAuth`, or secret in the others. Use separate operators if those namespaces belong to different teams.
>
> ```bash theme={"dark"}
> helm install operator infisical-helm-charts/secrets-operator \
>   --namespace operator-namespace \
>   --set "scopedNamespaces={ns1,ns2,ns3}" \
>   --set scopedRBAC=true
> ```
>
> > [accordion] Using values.yaml file
> >
> > ```yaml values.yaml theme={"dark"}
> >   scopedNamespaces:
> >     - ns1
> >     - ns2
> >     - ns3
> >   scopedRBAC: true
> > ```

**3. Verify the deployment**

Check the pods in the namespace you installed the operator into:

```bash theme={"dark"}
kubectl get pods --namespace <namespace>
```

> [!NOTE]
>
> If you installed cluster-wide without a `--namespace` flag, the operator is deployed into your current namespace (typically `default`), so run `kubectl get pods` without the flag.

### Using your own service account

By default a service account is created for the operator based on the release name.
You can bring your own service account by setting `controllerManager.serviceAccount.create` to `false` and `controllerManager.serviceAccount.name` to the name of your existing service account.

```yaml values.yaml theme={"dark"}
controllerManager:
  serviceAccount:
    create: false
    name: my-service-account
```

> [!NOTE]
>
> The service account must already exist in the namespace you're installing the operator in.

> [!TIP]
>
> Custom service accounts are supported in chart version `0.10.11` and above.

### Syncing resources in parallel

By default, the operator syncs one resource at a time.
To speed up syncing, set `maxConcurrency` at the top level of `values.yaml` to the number of resources the operator should sync at the same time.

```yaml values.yaml theme={"dark"}
maxConcurrency: 5
```

The value must be at least `1`, and a higher value sends more requests to Infisical at the same time.
`maxConcurrency` is supported in chart version `0.11.15` and above.

> [!NOTE]
>
> `maxConcurrency` currently only applies to [InfisicalStaticSecret](https://infisical.com/docs/integrations/platforms/kubernetes/infisical-static-secret-crd.md) resources. The operator still syncs every other resource type one at a time.

## Uninstall

The managed secrets created by the operator won't be deleted when the operator is uninstalled.

```bash theme={"dark"}
helm uninstall <release-name>
```

## Configuration reference

| Parameter | Default | Description |
| - | - | - |
| `hostAPI` | `"https://app.infisical.com/api"` | Infisical API URL. |
| `installCRDs` | `true` | Install CRD definitions. Set to `false` for secondary namespace-scoped installations. |
| `scopedNamespaces` | `[]` | Namespaces to watch. Empty means all namespaces. |
| `scopedRBAC` | `false` | Create namespaced Role/RoleBinding instead of cluster-wide. |
| `controllerManager.replicas` | `1` | Number of operator replicas. |
| `controllerManager.manager.image.repository` | `infisical/kubernetes-operator` | Container image. |
| `controllerManager.manager.image.tag` | `v0.11.2` | Image tag. |
| `controllerManager.manager.resources.requests.cpu` | `10m` | CPU request. |
| `controllerManager.manager.resources.requests.memory` | `64Mi` | Memory request. |
| `controllerManager.manager.resources.limits.cpu` | `500m` | CPU limit. |
| `controllerManager.manager.resources.limits.memory` | `128Mi` | Memory limit. |
| `controllerManager.serviceAccount.create` | `true` | Create a service account. |
| `controllerManager.serviceAccount.name` | `""` | Service account name override. |
| `controllerManager.serviceAccount.annotations` | `{}` | Service account annotations. |
| `controllerManager.nodeSelector` | `{}` | Node selector. |
| `controllerManager.tolerations` | `[]` | Pod tolerations. |
| `controllerManager.affinity` | `{}` | Pod affinity rules. |
| `controllerManager.manager.extraEnv` | `[]` | Extra environment variables. |
| `controllerManager.manager.extraVolumeMounts` | `[]` | Extra volume mounts. |
| `controllerManager.extraVolumes` | `[]` | Extra volumes. |
| `imagePullSecrets` | `[]` | Image pull secrets for private registries. |
| `telemetry.serviceMonitor.enabled` | `false` | Enable Prometheus ServiceMonitor. |

## Default Helm values

```yaml theme={"dark"}
# -- The Infisical API host URL. This is the default host used when no hostAPI is set on the CRD or global ConfigMap.
hostAPI: "https://app.infisical.com/api"

logger:
  # -- The output of the logs. Can be "stdout" or "stderr". Defaults to "stderr".
  writer: "stderr"

controllerManager:
  serviceAccount:
    create: true
    name: ""
    annotations: {}
  nodeSelector: {}
  tolerations: []
  affinity: {}
  topologySpreadConstraints: []
  # -- Extra volumes to add to the pod
  extraVolumes: []
  # -- Extra init containers to add to the pod
  extraInitContainers: []
  manager:
    args:
    - --metrics-bind-address=:8443
    - --leader-elect
    - --health-probe-bind-address=:8081
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
      readOnlyRootFilesystem: true
    image:
      repository: infisical/kubernetes-operator
      tag: v0.11.2
    resources:
      limits:
        cpu: 500m
        memory: 128Mi
      requests:
        cpu: 10m
        memory: 64Mi
    # -- Extra environment variables to add to the manager container
    extraEnv: []
    # -- Extra volume mounts to add to the manager container
    extraVolumeMounts: []
  podSecurityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  replicas: 1
kubernetesClusterDomain: cluster.local

# DEPRECATED: Use scopedNamespaces instead. This field will be removed in a future version.
# If both scopedNamespace and scopedNamespaces are set, scopedNamespaces takes precedence.
scopedNamespace: ""

# List of namespaces to watch. If empty, the operator watches all namespaces (cluster-scoped).
# When scopedRBAC is true, a Role and RoleBinding will be created in each namespace.
# Example:
#   scopedNamespaces:
#     - team-a-namespace
#     - team-b-namespace
scopedNamespaces: []

scopedRBAC: false
installCRDs: true
imagePullSecrets: []

metricsService:
  ports:
    - name: https
      port: 8443
      protocol: TCP
      targetPort: 8443
  type: ClusterIP

telemetry:
  serviceMonitor:
    enabled: false

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.