denofy.yml
Allow individual security findings with a reason — all fields, matching rules and examples.
Some packages legitimately do things the scanner flags: a release skill passes $GITHUB_TOKEN
to gh, an installer skill downloads an official binary. Instead of rewriting the package, you can
allow these findings in denofy.yml (or denofy.yaml) in the package root — with a reason
everybody can read.
# denofy.yml
allow:
- rule: env-secret
file: scripts/release.sh
match: GITHUB_TOKEN
reason: Passed to `gh release create` only; never printed or uploaded.
- rule: pipe-to-shell
file: SKILL.md
line: 42
reason: Official installer of the tool; the README tells users to verify the checksum.What an exception does#
- The finding stays in the verification report, marked allowed by author together with your reason. Users see it on the package page and in the CLI before installing.
- An allowed finding never fails a package. It counts as a warning at most, so a package with allowed medium/high/critical findings shows Warning, not Verified.
- Exceptions only apply to the package they are in, and only to findings they match.
- Rules that have no legitimate use cannot be allowed:
invisible-unicode,unicode-tag-smuggling.
Fields#
allow is a list of up to 50 entries. Every entry needs rule and reason; the other fields
narrow down which findings it covers. All given fields must match.
| Field | Required | Type | Matches when … |
|---|---|---|---|
rule | yes | string | the finding's rule id is exactly this (see all rules). * is not allowed. |
reason | yes | string | — at least 10 characters, shown publicly (max 500). |
file | no | string | the finding's file equals this path or glob (* within a folder, ** across folders, ?). |
line | no | integer | the finding is on this line. |
match | no | string | the finding's excerpt contains this text (case-insensitive). |
fingerprint | no | string | the finding has exactly this fingerprint (from the report; stable across versions). |
Prefer file + match over line: line numbers change with every edit, matches usually don't.
Validation#
denofy.yml itself is checked on every import. Problems show up as a Warning check
allowlist.invalid in the report:
- invalid YAML, or
allowis not a list - an entry without
rule, withrule: "*", or with a reason shorter than 10 characters - an entry for a rule that cannot be allowed
- more than 50 entries (only the first 50 are used)
Entries that matched nothing are reported as allowlist.unused, so stale exceptions do not pile up.
Findings inside denofy.yml itself are never allowed and are always informational.
Examples#
A release script that needs a token#
allow:
- rule: env-secret
file: scripts/*.sh
match: GITHUB_TOKEN
reason: The token is passed to the GitHub CLI for creating the release, nothing else.Documentation that explains a dangerous pattern#
Prose and negations are already lowered automatically (see context rules), so you rarely need an exception for documentation. If you do:
allow:
- rule: prompt-injection
file: reference/attacks.md
reason: Reference list of injection phrases the skill teaches the agent to recognise.A pinned installer#
allow:
- rule: pipe-to-shell
file: SKILL.md
match: get.example-tool.dev
reason: Official installer, version pinned in the URL and checksum verified in CI.Prefer fixing over allowing#
Before adding an exception, check if the package can avoid the pattern: pin a version and verify a checksum instead of piping to a shell, read only the one variable you need instead of dumping the environment, link to a file instead of embedding a large Base64 blob. Packages without exceptions can get the Verified badge; packages with them cannot.