Features¶
Everything GitHub Actions Gateway (GAG) does today, with a link to the doc that explains each one. For the argument against Actions Runner Controller (ARC), see Why GAG?; for what is not here yet, see the roadmap.
Two badges appear below: v2 marks a capability
available only in the actions-gateway.com/v2beta1 API, and
beta marks one whose API shape is still
under its first stability contract.
Check the version you're running
Use the version selector at the top of the page to switch between the
latest stable release
(the default) and dev, the unreleased main branch. A capability listed
under dev but not under a numbered release has not shipped in a tagged
chart yet.
Job intake and recovery¶
- Runner-scale-set acquisition — the same single-acquirer protocol ARC uses, with no many-acquirers fan-out. The default in v2.
- Quota-aware intake — a job the namespace
ResourceQuotahas no room for is never taken on, so it stays queued at GitHub until there is capacity. - Auto re-run for disrupted jobs — a worker lost to eviction, preemption, a node drain, or a bare
kubectl delete podhas its run re-run automatically, under a per-run budget. - Capacity gate for unplaceable workers — opt-in: stop claiming jobs while the cluster cannot place the worker shape, instead of claiming and cancelling them. Off by default.
- Priority tiers per runner set — reserve a guaranteed floor of slots for expensive runner types so cheap CPU jobs cannot starve critical GPU work.
- Worker scale-up rate limiting — opt-in token bucket capping how fast workers start, distinct from the count ceiling, to smooth cold-start stampedes on shared egress.
- Scale-to-zero workers — worker pods exist only while a job runs; listeners are ~12 KiB goroutines in one shared pod, not a listener pod per runner group.
- Unmodified upstream runner images — the wrapper is injected into each worker pod at runtime — an OCI image volume on Kubernetes 1.33+, an initContainer below — so the stock
actions/runnerimage, or any derivative, runs with no rebuild.
Capacity, cost, and right-sizing¶
- Measured worker right-sizing v2 beta — per-job CPU/memory peaks sampled and turned into recommended
requests/limitsinRunnerSetstatus, with an advisorySizingDriftcondition. - Sizing profiles v2 beta — opt-in
Binpack,Throughput, andNodeShareprofiles apply the measurement at pod-build time, with clamps, a confidence fallback, and GPUs never touched. - Managed AGC right-sizing v2 beta — opt-in
agcAutoscalingstamps aVerticalPodAutoscalernext to a gateway's AGC so requests track observed usage; explicitagcResourcesbecome the floor and ceiling, and a missing VPA install degrades to an advisory condition. ResourceQuotasizing guide — turn runner shapes and concurrency ceilings into the quota numbers a platform admin sets, including what the quota actually counts.- Per-tenant cost attribution — map tenant namespaces and
app.kubernetes.io/*labels to OpenCost/Kubecost allocation queries for real dollars per tenant. - Savings calculator — the interactive cost model behind the ARC comparison.
- Node shutdown budgets — how much shutdown time GKE, EKS, AKS, RKE2, Kubespray, and OpenShift actually grant, and why proxy pools stay off spot capacity.
Tenant isolation and egress¶
- Per-tenant egress IPs — a dedicated proxy pool per tenant gives each team its own GitHub egress IPs to allow-list, with a contained blast radius.
- Standalone
EgressProxyv2 beta — the proxy becomes its own object, optionally shared, or omitted entirely for direct — stillNetworkPolicy-restricted — egress. - FQDN egress policy — express GitHub egress by hostname instead of CIDR on Cilium, Calico, or GKE Dataplane V2.
- Auto-refreshed GitHub egress rules — the GMC re-reads GitHub's published IP ranges every 24 hours into each tenant's
NetworkPolicy, and anEgressRulesStalecondition — with a paging alert — fires when the refresh stalls past its window. - Bring your own proxy autoscaler v2 beta —
managedAutoscaling: falsehands the proxy pool to KEDA, VPA, or a custom HorizontalPodAutoscaler. - Service mesh coexistence — run alongside Istio, Linkerd, or ambient mode with injection opt-out and egress exclusions that keep the per-tenant proxy honored.
- One resource per tenant — a single
ActionsGatewayprovisions an isolated controller, proxy pool, RBAC, and network policies inside the platform-owned quota.
Security posture¶
- Secure-by-default hardening — Pod Security Admission per namespace, default-deny NetworkPolicies, and credentials kept out of environment variables, all reconciled rather than opt-in.
- Kata micro-VM workers — validated on nested virtualization, and the default for GAG's own end-to-end CI, which builds a
kindcluster inside an unprivileged worker pod. - In-runner image builds — a decision table mapping BuildKit rootless, Kaniko, Sysbox, Kata, and privileged Docker-in-Docker to the right
securityProfileand PSA level. - Signed images, SBOM, and SLSA provenance — every published image is keyless-signed and carries a Software Bill of Materials (SBOM) attestation.
- Admission policy compatibility — a Kyverno/Gatekeeper matrix covering whether GAG pods comply with common cluster policies, plus sample enforce and exception policies.
- Optional CONNECT destination allow-listing — defense in depth, off by default: an opted-in proxy refuses a CONNECT outside the permitted set and counts each refusal as an alertable Server-Side Request Forgery (SSRF) signal. The mandatory default-deny NetworkPolicy stays the primary gate.
- Self-confining controller privileges — shipped
ValidatingAdmissionPolicyguards deny the GMC's own cluster-wide writes outside admin-marked tenant namespaces, so a compromised manager cannot touchkube-systemor any unmarked namespace. - Restart-free platform allowlists — grow the PriorityClass and egress-destination allowlists by editing a watched
PriorityClassAllowlistCR or ConfigMap, no GMC restart; a missing or invalid object fails safe back to the flag baseline. - Credential redaction in logs — every GitHub response body passes one sanitizer that strips tokens, JWTs, and JIT configs before it can reach a log line, at every log level.
- Abuse detection and response — the threat model's abuse heuristics mapped to operator alerts, with compromise-response playbooks.
- Workload-identity credentials v2 beta — mint short-lived GitHub credentials through an external signer so the GitHub App private key never enters the cluster.
Observability¶
- Metrics reference — every Prometheus metric the GMC, AGC, and proxy export, scoped per tenant and runner group.
- Fleet rollups for platform admins — cross-tenant degraded, egress-stale, and quota gauges in a single pane.
- Scraping setup — wiring the mutual-TLS metrics endpoints into your Prometheus.
- Alerting and SLOs — ready-to-apply alert rules as code.
- Grafana dashboards — a tenant dashboard and a platform dashboard, both as code.
- Logging and tracing — structured logs and OpenTelemetry tracing across the four tiers.
Install and day-2 operations¶
- Helm install — the OCI chart, digest pinning, healthy-install verification, and a
scripts/e2e/validate-cluster.shpre-flight that fails loudly on a network-policy-less CNI. - Highly available manager — the GMC installs as two replicas with leader election, a
PodDisruptionBudget, and anti-co-location spread by default, releasing its lease on shutdown so failover takes seconds rather than a lease timeout. - Air-gapped install — relocate images and the OCI chart to a private registry with digests preserved, including pull Secrets for the runtime pods.
- GitOps install — declarative Argo CD
Applicationand FluxHelmReleaseexamples, with the CRD-pruning gotcha handled. - Upgrade and rollback — versioned upgrade procedures and the rollback path for each release.
- Backup and restore — backup posture and a recovery runbook, with a Velero-specific how-to.
- Troubleshooting — symptom to diagnosis to remediation, organised by observable failure mode.
- Production runbook — the operational procedures an on-call SRE needs.
- P2P image distribution — add a Spegel or Dragonfly mirror to survive ephemeral-worker pull storms.
API surface and migration¶
- The v2 API v2 beta — the recommended shape for new tenants: a decomposed
ActionsGateway+RunnerSet+RunnerTemplate, withv2beta1as the graduated storage and hub version. - Reusable runner templates v2 beta — one
RunnerTemplatereferenced by many runner sets, or a cluster-wideClusterRunnerTemplateshared across namespaces. - Multiple gateways per namespace v2 beta — scoped gateways coexist, each with its own GitHub binding and runner sets.
- GitHub Enterprise Server gateways — a gateway whose
gitHubURLnames a GHES appliance addresses that appliance on every GitHub surface, with aGitHubEgressIncompletecondition flagging an incomplete CIDR allow-list. Untested against a real GHES appliance. - GHES behind a private CA v2 —
spec.githubCABundleRefnames a ConfigMap whose CA bundle is added to the trust of both the gateway's AGC and its worker pods, never replacing the system roots. Untested against a real GHES appliance. gag-migrate— a one-shot fan-out that moves a tenant offv1alpha1without changing how jobs are acquired: dry-run, review, apply.- Deprecations and the
v2.0.0removal — whatv2.0.0removes, what keeps working until then, and the pre-upgrade checklist. - Migrating from ARC — concept mapping, behavioral differences, and a worked zero-downtime migration of one runner group.
- Getting started — first-time GitHub App setup, the v2 object set, and credential rotation. There is also a recorded demo of one real job on a local kind cluster.