The cloud maintainer is multi-tenant by construction. Every team brings its own Claude subscription, its own GitHub App install, and its own Secret Manager partition — and team_id is derived server-side from a signed request, so no team can ever act as another. Isolation isn't a promise here; it's an oracle that kills 6/6 attacks.
There is no shared Claude key and no shared repo token. The bot only ever holds what you hand it, in a partition keyed to your team.
Run claude setup-token, then rr connect POSTs the credential write-only into your team's Secret Manager partition. The maintainer fixes issues with your tokens — you pay your own usage, no shared key.
Install the App on only the repos you choose. rr connect registers the installation id; the bot's token is scoped so it can push only to heimdall/* branches — it cannot touch main or branch protection.
Your team_id is derived server-side from your Ed25519 signature — you never send it. Your cred lives in a secret named for your team, injected per-execution, and there is no cross-team enumeration path.
The enroll token is a one-time bootstrap credential, not a signing key. Your admin hands it out over a trusted channel; a teammate turns it into their own signed identity in three commands.
rr at the control planerr setup --mode control-plane --endpoint <endpoint> --enroll-token <enroll-token>The endpoint + enroll token come from your admin. The token bootstraps enrollment and is then spent — it never becomes your key.
heimdall-presence beatGenerates your local Ed25519 keypair and enrolls it. Your team membership is now bound to your public key — the server derives team_id from your signature on every request.
rr connect --gh-app-installation-id <id> --repo <owner/repo>Registers your Claude credential and GitHub App install for the team. Now rr "<task>" from any terminal reaches the maintainer.
The public surface is rate-, budget-, and registry-capped by construction — so opening enrollment is a knob, not a risk.
HEIMDALL_ENROLL_OPEN for tokenless self-serve — the caps below stay load-bearing either way.HEIMDALL_ENROLL_MAX_KEYS, default 1000) and per-team members (HEIMDALL_TEAM_MAX_MEMBERS).HEIMDALL_RR_TEAM_BUDGET_TOKENS (default 600,000) and a per-team daily spend cap — one team can't burn the plane./rr-task is capped per-IP (default 60) and per-team (default 30); per-team dispatch drain is bounded per window.{nonce, ts} — a captured request cannot be replayed, and a post-signature tamper fails verification.The presence roster is private by the team secret — the secret is the boundary, and only its holders can see each other. On your first run a solo team is auto-minted for you, so presence is never repo-public by default. And it's opt-out to the bone.
heimdall-presence off hides you in this repo; off --global is a machine-wide kill switch. OFF means invisible, not blind — you still see the wall; the team can't see you.heimdall-presence on --no-files keeps you present but sends file:null — handle and verdict only. Presence never carries file contents or code; --no-files withholds the filename too.Beyond the maintainer, Heimdall keeps a private presence roster — mint a team secret in your browser, and watch who's online, their HAID, and the verdict the watchman just gave them. Only holders of the secret can see each other.
A strong random team secret — it defines a private presence team. Same shape as the server's secrets.token_urlsafe(32) — 43 base64url characters. Generated locally; it is never transmitted from this page.
click generate — a fresh team secret appears here
This is your team secret. It is what teammates use to join the presence team and to see each other — anyone holding it can read the team's private roster (HAID + activity). Share it only with teammates, over a trusted channel. Treat it like a password.
curl -fsSL https://raw.githubusercontent.com/randomittin/heimdall/v2.0.16/install.sh \
| HEIMDALL_CP_URL='https://heimdall-cp-public-eqfrs7sfuq-uc.a.run.app' \
HEIMDALL_TEAM_SECRET='<generate a team secret above>' bash
Paste your team secret and project id to see your teammates — who's online right now, their HAID, and their latest verdict. Private: only holders of the team secret can see each other. The secret is sent in a request header, never in the URL. Refreshes every 15s.