diff --git a/.github/workflows/validate-skills.yml b/.github/workflows/validate-skills.yml index c578d5c5..5335ab7c 100644 --- a/.github/workflows/validate-skills.yml +++ b/.github/workflows/validate-skills.yml @@ -4,12 +4,12 @@ on: push: paths: - 'skills/**' - - 'tools/validate-skill.py' + - 'tools/**' - '.github/workflows/validate-skills.yml' pull_request: paths: - 'skills/**' - - 'tools/validate-skill.py' + - 'tools/**' - '.github/workflows/validate-skills.yml' workflow_dispatch: @@ -20,12 +20,47 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install dependencies + run: pip install pyyaml + + # All frontmatter is parsed by tools/skill_frontmatter.py (PyYAML). Any + # reintroduced regex parser silently truncates multi-line descriptions -- + # that bug shipped 604/817 broken descriptions before it was caught. + - name: Guard against hand-rolled YAML parsers + run: | + if grep -rnE '(re\.(search|match|compile)\([^)]*description|^\s*description:.*\(\.\*\))' \ + tools/ --include='*.py' ; then + echo "::error::Regex-based frontmatter parsing detected. Use tools/skill_frontmatter.py." + exit 1 + fi + echo "OK: no regex frontmatter parsers" + # Single source of truth: tools/validate-skill.py validates required # frontmatter fields, kebab-case name, description length, subdomain, and # tag count. (Previously this step duplicated a weaker inline parser.) - name: Validate SKILL.md frontmatter run: python3 tools/validate-skill.py --all + # agentskills.io conformance: name==directory, 1..1024 description, + # reserved-word ban, angle-bracket injection check. + - name: Validate agentskills.io conformance + run: python3 tools/validate-agentskills.py --strict + + # index.json is generated; a PR that changes a description must regenerate it. + - name: Check index.json is current + run: python3 tools/generate-index.py --check + + # Description quality gate. Pre-existing failures are grandfathered in + # tools/lint-baseline.json so this blocks NEW debt only; the baseline is + # allowed to shrink and never to grow. + - name: Lint descriptions + run: python3 tools/lint-descriptions.py --all --stats + + # Ratchet: the number of unreviewed near-duplicate description pairs may + # never increase. Lower this cap as disambiguation lands. + - name: Detect skill collisions + run: python3 tools/detect-collisions.py --max-unreviewed 55 + - name: Check for duplicate skill names run: | python3 << 'EOF' diff --git a/tools/collision-allowlist.json b/tools/collision-allowlist.json new file mode 100644 index 00000000..68ecba78 --- /dev/null +++ b/tools/collision-allowlist.json @@ -0,0 +1,25 @@ +{ + "_comment": [ + "Skill pairs that score as near-duplicates but are legitimately distinct.", + "", + "Add a pair here ONLY after reading both descriptions and confirming a real", + "difference in scope, platform, or offense-vs-defense posture. The 'reason'", + "is not bookkeeping: it is the wording each skill's negative trigger should", + "use, e.g. reason 'Linux vs Windows' becomes 'Do not use for Windows hosts", + "- use hardening-windows-endpoint-with-cis-benchmark.'", + "", + "A pair that is genuinely ambiguous does NOT belong here. Disambiguate the", + "two descriptions instead.", + "", + "Regenerate the candidate list with: python tools/detect-collisions.py" + ], + "reviewed_distinct": [ + { + "pair": [ + "hardening-linux-endpoint-with-cis-benchmark", + "hardening-windows-endpoint-with-cis-benchmark" + ], + "reason": "Same CIS Benchmark methodology, different operating systems. The controls, tooling and audit commands do not overlap, so both must exist; each description must name the OS explicitly and point at the other." + } + ] +} diff --git a/tools/detect-collisions.py b/tools/detect-collisions.py new file mode 100644 index 00000000..bbb46f88 --- /dev/null +++ b/tools/detect-collisions.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +"""Find skill pairs whose descriptions compete for the same user request. + +An agent picks a skill from its description alone. When two descriptions are +near-duplicates, the router cannot reliably choose between them and misroutes +-- "skill collision". This scores every pair by TF-IDF cosine similarity over +description + slug and reports the ones close enough to collide. + +A high score is NOT automatically a defect. Some near-twins are legitimately +distinct (Linux vs Windows CIS hardening; red-team DCSync vs blue-team DCSync +detection). Those belong in tools/collision-allowlist.json with a reason, which +is also a record of WHY they differ -- exactly the wording their negative +triggers need. + +Pure stdlib; no numpy/sklearn required. + +Usage: + python tools/detect-collisions.py + python tools/detect-collisions.py --threshold 0.5 + python tools/detect-collisions.py --json + python tools/detect-collisions.py --max-unreviewed 60 # CI gate +""" +from __future__ import annotations + +import argparse +import itertools +import json +import math +import os +import re +import sys +from collections import Counter + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +from skill_frontmatter import description_of, iter_skill_dirs, load_frontmatter, FrontmatterError + +ALLOWLIST_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), + "collision-allowlist.json") +DEFAULT_THRESHOLD = 0.45 + +# Words too common in this corpus to carry signal. +STOPWORDS = set(""" +the a an and or of to for in on with using use uses used when this that is are be by +from as it its into via at not skill security detect detects detecting analyze analyzes +analyzing perform performs performing implement implements implementing +""".split()) + +# A term appearing in more than this many skills is treated as a domain-wide +# background word and skipped when pairing (keeps the comparison O(usable pairs)). +MAX_DOCS_PER_TERM = 60 + + +# A negative trigger names the sibling skill on purpose ("Do not use for X - +# use other-skill."). Scoring that text would inject the sibling's own slug +# tokens into this skill's vector, so correctly disambiguating a pair would +# RAISE its similarity score -- the metric would punish the fix. Strip the +# disambiguation scaffolding and score only the descriptive part. +DISAMBIGUATION_RE = re.compile(r"\b(?:do\s+not\s+use|don'?t\s+use|avoid\s+(?:this\s+)?(?:skill\s+)?for)\b.*", + re.IGNORECASE | re.DOTALL) +KEYWORDS_LABEL_RE = re.compile(r"\bkeywords\s*:", re.IGNORECASE) + + +def strip_disambiguation(text: str) -> str: + """Drop negative-trigger sentences and the literal 'Keywords:' label. + + The keyword TERMS stay -- they are real content. Only the label is removed, + since it would otherwise be a shared token across every fixed skill. + """ + text = DISAMBIGUATION_RE.sub("", text) + return KEYWORDS_LABEL_RE.sub(" ", text) + + +def tokenize(text: str) -> Counter: + return Counter(w for w in re.findall(r"[a-z0-9]+", text.lower()) + if w not in STOPWORDS and len(w) > 2) + + +def build_vectors(skills_dir: str) -> dict[str, dict[str, float]]: + """L2-normalized TF-IDF vectors keyed by slug.""" + docs: dict[str, Counter] = {} + for slug, skill_dir in iter_skill_dirs(skills_dir): + try: + frontmatter = load_frontmatter(os.path.join(skill_dir, "SKILL.md")) + except FrontmatterError: + continue + described = strip_disambiguation(description_of(frontmatter)) + docs[slug] = tokenize(f"{described} {slug.replace('-', ' ')}") + + doc_freq: Counter = Counter() + for counts in docs.values(): + doc_freq.update(counts.keys()) + + total = len(docs) + vectors: dict[str, dict[str, float]] = {} + for slug, counts in docs.items(): + weights = {term: (1 + math.log(freq)) * math.log(total / doc_freq[term]) + for term, freq in counts.items()} + norm = math.sqrt(sum(w * w for w in weights.values())) or 1.0 + vectors[slug] = {term: w / norm for term, w in weights.items()} + return vectors + + +def score_pairs(vectors: dict[str, dict[str, float]], threshold: float): + """Cosine similarity for every pair sharing at least one discriminating term.""" + postings: dict[str, list[str]] = {} + for slug, vector in vectors.items(): + for term in vector: + postings.setdefault(term, []).append(slug) + + sims: dict[tuple[str, str], float] = {} + for term, slugs in postings.items(): + if len(slugs) > MAX_DOCS_PER_TERM: + continue + weight_by_slug = {s: vectors[s][term] for s in slugs} + for a, b in itertools.combinations(sorted(slugs), 2): + sims[(a, b)] = sims.get((a, b), 0.0) + weight_by_slug[a] * weight_by_slug[b] + + return sorted(((s, p) for p, s in sims.items() if s >= threshold), reverse=True) + + +def load_allowlist() -> dict[tuple[str, str], str]: + if not os.path.isfile(ALLOWLIST_PATH): + return {} + with open(ALLOWLIST_PATH, encoding="utf-8") as handle: + data = json.load(handle) + out: dict[tuple[str, str], str] = {} + for entry in data.get("reviewed_distinct", []): + pair = tuple(sorted(entry["pair"])) + out[pair] = entry.get("reason", "") + return out + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--threshold", type=float, default=DEFAULT_THRESHOLD) + parser.add_argument("--json", action="store_true", dest="as_json") + parser.add_argument("--max-unreviewed", type=int, default=None, + help="exit 1 if unreviewed colliding pairs exceed this") + parser.add_argument("--skills-dir", default="skills") + args = parser.parse_args() + + if not os.path.isdir(args.skills_dir): + print(f"ERROR: '{args.skills_dir}' not found. Run from the repository root.") + return 1 + + vectors = build_vectors(args.skills_dir) + pairs = score_pairs(vectors, args.threshold) + allowlist = load_allowlist() + + unreviewed = [(s, p) for s, p in pairs if p not in allowlist] + reviewed = [(s, p) for s, p in pairs if p in allowlist] + involved = {slug for _, pair in unreviewed for slug in pair} + + if args.as_json: + print(json.dumps({ + "threshold": args.threshold, + "total_pairs": len(pairs), + "unreviewed": [{"score": round(s, 3), "pair": list(p)} for s, p in unreviewed], + "reviewed_distinct": [{"score": round(s, 3), "pair": list(p), + "reason": allowlist[p]} for s, p in reviewed], + "skills_involved": sorted(involved), + }, indent=2)) + else: + print(f"Colliding pairs at cosine >= {args.threshold}: {len(pairs)} " + f"({len(reviewed)} reviewed-distinct, {len(unreviewed)} unreviewed)") + print(f"Skills involved in an unreviewed collision: {len(involved)} " + f"of {len(vectors)}\n") + for score, (a, b) in unreviewed: + print(f" {score:.2f} {a}\n {b}") + if reviewed: + print(f"\nReviewed as legitimately distinct ({len(reviewed)}):") + for score, (a, b) in reviewed: + print(f" {score:.2f} {a} || {b}\n reason: {allowlist[(a, b)]}") + + if args.max_unreviewed is not None and len(unreviewed) > args.max_unreviewed: + print(f"\nERROR: {len(unreviewed)} unreviewed colliding pairs " + f"exceeds --max-unreviewed {args.max_unreviewed}.") + print("Either disambiguate the descriptions or record the pair in " + f"{os.path.relpath(ALLOWLIST_PATH)} with a reason.") + return 1 + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/lint-baseline.json b/tools/lint-baseline.json new file mode 100644 index 00000000..6ee83092 --- /dev/null +++ b/tools/lint-baseline.json @@ -0,0 +1,992 @@ +{ + "_comment": "Pre-existing lint failures, grandfathered so CI can gate new work today. This file may only shrink. Never add a slug by hand -- fix the skill, then run: python tools/lint-descriptions.py --update-baseline", + "_total_grandfathered": 980, + "desc-ends-punctuation": [ + "analyzing-active-directory-acl-abuse", + "analyzing-malicious-url-with-urlscan", + "detecting-aws-iam-privilege-escalation", + "exploiting-active-directory-with-bloodhound", + "implementing-email-sandboxing-with-proofpoint", + "implementing-patch-management-workflow", + "implementing-secrets-scanning-in-ci-cd", + "performing-cryptographic-audit-of-application", + "performing-dark-web-monitoring-for-threats", + "performing-malware-ioc-extraction", + "performing-open-source-intelligence-gathering", + "performing-service-account-audit", + "prioritizing-vulnerabilities-with-cvss-scoring" + ], + "desc-has-use-when": [ + "analyzing-active-directory-acl-abuse", + "analyzing-android-malware-with-apktool", + "analyzing-apt-group-with-mitre-navigator", + "analyzing-certificate-transparency-for-phishing", + "analyzing-cobalt-strike-beacon-configuration", + "analyzing-docker-container-forensics", + "analyzing-ethereum-smart-contract-vulnerabilities", + "analyzing-heap-spray-exploitation", + "analyzing-ios-app-security-with-objection", + "analyzing-linux-audit-logs-for-intrusion", + "analyzing-linux-kernel-rootkits", + "analyzing-macro-malware-in-office-documents", + "analyzing-malicious-url-with-urlscan", + "analyzing-memory-dumps-with-volatility", + "analyzing-network-flow-data-with-netflow", + "analyzing-network-traffic-for-incidents", + "analyzing-network-traffic-of-malware", + "analyzing-network-traffic-with-wireshark", + "analyzing-office365-audit-logs-for-compromise", + "analyzing-pdf-malware-with-pdfid", + "analyzing-powershell-script-block-logging", + "analyzing-ransomware-encryption-mechanisms", + "analyzing-sbom-for-supply-chain-vulnerabilities", + "analyzing-security-logs-with-splunk", + "analyzing-supply-chain-malware-artifacts", + "analyzing-web-server-logs-for-intrusion", + "auditing-aws-s3-bucket-permissions", + "auditing-azure-active-directory-configuration", + "auditing-gcp-iam-permissions", + "auditing-kubernetes-cluster-rbac", + "auditing-terraform-infrastructure-for-security", + "auditing-tls-certificate-transparency-logs", + "auditing-uefi-firmware-with-chipsec", + "building-detection-rule-with-splunk-spl", + "bypassing-authentication-with-forced-browsing", + "coercing-authentication-with-coercer-petitpotam", + "collecting-indicators-of-compromise", + "conducting-api-security-testing", + "conducting-cloud-penetration-testing", + "conducting-domain-persistence-with-dcsync", + "conducting-internal-network-penetration-test", + "conducting-man-in-the-middle-attack-simulation", + "conducting-memory-forensics-with-volatility", + "conducting-mobile-app-penetration-test", + "conducting-network-penetration-test", + "conducting-post-incident-lessons-learned", + "conducting-social-engineering-pretext-call", + "conducting-spearphishing-simulation-campaign", + "conducting-wireless-network-penetration-test", + "containing-active-breach", + "deploying-decoy-files-for-ransomware-detection", + "detecting-anomalous-authentication-patterns", + "detecting-attacks-on-scada-systems", + "detecting-aws-cloudtrail-anomalies", + "detecting-aws-iam-privilege-escalation", + "detecting-azure-lateral-movement", + "detecting-business-email-compromise-with-ai", + "detecting-cryptomining-in-cloud", + "detecting-lateral-movement-in-network", + "detecting-lateral-movement-with-zeek", + "detecting-living-off-the-land-attacks", + "detecting-malicious-scheduled-tasks-with-sysmon", + "detecting-network-scanning-with-ids-signatures", + "detecting-port-scanning-with-fail2ban", + "detecting-process-injection-techniques", + "detecting-ransomware-precursors-in-network", + "detecting-s3-data-exfiltration-attempts", + "detecting-serverless-function-injection", + "detecting-sql-injection-via-waf-logs", + "detecting-suspicious-oauth-application-consent", + "detecting-typosquatting-packages-in-npm-pypi", + "emulating-cloud-attacks-with-stratus-red-team", + "enumerating-cloud-with-cloudfox", + "executing-active-directory-attack-simulation", + "executing-phishing-simulation-campaign", + "exploiting-active-directory-certificate-services-esc1", + "exploiting-active-directory-with-bloodhound", + "exploiting-bgp-hijacking-vulnerabilities", + "exploiting-insecure-deserialization", + "exploiting-ipv6-vulnerabilities", + "exploiting-oauth-misconfiguration", + "exploiting-server-side-request-forgery", + "exploiting-smb-vulnerabilities-with-metasploit", + "exploiting-sql-injection-vulnerabilities", + "exploiting-sql-injection-with-sqlmap", + "exploiting-websocket-vulnerabilities", + "extracting-windows-event-logs-artifacts", + "hunting-for-anomalous-powershell-execution", + "hunting-for-beaconing-with-frequency-analysis", + "hunting-for-command-and-control-beaconing", + "hunting-for-defense-evasion-via-timestomping", + "hunting-for-registry-run-key-persistence", + "hunting-for-spearphishing-indicators", + "implementing-aqua-security-for-container-scanning", + "implementing-cloud-trail-log-analysis", + "implementing-ddos-mitigation-with-cloudflare", + "implementing-diamond-model-analysis", + "implementing-email-sandboxing-with-proofpoint", + "implementing-honeypot-for-ransomware-detection", + "implementing-mitre-attack-coverage-mapping", + "implementing-network-deception-with-honeypots", + "implementing-patch-management-workflow", + "implementing-proofpoint-email-security-gateway", + "implementing-runtime-application-self-protection", + "implementing-secret-scanning-with-gitleaks", + "implementing-secrets-scanning-in-ci-cd", + "implementing-security-monitoring-with-datadog", + "implementing-semgrep-for-custom-sast-rules", + "implementing-velociraptor-for-ir-collection", + "investigating-ransomware-attack-artifacts", + "monitoring-scada-modbus-traffic-anomalies", + "performing-active-directory-compromise-investigation", + "performing-active-directory-vulnerability-assessment", + "performing-agentless-vulnerability-scanning", + "performing-api-inventory-and-discovery", + "performing-aws-privilege-escalation-assessment", + "performing-brand-monitoring-for-impersonation", + "performing-clickjacking-attack-test", + "performing-credential-access-with-lazagne", + "performing-cryptographic-audit-of-application", + "performing-csrf-attack-simulation", + "performing-dark-web-monitoring-for-threats", + "performing-dns-enumeration-and-zone-transfer", + "performing-external-network-penetration-test", + "performing-firmware-extraction-with-binwalk", + "performing-gcp-security-assessment-with-forseti", + "performing-graphql-depth-limit-attack", + "performing-graphql-security-assessment", + "performing-initial-access-with-evilginx3", + "performing-iot-security-assessment", + "performing-ip-reputation-analysis-with-shodan", + "performing-lateral-movement-with-wmiexec", + "performing-log-analysis-for-forensic-investigation", + "performing-malware-ioc-extraction", + "performing-malware-persistence-investigation", + "performing-memory-forensics-with-volatility3-plugins", + "performing-mobile-app-certificate-pinning-bypass", + "performing-oauth-scope-minimization-review", + "performing-open-source-intelligence-gathering", + "performing-ot-network-security-assessment", + "performing-ot-vulnerability-scanning-safely", + "performing-packet-injection-attack", + "performing-paste-site-monitoring-for-credentials", + "performing-physical-intrusion-assessment", + "performing-plc-firmware-security-analysis", + "performing-privilege-escalation-assessment", + "performing-s7comm-protocol-security-analysis", + "performing-sca-dependency-scanning-with-snyk", + "performing-scada-hmi-security-assessment", + "performing-second-order-sql-injection", + "performing-security-headers-audit", + "performing-serverless-function-security-review", + "performing-service-account-audit", + "performing-subdomain-enumeration-with-subfinder", + "performing-thick-client-application-penetration-test", + "performing-threat-hunting-with-yara-rules", + "performing-vulnerability-scanning-with-nessus", + "performing-web-application-penetration-test", + "performing-web-cache-poisoning-attack", + "performing-wifi-password-cracking-with-aircrack", + "performing-wireless-network-penetration-test", + "performing-wireless-security-assessment-with-kismet", + "prioritizing-vulnerabilities-with-cvss-scoring", + "reverse-engineering-ransomware-encryption-routine", + "scanning-infrastructure-with-nessus", + "testing-api-authentication-weaknesses", + "testing-cors-misconfiguration", + "testing-for-host-header-injection", + "testing-for-sensitive-data-exposure", + "testing-for-xml-injection-vulnerabilities", + "testing-for-xss-vulnerabilities-with-burpsuite", + "testing-for-xxe-injection-vulnerabilities", + "testing-jwt-token-security", + "validating-tpm-measured-boot-attestation", + "verifying-build-provenance-with-slsa-sigstore" + ], + "desc-has-negative-trigger": [ + "abusing-dpapi-for-credential-access", + "abusing-shadow-credentials-for-privesc", + "achieving-cmmc-level-2-compliance", + "acquiring-disk-image-with-dd-and-dcfldd", + "analyzing-active-directory-acl-abuse", + "analyzing-android-malware-with-apktool", + "analyzing-api-gateway-access-logs", + "analyzing-apt-group-with-mitre-navigator", + "analyzing-azure-activity-logs-for-threats", + "analyzing-bootkit-and-rootkit-samples", + "analyzing-browser-forensics-with-hindsight", + "analyzing-campaign-attribution-evidence", + "analyzing-certificate-transparency-for-phishing", + "analyzing-cloud-storage-access-patterns", + "analyzing-cobalt-strike-beacon-configuration", + "analyzing-cobaltstrike-malleable-c2-profiles", + "analyzing-command-and-control-communication", + "analyzing-cyber-kill-chain", + "analyzing-disk-image-with-autopsy", + "analyzing-dns-logs-for-exfiltration", + "analyzing-docker-container-forensics", + "analyzing-email-headers-for-phishing-investigation", + "analyzing-ethereum-smart-contract-vulnerabilities", + "analyzing-golang-malware-with-ghidra", + "analyzing-heap-spray-exploitation", + "analyzing-indicators-of-compromise", + "analyzing-ios-app-security-with-objection", + "analyzing-linux-audit-logs-for-intrusion", + "analyzing-linux-elf-malware", + "analyzing-linux-kernel-rootkits", + "analyzing-linux-system-artifacts", + "analyzing-lnk-file-and-jump-list-artifacts", + "analyzing-macro-malware-in-office-documents", + "analyzing-malicious-pdf-with-peepdf", + "analyzing-malicious-url-with-urlscan", + "analyzing-malware-behavior-with-cuckoo-sandbox", + "analyzing-malware-family-relationships-with-malpedia", + "analyzing-malware-persistence-with-autoruns", + "analyzing-malware-sandbox-evasion-techniques", + "analyzing-memory-dumps-with-volatility", + "analyzing-memory-forensics-with-lime-and-volatility", + "analyzing-mft-for-deleted-file-recovery", + "analyzing-network-covert-channels-in-malware", + "analyzing-network-flow-data-with-netflow", + "analyzing-network-packets-with-scapy", + "analyzing-network-traffic-for-incidents", + "analyzing-network-traffic-of-malware", + "analyzing-network-traffic-with-wireshark", + "analyzing-office365-audit-logs-for-compromise", + "analyzing-outlook-pst-for-email-forensics", + "analyzing-packed-malware-with-upx-unpacker", + "analyzing-pdf-malware-with-pdfid", + "analyzing-persistence-mechanisms-in-linux", + "analyzing-powershell-empire-artifacts", + "analyzing-powershell-script-block-logging", + "analyzing-prefetch-files-for-execution-history", + "analyzing-ransomware-encryption-mechanisms", + "analyzing-ransomware-leak-site-intelligence", + "analyzing-ransomware-network-indicators", + "analyzing-ransomware-payment-wallets", + "analyzing-sbom-for-supply-chain-vulnerabilities", + "analyzing-security-logs-with-splunk", + "analyzing-slack-space-and-file-system-artifacts", + "analyzing-supply-chain-malware-artifacts", + "analyzing-threat-actor-ttps-with-mitre-attack", + "analyzing-threat-actor-ttps-with-mitre-navigator", + "analyzing-threat-intelligence-feeds", + "analyzing-threat-landscape-with-misp", + "analyzing-tls-certificate-transparency-logs", + "analyzing-typosquatting-domains-with-dnstwist", + "analyzing-uefi-bootkit-persistence", + "analyzing-usb-device-connection-history", + "analyzing-web-server-logs-for-intrusion", + "analyzing-windows-amcache-artifacts", + "analyzing-windows-event-logs-in-splunk", + "analyzing-windows-lnk-files-for-artifacts", + "analyzing-windows-prefetch-with-python", + "analyzing-windows-registry-for-artifacts", + "analyzing-windows-shellbag-artifacts", + "assessing-vector-and-embedding-weaknesses", + "attacking-entra-id-with-roadtools", + "attacking-oauth-with-device-code-phishing", + "auditing-aws-s3-bucket-permissions", + "auditing-azure-active-directory-configuration", + "auditing-cloud-with-cis-benchmarks", + "auditing-entra-id-with-aadinternals", + "auditing-foundry-smart-contract-security", + "auditing-gcp-iam-permissions", + "auditing-kubernetes-cluster-rbac", + "auditing-mcp-servers-for-tool-poisoning", + "auditing-terraform-infrastructure-for-security", + "auditing-tls-certificate-transparency-logs", + "auditing-uefi-firmware-with-chipsec", + "automating-ioc-enrichment", + "building-adversary-infrastructure-tracking-system", + "building-attack-pattern-library-from-cti-reports", + "building-automated-malware-submission-pipeline", + "building-c2-infrastructure-with-sliver-framework", + "building-c2-redirector-infrastructure", + "building-detection-rule-with-splunk-spl", + "building-detection-rules-with-sigma", + "building-devsecops-pipeline-with-gitlab-ci", + "building-identity-federation-with-saml-azure-ad", + "building-identity-governance-lifecycle-process", + "building-incident-response-dashboard", + "building-incident-response-playbook", + "building-incident-timeline-with-timesketch", + "building-ioc-defanging-and-sharing-pipeline", + "building-ioc-enrichment-pipeline-with-opencti", + "building-malware-incident-communication-template", + "building-patch-tuesday-response-process", + "building-phishing-reporting-button-workflow", + "building-ransomware-playbook-with-cisa-framework", + "building-red-team-c2-infrastructure-with-havoc", + "building-role-mining-for-rbac-optimization", + "building-soc-escalation-matrix", + "building-soc-metrics-and-kpi-tracking", + "building-soc-playbook-for-ransomware", + "building-super-timelines-with-plaso", + "building-threat-actor-profile-from-osint", + "building-threat-feed-aggregation-with-misp", + "building-threat-hunt-hypothesis-framework", + "building-threat-intelligence-enrichment-in-splunk", + "building-threat-intelligence-feed-integration", + "building-threat-intelligence-platform", + "building-vulnerability-aging-and-sla-tracking", + "building-vulnerability-dashboard-with-defectdojo", + "building-vulnerability-exception-tracking-system", + "building-vulnerability-scanning-workflow", + "bypassing-authentication-with-forced-browsing", + "coercing-authentication-with-coercer-petitpotam", + "collecting-indicators-of-compromise", + "collecting-open-source-intelligence", + "collecting-threat-intelligence-with-misp", + "collecting-volatile-evidence-from-compromised-host", + "conducting-api-security-testing", + "conducting-cloud-incident-response", + "conducting-cloud-penetration-testing", + "conducting-cyber-risk-assessment-with-nist-800-30", + "conducting-domain-persistence-with-dcsync", + "conducting-external-reconnaissance-with-osint", + "conducting-full-scope-red-team-engagement", + "conducting-internal-network-penetration-test", + "conducting-internal-reconnaissance-with-bloodhound-ce", + "conducting-malware-incident-response", + "conducting-man-in-the-middle-attack-simulation", + "conducting-memory-forensics-with-volatility", + "conducting-mobile-app-penetration-test", + "conducting-network-penetration-test", + "conducting-pass-the-ticket-attack", + "conducting-phishing-incident-response", + "conducting-post-incident-lessons-learned", + "conducting-social-engineering-penetration-test", + "conducting-social-engineering-pretext-call", + "conducting-spearphishing-simulation-campaign", + "conducting-wireless-network-penetration-test", + "configuring-active-directory-tiered-model", + "configuring-aws-verified-access-for-ztna", + "configuring-certificate-authority-with-openssl", + "configuring-host-based-intrusion-detection", + "configuring-hsm-for-key-storage", + "configuring-identity-aware-proxy-with-google-iap", + "configuring-ldap-security-hardening", + "configuring-microsegmentation-for-zero-trust", + "configuring-multi-factor-authentication-with-duo", + "configuring-network-segmentation-with-vlans", + "configuring-oauth2-authorization-flow", + "configuring-pfsense-firewall-rules", + "configuring-snort-ids-for-intrusion-detection", + "configuring-suricata-for-network-monitoring", + "configuring-tls-1-3-for-secure-communications", + "configuring-windows-defender-advanced-settings", + "configuring-windows-event-logging-for-detection", + "configuring-zscaler-private-access-for-ztna", + "containing-active-breach", + "continuous-llm-red-teaming-with-promptfoo", + "correlating-security-events-in-qradar", + "correlating-threat-campaigns", + "defending-llms-with-guardrails", + "deobfuscating-javascript-malware", + "deobfuscating-powershell-obfuscated-malware", + "deploying-active-directory-honeytokens", + "deploying-cloud-deception-with-decoy-resources", + "deploying-cloudflare-access-for-zero-trust", + "deploying-decoy-files-for-ransomware-detection", + "deploying-edr-agent-with-crowdstrike", + "deploying-honeytokens-and-canarytokens", + "deploying-osquery-for-endpoint-monitoring", + "deploying-palo-alto-prisma-access-zero-trust", + "deploying-ransomware-canary-files", + "deploying-software-defined-perimeter", + "deploying-tailscale-for-zero-trust-vpn", + "designing-adversary-engagement-with-mitre-engage", + "detecting-ai-model-prompt-injection-attacks", + "detecting-anomalies-in-industrial-control-systems", + "detecting-anomalous-authentication-patterns", + "detecting-api-enumeration-attacks", + "detecting-arp-poisoning-in-network-traffic", + "detecting-attacks-on-historian-servers", + "detecting-attacks-on-scada-systems", + "detecting-aws-cloudtrail-anomalies", + "detecting-aws-credential-exposure-with-trufflehog", + "detecting-aws-guardduty-findings-automation", + "detecting-aws-iam-privilege-escalation", + "detecting-azure-lateral-movement", + "detecting-azure-service-principal-abuse", + "detecting-azure-storage-account-misconfigurations", + "detecting-beaconing-patterns-with-zeek", + "detecting-bluetooth-low-energy-attacks", + "detecting-broken-object-property-level-authorization", + "detecting-business-email-compromise", + "detecting-business-email-compromise-with-ai", + "detecting-cloud-threats-with-guardduty", + "detecting-command-and-control-over-dns", + "detecting-compromised-cloud-credentials", + "detecting-credential-dumping-techniques", + "detecting-cryptomining-in-cloud", + "detecting-data-and-model-poisoning", + "detecting-dcsync-attack-in-active-directory", + "detecting-deepfake-audio-in-vishing-attacks", + "detecting-dependency-confusion", + "detecting-dll-sideloading-attacks", + "detecting-dnp3-protocol-anomalies", + "detecting-dns-exfiltration-with-dns-query-analysis", + "detecting-email-account-compromise", + "detecting-email-forwarding-rules-attack", + "detecting-entra-offensive-tools-in-graph-logs", + "detecting-evasion-techniques-in-endpoint-logs", + "detecting-exfiltration-over-dns-with-zeek", + "detecting-fileless-attacks-on-endpoints", + "detecting-fileless-malware-techniques", + "detecting-golden-ticket-attacks-in-kerberos-logs", + "detecting-golden-ticket-forgery", + "detecting-indirect-prompt-injection", + "detecting-insider-data-exfiltration-via-dlp", + "detecting-insider-threat-behaviors", + "detecting-insider-threat-with-ueba", + "detecting-kerberoasting-attacks", + "detecting-lateral-movement-in-network", + "detecting-lateral-movement-with-splunk", + "detecting-lateral-movement-with-zeek", + "detecting-living-off-the-land-attacks", + "detecting-living-off-the-land-with-lolbas", + "detecting-malicious-npm-packages", + "detecting-malicious-scheduled-tasks-with-sysmon", + "detecting-mimikatz-execution-patterns", + "detecting-misconfigured-azure-storage", + "detecting-mobile-malware-behavior", + "detecting-modbus-command-injection-attacks", + "detecting-modbus-protocol-anomalies", + "detecting-model-extraction-attacks", + "detecting-network-anomalies-with-zeek", + "detecting-network-scanning-with-ids-signatures", + "detecting-ntlm-relay-with-event-correlation", + "detecting-oauth-token-theft", + "detecting-pass-the-hash-attacks", + "detecting-pass-the-ticket-attacks", + "detecting-port-scanning-with-fail2ban", + "detecting-privilege-escalation-attempts", + "detecting-process-hollowing-technique", + "detecting-process-injection-techniques", + "detecting-qr-code-phishing-with-email-security", + "detecting-ransomware-encryption-behavior", + "detecting-ransomware-precursors-in-network", + "detecting-rdp-brute-force-attacks", + "detecting-rootkit-activity", + "detecting-s3-data-exfiltration-attempts", + "detecting-secure-boot-bypass", + "detecting-serverless-function-injection", + "detecting-service-account-abuse", + "detecting-shadow-api-endpoints", + "detecting-shadow-it-cloud-usage", + "detecting-spearphishing-with-email-gateway", + "detecting-sql-injection-via-waf-logs", + "detecting-stuxnet-style-attacks", + "detecting-supply-chain-attacks-in-ci-cd", + "detecting-suspicious-oauth-application-consent", + "detecting-suspicious-powershell-execution", + "detecting-t1003-credential-dumping-with-edr", + "detecting-t1055-process-injection-with-sysmon", + "detecting-t1548-abuse-elevation-control-mechanism", + "detecting-typosquatting-packages", + "detecting-typosquatting-packages-in-npm-pypi", + "detecting-wmi-persistence", + "emulating-cloud-attacks-with-stratus-red-team", + "enumerating-cloud-with-cloudfox", + "eradicating-malware-from-infected-systems", + "evaluating-threat-intelligence-platforms", + "executing-active-directory-attack-simulation", + "executing-nist-rmf-authorization-to-operate", + "executing-phishing-simulation-campaign", + "executing-red-team-engagement-planning", + "executing-red-team-exercise", + "exploiting-active-directory-certificate-services-esc1", + "exploiting-active-directory-with-bloodhound", + "exploiting-adcs-with-certipy", + "exploiting-api-injection-vulnerabilities", + "exploiting-aws-with-pacu", + "exploiting-bgp-hijacking-vulnerabilities", + "exploiting-broken-function-level-authorization", + "exploiting-broken-link-hijacking", + "exploiting-constrained-delegation-abuse", + "exploiting-deeplink-vulnerabilities", + "exploiting-excessive-data-exposure-in-api", + "exploiting-http-request-smuggling", + "exploiting-idor-vulnerabilities", + "exploiting-insecure-data-storage-in-mobile", + "exploiting-insecure-deserialization", + "exploiting-ipv6-vulnerabilities", + "exploiting-jwt-algorithm-confusion-attack", + "exploiting-kerberoasting-with-impacket", + "exploiting-mass-assignment-in-rest-apis", + "exploiting-ms17-010-eternalblue-vulnerability", + "exploiting-nopac-cve-2021-42278-42287", + "exploiting-nosql-injection-vulnerabilities", + "exploiting-oauth-misconfiguration", + "exploiting-prototype-pollution-in-javascript", + "exploiting-race-condition-vulnerabilities", + "exploiting-server-side-request-forgery", + "exploiting-smb-vulnerabilities-with-metasploit", + "exploiting-sql-injection-vulnerabilities", + "exploiting-sql-injection-with-sqlmap", + "exploiting-template-injection-vulnerabilities", + "exploiting-type-juggling-vulnerabilities", + "exploiting-vulnerabilities-with-metasploit-framework", + "exploiting-websocket-vulnerabilities", + "exploiting-zerologon-vulnerability-cve-2020-1472", + "extracting-browser-history-artifacts", + "extracting-config-from-agent-tesla-rat", + "extracting-credentials-from-memory-dump", + "extracting-iocs-from-malware-samples", + "extracting-memory-artifacts-with-rekall", + "extracting-windows-event-logs-artifacts", + "fleet-hunting-with-velociraptor", + "generating-and-analyzing-sboms", + "generating-forensic-timelines-with-hayabusa", + "generating-threat-intelligence-reports", + "hardening-linux-endpoint-with-cis-benchmark", + "hardening-windows-endpoint-with-cis-benchmark", + "hunting-advanced-persistent-threats", + "hunting-bootkits-in-efi-system-partition", + "hunting-credential-stuffing-attacks", + "hunting-evtx-with-chainsaw", + "hunting-for-anomalous-powershell-execution", + "hunting-for-beaconing-with-frequency-analysis", + "hunting-for-cobalt-strike-beacons", + "hunting-for-command-and-control-beaconing", + "hunting-for-data-exfiltration-indicators", + "hunting-for-data-staging-before-exfiltration", + "hunting-for-dcom-lateral-movement", + "hunting-for-dcsync-attacks", + "hunting-for-defense-evasion-via-timestomping", + "hunting-for-dns-based-persistence", + "hunting-for-dns-tunneling-with-zeek", + "hunting-for-domain-fronting-c2-traffic", + "hunting-for-lateral-movement-via-wmi", + "hunting-for-living-off-the-cloud-techniques", + "hunting-for-living-off-the-land-binaries", + "hunting-for-lolbins-execution-in-endpoint-logs", + "hunting-for-ntlm-relay-attacks", + "hunting-for-persistence-mechanisms-in-windows", + "hunting-for-persistence-via-wmi-subscriptions", + "hunting-for-process-injection-techniques", + "hunting-for-registry-persistence-mechanisms", + "hunting-for-registry-run-key-persistence", + "hunting-for-scheduled-task-persistence", + "hunting-for-shadow-copy-deletion", + "hunting-for-spearphishing-indicators", + "hunting-for-startup-folder-persistence", + "hunting-for-supply-chain-compromise", + "hunting-for-suspicious-scheduled-tasks", + "hunting-for-t1098-account-manipulation", + "hunting-for-unusual-network-connections", + "hunting-for-unusual-service-installations", + "hunting-for-webshell-activity", + "hunting-saas-sso-token-abuse", + "implementing-aes-encryption-for-data-at-rest", + "implementing-alert-fatigue-reduction", + "implementing-anti-phishing-training-program", + "implementing-anti-ransomware-group-policy", + "implementing-api-abuse-detection-with-rate-limiting", + "implementing-api-gateway-security-controls", + "implementing-api-key-security-controls", + "implementing-api-rate-limiting-and-throttling", + "implementing-api-schema-validation-security", + "implementing-api-security-posture-management", + "implementing-api-security-testing-with-42crunch", + "implementing-api-threat-protection-with-apigee", + "implementing-application-whitelisting-with-applocker", + "implementing-aqua-security-for-container-scanning", + "implementing-attack-path-analysis-with-xm-cyber", + "implementing-attack-surface-management", + "implementing-aws-config-rules-for-compliance", + "implementing-aws-iam-permission-boundaries", + "implementing-aws-macie-for-data-classification", + "implementing-aws-nitro-enclave-security", + "implementing-azure-ad-privileged-identity-management", + "implementing-bgp-security-with-rpki", + "implementing-browser-isolation-for-zero-trust", + "implementing-canary-tokens-for-network-intrusion", + "implementing-cisa-zero-trust-maturity-model", + "implementing-cloud-trail-log-analysis", + "implementing-cloud-vulnerability-posture-management", + "implementing-cloud-waf-rules", + "implementing-cloud-workload-protection", + "implementing-code-signing-for-artifacts", + "implementing-conditional-access-policies-azure-ad", + "implementing-conduit-security-for-ot-remote-access", + "implementing-continuous-security-validation-with-bas", + "implementing-data-loss-prevention-with-microsoft-purview", + "implementing-ddos-mitigation-with-cloudflare", + "implementing-deception-based-detection-with-canarytoken", + "implementing-delinea-secret-server-for-pam", + "implementing-device-posture-assessment-in-zero-trust", + "implementing-devsecops-security-scanning", + "implementing-diamond-model-analysis", + "implementing-digital-signatures-with-ed25519", + "implementing-disk-encryption-with-bitlocker", + "implementing-dmarc-dkim-spf-email-security", + "implementing-ebpf-security-monitoring", + "implementing-email-sandboxing-with-proofpoint", + "implementing-end-to-end-encryption-for-messaging", + "implementing-endpoint-detection-with-wazuh", + "implementing-endpoint-dlp-controls", + "implementing-envelope-encryption-with-aws-kms", + "implementing-epss-score-for-vulnerability-prioritization", + "implementing-file-integrity-monitoring-with-aide", + "implementing-fuzz-testing-in-cicd-with-aflplusplus", + "implementing-gcp-binary-authorization", + "implementing-gcp-organization-policy-constraints", + "implementing-gdpr-data-protection-controls", + "implementing-gdpr-data-subject-access-request", + "implementing-github-advanced-security-for-code-scanning", + "implementing-google-workspace-admin-security", + "implementing-google-workspace-phishing-protection", + "implementing-google-workspace-sso-configuration", + "implementing-hardware-security-key-authentication", + "implementing-hashicorp-vault-dynamic-secrets", + "implementing-hipaa-security-rule-safeguards", + "implementing-honeypot-for-ransomware-detection", + "implementing-honeytokens-for-breach-detection", + "implementing-ics-firewall-with-tofino", + "implementing-identity-governance-with-sailpoint", + "implementing-identity-verification-for-zero-trust", + "implementing-iec-62443-security-zones", + "implementing-immutable-backup-with-restic", + "implementing-infrastructure-as-code-security-scanning", + "implementing-iso-27001-information-security-management", + "implementing-just-in-time-access-provisioning", + "implementing-jwt-signing-and-verification", + "implementing-llm-guardrails-for-security", + "implementing-log-forwarding-with-fluentd", + "implementing-log-integrity-with-blockchain", + "implementing-memory-protection-with-dep-aslr", + "implementing-microsegmentation-with-guardicore", + "implementing-mimecast-targeted-attack-protection", + "implementing-mitre-attack-coverage-mapping", + "implementing-mobile-application-management", + "implementing-mtls-for-zero-trust-services", + "implementing-nerc-cip-compliance-controls", + "implementing-network-access-control", + "implementing-network-access-control-with-cisco-ise", + "implementing-network-deception-with-honeypots", + "implementing-network-intrusion-prevention-with-suricata", + "implementing-network-segmentation-for-ot", + "implementing-network-segmentation-with-firewall-zones", + "implementing-network-traffic-analysis-with-arkime", + "implementing-network-traffic-baselining", + "implementing-next-generation-firewall-with-palo-alto", + "implementing-ot-incident-response-playbook", + "implementing-ot-network-traffic-analysis-with-nozomi", + "implementing-pam-for-database-access", + "implementing-passwordless-auth-with-microsoft-entra", + "implementing-passwordless-authentication-with-fido2", + "implementing-patch-management-for-ot-systems", + "implementing-patch-management-workflow", + "implementing-pci-dss-compliance-controls", + "implementing-policy-as-code-with-open-policy-agent", + "implementing-privileged-access-management-with-cyberark", + "implementing-privileged-access-workstation", + "implementing-privileged-session-monitoring", + "implementing-proofpoint-email-security-gateway", + "implementing-purdue-model-network-segmentation", + "implementing-ransomware-backup-strategy", + "implementing-ransomware-kill-switch-detection", + "implementing-rapid7-insightvm-for-scanning", + "implementing-rsa-key-pair-management", + "implementing-runtime-application-self-protection", + "implementing-saml-sso-with-okta", + "implementing-scim-provisioning-with-okta", + "implementing-secret-scanning-with-gitleaks", + "implementing-secrets-management-with-vault", + "implementing-secrets-scanning-in-ci-cd", + "implementing-security-chaos-engineering", + "implementing-security-information-sharing-with-stix2", + "implementing-security-monitoring-with-datadog", + "implementing-semgrep-for-custom-sast-rules", + "implementing-siem-correlation-rules-for-apt", + "implementing-siem-use-case-tuning", + "implementing-siem-use-cases-for-detection", + "implementing-sigstore-for-software-signing", + "implementing-soar-automation-with-phantom", + "implementing-soar-playbook-for-phishing", + "implementing-soar-playbook-with-palo-alto-xsoar", + "implementing-stix-taxii-feed-integration", + "implementing-syslog-centralization-with-rsyslog", + "implementing-taxii-server-with-opentaxii", + "implementing-threat-intelligence-lifecycle-management", + "implementing-threat-modeling-with-mitre-attack", + "implementing-ticketing-system-for-incidents", + "implementing-usb-device-control-policy", + "implementing-velociraptor-for-ir-collection", + "implementing-vulnerability-management-with-greenbone", + "implementing-vulnerability-remediation-sla", + "implementing-vulnerability-sla-breach-alerting", + "implementing-web-application-logging-with-modsecurity", + "implementing-zero-knowledge-proof-for-authentication", + "implementing-zero-standing-privilege-with-cyberark", + "implementing-zero-trust-dns-with-nextdns", + "implementing-zero-trust-for-saas-applications", + "implementing-zero-trust-in-cloud", + "implementing-zero-trust-network-access", + "implementing-zero-trust-network-access-with-zscaler", + "implementing-zero-trust-with-beyondcorp", + "implementing-zero-trust-with-hashicorp-boundary", + "integrating-dast-with-owasp-zap-in-pipeline", + "integrating-sast-into-github-actions-pipeline", + "intercepting-mobile-traffic-with-burpsuite", + "investigating-insider-threat-indicators", + "investigating-phishing-email-incident", + "investigating-ransomware-attack-artifacts", + "managing-cloud-identity-with-okta", + "managing-intelligence-lifecycle", + "managing-third-party-vendor-risk", + "mapping-attack-paths-with-bloodhound-ce", + "mapping-mitre-attack-techniques", + "migrating-to-post-quantum-cryptography", + "modeling-threats-with-opencti", + "monitoring-darkweb-sources", + "monitoring-scada-modbus-traffic-anomalies", + "moving-laterally-with-netexec", + "operating-havoc-c2", + "operating-sliver-c2", + "operationalizing-misp-threat-feeds", + "orchestrating-llm-attacks-with-pyrit", + "parsing-artifacts-with-eric-zimmerman-tools", + "performing-access-recertification-with-saviynt", + "performing-access-review-and-certification", + "performing-active-directory-bloodhound-analysis", + "performing-active-directory-compromise-investigation", + "performing-active-directory-forest-trust-attack", + "performing-active-directory-penetration-test", + "performing-active-directory-vulnerability-assessment", + "performing-adversary-in-the-middle-phishing-detection", + "performing-agentless-vulnerability-scanning", + "performing-ai-driven-osint-correlation", + "performing-alert-triage-with-elastic-siem", + "performing-android-app-static-analysis-with-mobsf", + "performing-api-fuzzing-with-restler", + "performing-api-inventory-and-discovery", + "performing-api-rate-limiting-bypass", + "performing-api-security-testing-with-postman", + "performing-asset-criticality-scoring-for-vulns", + "performing-authenticated-scan-with-openvas", + "performing-authenticated-vulnerability-scan", + "performing-automated-malware-analysis-with-cape", + "performing-aws-account-enumeration-with-scout-suite", + "performing-aws-privilege-escalation-assessment", + "performing-bandwidth-throttling-attack-simulation", + "performing-binary-exploitation-analysis", + "performing-blind-ssrf-exploitation", + "performing-bluetooth-security-assessment", + "performing-brand-monitoring-for-impersonation", + "performing-clickjacking-attack-test", + "performing-cloud-asset-inventory-with-cartography", + "performing-cloud-forensics-investigation", + "performing-cloud-forensics-with-aws-cloudtrail", + "performing-cloud-incident-containment-procedures", + "performing-cloud-log-forensics-with-athena", + "performing-cloud-native-forensics-with-falco", + "performing-cloud-native-threat-hunting-with-aws-detective", + "performing-cloud-penetration-testing-with-pacu", + "performing-cloud-storage-forensic-acquisition", + "performing-container-image-hardening", + "performing-content-security-policy-bypass", + "performing-credential-access-with-lazagne", + "performing-cryptographic-audit-of-application", + "performing-csrf-attack-simulation", + "performing-cve-prioritization-with-kev-catalog", + "performing-dark-web-monitoring-for-threats", + "performing-deception-technology-deployment", + "performing-directory-traversal-testing", + "performing-disk-forensics-investigation", + "performing-dmarc-policy-enforcement-rollout", + "performing-dns-enumeration-and-zone-transfer", + "performing-dns-tunneling-detection", + "performing-dynamic-analysis-of-android-app", + "performing-dynamic-analysis-with-any-run", + "performing-endpoint-forensics-investigation", + "performing-endpoint-vulnerability-remediation", + "performing-entitlement-review-with-sailpoint-iiq", + "performing-external-network-penetration-test", + "performing-false-positive-reduction-in-siem", + "performing-file-carving-with-foremost", + "performing-firmware-extraction-with-binwalk", + "performing-firmware-malware-analysis", + "performing-fuzzing-with-aflplusplus", + "performing-gcp-penetration-testing-with-gcpbucketbrute", + "performing-gcp-security-assessment-with-forseti", + "performing-graphql-depth-limit-attack", + "performing-graphql-introspection-attack", + "performing-graphql-security-assessment", + "performing-hardware-security-module-integration", + "performing-hash-cracking-with-hashcat", + "performing-http-parameter-pollution-attack", + "performing-indicator-lifecycle-management", + "performing-initial-access-with-evilginx3", + "performing-insider-threat-investigation", + "performing-ioc-enrichment-automation", + "performing-ios-app-security-assessment", + "performing-iot-security-assessment", + "performing-ip-reputation-analysis-with-shodan", + "performing-jwt-none-algorithm-attack", + "performing-kerberoasting-attack", + "performing-lateral-movement-with-wmiexec", + "performing-linux-log-forensics-investigation", + "performing-log-analysis-for-forensic-investigation", + "performing-log-source-onboarding-in-siem", + "performing-malware-hash-enrichment-with-virustotal", + "performing-malware-ioc-extraction", + "performing-malware-persistence-investigation", + "performing-malware-triage-with-yara", + "performing-memory-forensics-with-volatility3", + "performing-memory-forensics-with-volatility3-plugins", + "performing-mobile-app-certificate-pinning-bypass", + "performing-mobile-device-forensics-with-cellebrite", + "performing-network-forensics-with-wireshark", + "performing-network-packet-capture-analysis", + "performing-network-traffic-analysis-with-tshark", + "performing-network-traffic-analysis-with-zeek", + "performing-nist-csf-maturity-assessment", + "performing-oauth-scope-minimization-review", + "performing-open-source-intelligence-gathering", + "performing-osint-with-spiderfoot", + "performing-ot-network-security-assessment", + "performing-ot-vulnerability-scanning-safely", + "performing-packet-injection-attack", + "performing-paste-site-monitoring-for-credentials", + "performing-phishing-simulation-with-gophish", + "performing-physical-intrusion-assessment", + "performing-plc-firmware-security-analysis", + "performing-post-quantum-cryptography-migration", + "performing-privacy-impact-assessment", + "performing-privilege-escalation-assessment", + "performing-privilege-escalation-on-linux", + "performing-privileged-account-access-review", + "performing-privileged-account-discovery", + "performing-purple-team-atomic-testing", + "performing-purple-team-exercise", + "performing-ransomware-response", + "performing-ransomware-tabletop-exercise", + "performing-red-team-phishing-with-gophish", + "performing-red-team-with-covenant", + "performing-s7comm-protocol-security-analysis", + "performing-sca-dependency-scanning-with-snyk", + "performing-scada-hmi-security-assessment", + "performing-second-order-sql-injection", + "performing-security-headers-audit", + "performing-serverless-function-security-review", + "performing-service-account-audit", + "performing-service-account-credential-rotation", + "performing-soap-web-service-security-testing", + "performing-soc-tabletop-exercise", + "performing-soc2-type2-audit-preparation", + "performing-sqlite-database-forensics", + "performing-ssl-certificate-lifecycle-management", + "performing-ssl-stripping-attack", + "performing-ssl-tls-inspection-configuration", + "performing-ssl-tls-security-assessment", + "performing-ssrf-vulnerability-exploitation", + "performing-static-malware-analysis-with-pe-studio", + "performing-steganography-detection", + "performing-subdomain-enumeration-with-subfinder", + "performing-supply-chain-attack-simulation", + "performing-thick-client-application-penetration-test", + "performing-threat-emulation-with-atomic-red-team", + "performing-threat-hunting-with-elastic-siem", + "performing-threat-hunting-with-yara-rules", + "performing-threat-intelligence-sharing-with-misp", + "performing-threat-landscape-assessment-for-sector", + "performing-threat-modeling-with-owasp-threat-dragon", + "performing-timeline-reconstruction-with-plaso", + "performing-user-behavior-analytics", + "performing-vlan-hopping-attack", + "performing-vulnerability-scanning-with-nessus", + "performing-web-application-firewall-bypass", + "performing-web-application-penetration-test", + "performing-web-application-scanning-with-nikto", + "performing-web-application-vulnerability-triage", + "performing-web-cache-deception-attack", + "performing-web-cache-poisoning-attack", + "performing-wifi-password-cracking-with-aircrack", + "performing-windows-artifact-analysis-with-eric-zimmerman-tools", + "performing-wireless-network-penetration-test", + "performing-wireless-security-assessment-with-kismet", + "performing-yara-rule-development-for-detection", + "post-exploiting-microsoft-graph-with-graphrunner", + "prioritizing-vulnerabilities-with-cvss-scoring", + "processing-stix-taxii-feeds", + "profiling-threat-actor-groups", + "recovering-deleted-files-with-photorec", + "recovering-from-ransomware-attack", + "red-teaming-llms-with-garak", + "relaying-ntlm-for-adcs-esc8", + "remediating-s3-bucket-misconfiguration", + "reverse-engineering-android-malware-with-jadx", + "reverse-engineering-dotnet-malware-with-dnspy", + "reverse-engineering-ios-app-with-frida", + "reverse-engineering-malware-with-ghidra", + "reverse-engineering-ransomware-encryption-routine", + "reverse-engineering-rust-malware", + "scanning-containers-with-trivy-in-cicd", + "scanning-iac-and-images-with-trivy", + "scanning-infrastructure-with-nessus", + "scanning-network-with-nmap-advanced", + "securing-agentic-ai-tool-invocation", + "securing-api-gateway-with-aws-waf", + "securing-aws-iam-permissions", + "securing-aws-lambda-execution-roles", + "securing-azure-with-microsoft-defender", + "securing-container-registry-images", + "securing-github-actions-workflows", + "securing-historian-server-in-ot-environment", + "securing-kubernetes-on-cloud", + "securing-remote-access-to-ot-environment", + "securing-serverless-functions", + "testing-android-intents-for-vulnerabilities", + "testing-api-authentication-weaknesses", + "testing-api-for-broken-object-level-authorization", + "testing-api-for-mass-assignment-vulnerability", + "testing-api-security-with-owasp-top-10", + "testing-cors-misconfiguration", + "testing-for-broken-access-control", + "testing-for-business-logic-vulnerabilities", + "testing-for-email-header-injection", + "testing-for-host-header-injection", + "testing-for-json-web-token-vulnerabilities", + "testing-for-open-redirect-vulnerabilities", + "testing-for-sensitive-data-exposure", + "testing-for-system-prompt-leakage", + "testing-for-xml-injection-vulnerabilities", + "testing-for-xss-vulnerabilities", + "testing-for-xss-vulnerabilities-with-burpsuite", + "testing-for-xxe-injection-vulnerabilities", + "testing-jwt-token-security", + "testing-mobile-api-authentication", + "testing-oauth2-implementation-flaws", + "testing-prompt-injection-in-rag-pipelines", + "testing-ransomware-recovery-procedures", + "testing-websocket-api-security", + "tracking-threat-actor-infrastructure", + "triaging-security-alerts-in-splunk", + "triaging-security-incident", + "triaging-security-incident-with-ir-playbook", + "triaging-vulnerabilities-with-ssvc-framework", + "triaging-windows-with-kape", + "validating-backup-integrity-for-recovery", + "validating-tpm-measured-boot-attestation", + "verifying-build-provenance-with-slsa-sigstore" + ], + "body-max-lines": [ + "building-automated-malware-submission-pipeline", + "building-identity-governance-lifecycle-process", + "detecting-anomalous-authentication-patterns", + "detecting-attacks-on-scada-systems", + "detecting-command-and-control-over-dns", + "detecting-living-off-the-land-attacks", + "detecting-modbus-command-injection-attacks", + "detecting-ntlm-relay-with-event-correlation", + "detecting-serverless-function-injection", + "hunting-for-dcom-lateral-movement", + "implementing-data-loss-prevention-with-microsoft-purview", + "implementing-google-workspace-admin-security", + "implementing-hashicorp-vault-dynamic-secrets", + "implementing-iec-62443-security-zones", + "implementing-passwordless-auth-with-microsoft-entra", + "implementing-zero-trust-with-hashicorp-boundary", + "performing-cloud-log-forensics-with-athena", + "performing-graphql-introspection-attack", + "performing-ics-asset-discovery-with-claroty", + "performing-oauth-scope-minimization-review", + "performing-ot-network-security-assessment", + "performing-plc-firmware-security-analysis", + "performing-purple-team-atomic-testing" + ] +} diff --git a/tools/lint-descriptions.py b/tools/lint-descriptions.py new file mode 100644 index 00000000..a0160def --- /dev/null +++ b/tools/lint-descriptions.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 +"""Lint SKILL.md descriptions for the qualities that drive agent routing. + +The description is the ONLY signal an agent sees at discovery time, so it must +say what the skill does, when to fire, and -- critically -- when NOT to fire. +Skills whose descriptions overlap without a distinguishing negative trigger get +misrouted ("skill collision"). + +Rules +----- + name-matches-folder frontmatter name == directory name + desc-max-length description <= 1024 chars (agentskills.io limit) + desc-ends-punctuation ends in . ! ? ) " ' -- a truncation canary + desc-has-use-when carries an explicit trigger clause + desc-has-negative-trigger says what it is NOT for + body-max-lines SKILL.md <= 500 lines (Anthropic guidance) + +Grandfathering +-------------- +Known pre-existing failures live in tools/lint-baseline.json so CI can go green +today while the debt is paid down. A baselined skill that starts passing is +reported as a stale entry -- run --update-baseline to shrink the file. The +baseline can only ever shrink in review, never silently grow: any NEW failure +is a hard error. + +Usage: + python tools/lint-descriptions.py --all + python tools/lint-descriptions.py --all --stats + python tools/lint-descriptions.py --update-baseline + python tools/lint-descriptions.py skills/ +""" +from __future__ import annotations + +import argparse +import json +import os +import re +import sys + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +from skill_frontmatter import description_of, iter_skill_dirs, load_frontmatter, FrontmatterError + +BASELINE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "lint-baseline.json") + +DESCRIPTION_MAX_CHARS = 1024 +BODY_MAX_LINES = 500 +SENTENCE_ENDINGS = ".!?)\"'" + +# "Use when ...", "Use this skill when ...", "Use for ...", "Use during ..." +USE_WHEN_RE = re.compile( + r"\buse\s+(?:this\s+)?(?:skill\s+)?(?:when|whenever|for|during|after|before)\b", + re.IGNORECASE, +) + +# "Do not use for X", "Don't use when Y", "Not for Z" +NEGATIVE_TRIGGER_RE = re.compile( + r"\b(?:do\s+not\s+use|don'?t\s+use|not\s+for\b|avoid\s+(?:this\s+)?(?:skill\s+)?for)\b", + re.IGNORECASE, +) + +RULES = ( + "name-matches-folder", + "desc-max-length", + "desc-ends-punctuation", + "desc-has-use-when", + "desc-has-negative-trigger", + "body-max-lines", +) + +RED, GREEN, YELLOW, DIM, RESET = "\033[91m", "\033[92m", "\033[93m", "\033[2m", "\033[0m" + + +def check_skill(slug: str, skill_dir: str) -> dict[str, str]: + """Return {rule_id: human message} for every rule this skill violates.""" + skill_md = os.path.join(skill_dir, "SKILL.md") + violations: dict[str, str] = {} + + try: + frontmatter = load_frontmatter(skill_md) + except FrontmatterError as exc: + return {"name-matches-folder": f"unparseable frontmatter: {exc}"} + + name = str(frontmatter.get("name", "") or "") + if name != slug: + violations["name-matches-folder"] = f"name {name!r} != folder {slug!r}" + + description = description_of(frontmatter) + + if len(description) > DESCRIPTION_MAX_CHARS: + violations["desc-max-length"] = ( + f"{len(description)} chars, max {DESCRIPTION_MAX_CHARS}") + + if description and description[-1] not in SENTENCE_ENDINGS: + violations["desc-ends-punctuation"] = f"ends with {description[-40:]!r}" + + if not USE_WHEN_RE.search(description): + violations["desc-has-use-when"] = "no trigger clause (add 'Use when ...')" + + if not NEGATIVE_TRIGGER_RE.search(description): + violations["desc-has-negative-trigger"] = ( + "no negative trigger (add 'Do not use for X - use .')") + + with open(skill_md, encoding="utf-8") as handle: + line_count = sum(1 for _ in handle) + if line_count > BODY_MAX_LINES: + violations["body-max-lines"] = f"{line_count} lines, max {BODY_MAX_LINES}" + + return violations + + +def collect(skills_dir: str = "skills") -> dict[str, dict[str, str]]: + return {slug: v for slug, d in iter_skill_dirs(skills_dir) + if (v := check_skill(slug, d))} + + +def load_baseline() -> dict[str, list[str]]: + if not os.path.isfile(BASELINE_PATH): + return {} + with open(BASELINE_PATH, encoding="utf-8") as handle: + return {k: v for k, v in json.load(handle).items() if not k.startswith("_")} + + +def write_baseline(violations: dict[str, dict[str, str]]) -> dict[str, list[str]]: + baseline = {rule: sorted(s for s, v in violations.items() if rule in v) + for rule in RULES} + baseline = {rule: slugs for rule, slugs in baseline.items() if slugs} + payload = { + "_comment": ( + "Pre-existing lint failures, grandfathered so CI can gate new work today. " + "This file may only shrink. Never add a slug by hand -- fix the skill, then " + "run: python tools/lint-descriptions.py --update-baseline" + ), + "_total_grandfathered": sum(len(s) for s in baseline.values()), + **baseline, + } + with open(BASELINE_PATH, "w", encoding="utf-8") as handle: + json.dump(payload, handle, indent=2) + handle.write("\n") + return baseline + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("target", nargs="?", help="a single skills/ directory") + parser.add_argument("--all", action="store_true", help="lint every skill") + parser.add_argument("--stats", action="store_true", help="show per-rule totals") + parser.add_argument("--update-baseline", action="store_true", + help="rewrite lint-baseline.json from current state") + parser.add_argument("--skills-dir", default="skills") + args = parser.parse_args() + + if not os.path.isdir(args.skills_dir): + print(f"ERROR: '{args.skills_dir}' not found. Run from the repository root.") + return 1 + + single_skill = bool(args.target) and not (args.all or args.update_baseline) + if single_skill: + slug = os.path.basename(args.target.rstrip("/\\")) + violations = {slug: v} if (v := check_skill(slug, args.target.rstrip("/\\"))) else {} + else: + violations = collect(args.skills_dir) + + if args.update_baseline: + baseline = write_baseline(violations) + total = sum(len(s) for s in baseline.values()) + print(f"Baseline written: {total} grandfathered violation(s) across " + f"{len(baseline)} rule(s) -> {os.path.relpath(BASELINE_PATH)}") + for rule in RULES: + if baseline.get(rule): + print(f" {rule:26s} {len(baseline[rule])}") + return 0 + + baseline = load_baseline() + + new_failures: list[tuple[str, str, str]] = [] + grandfathered = 0 + for slug, rule_map in sorted(violations.items()): + for rule, message in sorted(rule_map.items()): + if slug in baseline.get(rule, []): + grandfathered += 1 + else: + new_failures.append((slug, rule, message)) + + # Only meaningful over the whole tree: linting one skill says nothing about + # whether the other 816 baselined violations still stand. + stale = [] if single_skill else [ + (rule, slug) for rule, slugs in baseline.items() for slug in slugs + if rule not in violations.get(slug, {}) + ] + + if args.stats: + print("Violations by rule (grandfathered + new):") + for rule in RULES: + count = sum(1 for v in violations.values() if rule in v) + remaining = len(baseline.get(rule, [])) + print(f" {rule:26s} {count:4d} baselined {remaining:4d}") + print() + + for slug, rule, message in new_failures: + print(f"{RED}FAIL{RESET} {slug}: {YELLOW}{rule}{RESET} - {message}") + + if stale: + print(f"\n{GREEN}{len(stale)} baselined violation(s) now pass.{RESET} " + f"Shrink the baseline: python tools/lint-descriptions.py --update-baseline") + for rule, slug in stale[:10]: + print(f" {DIM}fixed{RESET} {slug}: {rule}") + + print(f"\n{'=' * 60}") + checked = 1 if single_skill else sum(1 for _ in iter_skill_dirs(args.skills_dir)) + print(f"Skills: {checked} " + f"{RED}New failures: {len(new_failures)}{RESET} " + f"{YELLOW}Grandfathered: {grandfathered}{RESET}") + + return 1 if new_failures else 0 + + +if __name__ == "__main__": + sys.exit(main())