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

# Infisical Gateway Helm chart

> Deploy the Infisical Gateway on Kubernetes using the official Helm chart.

The Infisical Gateway enables secure outbound-only communication between your private resources and the Infisical platform, without exposing inbound ports in your network.

For a full overview of how gateways work, see the [Gateway documentation](https://infisical.com/docs/documentation/platform/gateways/overview.md).

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

> [tab] Token Auth
>
> ```bash theme={"dark"}
> helm install infisical-gateway infisical-helm-charts/infisical-gateway \
>   --namespace infisical-gateway \
>   --create-namespace \
>   --set gateway.name=<gateway-name> \
>   --set gateway.enrollment.method=token \
>   --set gateway.enrollment.token.value=<enrollment-token> \
>   --set gateway.domain=https://app.infisical.com
> ```
>
> > [!WARNING]
> >
> > The enrollment token is single-use and expires in 1 hour. Persistent storage (enabled by default) is required so credentials survive pod restarts.

> [tab] AWS Auth
>
> ```bash theme={"dark"}
> helm install infisical-gateway infisical-helm-charts/infisical-gateway \
>   --namespace infisical-gateway \
>   --create-namespace \
>   --set gateway.name=<gateway-name> \
>   --set gateway.enrollment.method=aws \
>   --set gateway.enrollment.aws.gatewayId=<gateway-id> \
>   --set gateway.domain=https://app.infisical.com \
>   --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::<account-id>:role/<role-name>
> ```

> [tab] GCP Auth
>
> ```bash theme={"dark"}
> helm install infisical-gateway infisical-helm-charts/infisical-gateway \
>   --namespace infisical-gateway \
>   --create-namespace \
>   --set gateway.name=<gateway-name> \
>   --set gateway.enrollment.method=gcp \
>   --set gateway.enrollment.gcp.gatewayId=<gateway-id> \
>   --set gateway.domain=https://app.infisical.com \
>   --set serviceAccount.annotations."iam\.gke\.io/gcp-service-account"=<gsa-name>@<project-id>.iam.gserviceaccount.com
> ```
>
> The gateway reads an identity token from the GKE metadata server, so no credential has to be
> distributed to the cluster.
>
> > [!WARNING]
> >
> > The Google service account in that annotation is the identity Infisical sees, so its email
> > must be in the gateway's allowed service account emails. Its IAM policy also needs a
> > `roles/iam.workloadIdentityUser` binding for the Kubernetes service account the chart
> > creates. A workload identity token carries no Compute Engine instance details, so a login
> > is refused while the gateway has an allowed projects or zones list. See
> > [Gateway Deployment](https://infisical.com/docs/documentation/platform/gateways/gateway-deployment.md) for the full
> > configuration.

> [tab] Kubernetes Auth
>
> ```bash theme={"dark"}
> helm install infisical-gateway infisical-helm-charts/infisical-gateway \
>   --namespace infisical-gateway \
>   --create-namespace \
>   --set gateway.name=<gateway-name> \
>   --set gateway.enrollment.method=kubernetes \
>   --set gateway.enrollment.kubernetes.gatewayId=<gateway-id> \
>   --set gateway.domain=https://app.infisical.com
> ```
>
> The gateway authenticates with the projected service account token of its own pod, so no
> credential has to be distributed to the cluster. The chart binds its service account to the
> `system:auth-delegator` ClusterRole by default, which is what lets that token be reviewed.
>
> > [!WARNING]
> >
> > The release namespace and service account name must match the allowlists configured on the
> > gateway in Infisical. With the command above those are `infisical-gateway` and
> > `infisical-gateway`. See [Gateway Deployment](https://infisical.com/docs/documentation/platform/gateways/gateway-deployment.md)
> > for the full configuration.

**3. Verify the deployment**

```bash theme={"dark"}
kubectl get pods -n infisical-gateway
```

## Uninstall

```bash theme={"dark"}
helm uninstall infisical-gateway --namespace infisical-gateway
```

## Configuration reference

| Parameter | Default | Description |
| - | - | - |
| `gateway.name` | `""` | Name of the gateway as created in the Infisical UI. |
| `gateway.domain` | `""` | Infisical instance URL (e.g., `https://app.infisical.com`). |
| `gateway.enrollment.method` | `""` | Enrollment method: `token`, `aws`, `gcp`, or `kubernetes`. |
| `gateway.enrollment.token.value` | `""` | Inline enrollment token. Mutually exclusive with `existingSecretRef`. |
| `gateway.enrollment.token.existingSecretRef` | `""` | Kubernetes secret containing the enrollment token. |
| `gateway.enrollment.token.secretKey` | `"enrollment-token"` | Key in the secret that holds the token. |
| `gateway.enrollment.aws.gatewayId` | `""` | Gateway ID from the Infisical UI. Required for AWS auth. |
| `gateway.enrollment.gcp.gatewayId` | `""` | Gateway ID from the Infisical UI. Required for GCP auth. |
| `gateway.enrollment.gcp.type` | `""` | How the identity is proven: `gce` reads a token from the metadata server, `iam` signs one through the IAM Credentials API. Empty means `gce`. |
| `gateway.enrollment.gcp.serviceAccountKeyFilePath` | `""` | Only for `type: iam` on a pod with no workload identity. Path to a service account key file, which you mount with `extraVolumes` and `extraVolumeMounts`. |
| `gateway.enrollment.kubernetes.gatewayId` | `""` | Gateway ID from the Infisical UI. Required for Kubernetes auth. |
| `gateway.enrollment.kubernetes.serviceAccountTokenPath` | `""` | Override the projected service account token path. Defaults to `/var/run/secrets/kubernetes.io/serviceaccount/token`. |
| `gateway.enrollment.kubernetes.externalTokenReview` | `false` | Set true when TokenReview permission comes from outside this chart, either a token reviewer JWT configured in Infisical or a binding you manage. Required to install with `serviceAccount.createAsAuthDelegator` disabled. |
| `gateway.enrollment.credentialsSecretRef` | `""` | Kubernetes secret with credentials injected as env vars. |
| `gateway.relayName` | `""` | Specific relay to connect to. Empty for automatic selection. |
| `gateway.listenAddress` | `""` | `host:port` that Infisical dials to reach the gateway, which runs it in direct listen mode. Empty for relay mode. |
| `persistence.enabled` | `true` | Enable persistent storage. Required for token auth, optional for AWS, GCP and Kubernetes auth. |
| `persistence.storageClass` | `""` | Storage class for the PVC. |
| `persistence.size` | `5Gi` | PVC size. |
| `persistence.existingClaim` | `""` | Use an existing PVC. |
| `image.repository` | `infisical/cli` | Container image. |
| `image.tag` | `"0.44.6"` | Image tag. |
| `resources.requests.cpu` | `100m` | CPU request. |
| `resources.requests.memory` | `128Mi` | Memory request. |
| `resources.limits.cpu` | `500m` | CPU limit. |
| `resources.limits.memory` | `128Mi` | Memory limit. |
| `serviceAccount.create` | `true` | Create a service account. |
| `serviceAccount.annotations` | `{}` | Service account annotations (e.g., IRSA role ARN). |
| `nodeSelector` | `{}` | Node selector. |
| `tolerations` | `{}` | Pod tolerations. |
| `affinity` | `{}` | Pod affinity rules. |
| `extraEnv` | `[]` | Extra environment variables for the gateway container. |
| `extraEnvFrom` | `[]` | Load environment variables from Secrets or ConfigMaps. |
| `extraArgs` | `[]` | Extra arguments appended to the gateway container command. |
| `extraVolumes` | `[]` | Additional volumes to attach to the gateway pod. |
| `extraVolumeMounts` | `[]` | Additional volume mounts for the gateway container. |
| `extraObjects` | `[]` | Extra Kubernetes manifests to deploy with this chart. |
| `service.type` | `ClusterIP` | Type of the Service created in direct listen mode. |
| `service.port` | `""` | Port the Service exposes. Empty means the port from `gateway.listenAddress`. Set it only to put a different port in front of the gateway. |

## Resource limits

PAM is heavier per session, so raise the chart's resource limits:

```yaml theme={"dark"}
resources:
  requests:
    cpu: 4
    memory: 8Gi
  limits:
    cpu: 4
    memory: 8Gi
```

Kubernetes schedules on requests, so requests below the minimum can place the gateway on a node that can't supply it.

Recordings share the volume with the gateway's credentials, so raise `persistence.size` above its 5Gi default if your sessions are long or numerous.

## Direct listen mode

By default the gateway connects out to a relay. To have Infisical connect to the gateway instead, set `gateway.listenAddress` to the address Infisical dials.

```bash theme={"dark"}
helm install infisical-gateway infisical-helm-charts/infisical-gateway \
  --namespace infisical-gateway \
  --create-namespace \
  --set gateway.name=<gateway-name> \
  --set gateway.listenAddress=infisical-gateway.infisical-gateway.svc.cluster.local:8443 \
  --set gateway.enrollment.method=token \
  --set gateway.enrollment.token.value=<enrollment-token> \
  --set gateway.domain=<your-infisical-domain>
```

The chart takes the container port from `gateway.listenAddress`, points the Service at it, and exposes that same port, which keeps all three in step. A `host:port` value is required, and the chart fails the render if the port is missing. Set `service.port` only if you want the Service to answer on a different port than the gateway binds, in which case the listen address has to name the Service's port.

The Service is created only in direct listen mode. A relay-mode gateway accepts no connections and needs none.

The address has to be one Infisical can resolve and reach. An in-cluster Service DNS name works when you self-host Infisical in the same cluster. From outside the cluster, expose the gateway through an Ingress or a `LoadBalancer` Service and register that address instead.

Direct listen is only available on self-hosted Infisical.

## Default Helm values

> [accordion] values.yaml
>
> ```yaml theme={"dark"}
> image:
>   repository: infisical/cli
>   tag: "0.44.6"
>   pullPolicy: IfNotPresent
>
> # Machine identity flow: name of the K8s Secret containing env vars like INFISICAL_AUTH_METHOD, etc.
> # Only used when gateway.enrollment.method is unset.
> secret:
>   name: "infisical-gateway-environment"
>
> gateway:
>   # Name of the gateway created in the Infisical UI. Required when enrollment.method is set.
>   name: ""
>
>   # Infisical instance URL (e.g. https://app.infisical.com). Required when enrollment.method is set.
>   domain: ""
>
>   enrollment:
>     # Enrollment method: "token", "aws", "gcp", or "kubernetes".
>     # Leave empty to use the legacy machine identity flow (env vars from secret.name).
>     method: ""
>
>     # Token enrollment settings (method=token)
>     token:
>       # Inline enrollment token value. Mutually exclusive with existingSecretRef.
>       value: ""
>       # Name of an existing K8s Secret containing the enrollment token.
>       existingSecretRef: ""
>       # Key within the secret that holds the enrollment token.
>       secretKey: "enrollment-token"
>
>     # AWS enrollment settings (method=aws)
>     aws:
>       # Required when method=aws. Gateway ID from the Infisical UI.
>       gatewayId: ""
>
>     # GCP enrollment settings (method=gcp)
>     gcp:
>       # Required when method=gcp. Gateway ID from the Infisical UI.
>       gatewayId: ""
>       # How the gateway proves its GCP identity: "gce" reads an identity token from the instance
>       # metadata server, which covers GKE workload identity; "iam" signs a JWT through the IAM
>       # Credentials API. Leave empty for the CLI default of "gce".
>       type: ""
>       # Only for type=iam, and only when the pod has no workload identity to sign with. Path to a
>       # service account key file, which you mount with extraVolumes and extraVolumeMounts.
>       serviceAccountKeyFilePath: ""
>
>     # Kubernetes enrollment settings (method=kubernetes).
>     kubernetes:
>       # Required when method=kubernetes. Gateway ID from the Infisical UI.
>       gatewayId: ""
>       # Path to the projected service account token. Only override for a non-default mount.
>       serviceAccountTokenPath: ""
>       # Set true only if TokenReview permission comes from somewhere other than this chart: a token
>       # reviewer JWT configured on the gateway in Infisical, or a binding you manage yourself.
>       # Required to install with serviceAccount.createAsAuthDelegator disabled.
>       externalTokenReview: false
>
>     # Name of a K8s Secret whose key-value pairs are injected as env vars.
>     # Use this to provide credentials for the enrollment method (e.g. AWS keys, GCP credentials).
>     # Not needed when credentials are provided via workload identity (IRSA, GCP Workload Identity, etc.).
>     credentialsSecretRef: ""
>
>   # Specific relay to connect to. Leave empty for automatic selection.
>   relayName: ""
>
>   # Stable host:port advertised by a gateway accepting direct connections.
>   # Requires an image.tag of 0.43.131 or newer; older images reject the flag and the pod
>   # crash-loops on startup.
>   listenAddress: ""
>
>   pamSessionRecordingsDirectory: /var/lib/infisical/session_recordings
>
> # Persistent storage for the gateway (credentials and session recordings).
> # Required when enrollment.method=token so credentials survive pod restarts.
> # Optional when enrollment.method is aws, gcp or kubernetes, since all three re-authenticate
> # on every start.
> # For legacy machine-identity installs (no enrollment.method), persistence only takes effect
> # when existingClaim is provided.
> persistence:
>   enabled: true
>   storageClass: ""
>   size: 5Gi
>   accessModes:
>     - ReadWriteOnce
>   existingClaim: ""
>
> resources:
>   limits:
>     cpu: 500m
>     memory: 128Mi
>   requests:
>     cpu: 100m
>     memory: 128Mi
>
> imagePullSecrets: []
> nameOverride: ""
> fullnameOverride: ""
>
> serviceAccount:
>   create: true
>   automount: true
>   createAsAuthDelegator: true
>   annotations: {}
>   name: ""
>
> podAnnotations: {}
> podLabels: {}
> podSecurityContext:
>   runAsNonRoot: true
>   fsGroup: 1000
>
> securityContext:
>   runAsNonRoot: true
>   runAsUser: 1000
>
> affinity: {}
> tolerations: {}
> nodeSelector: {}
> service:
>   type: ClusterIP
>   # Port the Service exposes. Empty means the port from gateway.listenAddress, which is the port
>   # the platform dials. Only set this to put a different port in front of the gateway.
>   port: ""
>
> ingress:
>   enabled: false
>
> # Extra environment variables for the gateway container
> extraEnv: []
> #  - name: LOG_LEVEL
> #    value: debug
> #  - name: MY_SECRET
> #    valueFrom:
> #      secretKeyRef:
> #        name: my-secret
> #        key: my-key
>
> # Load environment variables from Secrets or ConfigMaps
> extraEnvFrom: []
> #  - secretRef:
> #      name: my-secret
> #  - configMapRef:
> #      name: my-configmap
>
> # Extra arguments appended to the gateway container command
> extraArgs: []
> #  - --log-level=debug
>
> # Additional volumes to attach to the gateway pod
> extraVolumes: []
> #  - name: gcp-service-account-key
> #    secret:
> #      secretName: gcp-service-account-key
>
> # Additional volume mounts for the gateway container
> extraVolumeMounts: []
> #  - name: gcp-service-account-key
> #    mountPath: /var/secrets/gcp
> #    readOnly: true
>
> # Extra Kubernetes manifests to deploy with this chart
> extraObjects: []
> ```


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