agentsclimarketplace

Threat modeling

Skill ShieldNet-360/secure-vibe/dist/copilot-skills/.github/skills/threat-modeling

Review a design or architecture for security flaws — trust boundaries, authorization, data flow, and attack surface — before code is written — Applies to: when scaffolding a new feature, service, or endpoint; when writing or reviewing a design doc / RFC / ADR; when introducing a new trust boundary, integration, or data flow; when reviewing an architecture or module at the design levelFrom its SKILL.md

Install
npx -y skills add ShieldNet-360/secure-vibe --skill threat-modeling

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

5.3 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it

<!-- Native skill bundle for GitHub Copilot. Generated by `secure-vibe dev regenerate`. --> <!-- Do not edit by hand; the source of truth is skills/threat-modeling/SKILL.md. -->

Threat Modeling

Review a design or architecture for security flaws — trust boundaries, authorization, data flow, and attack surface — before code is written

ALWAYS

  • Start a new feature/service by naming the assets (data, funds, credentials, keys, compute) and the actors (users, tenants, services, admins, attackers). You cannot secure what you have not named.
  • Draw the trust boundaries — every point where data crosses from a less-trusted zone to a more-trusted one (internet→app, tenant→shared store, service→service, user-input→interpreter). Each crossing needs authentication, authorization, and input validation at the crossing.
  • Treat authorization as a design decision: for every resource decide who may read/write it and enforce it at the object level (owner/tenant scoping), not just "is authenticated". Design tenant isolation as a boundary the data model enforces, not a WHERE-clause a developer must remember every time.
  • Map the data flow of every sensitive datum (credentials, PII, tokens, keys, financial): where it enters, is stored, transits, and leaves, and who can read it at each hop. Apply least-privilege and encryption at rest / in transit by design.
  • Enumerate the attack surface each change adds — a new endpoint, input, dependency, integration, permission, or externally-reachable component — and state the threat + the control for each before writing code.
  • Design controls to fail closed / deny by default: on error, missing config, or an unhandled case, the secure outcome is to deny, not to allow.
  • Put each control at the component that owns the asset, behind (not instead of) any gateway — the owning service must authenticate and authorize even when a perimeter also does. Reachability is not trust.
  • Run a one-line STRIDE pass at each trust boundary: Spoofing (identity), Tampering (integrity), Repudiation (audit trail), Information disclosure (confidentiality), Denial of service (availability), Elevation of privilege (authz). Skip the categories that genuinely do not apply.

NEVER

  • Push a security decision to the client / edge and treat it as enforced. Anything the client controls — hidden fields, disabled buttons, client-side role checks, a signed-but-unverified token — is advisory, never a control.
  • Design a shared or global namespace (global gallery, shared catalog, org-wide list) that any authenticated user can write to without a function-level privilege gate — a low-privilege writer into a globally-visible store is a stored-XSS / malicious-link delivery vector.
  • Rely on network position (private subnet, VPN, "internal-only", IP allowlist, WAF) as the only control on a sensitive component. One SSRF, one foothold, or one boundary change opens it. Network is defense-in-depth, not the auth boundary.
  • Let "trusted internal service" mean "unauthenticated". Internal callers get spoofed (SSRF, a compromised peer, a new tenant on the network). Authenticate service-to-service (mTLS / SPIFFE); do not trust source IP.
  • Invent a bespoke crypto, authentication, session, or access-control primitive when a vetted one exists. Design in the standard building block (OIDC, mTLS, a policy engine); do not hand-roll security mechanics.
  • Add a new external integration, dependency, or webhook without a threat entry: who may call it, what it is trusted to assert, and what happens if the counterparty is compromised or spoofed.
  • Decide at design time to store or log secrets/PII in a place the model did not sanction — logs, error payloads, client bundles, URL params, analytics. Name the one sanctioned home for each sensitive datum instead.
  • Ship a design whose only security analysis is "we will add auth later". Retrofitting a trust boundary onto a built feature is exactly where the expensive misses happen.

KNOWN FALSE POSITIVES

  • A genuinely public, read-only, non-tenant surface (marketing site, public docs, public catalog) legitimately has no auth. The model's job is to confirm it holds nothing sensitive, not to bolt auth onto it.
  • Defense-in-depth network controls (mTLS mesh, NetworkPolicy, private ingress) layered on top of service-level auth are good design, not a finding — the anti-pattern is only when they are the sole control.
  • mTLS / SPIFFE workload identity is authentication (a cryptographic caller identity), so service-to-service calls over it do not also need network-position distrust.
  • A prototype/spike explicitly scoped as non-production with no real data does not need a full model — but "must not ship / must not touch prod data" is itself the control to state.
  • Not every function needs its own STRIDE table. Apply the pass at trust boundaries and asset stores, not to pure or internal helpers with no security-relevant input.

What ships with it: 1 file

1.0 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.