Multi-tenant runner platform for Kubernetes
Self-hosted GitHub Actions with zero idle compute¶
An Actions Runner Controller (ARC) alternative for multi-tenant Kubernetes: zero idle compute, zero guessed resources — and jobs disrupted by the cluster re-run themselves. Workers are right-sized from measured usage, critical jobs keep scheduling even on a full cluster, and tenants self-manage runners under quotas that are safe to enforce.
Get started Watch the demo Why GAG? View on GitHub
Drop-in for your existing setup — jobs target the same runner labels, so nothing in your .github/workflows changes.
helm install gag \
oci://ghcr.io/actions-gateway/charts/actions-gateway \
--version 1.3.0 \
--namespace gmc-system --create-namespace \
--set gmc.image.digest=sha256:<gmc> \
--set agc.image.digest=sha256:<agc> \
--set proxy.image.digest=sha256:<proxy> \
--set wrapper.image.digest=sha256:<wrapper>
# v2 API (recommended): apply the signed, pre-rendered CRDs
kubectl apply --server-side -f \
https://github.com/actions-gateway/github-actions-gateway/releases/download/v1.3.0/actions-gateway-crds-v2.yaml
What GAG gives you¶
Most of these ladder up to one outcome — lower cost: no idle GPUs, fewer always-on resources, and guaranteed throughput instead of blocked critical jobs. Estimate your savings vs ARC → · See every feature →
-
Tenant self-service under quotas
Quotas you can safely enforce:
- Platform-owned quota cap
- Blocked jobs auto-recover
- Zero manual reruns
- Self-serve
ActionsGatewayCRs — no platform ticket per change
-
No blocked critical jobs
Reserve capacity for key runners:
- Reserve N slots per runner type
- CPU tests can't starve GPU jobs
- Critical tests always schedule
-
No idle GPUs
Pods live only for the job:
- Created on acquire
- Deleted on completion
- GPU freed the instant a job ends
- Scale-to-zero by default
-
Isolated egress IPs
Each tenant's own proxy pool:
- Allow-list runners on GitHub Enterprise Managed Users (EMU)
- No shared cluster allow-list
- Flagged tenants stay isolated
- v2: proxy optional
-
Lower listener overhead
Listeners are goroutines, not pods:
- ~12 KiB per listener session
- One shared pod per tenant
- 1 pod vs 10 always-on pods for ten groups
-
Per-tenant observability
Scoped visibility, no cluster access:
- Prometheus per tenant + group
- Grafana dashboards + alerts, as code
- Job counts in
kubectl get - K8s Events on job transitions
- Cross-tenant fleet rollups for platform admins
-
Shared runner templates v2
Define once, reference by name:
RunnerTemplateper many sets- Platform
ClusterRunnerTemplate - Identical templates collapse
- Migrate v1→v2 with
gag-migrate
-
Secure by default
Hardening reconciled by default:
baselinePod Security Admission (PSA) per namespace- Default-deny NetworkPolicies
- Credentials never in env vars
- Signed images + Software Bill of Materials (SBOM) + SLSA
- Kata micro-VM workers, proven in our own CI
-
Right-size from measured usage v2
No more guessed
resources:- Per-job usage peaks sampled
- Recommendations in
RunnerSetstatus - Opt-in profiles auto-apply at pod build
SizingDriftwarns; GPUs never touched
Who GAG is for¶
GAG targets a specific audience: teams that must self-host runners and run them for many tenants on one cluster. If that's you, here's the value per segment.
-
Platform & developer-experience teams
Multi-tenant CI on a shared cluster:
- Enforce a per-team quota without stranding jobs
- Tenants self-serve from one
ActionsGateway - No ticket queue for every runner change
-
Orgs that must self-host
Driven by a hard constraint, not preference:
- Compliance or data-residency requirements
- EMU or firewalled-service IP allow-lists
- Per-tenant egress IPs you allow-list directly
-
GPU / ML platform teams
Done paying for accelerators between jobs:
- Workers scale to zero — no idle GPU
- GPU nodes return to the scheduler on completion
- Priority tiers keep critical GPU jobs scheduling
Not your setup? If you're happy running on a vendor's infrastructure, a managed-SaaS runner is the better fit. GAG competes with Actions Runner Controller (ARC) for self-hosted, multi-tenant clusters — not on raw build speed.
How it fits together¶
A four-tier system: a cluster-scoped manager gives each tenant an isolated gateway from its ActionsGateway. Jobs are acquired with the same single-acquirer runner-scale-set protocol ARC uses — the shipped default — so GAG is a strict superset of ARC's model, not a different-architecture trade-off.
Read the architecture overview for the full breakdown, jump to why GAG over ARC, browse every feature, or see the public roadmap for what's next.