Skip to content

Identity Firewall User Guide

Minh Tu Le edited this page Aug 9, 2026 · 2 revisions

Twingate Identity Firewall extends Zero Trust and Privileged Access Management controls to every user, resource, and agent in your organization. It introduces the Twingate Gateway, an open-source Layer 7 reverse proxy deployed within your cluster that terminates Twingate connections, authenticates the user, and propagates their Twingate identity to the upstream, so authorization and auditing at the upstream reflect the real user behind each request.

The operator currently supports two Identity Firewall resource types:

  • Kubernetes - the Gateway impersonates the authenticated user against the Kubernetes API server, so cluster RBAC and audit logs see the real identity.
  • Web App - the Gateway injects the user's identity into HTTP requests (via request header rewrites, e.g. a JWT), so the app can authorize without its own login.

For other protocols and Gateway internals, see the Gateway wiki.

Setup has two phases: deploy a Gateway, then declare the resources it protects.

Deploy a Gateway

The operator does not run the Gateway workload itself; it registers an existing in-cluster Gateway Service with Twingate through a TwingateGateway custom resource. You can let the operator's Helm chart deploy and register a Gateway for you, or deploy the Gateway yourself and wire it up.

Bundled subchart

The simplest path is the operator's bundled gateway subchart. Enabling it deploys the Gateway workload and renders the TwingateGateway and TwingateCertificateAuthority that register it. With kubernetesResource.enabled, it also exposes the in-cluster Kubernetes API server as a TwingateResource (see Kubernetes resources).

In your values.yaml:

gateway:
  enabled: true
  twingateOperator:
    gateway:
      enabled: true
    kubernetesResource:
      enabled: true

The certificate authority is registered with Twingate under a name that has to be unique across your network and is immutable once created. The chart derives it as <release>-gateway-ca-<hash>, hashing the cluster and the release namespace so separate clusters and namespaces do not collide.

Important

The hash is read from the cluster while the chart renders, so it is unavailable wherever rendering has no Kubernetes API access, as with Argo CD, helm template, or --dry-run=client. Rendering fails there, and you have to name the certificate authority yourself.

gateway:
  enabled: true
  twingateOperator:
    gateway:
      enabled: true
      certificateAuthority:
        name: "<a name unique within your Twingate network>"

spec.name on the TwingateCertificateAuthority is immutable, so choose this at install time. An install already running on the derived name cannot be switched to an explicit one without deleting and recreating the certificate authority.

Apply it the same way as any other operator upgrade:

helm upgrade twop oci://ghcr.io/twingate/helmcharts/twingate-operator --install --wait -f ./values.yaml

For end-to-end setup, including installing a Connector and configuring Kubernetes RBAC, see the Gateway wiki's Kubernetes Quick Start Guide. The Gateway wiki also documents Gateway logs and monitoring.

Bring your own Gateway

If you deploy the Gateway workload yourself (the standalone gateway Helm chart or Terraform/manual manifests), register it with the operator using two custom resources.

  1. A TwingateCertificateAuthority pointing at the TLS Secret whose ca.crt the Gateway presents (provisioned by the gateway chart or an external tool; the operator only reads the public certificate):
apiVersion: twingate.com/v1beta
kind: TwingateCertificateAuthority
metadata:
  name: example-ca
spec:
  name: Example Gateway CA
  type: X509
  secretRef:
    name: gateway-tls
  1. A TwingateGateway referencing the Gateway Service and the CA:
apiVersion: twingate.com/v1beta
kind: TwingateGateway
metadata:
  name: my-gateway
spec:
  serviceRef:
    name: my-gateway-svc
    port: 443
  x509CertificateAuthorityRef:
    name: example-ca

The operator resolves the Service address, combines it with the CA, and registers the Gateway with Twingate; it does not deploy the workload.

Multiple gateways

TwingateGateway is namespaced, so you can register as many Gateways as you need. Each resource binds to one by name: gatewayRef on a TwingateResource, or the resource.twingate.com/gatewayName annotation on a Web App Service.

Kubernetes resources

A Kubernetes resource exposes a cluster's API server as a TwingateResource of type: Kubernetes, bound to a Gateway with gatewayRef. There are two ways to create one.

Via the bundled subchart

Setting kubernetesResource.enabled: true (see Bundled subchart) exposes the in-cluster API server (kubernetes.default.svc.cluster.local) as a resource bound to the Gateway the subchart deploys, without a separate manifest. A TwingateResource spec field set under kubernetesResource in your values.yaml passes straight through, so you can set the resource's name, alias, securityPolicyId, and so on. The chart sets type, address, and gatewayRef itself, and adds alias to the SANs of the TLS certificate it generates for the Gateway:

gateway:
  enabled: true
  twingateOperator:
    gateway:
      enabled: true
    kubernetesResource:
      enabled: true
      name: "My cluster"
      alias: cluster.int
      securityPolicyId: "<security policy id>"

As a custom resource

To expose an additional cluster, or to manage the resource independently of the subchart, declare a TwingateResource of type: Kubernetes bound to a Gateway with gatewayRef:

apiVersion: twingate.com/v1beta
kind: TwingateResource
metadata:
  name: my-cluster
spec:
  type: Kubernetes
  name: My Cluster
  address: kubernetes.default.svc.cluster.local
  gatewayRef:
    name: my-gateway

Web App resources

Expose an in-cluster HTTP application as a Twingate Web App: a TwingateResource of type: WebApp bound to a Gateway with gatewayRef. The Gateway injects the authenticated user's identity into requests (via requestHeaderRewrites), so the app authorizes without its own login. There are two ways to create one.

Annotating a Service

Add resource.twingate.com: "true" and resource.twingate.com/type: "WebApp" to the Service, then point it at a Gateway with resource.twingate.com/gatewayName. The operator creates a TwingateResource named <service-name>-resource, owned by the Service.

apiVersion: v1
kind: Service
metadata:
  name: my-web-app
  annotations:
    resource.twingate.com: "true"
    resource.twingate.com/type: "WebApp"
    resource.twingate.com/gatewayName: "example-gateway"
    resource.twingate.com/alias: "webapp.internal"
spec:
  selector:
    app.kubernetes.io/name: MyWebApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
      name: http

The generated resource's address is always <service-name>.<namespace>.svc.cluster.local.

Annotations

Required:

  • resource.twingate.com - set to "true" to manage this Service. Setting it to "false" or removing it deletes the resource.
  • resource.twingate.com/type - must be "WebApp".
  • resource.twingate.com/gatewayName - name of the TwingateGateway protecting this Web App.

Optional:

  • resource.twingate.com/gatewayNamespace - namespace of the Gateway. Defaults to the Service's namespace.
  • resource.twingate.com/downstreamPort - the port clients connect to. Defaults to the Service's port when it exposes exactly one TCP port; required otherwise.
  • resource.twingate.com/upstreamPort - target port. Must match a TCP port the Service exposes. Defaults like downstreamPort.
  • resource.twingate.com/requestHeaderRewrites - JSON object mapping HTTP header names to string values, rewritten on requests to the upstream:
    resource.twingate.com/requestHeaderRewrites: '{"X-Forwarded-Host": "web-app.int", "Host": "example.com"}'
  • resource.twingate.com/alias - the resource's alias (the hostname users access).
  • resource.twingate.com/name - the resource's name in the Twingate Admin Console.
  • resource.twingate.com/isVisible - whether the resource appears in the client dropdown.
  • resource.twingate.com/securityPolicyId - assign a Security Policy.
  • resource.twingate.com/syncLabels - turn off syncing the Service's labels to Twingate as tags.

Annotation values are strings, so quote them (an unquoted true is parsed as a boolean).

As a custom resource

To manage a Web App independently of a Service, declare a TwingateResource of type: WebApp directly. Bind it to a Gateway with gatewayRef, set the client and target ports with downstream and upstream, and add any header rewrites with requestHeaderRewrites:

apiVersion: twingate.com/v1beta
kind: TwingateResource
metadata:
  name: my-web-app
spec:
  type: WebApp
  name: My Internal Dashboard
  address: web-app.default.svc.cluster.local
  alias: web-app.int
  gatewayRef:
    name: my-gateway
  downstream:
    port: 80
  upstream:
    port: 8080
  requestHeaderRewrites:
    - name: X-Forwarded-Host
      value: web-app.int

See also

  • Granting access - a resource is not reachable until you grant a principal access to it.