Secret Guardrails
How Mate keeps secrets out of agent context, indexes, and companion artifacts.
Mate keeps secret files and secret values away from the agents it runs. The guardrails are on by default and layered, so no single missed rule lets a secret through. One switch in the companion config turns them all off.
Secret Files
A path is a secret file when it matches a deny pattern and no allow pattern. An allow match always wins. Patterns use gitignore syntax: a pattern without a slash matches the file name at any depth.
| Default deny patterns | Default allow patterns |
|---|---|
.env, .env.* | .env.example |
*.pem, *.key, *.p12, *.pfx | .env.sample |
id_rsa, id_ecdsa, id_ed25519 | .env.template |
.netrc, .pgpass, .npmrc | .env.dist |
.npmrc is on the list because it often holds a registry _authToken. npm
itself still reads it; only agents are kept out.
The Layers
| Layer | What it does | Picks up a config change |
|---|---|---|
| Guidance | Injects a secret-handling rule: never read, print, copy, or write secrets; read only the example files; refer to a secret by its variable name. | Next session |
| Hook and middleware | Blocks Read, Write, Edit, MultiEdit, NotebookEdit, and patch calls on a secret file, content searches (Grep) in a secret file or with a glob aimed at one, and shell commands that name one, in Claude Code and OpenCode. | Next tool call |
| Companion content scan | Scans what an agent writes into the Companion Repository with secretlint’s recommended preset and blocks the write on a finding or a scanner error. | Next tool call |
| Projected deny rules | Adds Read/Edit deny rules for the default secret files to Mate’s managed Claude permissions.deny list (Claude’s Edit rule also covers Write) and read/edit rules to OpenCode’s permissions. | Next launch or mate wrap |
| Indexer exclusion | Excludes secret files from TokenSave’s .tokensave/config.json and from a Mate-managed region of .graphifyignore. | Next setup or mate cap index |
| Graphify gate | Before every extraction, including ones an agent runs through the graphify wrapper, rewrites the .graphifyignore region and passes the secret patterns as --exclude. Afterwards it removes any secret that still reached the output and keeps the rest. It never stops graphify. | Every extraction |
| Publish scan | mate artifact publish scans the files it would commit and stops at a secret-scan step on a finding. | Every publish |
Refusals name the path and, for content findings, the line and rule id. They never print the secret itself.
Only agent tool calls and Mate’s own commands are guarded. Your shell, your
editor, and your Git are not. A shell command that reaches a secret without
naming it, such as env or an unscoped grep -r, is covered by the guidance
rule only.
Configuration
Add a secrets block to the companion’s .mate/config/framework.yaml. Every
field is optional.
secrets:
guardrails: true # false turns every layer off
deny: ["config/master.key.enc"] # added to the defaults
allow: [".env.test"] # added to the defaults; an allow match wins- Extra
denyandallowpatterns add to the defaults; they never replace them. - Extra
denypatterns are enforced by the hook, the middleware, and the indexers. They are not projected into Claude or OpenCode deny rules. - A missing or unparseable
framework.yamlkeeps the guardrails on with the defaults. A broken config never disables protection.
For a documented fake key in an artifact, wrap it in secretlint’s inline comments instead of turning the guardrails off:
<!-- secretlint-disable -->
AKIA... (example only)
<!-- secretlint-enable -->