From Suspicion to a Defensible Security Claim

Cloudflare's security-audit skill is a workflow for turning coding agents into evidence-grounded security auditors. This opening focuses on the gap between noticing suspicious code and proving that a lower-trust actor can cross a real boundary, so readers can judge what the skill's later coverage, hunting, and verification stages are meant to establish.

That gap is larger than it first appears. A coding agent can find a missing check, an unusual data flow, a permissive configuration, or a dangerous-looking function in seconds. But a security audit does not end when a pattern looks wrong. It must answer harder questions: Who can reach the code? Which authority should stop them? What resource or principal is affected? What happens when the path is exercised? Which parts of that answer are visible in the source, and which depend on a deployment, browser, operating system, provider, or identity service that the repository does not contain?

The security-audit skill is built around those questions. Its central idea is simple but demanding: a useful audit is not a collection of suspicions. It is a chain of evidence that remains traceable as work moves from source exploration to local validation, independent challenge, and communication.

flowchart LR A["Lower-trust input or action"] --> B["Source trace and boundary"] B --> C["Bounded local result"] C --> D["Independent verification"] D --> E["Target-neutral report"] B --> F["Blocker or no demonstrated impact"] F --> E

The diagram shows two legitimate outcomes. A source path can lead to a bounded result and survive independent verification. Or the evidence can stop earlier: the source may refute the suspicion, or a decisive fact may sit outside the repository and safe local environment. The report must preserve that difference.

The subject is a workflow, not a scan

The skill describes six phases. Reconnaissance maps the architecture, trust boundaries, input surfaces, copies, sinks, and locally visible ways to operate the target. Coverage-led hunting assigns that map to explicit review units rather than asking agents to inspect “the code” in the abstract. Candidate validation gives each distinct lead to a fresh verifier that did not discover it. Structured output records confirmed, unresolved, and rejected work in separate forms. Independent record verification checks the final records again. Target-neutral reporting derives communication from those verified records and the coverage state.

The order matters because each phase answers a different question. Reconnaissance asks what exists and who has authority. Hunting asks whether an invariant is violated on a source-visible path. Validation asks whether the proposed explanation survives an adversarial reading and, where safe, a minimal local check. Reporting asks what can be said without making the prose stronger than the evidence. Skipping one phase may produce a faster document, but it also removes a distinct defense against false confidence.

This is why the skill does not present itself as a universal scanner. A scanner can identify a call to a shell, a missing annotation, or a suspicious string. The workflow must determine whether the call is reachable by a lower-trust principal, whether another control already contains it, whether the input reaches the claimed sink, and whether the result affects someone or something outside the requester's intended authority. The same surface pattern can be a vulnerability in one context, a hardening opportunity in another, and a harmless implementation choice in a third.

The workflow also distinguishes guidance from a complete audit. A focused security question can use the relevant reasoning without automatically creating a full set of audit artifacts or launching every phase. A complete audit is reserved for an explicit audit, penetration test, comprehensive review, or requested report artifacts. If the request is ambiguous, the stated rule is to clarify before broad orchestration begins. That is an important boundary of the subject itself: loading a methodology is not the same as authorizing a wide investigation.

The distinction protects more than files and agent time. It prevents an assistant from treating every security-flavored question as permission to run target-controlled code, contact services, or create a report that may be mistaken for a formal assessment. The skill's design begins by deciding what kind of work has actually been requested.

A security claim needs a boundary and a result

The minimum unit of meaning in this workflow is not a rule violation. It is a boundary failure with a consequence.

Start with the lower-trust principal. That might be an ordinary account, a tenant with limited access, a contributor-controlled workflow event, an untrusted document, a browser origin, a local application, a message producer, or model-supplied content. “Attacker” is not a sufficient description if the starting authority is left vague. A user who can already edit their own record is not automatically gaining privilege by editing it. A process that loads its own intended plugin is not automatically crossing a security boundary. A model executing an action that the requester explicitly authorized is not automatically a confused deputy.

Next name the protected resource or authority. It may be another tenant's data, a privileged operation, a release credential, a shared worker pool, a private browser state, a cloud resource, or the integrity of a process. Then identify the control that should bind the action to the right principal, resource, origin, identity, amount, state, or time. Security controls are often about relationships: this account owns that object; this callback belongs to that session; this message came from that peer; this tool call is approved for these exact arguments; this workload may act only on this resource.

Finally, state the observable result. A candidate is not strengthened by dramatic vocabulary. A parser crash does not prove code execution. An expensive operation in a requester's own process does not prove a shared denial of service. A missing second layer does not matter as a vulnerability if the first layer already prevents the attack. The skill asks the reviewer to stop at the smallest affected record, wrong return value, process-integrity effect, or shared-resource effect that actually establishes the claim.

That standard produces three different evidence states rather than one sliding scale of confidence.

A confirmed record has a complete source trace, the intended behavior, conditions, a target-native bounded reproduction with an observed result, a source-level remediation, and calibrated severity and confidence. The result must demonstrate a meaningful boundary impact. Severity is not a reward for how alarming the code looks: overall severity cannot exceed the impact that has been shown.

A needs-validation record is a source-grounded lead whose decisive fact remains outside safe observation. The record must name the claimed root cause, trace, evidence, exact blocker, and a local or owner-observed plan. It receives no severity. For example, source may show that a backend trusts a forwarded identity header, while the repository does not show whether only a trusted ingress can reach that path. The correct conclusion is not “high severity, pending confirmation,” nor “safe because the proxy probably strips it.” It is a precise unresolved boundary question and a safe way for the owner to answer it.

A rejected record preserves a disproved claim and the reason it failed. That prevents the same unsupported lead from being rediscovered as if it were new, while leaving the underlying coverage area available for different evidence. These branches are not labels for how persuasive a paragraph sounds. They are different contracts for what the record may contain and what it may claim.

The chain begins before the first finding

Because a finding depends on a boundary, the workflow maps the system before it hunts. It asks what the product does, who uses and operates it, which resources matter, where lower-trust input enters, how that input is transformed or copied, and where a security-relevant decision or sink occurs. It also asks what the repository can establish about local execution and deployment. This map prevents a common failure in automated review: mistaking a list of files or agent assignments for an understanding of authority.

The same preparation explains why coverage must be represented explicitly. “Authentication reviewed” does not say which entry surface, identity, subsystem, or attack class was examined, nor whether the parallel route, retry path, migration, or lifecycle transition received the same attention. The skill's coverage model turns those dimensions into units with stable source-derived identities, owners, reviewed paths, checks, candidate fingerprints, unresolved facts, and status. A unit can be planned, in progress, covered, blocked, or associated with a candidate; those states carry different evidence obligations.

The ledger is not a promise that every relevant bug has been found. It is a way to make the promise narrower and inspectable. Prior runs can add evidence, but unchanged source does not let a prior confirmation skip current verification. Changed source becomes revalidation work. A limited profile or budget can reduce breadth and redundancy, but it cannot lower the bar for confirmation. Work that cannot be funded or observed is marked deferred or incomplete instead of being silently counted as covered.

Safety is part of this chain, not a separate operational appendix. The skill permits source inspection but requires target-controlled builds, tests, processes, browsers, emulators, and fixtures to run only inside a sandbox with no external network, an empty allowlisted environment, read-only target and tools, scratch-only writes, and explicit resource limits. It forbids live or shared targets, real credentials, production data, publishing, stress, and paid or shared services. If those controls are unavailable, the workflow does not convert uncertainty into an unsafe experiment. It retains the source-grounded lead as needs_validation with the missing capability stated.

That choice can feel conservative when a suspicious path is easy to demonstrate against a live service. It is also what keeps the result defensible. The goal is not to maximize the visible damage of a test; it is to establish the smallest fact needed to decide whether an invariant holds. A local dummy tenant, a small fixture, a bounded function harness, or a rendered policy may be enough. Going further can add risk without adding certainty.

The practical implication for this series is that the security-audit skill should be read as a system of linked decisions. Its attack prompts matter because they are attached to boundaries discovered during reconnaissance. Its validators matter because agent output is itself an input that must not corrupt the evidence record. Its independent verifiers matter because a plausible trace is not yet a proved result. Its reports matter because communication can silently overstate what the source and local environment established.

The governing question is therefore not “How many issues did the agent find?” It is “What can an owner reconstruct, challenge, and act on?” A trustworthy answer identifies the principal, the protected resource, the intended control, the source path, the smallest observed result, and the limits of what remains unknown. Everything else—coverage breadth, domain-specific attack classes, machine-readable records, and report language—exists to preserve that chain rather than replace it.

References