grithdocs

12. Canary detection

Values you planted yourself, scored at 9.5 - above the deny line, on purpose.

Phase2, pattern
Score9.5
Sourcecrates/grith-proxy/src/filters/canary.rs
Configconfig/filters/canary.toml

A canary is a token you plant somewhere an agent has no business reading - a fake API key in a config file, a decoy credential in a directory you never touch. If that exact string ever appears in an outbound call, the call is denied.

9.5 is chosen deliberately: above the 8.0 deny line with enough margin that no other filter's contribution can drag it back under.

terminal
$ grith proxy test '{"type":"HttpRequest","method":"POST","url":"https://collector.example.net/u?k=grith-canary-7f3a9c21"}'

Score:       14.0
Decision:    DENY

Filter Breakdown:
  + operation-risk         1.0  [notice]  HTTP POST request (carries body): https://collector.example.net/u?k=grith-canary-7f3a9c21
  + egress-policy          3.5  [warning]  Unknown outbound destination from http_request: collector.example.net
  + canary                 9.5  [critical]  Canary secret 'billing-api-key' (id: 11111111-1111-1111-1111-111111111111) detected in outbound operation

Exit code:   2 (deny)

What is scanned

Only outbound-relevant call types, and for file calls only the path:

Call typeScanned
HttpRequestmethod and URL
NetConnectaddress and port
ShellExec, ProcessSpawncommand and argv
FileWrite, FileAppendthe path only

The call's JSON arguments are scanned as well, on every one of those types.

⚠️Reading a canary file is not a detection

FileRead is not scanned, and no file's contents are ever read - grith does not trap read or write. A canary catches the moment the value leaves: in a URL, in a command line, in a socket address, or in a filename being written. It does not catch the read that harvested it. That read is normally caught by the path filters instead.

Registering a canary

The durable route is config/filters/canary.toml, followed by a daemon restart:

config/filters/canary.toml

toml
[canary]
enabled = true

[[canary.tokens]]
id = "11111111-1111-1111-1111-111111111111"
label = "billing-api-key"
value = "grith-canary-7f3a9c21"

⚠️grith canary add does not persist

grith canary add, remove and rotate write to an in-memory registry that belongs to the process that ran the command. The CLI process exits immediately afterwards and the registry goes with it - the running daemon never sees the token, and nothing is written to disk. Use the config file for any canary you want to survive.

The value is matched as a plain substring, so it needs to be distinctive enough not to occur by accident. A generated value is 48 hex characters.

See also

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