grithdocs

grith canary

Register decoy credentials the exfiltration filter watches for - and the persistence gap you must know about.

grith canary list
grith canary add --label <LABEL> [--value <V> | --generate]
grith canary remove <ID>
grith canary rotate <ID> [--value <V> | --generate]

Canary tokens are fake credentials. If one ever appears in an outbound call, the canary filter scores 9.5 and the call is denied.

🚨grith canary add does not persist

The registry lives in process memory and has no save path. A token added by the CLI survives exactly as long as that CLI process - the daemon never sees it, and list in the next process shows nothing. This is real behaviour, not a bug in your setup.

terminal
$ grith canary add --label db-password --generate
Added canary:
id:    2c622402-96ed-466b-9deb-a35b45ec8b20
label: db-password
value: 988516b8d5414669bc2c8535e779e677ef636f5fe0c46ad5

$ grith canary list
No canary tokens registered.

How to actually seed a canary

The daemon seeds its registry at start from config/filters/canary.toml, resolved relative to the working directory, then relative to the repository, then from the copy embedded in the binary. There is no ~/.config/grith candidate for this file.

So the durable route is a config/filters/canary.toml in the directory the daemon starts from, and a daemon restart to pick it up. See Filter config files for the format and the load order.

Flags

FlagApplies toNotes
--label <LABEL>addRequired. Human-readable name shown in the decision reason.
--value <V>add, rotateThe exact string to watch for.
--generateadd, rotateGenerate a random 24-byte hex value instead.

rotate keeps the label and replaces the value.

What detection covers

Only outbound-relevant call types: HttpRequest, NetConnect, ShellExec, ProcessSpawn, and the path of FileWrite and FileAppend. Reading a file that contains a canary is not a detection - grith does not inspect file contents.

See also

Last updated: 2026-08-24Edit this page on GitHub →