Generated banner for Threat Model Analyst
Generated logo for Threat Model Analyst

Threat Model Analyst

GitHubOfficialFirst committed by cheguvDistributed by GitHub

  • Skill
  • Review and audit
  • Security
  • MIT
  • No issues found

From the author

Full STRIDE-A threat model analysis and incremental update skill for repositories and systems. Supports two modes: (1) Single analysis — full STRIDE-A threat model of a repository, producing architecture overviews, DFD diagrams, STRIDE-A analysis, prioritized findings, and executive assessments. (2) Incremental analysis — takes a previous threat model report as baseline, compares the codebase at the latest (or a given commit), and produces an updated report with change tracking (new, resolved, still-present threats), STRIDE heatmap, findings diff, and an embedded HTML comparison. Only activate when the user explicitly requests a threat model analysis, incremental update, or invokes /threat-model-analyst directly.
— the description by cheguv

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

Threat Model Analyst is a specialized agent skill designed to perform rigorous security audits using the STRIDE-A (STRIDE + Abuse) methodology. It operates in two primary modes: a full initial analysis for new systems and an incremental mode for tracking security posture changes over time. The skill enforces strict architectural modeling rules, particularly regarding Kubernetes sidecar co-location, and provides structured, evidence-based reporting including DFD diagrams, prioritized findings, and executive assessments.

What it does

  • Performs full STRIDE-A threat modeling including DFD generation and architectural risk assessment.
  • Executes incremental analysis to track new, resolved, and persistent threats between code versions.
  • Identifies security gaps by verifying infrastructure components and platform defaults before flagging.
  • Generates standardized security reports including architecture overviews and prioritized findings.
  • Maps security findings to industry standards like CVSS 4.0, CWE, and OWASP.
  • Enforces consistent diagramming conventions for complex system architectures.

When to use it

  • When you need a comprehensive security audit of a new repository or system architecture.
  • When you need to update an existing threat model to reflect recent code changes.
  • When you need to compare the security posture between two specific commits or report versions.
  • When you need to identify trust boundary violations or architectural security risks.

Advantages

  • Reduces false positives by requiring evidence-based verification of security controls.
  • Maintains continuity in security documentation through incremental change tracking.
  • Ensures architectural diagrams accurately reflect Kubernetes pod-level sidecar co-location.
  • Provides actionable, prioritized security findings mapped to recognized industry frameworks.

Usage examples

“Perform a full STRIDE-A threat model analysis on this repository.”
The agent will analyze the codebase, generate architecture diagrams, identify threats, and produce a comprehensive security report.
“Run an incremental threat model analysis using the report from last week as a baseline.”
The agent will compare the current codebase against the previous report to identify new, fixed, or remaining security threats.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/github/threat-model-analyst/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip threat-model-analyst.zip -d .agents/skills

Documentation by cheguv

Threat Model Analyst

You are an expert Threat Model Analyst. You perform security audits using STRIDE-A (STRIDE + Abuse) threat modeling, Zero Trust principles, and defense-in-depth analysis. You flag secrets, insecure boundaries, and architectural risks.

Getting Started

FIRST — Determine which mode to use based on the user's request:

Incremental Mode (Preferred for Follow-Up Analyses)

If the user's request mentions updating, refreshing, or re-running a threat model AND a prior report folder exists:

  • Action words: "update", "refresh", "re-run", "incremental", "what changed", "since last analysis"

  • AND a baseline report folder is identified (either explicitly named or auto-detected as the most recent threat-model-* folder with a threat-inventory.json)

  • OR the user explicitly provides a baseline report folder + a target commit/HEAD

Examples that trigger incremental mode:

  • "Update the threat model using threat-model-20260309-174425 as the baseline"

  • "Run an incremental threat model analysis"

  • "Refresh the threat model for the latest commit"

  • "What changed security-wise since the last threat model?"

→ Read incremental-orchestrator.md and follow the incremental workflow. The incremental orchestrator inherits the old report's structure, verifies each item against current code, discovers new items, and produces a standalone report with embedded comparison.

Comparing Commits or Reports

If the user asks to compare two commits or two reports, use incremental mode with the older report as the baseline. → Read incremental-orchestrator.md and follow the incremental workflow.

Single Analysis Mode

For all other requests (analyze a repo, generate a threat model, perform STRIDE analysis):

→ Read orchestrator.md — it contains the complete 10-step workflow, 34 mandatory rules, tool usage instructions, sub-agent governance rules, and the verification process. Do not skip this step.

Reference Files

Load the relevant file when performing each task:

FileUse WhenContent
OrchestratorAlways — read firstComplete 10-step workflow, 34 mandatory rules, sub-agent governance, tool usage, verification process
Incremental OrchestratorIncremental/update analysesComplete incremental workflow: load old skeleton, change detection, generate report with status annotations, HTML comparison
Analysis PrinciplesAnalyzing code for security issuesVerify-before-flagging rules, security infrastructure inventory, OWASP Top 10:2025, platform defaults, exploitability tiers, severity standards
Diagram ConventionsCreating ANY Mermaid diagramColor palette, shapes, sidecar co-location rules, pre-render checklist, DFD vs architecture styles, sequence diagram styles
Output FormatsWriting ANY output fileTemplates for 0.1-architecture.md, 1-threatmodel.md, 2-stride-analysis.md, 3-findings.md, 0-assessment.md, common mistakes checklist
SkeletonsBefore writing EACH output file8 verbatim fill-in skeletons (skeleton-*.md) — read the relevant skeleton, copy VERBATIM, fill [FILL] placeholders. One skeleton per output file. Loaded on-demand to minimize context usage.
Verification ChecklistFinal verification pass + inline quick-checksAll quality gates: inline quick-checks (run after each file write), per-file structural, diagram rendering, cross-file consistency, evidence quality, JSON schema — designed for sub-agent delegation
TMT Element TaxonomyIdentifying DFD elements from codeComplete TMT-compatible element type taxonomy, trust boundary detection, data flow patterns, code analysis checklist

When to Activate

Incremental Mode (read incremental-orchestrator.md for workflow):

  • Update or refresh an existing threat model analysis

  • Generate a new analysis that builds on a prior report's structure

  • Track what threats/findings were fixed, introduced, or remain since a baseline

  • When a prior threat-model-* folder exists and the user wants a follow-up analysis

Single Analysis Mode:

  • Perform full threat model analysis of a repository or system

  • Generate threat model diagrams (DFD) from code

  • Perform STRIDE-A analysis on components and data flows

  • Validate security control implementations

  • Identify trust boundary violations and architectural risks

  • Write prioritized security findings with CVSS 4.0 / CWE / OWASP mappings

Comparing commits or reports:

  • To compare security posture between commits, use incremental mode with the older report as baseline

Files

references/analysis-principles.md

Analysis Principles — Security Analysis Methodology

This file contains ALL rules for how to analyze code for security threats. It is self-contained — everything needed to perform correct, evidence-based security analysis is here.


⛔ CRITICAL: Verify Before Flagging

NEVER flag a security gap without confirming it exists. Many platforms have secure defaults.

Three-Step Verification
  1. Check for security infrastructure components before claiming security is missing:

    • Certificate authorities (Dapr Sentry, cert-manager, Vault)

    • Service mesh control planes (Istio, Linkerd, Dapr)

    • Policy engines (OPA, Kyverno, Gatekeeper)

    • Secret managers (Vault, Azure Key Vault, AWS Secrets Manager)

    • Identity providers (MISE, OAuth proxies, OIDC)

  2. Understand platform defaults — research before assuming:

    • Dapr: mTLS enabled by default when Sentry is deployed

    • Kubernetes: RBAC enabled by default since v1.6

    • Istio: mTLS in PERMISSIVE mode by default, STRICT available

    • Azure: Many services encrypted at rest by default

  3. Distinguish configuration states:

    • Explicitly disabled: enabled: false → Flag as finding

    • Not configured: No setting present → Check platform default first

    • Implicitly enabled: Default behavior is secure → Document as control, not gap

Evidence Quality Requirements

For every finding:

  • Show the specific config/code that proves the gap (not just absence of config)

  • For "missing security" claims, prove the default is insecure

  • Cross-reference with platform documentation when uncertain


Security Infrastructure Inventory

Before STRIDE-A analysis, identify ALL security-enabling components present in the codebase:

CategoryComponents to Look ForSecurity They Provide
Service MeshDapr, Istio, Linkerd, Consul ConnectmTLS, traffic policies, observability
Certificate ManagementSentry, cert-manager, Vault PKIAutomatic cert issuance/rotation
AuthenticationMISE, OAuth2-proxy, Dex, KeycloakToken validation, SSO
AuthorizationOPA, Kyverno, Gatekeeper, RBACPolicy enforcement
SecretsVault, External Secrets, CSI driversSecret injection, rotation
NetworkNetworkPolicy, Calico, CiliumMicrosegmentation

If these components exist, their security features are likely active unless explicitly disabled.


Security Analysis Lenses

Apply these frameworks during analysis:

  • Zero Trust: Verify explicitly, least privilege, assume breach

  • Defense in Depth: Identify missing security layers

  • Abuse Cases: Business logic abuse, workflow manipulation, feature misuse


Comprehensive Coverage Requirements

Do NOT truncate analysis for larger codebases. All components must receive equal analytical depth.

Sidecar Security Analysis

⚠️ Sidecars (Dapr, MISE, Envoy, etc.) are NOT separate components in the DFD — they are co-located in the same pod as the primary container (see diagram-conventions.md Rule 2). However, sidecar communication MUST still be analyzed for security vulnerabilities.

How to analyze sidecar threats:

  • Sidecars with distinct threat surfaces (e.g., MISE auth bypass, Dapr mTLS) get their own ## Component section in 2-stride-analysis.md — but are NOT separate DFD nodes (see diagram-conventions.md Rule 2)

  • Use the format: threat title includes the sidecar name, e.g., "Dapr Sidecar Plaintext Communication"

  • Common sidecar threats:

    • Information Disclosure (I): Dapr/MISE sidecar communicating with main container over plaintext HTTP within the pod

    • Tampering (T): Dapr pub/sub messages not signed or encrypted

    • Spoofing (S): MISE token validation bypass if sidecar is compromised

    • Elevation of Privilege (E): Sidecar running with elevated privileges that the main container doesn't need

  • CWE mapping: CWE-319 (Cleartext Transmission), CWE-311 (Missing Encryption), CWE-250 (Unnecessary Privileges)

  • These threats appear in the sidecar's own STRIDE section (if it has a distinct threat surface) or under the primary component's table (if the sidecar is a simple infrastructure proxy)

  • If the sidecar vulnerability warrants a finding, list it under the sidecar component with a note: "Affects [Dapr/MISE] sidecar communication"

  1. Minimum coverage: Every component in 0.1-architecture.md MUST have a corresponding section in 2-stride-analysis.md with actual threat enumeration (not just "no threats found").

  2. Finding density check: As a guideline, expect roughly 1 finding per 2-3 significant components. If a repo has 15+ components and you have fewer than 8 findings, re-examine under-analyzed components.

  3. Use sub-agents for scale: For repos with 10+ components, delegate component-specific STRIDE analysis to sub-agents to maintain depth. Each sub-agent should analyze 3-5 components.

  4. OWASP checklist sweep: After component-level STRIDE, do a cross-cutting pass using the OWASP Top 10:2025 checklist below. This catches systemic issues (missing auth, no audit logging, no rate limiting, unsigned images) that component-level analysis may miss.

  5. Infrastructure-layer check: Explicitly check for: container security contexts, network policies, resource limits, image signing, secrets management, backup/DR controls, and monitoring/alerting gaps.

  6. Exhaustive findings consolidation: After STRIDE analysis is complete, scan the STRIDE output for ALL identified threats. Every threat MUST map to either:

    • A finding in 3-findings.md (consolidated with related threats)

    • A 🔄 Mitigated by Platform entry in the Threat Coverage Verification table (for platform-handled threats only)

    ⛔ EVERY Open THREAT MUST HAVE A FINDING. The tool does NOT have authority to accept risks, defer threats, or decide that a threat is "acceptable." That is the engineering team's decision. The tool's job is to identify ALL threats and create findings for them. The Coverage table should show ✅ Covered (FIND-XX) for every Open threat — NEVER ⚠️ Accepted Risk.

    If you have 40+ threats in STRIDE but only 10 findings, you are under-consolidating. Check for missed data store auth, operational controls, credential management, and supply chain issues.

    ⛔ "ACCEPTED RISK" IS FORBIDDEN (MANDATORY):

    • NEVER use ⚠️ Accepted Risk as a Coverage table status. This label implies the tool has accepted a risk on behalf of the engineering team. It has not. It cannot.

    • NEVER use Accepted as a STRIDE Status value. Use Open, Mitigated, or Platform only.

    • If you are tempted to write "Accepted Risk" → create a finding instead. The finding's remediation section tells the team what to do. The team decides whether to accept, fix, or defer.

    ⛔ NEEDS REVIEW RESTRICTIONS (MANDATORY):

    • Tier 1 threats (prerequisites = None) MUST NEVER be classified as "⚠️ Needs Review." A threat exploitable by an unauthenticated external attacker cannot be deferred — it MUST become a finding.

    • If a threat has a mitigation listed in the STRIDE analysis, it SHOULD become a finding. The mitigation text is the remediation — use it to write the finding. Only defer to "Needs Review" if the mitigation is genuinely not actionable.

    • DoS threats with None prerequisites are Tier 1 findings, not hardening opportunities. An unauthenticated attacker flooding an API with no rate limiting is a directly exploitable vulnerability (CWE-770, CWE-400).

    • Do NOT batch-classify entire STRIDE categories as Needs Review. Each threat must be evaluated individually based on its prerequisites and exploitability.

    • "⚠️ Needs Review" is reserved for: Tier 2/3 threats where no technical mitigation is possible (e.g., social engineering), or threats requiring business context the tool doesn't have.

    • The automated analysis does NOT have authority to accept risks — it only identifies them. "Needs Review" signals that a human must decide.

    • Maximum Needs Review ratio: If more than 30% of threats are classified as "Needs Review", re-examine — you are likely under-reporting findings. Typical ratio: 10-20% for a well-analyzed codebase.

  7. Minimum finding thresholds by repo size:

    • Small repo (< 20 source files): 8+ findings expected

    • Medium repo (20-100 source files): 12+ findings expected

    • Large repo (100+ source files): 18+ findings expected

    If below threshold, systematically review: auth per component, secrets in code, container security, network segmentation, logging/monitoring, input validation.

  8. Context-aware Platform ratio limits (MANDATORY):

    After completing the security infrastructure inventory (Step 1), detect the deployment pattern:

    PatternDetection SignalPlatform Limit
    K8s Operatorcontroller-runtime, kubebuilder, or operator-sdk in go.mod/go.sum; Reconcile() functions in source≤35%
    Standalone ApplicationAll other repos (web apps, CLI tools, services)≤20%

    Why K8s operators have higher Platform ratios: Operators delegate security to the K8s platform (RBAC for CR access, etcd encryption, API server TLS, webhook cert validation, Azure AD token validation). The operator code CANNOT implement these controls — they are the platform's responsibility. Classifying them as Platform is correct.

    Action when Platform exceeds limit:

    • Review each Platform-classified threat

    • If the operator CAN take action (e.g., add input validation, add RBAC checks at startup) → reclassify as Open with a finding

    • If the operator genuinely cannot act (e.g., etcd encryption is a cluster admin concern) → Platform is correct

    • Document the detected pattern and ratio in 0-assessment.md → Analysis Context & Assumptions


Technology-Specific Security Checklist

After completing STRIDE analysis, scan the codebase for each technology below. For every technology found, verify the corresponding security checks are covered in findings or documented as mitigated. This catches specific vulnerabilities that component-level STRIDE often misses.

Technology FoundMUST Check ForCommon Finding
Redisrequirepass disabled, no TLS, no ACLAuth disabled by default → finding
MilvusauthorizationEnabled: false, no TLS, public gRPC portAuth disabled by default → finding
PostgreSQL/SQL DBSuperuser usage, ssl=false, SQL injection, connection string credentialsInput validation + auth
MongoDBAuth disabled, no TLS, --noauth flagAuth disabled by default
NGINX/IngressMissing TLS, server_info headers, snippet injection, rate limitingConfig hardening
Docker/ContainersRunning as root, no USER directive, host mounts, no seccomp/AppArmor, unsigned imagesContainer hardening
ML/AI ModelsUnauthenticated inference endpoint, model poisoning, prompt injection, no input validationEndpoint auth + input validation
LLM/Cloud AIPII/secrets sent to external LLM, no content filtering, prompt injection, data exfiltrationData exposure to cloud
KubernetesNo NetworkPolicy, no PodSecurityPolicy/Standards, no resource limits, RBAC gapsNetwork segmentation + resource limits
Helm ChartsHardcoded secrets in values.yaml, no image tag pinning, no security contextsConfig + supply chain
Key ManagementHardcoded RSA/HMAC keys, weak key generation, no rotation, keys in sourceCryptographic failures
CI/CD PipelinesSecrets in logs, no artifact signing, mutable dependencies, script injectionSupply chain
REST APIsMissing auth, no rate limiting, verbose errors, no input validationAuth + injection
gRPC ServicesNo TLS, no auth interceptor, reflection enabled in productionAuth + encryption
Message QueuesNo auth on pub/sub, no encryption, no message signingAuth + integrity
NFS/File SharesPath traversal, no access control, world-readable mountsAccess control
Audit/LoggingNo security event logging, log injection, no tamper protectionMonitoring gaps

Process: After writing 3-findings.md, scan this table for technologies present in the repo. For each technology, evaluate its common technology-specific threat patterns based on how that technology is actually used, and ensure any relevant risks are accounted for in the assessment. Add a finding only if an actual threat or meaningful mitigation gap is identified.


OWASP Top 10:2025 Checklist

Check for these vulnerability categories during analysis:

IDCategoryCheck For
A01Broken Access ControlMissing authZ, privilege escalation, IDOR, CORS misconfig
A02Security MisconfigurationDefault creds, verbose errors, unnecessary features, missing hardening
A03Software Supply Chain FailuresVulnerable dependencies, malicious packages, compromised CI/CD
A04Cryptographic FailuresWeak algorithms, exposed secrets, improper key management, plaintext data
A05InjectionSQL, NoSQL, OS command, LDAP, XSS, template injection
A06Insecure DesignMissing security controls at architecture level, threat modeling gaps
A07Authentication FailuresBroken auth, weak sessions, credential stuffing, missing MFA
A08Software/Data Integrity FailuresInsecure deserialization, unsigned updates, CI/CD tampering
A09Security Logging & Alerting FailuresMissing audit logs, no alerting, log injection, insufficient monitoring
A10Mishandling of Exceptional ConditionsPoor error handling, race conditions, resource exhaustion

Reference: https://owasp.org/Top10/2025/


Platform Security Defaults Reference

Before flagging missing security, check these common secure-by-default behaviors:

PlatformFeatureDefault BehaviorHow to Verify
DaprmTLSEnabled when Sentry deployedCheck for dapr_sentry or sentry component
DaprAccess ControlDeny if policies definedLook for accessControl in Configuration
KubernetesRBACEnabled since v1.6Check --authorization-mode includes RBAC
KubernetesSecretsBase64 encoded (not encrypted)Check for encryption provider config
IstiomTLSPERMISSIVE by defaultCheck PeerAuthentication resources
Azure StorageEncryption at restEnabled by defaultAlways encrypted, check key management
Azure SQLTDEEnabled by defaultTransparent data encryption on
PostgreSQLSSLOften disabled by defaultCheck ssl parameter
RedisAuthDisabled by defaultCheck requirepass configuration
MilvusAuthDisabled by defaultCheck authorizationEnabled
NGINX IngressTLSNot enabled by defaultCheck for TLS secret in Ingress
DockerUserRoot by defaultCheck USER in Dockerfile

Key insight: Service meshes (Dapr, Istio, Linkerd) typically enable mTLS automatically. Databases (Redis, Milvus, MongoDB) typically have auth disabled by default.


Exploitability Tiers

Threats are classified into three exploitability tiers based on prerequisites:

TierLabelPrerequisitesAssignment Rule
Tier 1Direct ExposureNoneExploitable by unauthenticated external attacker with NO prior access.
Tier 2Conditional RiskSingle prerequisiteRequires exactly ONE form of access: Authenticated User, Privileged User, Internal Network, or single {Boundary} Access.
Tier 3Defense-in-DepthMultiple prerequisites or infrastructure accessRequires Host/OS Access, Admin Credentials, {Component} Compromise, Physical Access, or multiple prerequisites with +.
Tier Assignment Rules

⛔ CANONICAL PREREQUISITE → TIER MAPPING (deterministic, no exceptions):

Prerequisites MUST use only these values (closed enum). The tier follows mechanically:

PrerequisiteTierRationale
NoneTier 1Unauthenticated external attacker, no prior access
Authenticated UserTier 2Requires valid credentials
Privileged UserTier 2Requires admin/operator role
Internal NetworkTier 2Requires position on internal network
Local Process AccessTier 2Requires code execution on same host (localhost listener, IPC)
Host/OS AccessTier 3Requires filesystem, console, or debug access to the host
Admin CredentialsTier 3Requires admin credentials + host access
Physical AccessTier 3Requires physical presence (USB, serial)
{Component} CompromiseTier 3Requires prior compromise of another component
Any A + B combinationTier 3Multiple prerequisites = always Tier 3

⛔ FORBIDDEN prerequisite values: Application Access, Host Access (ambiguous — use Local Process Access or Host/OS Access).

Deployment context overrides: If Deployment Classification is LOCALHOST_DESKTOP or LOCALHOST_SERVICE, the prerequisite None is FORBIDDEN for all components — use Local Process Access or Host/OS Access instead. The tier then follows from the corrected prerequisite.

⛔ Prerequisite Determination (MANDATORY — Evidence-Based, Not Judgment-Based)

Prerequisites MUST be determined from deployment configuration evidence, not from general knowledge or assumptions. Two independent analysis runs on the same code MUST assign the same prerequisites because they are objective facts about the deployment.

Generic Decision Procedure (applies to ALL environments):

  1. Network Exposure Check — Is the component reachable from outside?

    • Look for evidence of external exposure in the codebase:

      • API gateway / reverse proxy routes pointing to the component

      • Firewall rules or security group configurations

      • Load balancer configurations

      • DNS records or public endpoint definitions

    • If ANY external route exists → prerequisites = None for network-based threats

    • If NO external route exists AND the component is on an internal-only network → prerequisites = Internal Network

  2. Authentication Check — Does the endpoint require credentials?

    • Look for authentication middleware, decorators, or filters in the component's code:

      • @require_auth, [Authorize], @login_required, auth middleware in Express/FastAPI

      • API key validation in request handlers

      • OAuth/OIDC token validation

      • mTLS certificate requirements

    • If auth is ENFORCED on all endpoints → prerequisite = Authenticated User

    • If auth is OPTIONAL or DISABLED by config flag → prerequisite = None (disabled auth = no barrier)

    • If auth exists but has bypass routes (e.g., /health, /metrics without auth) → those specific routes have prerequisite = None

  3. Authorization Check — What level of access is required?

    • If no RBAC/role check beyond authentication → prerequisite stays Authenticated User

    • If admin/operator role required → prerequisite = Privileged User

    • If specific permissions required → prerequisite names the permission (e.g., ClusterAdmin Role)

  4. Physical/Local Access Check:

    • If the component only listens on localhost/127.0.0.1 → prerequisite = Local Process Access (T2)

    • If access requires console/SSH/filesystem → prerequisite = Host/OS Access (T3)

    • If access requires physical presence (USB, serial port) → prerequisite = Physical Access (T3)

    • If component has no listener (console app, library, outbound-only) → prerequisite = Host/OS Access (T3)

  5. Default Rule: If you cannot determine exposure from config → look up the component's Min Prerequisite in the Component Exposure Table. If the table is not yet filled, assume Local Process Access (T2) as a safe default for unknown components. NEVER assume None without positive evidence of external reachability. NEVER assume Internal Network without evidence of network restriction.

Platform-Specific Evidence Sources:

PlatformWhere to check exposureInternal indicatorExternal indicator
KubernetesService type, Ingress rules, values.yamlClusterIP service, no IngressLoadBalancer/NodePort, Ingress path exists
Docker Composeports: mapping, network configNo ports: mapping, internal network onlyports: "8080:8080" maps to host
Azure App ServiceApp settings, access restrictionsVNet integration, private endpointPublic URL, no IP restrictions
VM / Bare MetalFirewall rules, NSG, iptablesPort blocked in firewall/NSGPort open, public IP bound
Serverless (Functions)Function auth level, API ManagementauthLevel: function/adminauthLevel: anonymous
.NET / Java / NodeStartup config, middleware pipelineapp.UseAuthentication() enforcedNo auth middleware, or auth disabled
Python (FastAPI/Flask)Middleware, dependency injectionDepends(get_current_user) on routesNo auth dependency, open routes

⛔ NEVER assign prerequisites based on "what seems reasonable" or architecture assumptions. Check the actual deployment config. The same component MUST get the same prerequisite across runs because the config doesn't change between runs.

Common violations:

  • Assigning Internal Network to a component that has an ingress route → hides real external exposure

  • Assuming databases are "internal only" without checking if they have a public endpoint or ingress route

  • Assuming ML model servers are "internal" when they may be exposed for direct inference requests

CVSS-to-Tier Consistency Check (MANDATORY)

After assigning CVSS vectors AND tiers, cross-check for contradictions:

CVSS MetricValueTier Implication
AV:L (Attack Vector: Local)Requires local accessCannot be Tier 1 — must be T2 or T3
AV:A (Attack Vector: Adjacent)Requires adjacent networkCannot be Tier 1 — must be T2 or T3
AV:P (Attack Vector: Physical)Requires physical accessMust be Tier 3
PR:H (Privileges Required: High)Requires admin/privileged accessCannot be Tier 1 — must be T2 or T3
PR:L (Privileges Required: Low)Requires authenticated userCannot be Tier 1 — must be T2
PR:N + AV:NNo privileges, network accessibleTier 1 candidate (confirm no deployment override)

⚠️ If a finding has AV:L and Tier 1, this is ALWAYS an error. Fix by either:

  • Changing the tier to T2/T3 (correct approach for localhost-only services), OR

  • Changing the CVSS AV to AV:N if the service is actually network-accessible (rare)

⚠️ If a finding has PR:H and Tier 1, this is ALWAYS an error. Admin-required findings are T2 minimum.

Deployment Context Affects Tier Classification

CRITICAL: This section OVERRIDES the default tier rules above when specific deployment conditions apply.

Before assigning tiers, determine the system's deployment model from code, docs, and architecture. Record the Deployment Classification and Component Exposure Table in 0.1-architecture.md (see skeleton-architecture.md).

Deployment Classifications and their tier implications:

ClassificationDescriptionT1 Allowed?Min Prerequisite
LOCALHOST_DESKTOPConsole/GUI app, no network listeners (or localhost-only), single-user workstation❌ NO — all findings T2+Host/OS Access (T3) or Local Process Access (T2)
LOCALHOST_SERVICEDaemon/service binding to 127.0.0.1 only❌ NO — all findings T2+Local Process Access (T2)
AIRGAPPEDNo internet connectivity❌ for network-originated attacksInternal Network
K8S_SERVICEKubernetes Deployment with ClusterIP/LoadBalancer✅ YESDepends on Service type
NETWORK_SERVICEPublic API, cloud endpoint, internet-facing✅ YESNone (if no auth)

The Component Exposure Table in 0.1-architecture.md sets the prerequisite floor per component. No threat or finding may have a lower prerequisite than the table permits. This table is filled in Step 1 and is binding on all subsequent analysis steps.

Legacy override table (still applies as fallback):

Deployment IndicatorTier Override Rule
Binds to localhost/127.0.0.1 onlyCannot be T1 — requires local access (T2 minimum)
Air-gapped / no internetDowngrade network-based attacks by one tier
Single-admin workstation toolCannot be T1 unless exploitable by a non-admin local user
Docker/container on single machineDocker socket access = T2 (local admin required)
Named pipe / Unix socketCannot be T1 — requires local process access

How to apply:

  1. In Step 1 (context gathering), identify deployment model and record in 0.1-architecture.md

  2. In Step 6/7 (finding verification), check each T1 candidate against the table above

  3. If ANY override applies, downgrade to T2 (or T3 if multiple)

  4. Document the override rationale in the finding’s Description

Example: Kusto container on air-gapped workstation, listening on port 80 without auth:

  • Default classification: T1 (unauthenticated, port 80)

  • Override: localhost-only + single-admin → T2 (attacker needs local access to an admin workstation)

Do NOT override for:

  • Kubernetes services (any pod can reach them → lateral movement is realistic → keep T1)

  • Network-exposed APIs (any network user can reach them → keep T1)

  • Cloud endpoints (public internet → keep T1)

  • Network-exposed APIs: An unauthenticated API on a listening port IS Tier 1.

The prerequisite for Tier 1 is None — meaning an unauthenticated external attacker with no prior access. If exploiting a vulnerability requires local admin access, OS-level access, or physical presence, it cannot be Tier 1.


Finding Classification

Before documenting each finding, verify:

  • [ ] Positive evidence exists: Can you show config/code that proves the vulnerability?

  • [ ] Not a secure default: Have you checked if the platform enables security by default?

  • [ ] Security infrastructure checked: Did you look for Sentry/cert-manager/Vault/etc.?

  • [ ] Explicit vs implicit: Is security explicitly disabled, or just not explicitly enabled?

  • [ ] Platform documentation consulted: When uncertain, verify against official docs

Classification outcomes:

  • Confirmed: Positive evidence of vulnerability → Document as finding in 3-findings.md

  • Needs Verification: Unable to confirm but potential risk → Add to "Needs Verification" in 0-assessment.md

  • Not a Finding: Confirmed secure by default or explicitly enabled → Do not document


Severity Standards

SDL Bugbar Severity

Classify each finding per: https://www.microsoft.com/en-us/msrc/sdlbugbar

CVSS 4.0 Score

Use CVSS v4.0 Base score (0.0-10.0) with vector string. Reference: https://www.first.org/cvss/v4.0/specification-document

CWE

Assign Common Weakness Enumeration ID and name. Reference: https://cwe.mitre.org/

OWASP

Map to OWASP Top 10:2025 category if applicable (A01-A10). ALWAYS use :2025 suffix (e.g., A01:2025), never :2021. Reference: https://owasp.org/Top10/2025/

Remediation Effort
  • Low: Configuration change, flag toggle, or single-file fix

  • Medium: Multi-file code change, new validation logic, or dependency update

  • High: Architecture change, new component, or cross-team coordination

STRIDE Scope Rule
  • External services (AzureOpenAI, AzureAD, Redis, PostgreSQL) DO get STRIDE sections — they are attack surfaces from your system's perspective

  • External actors (Operator, EndUser) do NOT get STRIDE sections — they are threat sources, not targets

  • If you have 20 elements and 2 are external actors, you write 18 STRIDE sections

⚠️ DO NOT include time estimates. Never add "(hours)", "(days)", "(weeks)", "~1 hour", "~2 hours", or any duration/effort-to-fix estimates anywhere in the output. The effort level (Low/Medium/High) is sufficient.

Mitigation Type (OWASP-aligned)
  • Redesign: Eliminate the threat by changing architecture (OWASP: Avoid)

  • Standard Mitigation: Apply well-known, proven security controls (OWASP: Mitigate)

  • Custom Mitigation: Implement a bespoke code fix specific to this system (OWASP: Mitigate)

  • Existing Control: Team already built a control that addresses this threat — document it (OWASP: Fix)

  • Accept Risk: Acknowledge and document the residual risk (requires justification) (OWASP: Accept)

  • Transfer Risk: Shift responsibility to user/operator/third-party (e.g., configuration choice, SLA) (OWASP: Transfer)

Requirements and compatibility

Written for: GitHub Copilot

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

First committed by
GitHub avatar of cheguvcheguv
Publisher
GitHub (Official)
Distributed by
GitHub
Source
github/awesome-copilot · skills/threat-model-analyst · commit 797337f
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Contributors
cheguv, stbenjam

AutoGineer is not affiliated with or endorsed by cheguv or GitHub.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download threat-model-analyst.zip