Skip to content

Secrets

A task’s driver log is shipped to the server, where anyone in the organisation can read it with gritz logs and in the Web UI, long after the sandbox is gone. Credentials that reach that log would be stored with it. Declare them in the workspace’s secrets: map and gritz keeps them out of the shipped copy:

workspaces:
pets-workshop:
secrets:
GH_TOKEN: ${sh:gh auth token}
commands:
- git clone https://x-access-token:${GH_TOKEN}@github.com/private/repo.git
  • Each entry becomes an environment variable in the sandbox, exactly like a container.environment entry, for the setup commands and the agent. Values go through the same ${env:}/${sh:} expansion on the runner. To protect a credential that is in environment: today, move it to secrets:; nothing else about it changes.
  • Secrets work the same on every backend. They travel to the driver with each run, not in the sandbox’s own config, so a sandbox reused for a later run never holds stale values.
  • In the log shipped to the server, every occurrence of a declared value is replaced by [gritz:masked NAME], such as [gritz:masked GH_TOKEN]. That includes values echoed by a setup command’s output, set -x traces or an env dump.
  • The task’s own token, GRITZ_TOKEN, is masked the same way, as [gritz:masked token].

Reference secrets from commands: by variable, as ${GH_TOKEN}. The runner only expands ${namespace:value}, so it leaves ${GH_TOKEN} for the sandbox’s shell to expand when the command runs. The command line the driver logs then carries the name rather than the value.

Writing ${env:GH_TOKEN} in a command would put the value into the command line itself. The mask still catches it, but the name is the clearer record.

Where Masked
The log shipped to the server: gritz logs and the Web UI Yes
/gritz/log inside the sandbox No
The sandbox’s stderr (docker logs) No

The raw copies stay inside the boundary the secrets already live in: anyone who can read them can read the sandbox’s environment too. Full fidelity there is what makes post-mortems with gritz shell useful.

gritz doesn’t detect credentials: it masks exactly the values you declare.

  • An undeclared credential ships unmasked.
  • A secret that another tool shortens before it reaches the log, such as a long value cut off in a tool-call summary, arrives as a fragment the mask can’t match.
  • A value that is encoded on its way to the log, such as base64 in an HTTP header dump, no longer matches the declared value.

Masking matches the longest declared value at each position, so a secret that is a prefix of another can’t leave part of the longer one exposed. A value split across two writes to the log is still masked.