fix(skills): vendor the support files the vendored skills point at
The vendored SKILL.md files were byte-identical to upstream, but the playbooks, templates and schemas they reference were left behind in the original repos, so a loading skill pointed at a file that does not exist anywhere in this repository. Vendored 1:1 into each skill directory (so they survive `cp -r skills/* ~/.hermes/skills/`): - plays/ for api-security-review, code-review-security, sca-audit, secrets-scan, web-security-review (OWASP/secure-agent-playbook) - templates/finding.md for the four OWASP skills that cite it - schemas/finding.schema.json for cve-triage, patch-prioritization, dependency-scanning (UnitOneAI/SecuritySkills) - docs/sarif-output.md, docs/fixer-policy.md and docs/normalized-json-output.md for dependency-scanning Path fixes, the only edit to vendored text: - the three UnitOneAI skills referenced ../../../schemas/ and ../../../docs/ which assumed upstream's skills/<category>/<skill>/ depth; this repo is flat, so the links now resolve inside the skill directory - safedeps told the agent to run <skill_dir>/../../check_deps.py while the script is vendored next to SKILL.md; corrected to <skill_dir>/check_deps.py and documented the script's exit codes (1 = finding, not a crash) - NOTICE.md records the new files, the path edits, and the remaining known gaps (hermaguard's kensei-pipeline references, the ASVS dataset citations, and hermaguard being behind upstream) Verified: every backticked path in every SKILL.md now resolves; check_deps.py runs from the installed location and returns live OSV.dev data ([email protected] -> 2 advisories); hermaguard's 46 tests still pass.
This commit is contained in:
1 parent
eba8bb1d94
commit
bb3fe21766
20 files changed
+4156
-11
No files matched your search
@@ -415,7 +415,7 @@ When triaging multiple CVEs (e.g., from a scan report), produce a summary table
|
||||
- **Blind spots:** This skill depends on available code, configuration, logs, documentation, and user-provided context; it cannot prove controls exist or threats are absent when evidence is missing, runtime-only, or outside the review scope.
|
||||
- **False-positive risks:** Treat findings as hypotheses until validated against asset criticality, compensating controls, environment intent, and recent authorized changes.
|
||||
- **Required evidence:** Support each finding with concrete artifacts such as file paths and line numbers, policy snippets, scanner output, logs, screenshots, control records, or reproducible steps.
|
||||
- **Normalized JSON:** When machine-readable output is requested, findings MUST be available as JSON that validates against [`schemas/finding.schema.json`](../../../schemas/finding.schema.json).
|
||||
- **Normalized JSON:** When machine-readable output is requested, findings MUST be available as JSON that validates against [`schemas/finding.schema.json`](schemas/finding.schema.json).
|
||||
- **Escalation rules:** Escalate immediately for suspected active compromise, exposed secrets, regulated-data exposure, critical exploitable vulnerabilities, privileged-access abuse, or when evidence is insufficient to safely disposition a high-impact risk.
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://github.com/UnitOneAI/SecuritySkills/schemas/finding.schema.json",
|
||||
"title": "SecuritySkills Normalized Finding Output",
|
||||
"description": "Machine-readable envelope for normalized security findings and remediation recommendations emitted by SecuritySkills workflows. This contract is independent of SARIF and may be mapped to downstream enterprise formats later.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["schema_version", "run", "skill", "findings"],
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": "1.0.0",
|
||||
"description": "Version of this normalized SecuritySkills finding envelope."
|
||||
},
|
||||
"run": {
|
||||
"$ref": "#/$defs/run",
|
||||
"description": "Metadata for the analysis run that produced this output."
|
||||
},
|
||||
"skill": {
|
||||
"$ref": "#/$defs/skill",
|
||||
"description": "Metadata for the SecuritySkills entrypoint that produced this output."
|
||||
},
|
||||
"findings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/finding"
|
||||
},
|
||||
"description": "Normalized findings produced by a skill run."
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"riskLevel": {
|
||||
"type": "string",
|
||||
"enum": ["low", "medium", "high"]
|
||||
},
|
||||
"nonEmptyString": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"uriString": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"run": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "timestamp"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Stable run identifier supplied by the agent, CI job, or enterprise orchestrator."
|
||||
},
|
||||
"timestamp": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "ISO 8601 timestamp for when the run output was produced."
|
||||
},
|
||||
"tool": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Agent, CLI, scanner, or workflow that executed the skill."
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Repository, project, service, artifact, environment, or other target reviewed."
|
||||
},
|
||||
"source_ref": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Optional commit SHA, branch, image digest, build ID, ticket ID, or evidence package reference."
|
||||
}
|
||||
}
|
||||
},
|
||||
"skill": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "version"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "SecuritySkills skill name from SKILL.md frontmatter."
|
||||
},
|
||||
"version": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "SecuritySkills skill version from SKILL.md frontmatter."
|
||||
},
|
||||
"path": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Path to the SKILL.md entrypoint used for the run."
|
||||
},
|
||||
"frameworks": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"description": "Framework identifiers declared by the skill frontmatter."
|
||||
}
|
||||
}
|
||||
},
|
||||
"finding": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "title", "severity", "status", "evidence", "remediations"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Stable finding identifier within the output."
|
||||
},
|
||||
"fingerprint": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Stable deduplication key based on finding type, affected asset, and evidence location."
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"description": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "What the issue is and why it matters."
|
||||
},
|
||||
"severity": {
|
||||
"type": "string",
|
||||
"enum": ["info", "low", "medium", "high", "critical"]
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["open", "mitigated", "accepted_risk", "false_positive"]
|
||||
},
|
||||
"cwe": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^CWE-[0-9]+$"
|
||||
},
|
||||
"description": "Optional CWE mappings, when applicable."
|
||||
},
|
||||
"framework_refs": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/frameworkRef"
|
||||
},
|
||||
"description": "Framework/control references from the skill frontmatter frameworks."
|
||||
},
|
||||
"references": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/reference"
|
||||
},
|
||||
"description": "Optional advisory, standard, vendor, or knowledge-base references."
|
||||
},
|
||||
"evidence": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["location", "summary"],
|
||||
"properties": {
|
||||
"location": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "File path, line range, asset ID, log source, policy path, or other concrete evidence location."
|
||||
},
|
||||
"summary": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"artifact_type": {
|
||||
"type": "string",
|
||||
"enum": ["source", "config", "policy", "log", "scan_result", "cloud_resource", "identity", "network", "document", "other"]
|
||||
},
|
||||
"snippet": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Minimal redacted snippet or observation needed to support the finding."
|
||||
},
|
||||
"redacted": {
|
||||
"type": "boolean",
|
||||
"description": "True when sensitive values were intentionally removed from this evidence."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediations": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/remediation"
|
||||
},
|
||||
"description": "Every fix recommendation for this finding. Each item must include remediation guidance, confidence, blast radius, behavior-change risk, and test strategy."
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
"required": ["cwe"]
|
||||
},
|
||||
{
|
||||
"required": ["framework_refs"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"frameworkRef": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["framework", "control"],
|
||||
"properties": {
|
||||
"framework": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"control": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"name": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
}
|
||||
}
|
||||
},
|
||||
"reference": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["type", "id"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["cve", "cwe", "framework", "advisory", "vendor", "documentation", "other"]
|
||||
},
|
||||
"id": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"url": {
|
||||
"$ref": "#/$defs/uriString"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remediation": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["guidance", "confidence", "blast_radius", "behavior_change_risk", "test_strategy"],
|
||||
"properties": {
|
||||
"guidance": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Concrete remediation steps or patch guidance for the finding."
|
||||
},
|
||||
"confidence": {
|
||||
"$ref": "#/$defs/riskLevel",
|
||||
"description": "How confident the skill is that this recommendation is correct for the observed evidence."
|
||||
},
|
||||
"blast_radius": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Expected scope of systems, files, users, integrations, data, or workflows affected by the change."
|
||||
},
|
||||
"behavior_change_risk": {
|
||||
"$ref": "#/$defs/riskLevel",
|
||||
"description": "Risk that the remediation changes intended application or operational behavior."
|
||||
},
|
||||
"test_strategy": {
|
||||
"$ref": "#/$defs/testStrategy",
|
||||
"description": "Required validation strategy proving the remediation fixes the finding. Include recommended tests, generated tests, or both."
|
||||
}
|
||||
}
|
||||
},
|
||||
"testStrategy": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["summary"],
|
||||
"properties": {
|
||||
"summary": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Concise explanation of what proves the remediation fixed the issue."
|
||||
},
|
||||
"recommended_tests": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/recommendedTest"
|
||||
},
|
||||
"description": "Tests the user or agent should run when tests are not generated directly."
|
||||
},
|
||||
"generated_tests": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "#/$defs/generatedTest"
|
||||
},
|
||||
"description": "Test files or cases produced as part of the remediation."
|
||||
}
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
"required": ["recommended_tests"]
|
||||
},
|
||||
{
|
||||
"required": ["generated_tests"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"recommendedTest": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["name", "type", "purpose", "command", "expected_result"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["static", "unit", "integration", "e2e", "regression", "manual"]
|
||||
},
|
||||
"purpose": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Behavior, vulnerability condition, or regression this test proves."
|
||||
},
|
||||
"command": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Command or manual check to execute for this test."
|
||||
},
|
||||
"expected_result": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
}
|
||||
}
|
||||
},
|
||||
"generatedTest": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "type", "purpose", "command", "expected_result"],
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Path to the generated or modified test file."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["static", "unit", "integration", "e2e", "regression"]
|
||||
},
|
||||
"purpose": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Behavior, vulnerability condition, or regression this generated test proves."
|
||||
},
|
||||
"command": {
|
||||
"$ref": "#/$defs/nonEmptyString",
|
||||
"description": "Command that runs the generated test."
|
||||
},
|
||||
"expected_result": {
|
||||
"$ref": "#/$defs/nonEmptyString"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user