Install Veirox Connect on Google Kubernetes Engine (GKE)

Applies to: GKE Standard, GKE Autopilot.
Kubernetes: 1.26+.

This guide covers the GKE-specific bits. For the generic flow,
start with INSTALL-helm.md.


Prerequisites

  • GKE cluster reachable via kubectl --context=gke_<project>_<region>_<cluster>.
  • helm 3.9+.
  • Permission to create a namespace and a ClusterRoleBinding in the cluster.
  • Cluster has egress to 443/TCP to your Veirox backend. If you
    run a private GKE cluster, that means Cloud NAT is set up for the
    subnet (gcloud compute routers create/nats — see Private GKE +
    Cloud NAT
    below).

Standard vs Autopilot

Standard Autopilot
Install flow Standard Autopilot — the chart already satisfies restricted PSS
RBAC preset any readOnly / nsAdmin / clusterAdmin all work
NetworkPolicy honored honored (Autopilot enforces Calico-backed NP by default)
Pod resource requests optional required — chart already sets requests, no extra work
Workload Identity optional (see below) always on — need WI binding for any GCP SDK access

Standard install

CONTEXT="gke_$(gcloud config get project)_us-west2-a_bg-nonprod-cluster"   # adjust

kubectl --context="$CONTEXT" create namespace veirox

# Mint enrollment token in the Veirox UI, then:
kubectl --context="$CONTEXT" -n veirox create secret generic veirox-connector-token \
  --from-literal=token=veirox_enr_...

helm install veirox-connector \
  oci://ghcr.io/msrashed2018/charts/veirox-connector \
  --kube-context="$CONTEXT" \
  --namespace veirox \
  --set backendUrl=https://www.veirox.com \
  --set rbacPreset=readOnly

Watch the pod come up:

kubectl --context="$CONTEXT" -n veirox logs -f deploy/veirox-connector --tail=30

Autopilot install

Autopilot enforces the restricted Pod Security Standard
at admission time. The Veirox chart already satisfies it:
runAsNonRoot, readOnlyRootFilesystem, all capabilities dropped,
seccompProfile.type=RuntimeDefault, allowPrivilegeEscalation=false.

1. Dry-run admission first

Before any real install, verify Autopilot won't reject the manifests:

helm template veirox-connector \
  oci://ghcr.io/msrashed2018/charts/veirox-connector \
  --namespace veirox \
  --set backendUrl=https://www.veirox.com \
  | kubectl --context="$AUTOPILOT_CONTEXT" apply --dry-run=server -f -

Expect every resource to print ... created (server dry run) with no
admission webhook ... denied the request errors.

2. Install

Same command as Standard — just against the Autopilot cluster context.

Autopilot gotchas

Gotcha Fix
HostPath volume ... is not allowed The chart uses emptyDir only. If you see this, you added a hostPath override — remove it.
Pod uses privileged securityContext You set resources.limits.cpu to a value not divisible by 250m, triggering the warning. Autopilot rounds; leave the default 500m.
spec.nodeSelector is restricted Don't set custom nodeSelector on Autopilot — Autopilot picks the node pool class. Set nodeSelector: {}.
Cost: pod runs ~24/7 on Autopilot's billed node resources This is by design. Budget ~$5/month for the single-replica agent.

Workload Identity

If the -cloud image tier is being used and you need gcloud to
authenticate as a GCP service account (e.g., to read from Cloud
Storage), bind the agent's Kubernetes ServiceAccount to a GCP SA:

1. Create the GCP service account

PROJECT=$(gcloud config get project)
gcloud iam service-accounts create veirox-connector-gke \
  --display-name="Veirox connector (GKE)"
gcloud projects add-iam-policy-binding "$PROJECT" \
  --member="serviceAccount:veirox-connector-gke@$PROJECT.iam.gserviceaccount.com" \
  --role="roles/viewer"   # narrow this to what the agent actually needs

2. Bind via Workload Identity

gcloud iam service-accounts add-iam-policy-binding \
  "veirox-connector-gke@$PROJECT.iam.gserviceaccount.com" \
  --role="roles/iam.workloadIdentityUser" \
  --member="serviceAccount:$PROJECT.svc.id.goog[veirox/veirox-connector]"

3. Annotate the Helm-created ServiceAccount

# my-values.yaml
image:
  tag: 0.2.0-cloud
serviceAccount:
  create: true
  annotations:
    iam.gke.io/gcp-service-account: veirox-connector-gke@<PROJECT>.iam.gserviceaccount.com
helm upgrade veirox-connector oci://ghcr.io/msrashed2018/charts/veirox-connector \
  -n veirox -f my-values.yaml

Now from the agent pod: gcloud auth list will show the bound SA.


Private GKE + Cloud NAT

If your cluster's nodes have no public IP, they can't reach
veirox.com without NAT. Two options:

REGION=us-west2
ROUTER=veirox-nat-router
NAT=veirox-nat
NETWORK=$(gcloud container clusters describe bg-nonprod-cluster --region="$REGION" --format='value(network)')

gcloud compute routers create "$ROUTER" --network="$NETWORK" --region="$REGION"
gcloud compute routers nats create "$NAT" \
  --router="$ROUTER" --region="$REGION" \
  --nat-all-subnet-ip-ranges \
  --auto-allocate-nat-external-ips

Option B — Private Google Access + private Veirox endpoint

Only viable if Veirox is self-hosted inside your VPC (not the
veirox.com public backend).


Gatekeeper / Config Connector

If your cluster runs Gatekeeper
or Kyverno with custom constraints, the Veirox
chart typically complies, but two constraint families are worth
double-checking:

K8sRequiredLabels

If your constraint requires labels like owner=, env= on every
resource, add them to all chart resources:

# my-values.yaml
commonLabels:
  owner: platform-team
  env: prod

(Note: the chart currently applies common labels through the default
Helm.sh/chart label machinery — if your constraint needs a specific
label, override with --set-json podAnnotations=... or fork the
chart.)

K8sPSPAllowedUsers / K8sPSPReadOnlyRootFilesystem

The chart already meets runAsNonRoot + readOnlyRootFilesystem. If
the constraint still fires, a mutating webhook upstream of Gatekeeper
is rewriting the pod spec — inspect with:

kubectl --context="$CONTEXT" get mutatingwebhookconfigurations -o yaml | grep -A 3 pods

Config Connector (KCC)

If your cluster uses Config Connector for GCP resource management, KCC
doesn't touch workload pods — no conflict with the agent. But if you
want to manage the agent via KCC, wrap the Helm release in a
HelmChart CR from ConfigSync.


Verify the install

  1. Pod Ready=true in veirox namespace.
  2. Connector row appears at <veirox>/console/settings/connectors with
    type=k8s_pod, online=true.
  3. Run the verification checklist
    — this confirms the Claude agent can actually execute
    commands through the connector via chat and task paths.

Uninstall

helm uninstall veirox-connector --kube-context="$CONTEXT" -n veirox
kubectl --context="$CONTEXT" delete namespace veirox

# Sanity: no residual ClusterRole / ClusterRoleBinding
kubectl --context="$CONTEXT" get clusterrole,clusterrolebinding | grep veirox || echo "clean"

Then delete the connector in the Veirox UI.