-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Skills Guard: Official/builtin skills blocked by scan + --force flag doesn't override DANGEROUS verdict #1006
Description
Problem
Two issues with the Skills Guard install flow that prevent installing official optional skills:
1. Official/builtin skills are blocked despite policy allowing them
The INSTALL_POLICY table in tools/skills_guard.py correctly declares that builtin trust level should allow all verdicts including dangerous:
INSTALL_POLICY = {
# safe caution dangerous
"builtin": ("allow", "allow", "allow"),
...
}And _resolve_trust_level() correctly maps official/ sources to "builtin" trust level.
However, should_allow_install() has a hard-coded early return that blocks ALL dangerous verdicts before ever checking the trust-based policy table:
def should_allow_install(result: ScanResult, force: bool = False) -> Tuple[bool, str]:
if result.verdict == "dangerous":
return False, f"Scan verdict is DANGEROUS ({len(result.findings)} findings). Blocked."
# ^ This fires BEFORE the policy table is consulted
policy = INSTALL_POLICY.get(result.trust_level, ...) # Never reached for dangerousThis means the builtin: ("allow", "allow", "allow") row is dead code — it can never take effect for dangerous verdicts.
Reproduction: Try installing official/email/agentmail — it triggers persistence (mentions ~/.hermes/config.yaml) and supply_chain (mentions pip install mcp) patterns, gets classified as DANGEROUS, and is blocked despite being an official skill with builtin trust.
2. --force flag does not override DANGEROUS blocks
The docstring explicitly says "never overrides dangerous" and the code enforces this — force is only checked after the hard dangerous block (line 653), so it can only override caution-level blocks. This means there is literally no way for a user to install a skill flagged as DANGEROUS, even with --force.
Additionally, the /skills install slash command does not parse --yes — only --force is recognized (line 936 of hermes_cli/skills_hub.py). So /skills install ... --yes --force only applies --force, and --yes is silently ignored.
Proposed Fix
Fix 1: Let the policy table handle builtin/official trust decisions
Reorder should_allow_install() so the trust-based policy table is checked before the hard dangerous block. If the policy says "allow", allow it regardless of verdict. This makes the builtin row actually functional.
def should_allow_install(result: ScanResult, force: bool = False) -> Tuple[bool, str]:
policy = INSTALL_POLICY.get(result.trust_level, INSTALL_POLICY["community"])
vi = VERDICT_INDEX.get(result.verdict, 2)
decision = policy[vi]
if decision == "allow":
return True, f"Allowed ({result.trust_level} source, {result.verdict} verdict)"
if force:
return True, f"Force-installed despite {result.verdict} verdict ({len(result.findings)} findings)"
return False, (
f"Blocked ({result.trust_level} source + {result.verdict} verdict, "
f"{len(result.findings)} findings). Use --force to override."
)This way:
- builtin (official) skills: always allowed (policy says allow for all verdicts)
- trusted skills: allowed for safe/caution, blocked for dangerous (overridable with
--force) - community skills: allowed for safe only, blocked for caution/dangerous (overridable with
--force)
Fix 2: --force overrides everything
Remove the hard block on dangerous that prevents --force from working. The revised function above handles this naturally — if the policy says "block", --force overrides it regardless of verdict severity.
Affected Files
tools/skills_guard.py—should_allow_install()(lines 642-669)hermes_cli/skills_hub.py— optional: parse--yesas alias for--forcein slash command (line 936)
Severity
High — Users literally cannot install official optional skills that reference config files or mention pip installs, which is most of them.