Skip to main content
terma setup normally signs you in through your browser. A machine with no one to sign in, such as a CI runner or a VM created for each agent session, signs in with a team server key instead. Setup reads the key from TERMA_API_KEY and never opens a browser.

Create an Ingest only key

1

Open the team's API keys

In Terma, open Team settings → API keys for the team the machine reports to.
2

Create the key

Enter a name, for example ci-runners, keep Ingest only selected, and select Create key.
3

Copy it into your secret store

Copy the key now: the panel doesn’t show it again. Select Copy key and store it where the machine reads its secrets, such as a CI secret or the VM’s start-up configuration, before you select Done.
An Ingest only key can send telemetry into its team but cannot read the team’s sessions or metrics (what each key can do). Use one: setup keeps the key on the machine, where anything running there can use it. Setup warns when a key can also read or write the team’s data. Revoking a key cuts off every machine that uses it, so give each pool of machines, such as one CI fleet, its own key.

Run setup with the key

Setup sets up the key’s own team, so there is no organization or team to choose. --org and --team accept only that organization’s and team’s ids. --yes and --harness skip the agent picker: name the agents installed on the machine, claude, codex, or both. Setup then works as it does for a person: it fetches the team’s collection policy, points your agents at the local relay, and writes their machine-wide hooks. In its summary, Signed in names the key by its first characters, for example server key ter_srv_3f9a…, and Server key says where the key is kept.
On a VM created for each session, run setup as part of the VM’s start-up, before any coding agent starts. An agent that was already running keeps the configuration it started with. Don’t run setup while building the VM image or container: every copy made from it would carry the key, in plain text where there is no keychain, and rotating it would mean a rebuild. On a machine with no per-user service manager, as in many containers and VMs, add --relay-service off: the relay then starts when an agent needs it, and setup doesn’t warn that it couldn’t install the background service.

After setup

Setup keeps the key as the team’s key, so your agents’ hooks, the relay, and terma doctor need no TERMA_API_KEY afterwards. The relay keeps the team’s collection policy current with the key, as it would with a person’s sign-in. Pass the key to setup alone, for example as an environment variable of the setup step only. While TERMA_API_KEY stays set, terma uses it as given instead of the key it kept: terma doctor reports using TERMA_API_KEY, and terma teardown --sign-out refuses. Clear it for those commands; an empty value counts as unset. Only terma setup needs the key again: --sign-out stops the key being the machine’s sign-in, and --yes skips the confirmation, which a machine with no terminal can’t answer. The key stays stored on the machine and keeps working until you revoke it in Team settings → API keys. Signing out is not enough before you run code you don’t trust on the machine: revoke the key. Server-key setup creates no key or sign-in in Terma, so a per-session VM you destroy needs no teardown first. Sign-out is for a machine you keep.

Where the key is kept

Setup keeps the key in the system keychain. On a machine with no usable keychain, which is common on CI runners and minimal VMs, it keeps the key in plain text in keys.json in terma’s configuration directory (~/.config/terma by default, %APPDATA%\terma on Windows), readable only by you, and its summary names the file. --insecure-storage chooses the file up front. Setup checks that TERMA_API_KEY holds a team server key before sending it anywhere, so a personal token set there by mistake never leaves the machine. The key is sent only to the Terma host it was set up against.

When setup refuses

Check it

terma doctor’s signed in check names the key, for example server key ter_srv_3f9a… in <organization>. It fails when the machine was set up with a server key but no longer holds one for the team, or when the key was set up against a different Terma host. Either way the fix it names is TERMA_API_KEY=<the team's server key> terma setup. Run doctor with TERMA_API_KEY cleared: while it is set, the check reports using TERMA_API_KEY and doesn’t look at the kept key.

Next step

terma doctor

Check the whole chain end to end.