Access and keys
Who can act on your site, and the keys your site, your builds and your backends use: what each allows, where it lives, how to replace it, and what a leak would allow.
Add and remove people
A site has one owner, the person whose sign-in created it with npx routingcat init, and the members the owner adds.
- Add a member by email: under People in the site’s settings on the dashboard, or with
npx routingcat members add ana@lumen.so. This sends that address an invitation, unless it already has a RoutingCat account, and access starts at that person’s next sign-in with that verified address. - Remove one under People too, or with
npx routingcat members remove ana@lumen.so. Access ends at once. - Members can do everything but manage people, keys, domains, the link to your GitHub repository and the plan the site is on, which stay the owner’s alone, so no member can open the site to others or change what it pays. The plan is the owner’s, for every site they own: a member sees it, and the site’s own visitors, never the owner’s other sites. The owner can’t be removed.
$ routingcat memberspantry · members theo@pantry.app owner active since 2026-07-08 ana@pantry.app member active since 2026-07-08 sam@pantry.app member pending added 2026-10-10, until their first sign-inRoutingCat’s support joins your site only when you add it as a member. RoutingCat’s operators act on a site they don’t belong to only to contain an incident, by turning routing off, blocking ingestion or revoking a credential, or to archive the site when its owner asks. Each such act is recorded, and npx routingcat status --since <date> lists it.
Keep each key where it belongs
| Key | Allows | Lives in | Replace it with |
|---|---|---|---|
Public key, pk_… |
Naming the site, and sending the page’s records and events, accepted only from your site’s domains and rate-limited. It writes and never reads. | routingcat.config.json, and the head partial every page includes |
Nothing: it is public, one per site |
Server events key, sk_… |
Writing events and identity links for one environment, and nothing else | The secrets of your server and other backends, or a PostHog destination | npx routingcat keys server --rotate |
Deploy key, dk_… |
What npx routingcat push does in your CI or your host’s deploy script: registering your templates, which a push on your production branch makes live |
Your CI’s secrets, or your host’s deploy environment, as ROUTINGCAT_DEPLOY_KEY, where no linked GitHub repository proves the run |
npx routingcat keys deploy --rotate --branch <production branch>, or --env preview --rotate; --revoke stops it at once |
| Your sign-in | What your role allows on your sites, and registering production from your machine with npx routingcat push --env production, once you confirm its plan |
Your machine’s keychain | npx routingcat logout revokes it |
- A linked GitHub repository needs no secret. Once
npx routingcat link githubhas linked your site, a workflow run proves itself with GitHub’s own token, its job givenpermissions: id-token: write. GitHub Actions without the link, Cloudflare’s builds, Netlify and Vercel push with the deploy key; without a CI, your sign-in registers production once you confirm the plan. A push with none of them registers nothing. - One server key per environment.
--env previewgives the preview key, whose events stay out of results, which count production only.doctorflags the preview key used in production. - The deploy key shows once.
npx routingcat keys servershows the server key whenever the owner asks, but the deploy key shows only when it is minted or rotated, so store it then. - The production deploy key is bound to your production branch, given as
--branch: it proves production only where your CI reports that branch, so another branch’s runs never register production with it, even with the key in their variables. - A rotated key keeps working for 24 hours, time to put its replacement in place.
Know what a leaked key allows
None of these keys reads your results, members or keys: only a person does, as their role allows.
- The public key: nothing beyond what any visitor’s browser can do. What a browser sends is a report anyone can forge, which is why an objective worth defending comes from a server.
- The server events key: false conversions and identity links in its environment, and no reads. Anyone who can open your PostHog project’s destinations can read a key that a destination holds. Rotate it.
- The deploy key: registering declarations in your site’s name, which could change which of your deployed variants are live, and writing false records. Revoke the environment’s deploy keys at once, the one its last rotation replaced included, with
npx routingcat keys deploy --env <env> --revoke, then mint another.
Decide which domains send browser events
RoutingCat accepts browser calls only from your site’s domains, checked against each call’s Origin, else its Referer:
- your production domain and its subdomains, from the hosts
routingcat.config.jsonlists, registered with each production push; - the domains the owner adds, for your pages on another registrable domain:
npx routingcat domains add lumen.app.
Sign in on a machine
- Run
npx routingcat login, or letinitdo it. It prints a link and tries to open your browser. - Sign in on that page, then allow the command on this machine.
- The command waits 50 seconds. If you approve later, it exits with code 3: run the same command again, and it continues.
The credential is kept in the machine’s keychain, else in a file only your user can read, and it renews itself, so a new agent conversation needs no new sign-in. The command acts as you, with your role on each site. npx routingcat logout revokes the credential and deletes it.
A coding agent’s sandbox may be unable to keep the command’s credential, or to reach RoutingCat: Troubleshooting gives the fix for each.