Skip to content

One hangar for a team: the team release

One hangar for a team of six. What the four waves add and what you configure; then what changes as soon as it starts, the steps (1–8, 9–11, 12–14 and rolling back). Every release is listed on release notes.

The short version, in order:

hangar admin backup                                   # 1. back up; record the running image; the vault key in Secret Manager
#                                                       2. request quotas (days ahead; N2 too for a heavy pool)
uv run hangar images build --registry "$REG"          # 3. prebuild the new image and pack tags
#                                                       4. in the power-down window: terraform apply (node pool, power
#                                                          schedule; optional: the heavy pool, the Docker Hub remote repo)
bash deploy/gke/power.sh up && bash deploy/gke/up.sh  # 5. bring the cluster up, roll out
hangar doctor && hangar status                        # 6. check
hangar cred migration                                 # 7. people: your logins became yours; add team API keys
hangar person add alice
hangar config set HANGAR_JOB_BUDGET_MAX_COST_USD 10   # 8. budgets (yours to choose; jobs run on balanced), then concurrency
hangar doctor --fix                                   # 9. front doors: the pull_request event; then the App, Jira, Projects
hangar config set HANGAR_EGRESS_URL http://hangar-gateway.hangar.svc:3128   # 10. sandboxes: egress, mirrors, cloud, previews,
#                                                       the heavy tier, build caches, test results
hangar config set HANGAR_MODEL_LIST_CREDENTIALS '{"anthropic": "anthropic-models"}'   # 11. models, the canary, env setup,
#                                                       the sister tool's interfaces
hangar admin doctor run --dry-run                     # 12. operations: the Cloud Doctor, the console, the vault key
#                                                       13. deploy.yml: the production environment and its secrets
bash scripts/acceptance/gke.sh --no-kubectl           # 14. clients and proof: docs/acceptance.md, in its order

What you configure

Everything the owner sets up, in the order of the steps. Required means the release, or the feature named, doesn't work without it; optional means it is off (or keeps its old behaviour) until you set it. hangar config set NAME VALUE keeps a setting in hangar's database; hangar-site wins over it.

What Required? Step
The vault key in Secret Manager (hangar-vault-key), copied from the hangar Secret, never to a laptop Required on GKE before step 5 (a backup can't be restored without it, and rotation reads it from there) 1
HANGAR_BACKUP_STORE: a bucket of its own, write-only for hangar's service account (roles/storage.objectCreator), with a lifecycle rule Optional (backups stay beside the checkpoints; hangar doctor warns) 1
Quotas: N2D_CPUS ≥ 160, CPUS_ALL_REGIONS, SSD_TOTAL_GB ≥ 2,250 Required on GKE 2
Quotas for the heavy pool: N2_CPUS ≥ 128 (4 × n2-standard-32) on top of the Kata pool's, and 2,000 GB more SSD_TOTAL_GB Optional; required for the heavy tier on GKE 2
Images workflow secrets (GCP_WORKLOAD_IDENTITY_PROVIDER, GCP_SERVICE_ACCOUNT, HANGAR_REGISTRY, repository secrets) Optional: without them, prebuild by hand 3
terraform apply: the n2d-standard-16 node pool, power_up_cron 09:50, sandbox_warm_nodes, hangar's roles/run.invoker on the power-up job Required on GKE 4
terraform apply with enable_heavy_pool = true (and heavy_machine_type, heavy_max_nodes, heavy_spot, heavy_disk_gb): the sandboxes-heavy pool and its hangar-heavy-nodes service account Optional; required for the heavy tier on GKE 4
terraform apply with enable_dockerhub_mirror = true (dockerhub_username, dockerhub_token_secret): the Artifact Registry remote repository for Docker Hub Optional (heavy sandboxes pull from Docker Hub, rate-limited, or HANGAR_HEAVY_REGISTRY_MIRRORS) 4
HANGAR_POWER_UP_JOB Set by up.sh; required for hangar power up 5
Team credentials: API keys (hangar cred add NAME --team --kind api_key). A subscription login is refused as one Required for work no person owns (webhooks, schedules without a person, unlinked senders) 7
People, their tokens and linked GitHub, Slack and Jira accounts Optional (required for a team) 7
HANGAR_BUDGET_DAY_TIMEZONE, HANGAR_JOB_BUDGET_MAX_COST_USD, HANGAR_PERSON_MAX_USD_PER_DAY, repo max_usd_per_day Optional; required before raising HANGAR_JOB_CONCURRENCY. hangar sets no amount: jobs default to balanced, uncapped, and hangar doctor warns (model spend) until one is set 8
The webhook's pull_request event (hangar doctor --fix) Required 9a
GitHub App: github_app credential and HANGAR_GITHUB_APP_CREDENTIAL Optional; required for landing 9b
Branch protection (1 approval, dismiss stale approvals, approval of the latest push, required checks) and Allow auto-merge Required on every repo with land: auto_after_approval: without stale dismissal hangar doesn't arm and hangar doctor fails (opt out per repo: --no-require-stale-dismissal) 9b
Repo policy land, approvers, merge_method, risk_paths Optional (landing is off by default) 9b
Jira: an account and API token (jira-api), the webhook and its secret (jira-webhook) or an Automation token, HANGAR_JIRA Optional 9c
GitHub Projects: an organization webhook (Projects v2 items), the control token's project scope, HANGAR_GITHUB_PROJECTS Optional 9d
The control token's organization Webhooks: Read and write (classic: admin:org_hook) Optional: without it, missed Projects deliveries aren't redelivered (a warning) 9d
HANGAR_EGRESS_URL Required on GKE before any environment uses egress: allowlist or none 10a
HANGAR_EGRESS_DEFAULT Optional (default open for people's own work, as before; intake jobs get an allowlist floor regardless) 10a
HANGAR_GATEWAY_URL and HANGAR_EGRESS_URL (both now set in deploy/k8s/config.yaml); HANGAR_INTAKE_POSTURE=warn on v0.2.0 only Required for jobs from GitHub, Slack, Jira, GitHub Projects and webhooks: the default posture enforce refuses them without the gateway (#123) 10a
GKE: Artifact Registry remote repositories for PyPI and npm (Go stays on the public proxy), roles/artifactregistry.reader for hangar's service account, and HANGAR_PACKAGE_MIRRORS Optional (the mirror reads the public registries by default) 10a
presets: [packages, github] on proxied credential_mode: direct environments that clone from GitHub Required for them: packages no longer includes github 10a
GitHub App: Actions, Checks and Issues: Read Optional: the read-only API through the gateway asks for them 10a
cloud.lifetime_minutes at most 60 Required for environments that set more (they no longer load) 10b
HANGAR_OIDC_KEY_ROTATION_DAYS Optional (off) 10b
Computer environments: rebuild their images Required for their browsers in proxied environments (Chromium's ECH policy) 10a
Docker hosts: Docker Engine ≥ 26.0.0 (or 25.0.4, 23.0.11), and the host firewall accepting TCP 3128 and 8788 from hangar1 Required for proxied environments on Docker 10a
HANGAR_OIDC_ISSUER (https; public for AWS), and the cloud's trust (a GCP workload identity pool, an AWS role) Optional; required for environments with cloud: 10b
Build secrets: build_secrets on an environment or repo policy Optional; required for repos whose .hangar/environment.yaml names any 10c
HANGAR_ENV_SERVICE_IMAGES Optional (Docker's official images by default) 10c
HANGAR_PREVIEW_DOMAIN, its wildcard DNS and certificate, and deploy/k8s/preview-network.yaml's NetworkPolicy Optional (previews are off) 10d
HANGAR_PR_MEDIA_LINKS=signed Optional (screenshots and demos are listed by name) 10e
The heavy tier: HANGAR_TIERS heavy (["kubernetes"] or ["e2b"]), kata-deploy on the heavy pool (KATA=1 up.sh), HANGAR_HEAVY_RUNTIME_CLASS, HANGAR_HEAVY_NODE_SELECTOR Optional (the tier is off; heavy environments fail to start, saying so); required for Docker in sandboxes and the large/xlarge profiles 10f
On a cluster with GKE's Agent Sandbox add-on: the open-source controller instead, or the heavy tier on microVMs Required for the heavy tier there (the add-on's policy refuses privileged Kata pods) 10f
Repo policy heavy: allow (or on) per repo, profile, max_profile Optional; required for a repo whose .hangar/environment.yaml asks for Docker: it is deny by default 10f
HANGAR_HEAVY_MIRROR and HANGAR_HEAVY_MIRROR_UPSTREAM (terraform output dockerhub_mirror), HANGAR_HEAVY_REGISTRY_MIRRORS Optional (off) 10f
HANGAR_HEAVY_PERSON_MAX, HANGAR_HEAVY_WARM_POOLS, HANGAR_HEAVY_DOCKER_IMAGE Optional (3 large, 1 xlarge per person and for unattributed work together; no heavy warm pools; docker:29.8.2-dind) 10f
HANGAR_HEAVY_DOCKER_PRIVILEGED Optional, Docker provider only, for CI and throwaway machines (root on the host) 10f
Build caches: HANGAR_GATEWAY_URL Required for caches (sandboxes reach /cache on the gateway with its grant; without it nothing is cached) 10g
A cache bucket of its own: HANGAR_BUILD_CACHE_STORE=gs://…, with roles/storage.objectAdmin on it for hangar's service account Optional (the session bucket's caches/ prefix, which hangar can already write) 10g
HANGAR_BUILD_CACHE_MAX_GB, _REPO_MAX_GB, _RETENTION_DAYS, _PRIVATE_DAYS, _PRIVATE_WRITES, _TRANSFER_MB, _WAIT_MINUTES Optional (100 GB in a bucket, 20 GB a repo, 14 and 3 days, private writes on, 256 MB, 10 min) 10g
HANGAR_TEST_REPORTS; repo policy verify_reports and rerun_flaky Optional (inject; reports at the usual paths; no reruns) 10h
HANGAR_TRACE_LIVE_TOOLS, HANGAR_EXPERIMENT_MAX_TRIALS, HANGAR_EXPERIMENT_PARALLEL Optional (off, 200, 8) 11d
Model list keys: HANGAR_MODEL_LIST_CREDENTIALS (webhook credentials holding Anthropic, OpenAI and Gemini API keys, kept from sandboxes) Optional: without them, balanced and frontier resolve to hangar's built-in ids (OpenRouter's list needs no key). Env setup now lists models with these, not with the team's harness keys 11a
Harness canary, on hangar's own repository: branch protection on main (required approval, contract as a required check) and Allow auto-merge Required before the first bump PR can land (without required approvals auto-merge would need none) 11b
Harness canary: repository secrets CANARY_APP_CLIENT_ID and CANARY_APP_PRIVATE_KEY (a dedicated App, Contents and Pull requests: Read and write); variable CANARY_APPROVERS Optional; the App is required for checks to run on the bump PR by themselves and for images to run on its merge 11b
Env setup: HANGAR_ENV_SETUP_MODELS, HANGAR_ENV_SETUP_MAX_COST_USD / _MAX_TURNS, HANGAR_ENV_SETUP_LABEL Optional (defaults: balanced, $30 and 16 turns, hangar-env-setup) 11c
The Cloud Doctor: a team API key for its harness (Claude Code unless HANGAR_DOCTOR_HARNESS) Optional: without one the doctor only reports, never starts a job 12a
HANGAR_DOCTOR_SPECS_REPO (and HANGAR_DOCTOR_SPECS_PATHS): the repo holding environment specs as files Optional: without it, fixes to environment specs are reported, not opened as PRs 12a
HANGAR_DOCTOR_MODEL Optional (balanced); frontier for the strongest, or best for that on a team key that may lack Fable access 12a
HANGAR_DOCTOR_MAX_USD, HANGAR_DOCTOR_JOB_MAX_USD, HANGAR_DOCTOR_SCHEDULE Optional ($10 a run, $3 a job, 00:30; off turns it off) 12a
A new vault key in Secret Manager, then hangar admin rotate-key Optional (rotate on a schedule, when someone who could read it leaves, at once on a leak) 12c
deploy.yml: the production environment (you as required reviewer; main and v* tags only), its secrets GCP_DEPLOY_SERVICE_ACCOUNT, GKE_CLUSTER, GKE_LOCATION, HANGAR_URL, HANGAR_DEPLOY_TOKEN, and the hangar-deploy service account and Role Optional; required to deploy with deploy.yml 13
claude.ai users re-add the hangar connector Required for claude.ai 14
Acceptance fixtures: a test repo (App installed, Allow auto-merge, branch protection with code owners), an approver account's classic repo token, a fixture repo, a Jira project mapped to the test repo; deploy.yml's HANGAR_ACCEPT_TEST_REPO, HANGAR_ACCEPT_FIXTURE_REPO (variables), HANGAR_ACCEPT_GITHUB_TOKEN, HANGAR_ACCEPT_APPROVER_TOKEN, HANGAR_ACCEPT_JIRA_WEBHOOK_SECRET (secrets) Optional: each check skips, saying why, without its fixture; required for secrets, landing, envbuild and intake to prove anything 14