Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions skills/wgo/references/reviewers/security-privacy/reviewer.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
id: security-privacy
name: Security and Privacy
summary: What material identity, credential, exposure, privacy, PII, and operating-control risks are evidenced?
version: 0.1
summary: What material identity, credential, exposure, privacy, PII, supply-chain, and operating-control risks are evidenced?
version: 0.2
codegraph: optional
depends_on:
- architecture
Expand All @@ -15,14 +15,22 @@ depends_on:
Assess evidence-bounded security and privacy posture without copying secrets or
claiming an unperformed penetration test or compliance certification. Reconcile
material public security, privacy, and disclosure claims with the available
implementation and operational evidence.
implementation and operational evidence. Answer the applicable
vulnerability-class checklist items selected from topology. For every trust
anchor the source produces, such as signatures, checksums, or provenance,
locate its consuming verifier; absent or unclear verifier use is a finding.
Identify material product-class abuse paths and assess project countermeasures
as security controls. When the brief declares an OSPS Baseline tier, assess
against that tier without claiming certification.

## Output Menu

| Category | Output and canonical path | Trigger |
|---|---|---|
| Required | Security/privacy posture | Always, in `reviewer-reports/security-privacy/report.md` |
| Required | Vulnerability-class checklist verdicts, using `vulnerability-class-checklist.md` | Always, in the report; mark non-applicable classes with reason |
| Conditional | Secret surface, credential exposure, privilege/offboarding, or trust/data-flow view in `controls/security/` | A material secret, identity, privilege, data, or boundary question is found |
| Conditional | Supply-chain and tooling results view: `controls/security/supply-chain-and-tooling.md` | Tooling, dependency, release-provenance, SBOM, or verifier evidence is material |
| Conditional | Edge exposure view: `controls/security/diagrams/edge-exposure-view.md` | Detailed work has approved DNS, TLS, ingress, WAF, or reachability evidence |
| Not owned | Business continuity ownership and technical model | Link Business Continuity and Architecture |

Expand Down Expand Up @@ -51,16 +59,22 @@ writes artifacts; collectors never call CodeGraph or shared collectors.
|---|---|---|
| Identity, secrets, and privacy boundaries | Authn/authz, service identity, secret consumers/metadata, PII/data boundaries, and lifecycle controls | `workers/identity-secrets-data-boundaries.md` |
| Edge and runtime exposure | Ingress, DNS/TLS/WAF declarations, network paths, admin/public routes, and runtime exposure configuration | `workers/edge-runtime-exposure.md` |
| Supply chain and tooling | Authorized local Scorecard, OSV, and secret-scanner runs; dependency, release-provenance, SBOM, and trust-anchor consumption evidence | `workers/supply-chain-and-tooling.md` |

## Completion Criteria

State material exposed surfaces, evidence limits, selected controls, and closure
routes without secret values or unbounded claims.
State material exposed surfaces, checklist verdicts, claim reconciliation,
trust-anchor consumption, abuse-control position, strongest security assets for
the mandate outcome, evidence limits, selected controls, and closure routes
without secret values or unbounded claims.

## Escalation Conditions

- A credential-like surface may have production privilege or unknown revocation.
- PII, tenant, or privilege boundaries are unknown on a critical path.
- A produced trust anchor has no locatable verifier on a consumption path.
- A public security, privacy, or disclosure claim materially contradicts
implementation evidence.

## Cross-Reviewer Links

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Vulnerability-Class Checklist

Loaded by the Security and Privacy reviewer. Select applicable classes from the
Architecture topology and approved evidence boundary. Answer each selected item
`verified` with a locator, `finding` with a locator, `not-applicable` with a
reason, or `unknown` with the limitation. Do not skip a selected class silently.
This checklist is derived from OWASP ASVS-style source-review questions and is
not a penetration test or certification claim.

## Input Handling And Injection

- Canonicalization: untrusted paths, slugs, URLs, hostnames, and identifiers are
normalized before validation, and validation happens after decoding.
- Injection sinks: query, command, template, header, log, and analytics sinks
use parameterization or encoding appropriate to the sink.
- Redirect or forward targets: externally influenced targets constrain protocol,
host, credentials, protocol-relative forms, backslashes, and encoded variants.
- Deserialization and parsing: untrusted formats are bounded for size, depth,
entity expansion, prototype pollution, and parser-specific hazards.

## Authentication, Session, And Access

- Verifier correctness: token signatures, issuers, audiences, algorithms, and
time claims are verified, and verification failures close access.
- Key lifecycle: verification keys have bounded fetch, cache, rotation, and
pinning behavior; stale or attacker-supplied keys are not accepted silently.
- Authorization placement: privileged routes are guarded at the handler or
enforceable boundary, not only in routing, UI state, or documentation.

## Web Platform And Edge Defenses

- Response headers: CSP, frame, content-type, and referrer policies match each
response class; relaxed policies are scoped and justified.
- CORS: allowed origins are explicit and non-reflective; credentialed responses
do not pair with permissive origins.
- Cache and CDN behavior: responses do not vary on attacker-controlled keys in a
way that enables poisoning or shared-cache data leakage.
- Request construction: no layer constructs outbound requests or headers from
untrusted input without validation and encoding.

## Data Protection And Privacy

- Data minimization: collected, logged, or forwarded fields match public
disclosure exactly, including non-pageview, background, and error events.
- Secrets in motion: secrets, tokens, and private identifiers cannot enter logs,
analytics, URLs, diagnostics, or error responses.
- Protection claims: declared transport, storage, retention, and deletion
protections are implemented where the data actually flows.

## Configuration, Operations, And Supply Chain

- Fail posture: each guard has an evidenced absent-config or dependency-failure
behavior, and the behavior matches documented intent.
- Trust-anchor consumption: every produced signature, checksum, or attestation is
verified where consumed, or the absence is reported.
- Diagnostic surfaces: debug, test, and admin surfaces are discoverable from
source, guarded, and excluded from production paths where required.
- Dependency and build integrity: lockfiles, install scripts, CI token
permissions, release provenance, and scanner results are bounded as evidence.

## Product-Class Abuse

- Identify the dominant real-world abuse paths for this product class from the
brief, topology, and public claims.
- Assess specific countermeasures as controls: presence, coverage, bypass paths,
reporting or takedown flow, and evidence limits.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
You collect supply-chain and tooling evidence for Security and Privacy; you do not write audit artifacts.
Scope: authorized local security-tool runs, dependency and lockfile state, release provenance, SBOM presence, and trust-anchor consumption.
Use the reviewer's topology packet; do not invoke CodeGraph or shared collectors.
Run tools only when the brief approves local execution; record tool name, exact version, command, and scope for every run.
Run OpenSSF Scorecard when available and authorized; record each check name, score, and unauthenticated-API limitation where it applies.
Run OSV-Scanner or the ecosystem's native audit against committed lockfiles; record each finding identifier, package, version, and fixed version.
Run a recognized secret scanner, such as gitleaks, across full history; record rule matches by locator without copying candidate secret values.
Never install project dependencies, modify lockfiles, alter repository state, or send repository content to unapproved external services.
Record whether releases publish an SBOM, provenance attestation, signed artifact, or checksum, with exact release locators.
For each produced trust anchor, locate its consuming verifier in source or documentation; record verifier presence, locator, or absence.
Do not infer exploitability, compromise, live exposure, or compliance from tool results; record bounded evidence and limitations.
If a tool cannot run, record the blocker and affected decision instead of substituting judgment.
Verify every result and give exact file, release, identifier, or check-name locators.
Separate executed observation, declared configuration, and unknown.
Return each material observation concisely:
- statement and exact locator or check identifier;
- observed / inferred / unknown status and limitation;
- affected dependency, release, anchor, or repository-control boundary;
- stable file/symbol target for shared history when rationale matters;
- candidate for the supply-chain results view or a report finding, with reason.
Combine duplicate evidence only; stop when this scope's material observations are exhausted.
19 changes: 17 additions & 2 deletions tests/test_skill_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
"product-value", "project-health", "revenue-risk", "scalability",
"security-privacy",
}
EXPECTED_REVIEWER_VERSIONS = {
"security-privacy": "0.2",
}


def reviewer_card(reviewer_id: str) -> Path:
Expand Down Expand Up @@ -67,7 +70,8 @@ def test_every_reviewer_has_a_compact_output_menu(self) -> None:
for reviewer_id, path in files.items():
content = path.read_text(encoding="utf-8")
self.assertRegex(content, rf"(?m)^id: {re.escape(reviewer_id)}$")
self.assertRegex(content, r"(?m)^version: 0\.1$")
expected_version = EXPECTED_REVIEWER_VERSIONS.get(reviewer_id, "0.1")
self.assertRegex(content, rf"(?m)^version: {re.escape(expected_version)}$")
self.assertRegex(content, r"(?m)^codegraph: (?:none|optional|required)$")
dependencies = set(frontmatter_dependencies(path))
self.assertLessEqual(dependencies, EXPECTED_REVIEWERS)
Expand Down Expand Up @@ -660,6 +664,17 @@ def test_minor_evidence_and_reviewer_improvements_remain_bounded(self) -> None:
self.assertIn("public security, privacy, and disclosure claims", security)
self.assertIn("abuse or\nmisuse controls", security)
self.assertIn("trust material to its consumer validation", identity)
self.assertIn("vulnerability-class checklist", security)
self.assertIn("OSPS Baseline tier", security)
self.assertIn("trust-anchor consumption", security)
self.assertIn("supply-chain-and-tooling.md", security)

checklist = (REVIEWERS / "security-privacy/vulnerability-class-checklist.md").read_text(encoding="utf-8")
tooling = (REVIEWERS / "security-privacy/workers/supply-chain-and-tooling.md").read_text(encoding="utf-8")
for phrase in ("Canonicalization", "Data minimization", "Product-Class Abuse"):
self.assertIn(phrase, checklist)
for phrase in ("OpenSSF Scorecard", "OSV-Scanner", "gitleaks", "SBOM", "trust anchor"):
self.assertIn(phrase, tooling)

def test_structural_validation_is_optional(self) -> None:
workflow = (SKILL / "references/common/reviewer-audit.md").read_text(encoding="utf-8")
Expand Down Expand Up @@ -730,7 +745,7 @@ def test_workerized_reviewers_have_one_preflight_and_compact_collectors(self) ->
"architecture": 3,
"code-quality": 4,
"product-value": 5,
"security-privacy": 2,
"security-privacy": 3,
"business-continuity": 2,
"scalability": 2,
"contributor-vendor-value": 1,
Expand Down