agentleFS
zeljkoobrenoviczeljkoobrenovic/sokrates-skills/skills/scanners/security-scan/SKILL.md

security-scan

Skill3 starsChanged 31 days agoMITView on GitHub

Security review in one pass, design first and code second: identity, authentication and permission design, secrets by design and in the tree, boundary validation and injection (command, SQL, path, template), crypto and randomness, unsafe and dynamic code, trust in third-party code (plugins, models, dependencies), with a posture stating what was swept clean and what was not covered. Use for security reviews or audits, auth or permission design, secrets, injection, crypto, unsafe code, plugin trust, or the threat surface.

We split this skill into the rules it gives an agent

2 rules. 0 are common, 0 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 74 edited versions we read keep these.

  • 0

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Write findings, validate, render.

    line 42
  2. Very specific:

    Follow the core workflow: write _sokrates/reports/ai-insights/security-scan.json, validate until OK, render the explorer, re-merge if a …

    line 93

“Common” is measured: kept by at least 6 in 10 of the 74 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Security scan

A design can be sound while a single line betrays it, and a line can look dangerous while the design already contains it. This scanner does both readings in the right order: first the security design — identity, permissions, secrets, validation posture, third-party trust — reconstructed from the enforcement points; then the hunt for concrete dangerous patterns, judged in the light of that design. The output is the document a security reviewer wishes the team had written, plus an honest statement of what was probed and what was not.

First read sokrates-scan-core/SKILL.md (sibling skill) — output format, evidence rules, validate/render scripts, _sokrates layout. This file adds only what is specific to security scanning.

The one question

What untrusted thing can reach what dangerous thing, and what stands in between? Ask it per input path and per sink; the design groups say what stands in between, the audit groups say whether it actually holds.

The false-positive discipline

This scanner's failure mode is crying wolf. A grep hit is a candidate, never a finding: before reporting, read enough context to answer (a) can attacker-influenced data actually reach this line, and (b) what mitigation already stands in front of it — including the design mechanisms you mapped in the first half. A pattern that is present but mitigated, unreachable, or test-only is info with the mitigation named, or folded into the clean verdict of its category. When exploitability is uncertain after reading, say so and cap severity at medium with confidence possible. One confirmed finding with a traced input path outweighs twenty "looks suspicious" entries; one false critical destroys the report's credibility.

Scope and boundaries with sibling scanners

  • architecture-scan (security-boundaries) owns the structure of trust: where untrusted data enters, process/sandbox/privilege boundaries, network confinement of executed code, and their escape hatches. Read it first and reference it; this scanner does not re-map boundaries — it reads what crosses them and how the crossings are checked. Verify any mechanism architecture asserts before building on it (that hardening runs in the main binary, that a filter is on by default); a wrong sibling claim is recorded here as a finding with the correction, not inherited. When the enforcement line you must cite is the same line a sibling cited, cite it — the rule against copying evidence forbids copying blocks, not reading the same line; your note states your own reading.
  • cicd-scan owns pipeline security (action pinning, publish credentials, signing steps). This scanner owns how the shipped product decides what to trust at runtime (installer/update verification, plugin vetting, dependency trust at load time).
  • observability-scan owns telemetry egress and its privacy; network-scan owns TLS/proxy configuration as connectivity. Here, TLS verification disabled and secrets on the wire are audited; the decision framework for what user data may leave the machine is secrets design.
  • reliability-scan owns panics/unwraps and error handling as robustness; here they count only as denial-of-service or memory-safety concerns. storage-scan owns data-at-rest mechanics; here only secrets at rest and permission bits.
  • network-scan and storage-scan may already cite the sandbox egress proxy, auth headers or secret files; reference their ids and keep the security judgment.
  • Dependency CVE auditing needs a vulnerability database this scanner lacks: do not guess CVE status. Report the mechanisms (cargo-deny, npm audit, Dependabot, lockfile policy) under third-party-trust.

Cross-referencing. List existing ids first (grep -h '"id"' _sokrates/reports/ai-insights/*.json --exclude=combined-report.json) and reference siblings as sokrates_refs: ["finding:<scanner>/<group>/<slug>"] — only ids you saw. Never copy another scanner's evidence blocks; every citation is minted from files you read in this run.

Workflow

  1. Orient per the core skill. Read architecture-scan/security-boundaries (the trust map and sandbox model), tech-stack-scan (auth/crypto/sandbox technologies), cicd-scan (artifact flow), network-scan (endpoints, TLS, proxies), storage-scan (secret files), observability-scan (egress). Use Sokrates' ignore rules to skip vendored/generated code — vendored findings are noise unless locally patched. Decide the system kind: a service with users and roles, a local tool acting on behalf of one user, an agent runtime executing model-suggested actions, a library.
  2. Find the security vocabulary and trace each mechanism to its enforcement point. Grep for policy|permission|approval|approval_mode|trust|untrusted|auth|token|credential|secret|redact|escalat|privilege|verify|signature|allowlist|denylist|sanitiz|validate|environment|inherit|annotation|hint; note crate/module names (*-auth, execpolicy, *-sandbox), SECURITY.md, threat-model docs. For each mechanism read where it is enforced, not where it is defined: the function that says yes/no, the middleware that checks the token, the schema check at the parser. Record the default (secure or open when unconfigured) and the bypass surface (flags, env vars, config that disable it — deliberate escape hatches are design facts, not automatically flaws). For each untrusted party (model, plugin, MCP server, remote peer, user file) find the classifier that decides whether a human is asked (auto-approve heuristics, tool annotations, trust levels, env-passing policies) and check who supplies its inputs — a classifier fed by the untrusted party itself is the recurring design gap, and it does not show up in the vocabulary grep.
  3. Walk the untrusted inputs across the boundaries architecture mapped — reference trust-map for the entry-point list instead of re-listing it; input-handling/boundary-validation describes the validation posture at those entries, not the entries. Operator-supplied arguments (an output folder, a CLI flag) are not untrusted input; do not invent checks for them even when a sibling's hand-off suggests it. Network responses, model output, user files and repositories, plugins/extensions, IPC, request bodies: follow the two or three most important paths from entry to the first sink and note where each is validated, constrained, or trusted. In AI systems the model-output path is untrusted input: what can it cause without a human gate?
  4. Sweep for secrets. Credential shapes (api_key, secret, token, password, BEGIN.*PRIVATE KEY, long base64/hex literals near auth words, known prefixes sk-, ghp_, AKIA, xox); read every hit: real credentials (critical), fixtures and placeholders (fold into the clean verdict), intentional published identifiers such as OAuth client ids or telemetry keys (info, intent stated). Then the design side of the same group: where secrets live at rest (path, permissions, keyring, encryption), how they are held in memory, what redaction layers exist, what is deliberately never persisted.
  5. Sweep injection surfaces. Command construction (sh -c, Command::new with formatted args), SQL string building vs bound parameters, path joins from external input (traversal, symlink, zip-slip in extractors), template/format-string sinks, markup construction. Per category, trace one or two representative paths from an input found in step 3 to the sink; report the category's verdict, not every call site.
  6. Audit crypto and randomness. Algorithms and their jobs (integrity vs identity vs passwords), RNG sources where it matters, TLS overrides (danger_accept_invalid_certs, rejectUnauthorized: false), home-rolled primitives, timing of secret comparison. Judge fitness-for-purpose: SHA-1 as a cache key is fine; as a signature it is not.
  7. Audit unsafe, native and dynamic code. unsafe blocks (count blocks and files separately, read the load-bearing ones, check safety comments), FFI seams, eval/dynamic code execution, deserialization of untrusted data, archive extraction, size and recursion limits on parsers, check-then-use shapes.
  8. Read third-party trust at runtime. Plugin/extension/marketplace vetting, installer and update verification (signatures, checksums, pinned channels), dependency trust at load time (lockfiles, audit tooling, vendored patches), model-output containment beyond the sandbox (tool allowlists, approval gates).
  9. Synthesize the posture. One security-posture/posture finding, severity: info, confidence: likely: the design in three sentences (layers, how they compose — defense in depth or one wall — what it defends against and visibly does not), the worst confirmed finding, the coverage statement (categories swept and clean, categories not covered and why), and the three things a reviewer should probe next as finding: refs. Evidence cites the central policy or enforcement point.
  10. Write findings, validate, render; re-run the merge script if a combined-report.json exists. Report per the core workflow. Scanner id: security-scan, version 2.0.

Group taxonomy

groupcontents
identity-accessAuthentication and authorization design: identity/credential flows, token lifecycle and storage, permission/policy models, approval and consent flows, admin/managed overrides, defaults and bypasses
secretsSecrets by design and in the tree: where they live at rest and how protected, in-memory handling, redaction layers, what is never persisted; real leaks (critical), intentional published identifiers (info), the hygiene verdict
input-handlingValidation posture at the boundaries: parsers and schema checks, canonicalization, deserialization of untrusted data, archive extraction, size/recursion limits, check-then-use shapes — and crossings that arrive unvalidated
injectionCommand/SQL/path/template/markup construction from attacker-influenceable data — one finding per category with representative traced paths, including the mitigated-by-design verdicts
cryptoAlgorithm fitness-for-purpose, randomness sources, TLS overrides, secret comparison, home-rolled primitives
unsafe-codeunsafe blocks, FFI seams, dynamic code execution: counts, the load-bearing instances read, safety-argument hygiene
third-party-trustRuntime trust in code and content the team did not write: plugin/extension vetting, installer and update verification, dependency trust at load time and audit tooling, model-output containment beyond the sandbox
security-postureThe synthesis (one finding, info, id security-posture/posture): the design narrative, the worst confirmed finding, the coverage statement, what to probe next

Precedence: file by the mechanism a finding concerns, never in security-posture; a weak or disabled default belongs with its mechanism (a secrets-leaking default is secrets); a sink category → injection, a source/parser category → input-handling (a path traversal in an extractor is input-handling; a shell command built from an entry name is injection); trust boundaries and sandbox mechanics → reference architecture-scan, only their crossings are judged here; TLS disabled → crypto, TLS configuration otherwise → reference network-scan.

Stable ids

Slugs are mechanism, category or artifact names, never consequences. Fixed slugs (use only when the subject exists). Clean verdicts: one per group, under the group's most relevant slug, with every swept sub-category listed in attributes.swept — never one finding per clean sub-category (that is padding, and on a thin target it would be ten findings saying "none"):

groupfixed slugs
identity-accessauthentication, authorization-model, approval-flow, token-lifecycle, managed-overrides
secretsat-rest, in-memory-and-redaction, in-tree (the sweep verdict: leaks or clean), published-identifiers
input-handlingboundary-validation (the posture), deserialization, archives-and-paths, parser-limits, check-then-use
injectioncommand, sql, path, template-and-markup
cryptoalgorithms (one finding covering randomness and secret comparison too when each is a sentence — list them in attributes.mechanisms; randomness and secret-comparison only when they carry their own defect), tls-overrides
unsafe-codeunsafe-blocks, ffi, dynamic-execution
third-party-trustplugins-and-extensions, updates-and-installers, dependencies, runtime-loaded-scripts (CDN scripts in produced or served pages: SRI, pinning, what they can read), model-output
security-postureposture

Project-specific findings get a free slug naming the mechanism or artifact (secrets/auth-json-permissions, secrets/exec-env-inheritance), never the consequence. Several mechanisms sharing a slug are listed in attributes. A fixed slug whose subject is absent but was swept (no self-updater, no templates) is a line in its group neighbour's attributes.swept, not a finding. Clean verdicts carry attributes.swept (what was checked) so a re-run can see coverage change. injection/path is for path construction from untrusted input (joins, normalization of a patch's target paths); input-handling/archives-and-paths is for extraction of archives and the traversal checks inside extractors.

What a good finding looks like

A design finding answers: what the mechanism is (from its enforcement point), what it defends against, its default and bypass surface, how it composes with neighbours; cite the enforcement line and the default/bypass line. An audit finding cites the sink and the input path that reaches it (or the mitigation that stops it). A clean verdict cites a representative instance of the safe pattern (the bound-parameter query, the CSPRNG call) at confidence: certain; a test that asserts a security property (file modes, constant-time comparison) is citable support. Absences are evidenced by the nearest delimiting positive fact with the evidence note saying what it delimits.

Strengths are findings: a well-built approval flow documented as info is what makes the gap findings credible. Aggregate by mechanism or category, not by file. Expect 14–22 findings for a security-conscious codebase and up to 26 for a large multi-surface one (an agent runtime with plugins, MCP, sandboxes and several frontends) — roughly half design, a third clean verdicts, the rest project-specific defects; for a project where security design is thin, "the design is thin, here is the entire surface" is itself the posture, and the audit half still runs.

Severity calibration

  • critical — a real credential in the tree; a confirmed injection path (attacker-influenceable data reaches the sink, nothing in between) with material impact — code execution, credential or data theft, or a served origin; a boundary whose "check" is demonstrably a no-op on a dangerous path. A confirmed injection into a static artifact with nothing to steal is high.
  • high — a load-bearing boundary crossed unchecked by design (untrusted content reaching execution or credentials without any gate); a security mechanism whose default silently disables it in real deployments; a dangerous pattern on a plausible input path with weak or bypassable mitigation; TLS verification disabled on non-test paths; non-constant-time secret comparison where an oracle exists.
  • medium — scripts loaded from a CDN without SRI or version pinning into a page that also holds user content or source (high when the page is served from an origin with credentials, low when it holds nothing sensitive); single-wall defenses where depth is warranted; escape hatches reachable without consent or audit trail; a deliberate, documented insecure default with the safe mode available (present the trade-off); a pattern whose exploitability stays uncertain after reading; missing limits on parsers fed external data; unsafe blocks without safety arguments in load-bearing code; sensitive data handled inconsistently across components that should share one design.
  • low — hardening and drift: duplicated policy logic that will diverge, validation present in some entry points but not equivalent siblings, deprecated algorithms in low-stakes roles, lint suppressions on security lints without justification, test-only shortcuts adjacent to production code.
  • info — the mechanism map, clean verdicts, intentional published identifiers, mitigated patterns worth documenting, the posture; an output that is sensitive by purpose (a report embedding the analyzed source) with documented switches to reduce it.
  • When unsure between two levels, pick the lower; never let a possible-confidence finding carry more than medium. Confidence for a design finding is certain when the enforcement line and the default value are both cited, likely when the default is inferred from docs or a single caller. In AI-agent systems, weigh the model-output path like any untrusted input: prompt-injection resilience is the set of gates between model output and side effects, not a code bug.

Output

Follow the core workflow: write _sokrates/reports/ai-insights/security-scan.json, validate until OK, render the explorer, re-merge if a combined report exists, report leading with the verdict sentence (worst confirmed finding, or the clean bill) and the design narrative in three sentences.

stats keys (canonical; counting things checked or designed, never findings): mechanisms_traced (enforcement points read, one per mechanism), escape_hatches (the union of architecture's list and the switches found here), unchecked_crossings (entry points from trust-map whose data reaches a sink with no validation or encoding on the way — count crossings, not entry points), secret_candidates_reviewed, categories_swept and sweeps_clean, unsafe_blocks_total (occurrences of unsafe {, non-test; unsafe fn/unsafe impl under unsafe_items), unsafe_files (files with at least one block), unsafe_blocks_read, safety_comments, not_covered (categories this run could not sweep and why — tooling missing, offline; structurally inapplicable categories go in not_applicable). The posture finding may reference this scanner's own ids. Add extras freely alongside.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.