> ## 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

> 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](/integrations/platforms/kubernetes/overview).

## Installation

<Steps>
  <Step title="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
    ```
  </Step>

  <Step title="Install the chart">
    The operator can be installed either cluster-wide or restricted to specific namespaces.
    If you require stronger isolation and stricter access controls, a namespace-scoped installation may make more sense.

    <Tabs>
      <Tab title="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>

      <Tab title="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.

        <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 theme={"dark"}
        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.yaml theme={"dark"}
            scopedNamespaces: single-namespace
            scopedRBAC: true
            installCRDs: true
          ```
        </Accordion>

        **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 title="Using values.yaml file">
          ```yaml values-operator1.yaml theme={"dark"}
            scopedNamespaces: ns1
            scopedRBAC: true
            installCRDs: false
          ```

          ```yaml values-operator2.yaml theme={"dark"}
            scopedNamespaces: ns2
            scopedRBAC: true
            installCRDs: false
          ```
        </Accordion>

        **Multiple namespaces (single operator):**

        ```bash theme={"dark"}
        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 theme={"dark"}
            scopedNamespaces:
              - ns1
              - ns2
              - ns3
            scopedRBAC: true
          ```
        </Accordion>
      </Tab>
    </Tabs>
  </Step>

  <Step title="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.
    </Note>
  </Step>
</Steps>

### 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 are installing the operator in.
</Note>

<Tip>
  Custom service accounts are supported in chart version `0.10.11` and above.
</Tip>

## Uninstall

The managed secrets created by the operator will not 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
```
