fix(skills-guard): stop flagging benign skill content + honor skill ignore files - #36231
Merged
Conversation
Contributor
🔎 Lint report:
|
teknium1
force-pushed
the
hermes/hermes-22cdaeeb
branch
from
June 1, 2026 04:21
5934b3a to
c1dd910
Compare
…gnore files
The skill security scanner blocked legitimate community skills on three
intrinsic false-positive patterns:
- read_secrets_file matched `cat > file.env <<` heredocs (writing the
user's own keys into their own local .env), not just `cat file.env`
reads. Exclude output redirections.
- allowed-tools frontmatter is REQUIRED by the agent-skill spec; every
compliant skill declares it. Drop from HIGH privilege_escalation to a
LOW informational finding so it no longer drives the verdict.
- python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads
as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated
CRITICAL python_environ_get_secret pattern so secret-named reads
(OPENAI_API_KEY etc.) are still caught.
Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore
(gitignore-style) so dev/docs artifacts shipped in a skill root are excluded
from both structural checks and pattern scanning. SKILL.md is never ignorable.
80 tests pass (64 existing + 16 new).
teknium1
force-pushed
the
hermes/hermes-22cdaeeb
branch
from
June 1, 2026 08:39
c1dd910 to
c134fe1
Compare
Contributor
|
goat emoji. Thanks @teknium1 ! |
SuperInstance
pushed a commit
to SuperInstance/hermes-construct
that referenced
this pull request
Jun 1, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
alt-glitch
pushed a commit
that referenced
this pull request
Jun 14, 2026
…gnore files (#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
kossteg
pushed a commit
to kossteg/hermes-agent
that referenced
this pull request
Jun 16, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
T02200059
pushed a commit
to T02200059/hermes-agent
that referenced
this pull request
Jun 18, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
xyshanren
pushed a commit
to xyshanren/hermes-agent-cn
that referenced
this pull request
Jun 25, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
waefrebeorn
pushed a commit
to waefrebeorn/slermes
that referenced
this pull request
Jul 2, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
santhreal
pushed a commit
to santhreal/hermes-agent
that referenced
this pull request
Jul 13, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
donbowman
pushed a commit
to donbowman/hermes-agent
that referenced
this pull request
Jul 13, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
Gravezzz
pushed a commit
to Gravezzz/hermes-agent
that referenced
this pull request
Jul 21, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
leewenjie
pushed a commit
to leewenjie/hermes-agent
that referenced
this pull request
Aug 7, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
melon-xf
added a commit
to melon-xf/hermes-agent
that referenced
this pull request
Sep 3, 2026
…gnore files (NousResearch#36231) The skill security scanner blocked legitimate community skills on three intrinsic false-positive patterns: - read_secrets_file matched `cat > file.env <<` heredocs (writing the user's own keys into their own local .env), not just `cat file.env` reads. Exclude output redirections. - allowed-tools frontmatter is REQUIRED by the agent-skill spec; every compliant skill declares it. Drop from HIGH privilege_escalation to a LOW informational finding so it no longer drives the verdict. - python_os_environ flagged `os.environ.get("CONFIG_VAR")` config reads as HIGH exfiltration. Exempt non-secret `.get()` reads; add a dedicated CRITICAL python_environ_get_secret pattern so secret-named reads (OPENAI_API_KEY etc.) are still caught. Also: scan_skill() now honors a skill-provided .skillignore / .clawhubignore (gitignore-style) so dev/docs artifacts shipped in a skill root are excluded from both structural checks and pattern scanning. SKILL.md is never ignorable. 80 tests pass (64 existing + 16 new).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The skill security scanner now stops flagging three classes of benign, intrinsic skill content, and honors a skill-provided
.skillignore/.clawhubignore. This unblocks legitimate community skills that were previously hard-blocked on false positives.Reported via mvanhorn/last30days-skill#464 — the scanner returned DANGEROUS with
--forceunable to override, on patterns that every compliant skill trips.Changes
tools/skills_guard.py—read_secrets_file: excludecat > file.env <<output redirections (a setup doc writing the user's own keys into their own local.envis the opposite of exfiltration); onlycat file.envreads are flagged.tools/skills_guard.py—allowed_tools_field: dropped HIGH → LOW.allowed-tools:is REQUIRED SKILL.md frontmatter per the agent-skill spec; flagging it as privilege escalation made every compliant skill caution/dangerous. Kept as an informational finding for auditability; it no longer drives the verdict.tools/skills_guard.py—python_os_environ: exemptos.environ.get("NONSECRET")config reads (the common, benign form). Added a dedicated CRITICALpython_environ_get_secretpattern so secret-named reads (OPENAI_API_KEY,GITHUB_TOKEN, …) are still caught — no coverage regression.tools/skills_guard.py—scan_skill()now reads a skill's.skillignore(Hermes-native) or.clawhubignore(ClawHub compat), gitignore-style, and excludes matching paths from BOTH structural checks and pattern scanning. The ignore files are always excluded;SKILL.mdcan never be excluded.tests/tools/test_skills_guard.py— 16 new tests covering each fix (positive + negative cases) and the ignore matcher.Validation
tests/tools/test_skills_guard.pycat > x.env <<heredoccat x.envreadallowed-tools:frontmatteros.environ.get("CONFIG_DIR")os.environ.get("API_KEY")dict(os.environ)bare dumpScope note (honest)
These fixes are a scanner-quality win across all community skills, but they do not flip last30days-skill itself to installable. E2E scan of the actual install target (
skills/last30days/, old vs new code) showed the verdict stays DANGEROUS: it genuinely contains 7 secret-named env reads (OPENAI_API_KEY,GITHUB_TOKEN,SCRAPE_CREATORS_API_KEY), vendored JS readingprocess.env[key],os.environ.copy(), and a 15MB skill dir. The author's.clawhubignorelives at the repo root, not the installed skill subdir, so it never entered the install scan to begin with. A real unblock for that skill needs a trust/attested-source path (separate work) or author-side secret-handling changes — not a looser scanner.Reported-by: @kylehagler (mvanhorn/last30days-skill#464)
Infographic