<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Travis Felder</title>
    <description>The latest articles on Forem by Travis Felder (@tfelder).</description>
    <link>https://forem.com/tfelder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3796590%2F47d4840b-73fa-4644-b24f-199445a89024.png</url>
      <title>Forem: Travis Felder</title>
      <link>https://forem.com/tfelder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tfelder"/>
    <language>en</language>
    <item>
      <title>Automated Threat Modeling with AI - How Thr8 Works</title>
      <dc:creator>Travis Felder</dc:creator>
      <pubDate>Fri, 27 Feb 2026 15:02:30 +0000</pubDate>
      <link>https://forem.com/tfelder/automated-threat-modeling-with-ai-how-thr8-works-76h</link>
      <guid>https://forem.com/tfelder/automated-threat-modeling-with-ai-how-thr8-works-76h</guid>
      <description>&lt;p&gt;Every security compliance framework asks the same question: "Where is your threat model?"&lt;/p&gt;

&lt;p&gt;And every engineering team gives the same answer: "We will get to it."&lt;/p&gt;

&lt;p&gt;PASTA (Process for Attack Simulation and Threat Analysis) is one of the most thorough threat modeling frameworks. It is risk-centric, covers 7 stages from business objectives through attack simulation, and produces actionable output. But it takes days of manual work per application. Most teams never start.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/cybrking/thr8" rel="noopener noreferrer"&gt;thr8&lt;/a&gt; to automate this. It is a GitHub Action that generates complete PASTA threat models by combining static codebase analysis with AI-powered threat reasoning. This article walks through the architecture, the PASTA methodology, and how it integrates into CI/CD.&lt;/p&gt;

&lt;h2&gt;
  
  
  The PASTA Framework in 60 Seconds
&lt;/h2&gt;

&lt;p&gt;PASTA has 7 stages. Most threat modeling tools skip half of them. thr8 covers all 7:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;What thr8 Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Business Objectives&lt;/td&gt;
&lt;td&gt;Identifies what the system protects and the impact of a breach&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Technical Scope&lt;/td&gt;
&lt;td&gt;Detects tech stack, infrastructure, data classification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Application Decomposition&lt;/td&gt;
&lt;td&gt;Generates data flow diagrams across trust boundaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Threat Analysis&lt;/td&gt;
&lt;td&gt;Maps attack surfaces and threat vectors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Vulnerability Analysis&lt;/td&gt;
&lt;td&gt;Identifies specific weaknesses with severity ratings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Attack Modeling&lt;/td&gt;
&lt;td&gt;Creates realistic kill chain scenarios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Risk &amp;amp; Impact Analysis&lt;/td&gt;
&lt;td&gt;Scores business risk with tactical recommendations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key insight behind PASTA is that threats only matter in the context of business risk. A SQL injection in an internal admin tool is a different risk than a SQL injection in a payment processing API. thr8 captures that context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture: Static Analysis + AI Reasoning
&lt;/h2&gt;

&lt;p&gt;thr8 runs a 4-stage pipeline. The first stage is deterministic (no AI). The second uses Claude. The third is templating. The fourth is optional GitHub integration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Discovery (Static)           Reasoning (Claude AI)         Output            Remediation
+---------------------+      +----------------------+      +----------+      +--------------+
|                     |      | Business Objectives   |      | Markdown |      | GitHub Issues|
|  Codebase Scanner   |-----&amp;gt;| Attack Surfaces       |-----&amp;gt;| JSON     |-----&amp;gt;| Fix PRs      |
|                     |      | Kill Chain Scenarios   |      | HTML     |      |              |
| - Tech stack        |      | Risk Analysis         |      | PDF      |      | (optional)   |
| - Infrastructure    |      | Recommendations       |      |          |      |              |
| - API endpoints     |      |                       |      |          |      |              |
| - Data flows        |      | (3 focused API calls)  |      |          |      |              |
+---------------------+      +----------------------+      +----------+      +--------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stage 1: Discovery (Static Analysis)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;CodebaseScannerAgent&lt;/code&gt; walks the repository tree, prioritizing security-relevant files. It uses a scoring system to read the most important files first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Priority files&lt;/strong&gt; (always included): &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;docker-compose.yml&lt;/code&gt;, &lt;code&gt;terraform/*.tf&lt;/code&gt;, &lt;code&gt;.env.example&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-signal source files&lt;/strong&gt; (read first): routes, controllers, auth middleware, security configs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure configs&lt;/strong&gt;: Terraform HCL, Kubernetes manifests, Docker Compose YAML&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General source&lt;/strong&gt;: remaining source files up to a 120K character budget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scanner does not use AI for this step. It reads files, respects a configurable size budget (8K chars per file, 120K total), skips binary files and lock files, and produces a structured context document.&lt;/p&gt;

&lt;p&gt;Here is what the file prioritization looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Files sorted by security relevance&lt;/span&gt;
&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/route|controller|handler|endpoint|api/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/auth|security|middleware|guard/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/config|setting/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;tf$|docker|k8s|helm|deploy/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/model|schema|migration|database/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/service|util|helper|lib/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of this stage is a JSON document containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;system_context&lt;/code&gt;: project name, tech stack (languages, frameworks, databases, external services, auth mechanisms, security controls), infrastructure (cloud provider, containerization, services), API surface (endpoints with methods, paths, auth requirements, sensitive data), and sensitive patterns found in code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data_flows&lt;/code&gt;: traced data movement through the system with steps, protocols, data classification, and trust boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stage 2: Reasoning (Claude API)
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ThreatGeneratorAgent&lt;/code&gt; sends the discovery context to Claude along with a STRIDE attack pattern database. The pattern database contains ~40 pre-built attack patterns across 4 categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;stride-api.json&lt;/strong&gt;: API key theft, request body tampering, CORS misconfiguration, rate limiting bypass&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stride-auth.json&lt;/strong&gt;: Credential stuffing, session hijacking, JWT forgery, privilege escalation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stride-database.json&lt;/strong&gt;: SQL injection, unencrypted data at rest, connection pool exhaustion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stride-storage.json&lt;/strong&gt;: Unauthorized access, pre-signed URL abuse, missing encryption&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude performs the PASTA analysis (Stages 1-2 and 4-7) and returns structured JSON covering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"business_objectives"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"overall_risk_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MEDIUM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attack_surfaces"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Public API Endpoint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"vector"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HTTP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"weakness"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Missing rate limiting on authentication endpoint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"vulnerabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API-AUTH-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brute Force Authentication"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"No rate limiting on /api/auth/login allows..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"High"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attack_scenarios"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Account Takeover via Credential Stuffing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"objective"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gain access to user accounts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"steps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"phase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Reconnaissance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enumerate valid usernames via registration endpoint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"exploits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"API-AUTH-002"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"phase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Exploitation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brute force login with credential lists"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"exploits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"API-AUTH-001"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"risk_analysis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tactical_recommendations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model is &lt;code&gt;claude-sonnet-4-6&lt;/code&gt;. Total token usage is typically 2-5K input and 3-8K output per call (3 calls total). Cost: $0.05-0.15 per run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 3: Output Generation
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ReporterAgent&lt;/code&gt; renders the analysis into multiple formats using Handlebars templates:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Markdown&lt;/strong&gt; (&lt;code&gt;THREAT_MODEL.md&lt;/code&gt;) -- renders natively on GitHub with embedded Mermaid data flow diagrams:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph LR
    auth_flow_0["Browser&amp;lt;br/&amp;gt;&amp;lt;i&amp;gt;external_user&amp;lt;/i&amp;gt;"]
    auth_flow_1["API Gateway&amp;lt;br/&amp;gt;&amp;lt;i&amp;gt;load_balancer&amp;lt;/i&amp;gt;"]
    auth_flow_2["Auth Service&amp;lt;br/&amp;gt;&amp;lt;i&amp;gt;application&amp;lt;/i&amp;gt;"]
    auth_flow_3["User Database&amp;lt;br/&amp;gt;&amp;lt;i&amp;gt;database&amp;lt;/i&amp;gt;"]
    auth_flow_0 --&amp;gt;|"HTTPS"| auth_flow_1
    auth_flow_1 --&amp;gt;|"internal"| auth_flow_2
    auth_flow_2 --&amp;gt;|"TLS"| auth_flow_3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;JSON&lt;/strong&gt; (&lt;code&gt;threat-model.json&lt;/code&gt;) -- machine-readable for CI/CD integration, custom dashboards, or feeding into other security tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt; (&lt;code&gt;THREAT_MODEL.html&lt;/code&gt;) -- professional report with sidebar navigation, executive summary dashboard, color-coded severity levels, and embedded diagrams. Print-friendly for stakeholder distribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF&lt;/strong&gt; (&lt;code&gt;THREAT_MODEL.pdf&lt;/code&gt;) -- generated from HTML via headless Chrome when available on the runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 4: Automated Remediation
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;RemediatorAgent&lt;/code&gt; is the most interesting part. When you provide a &lt;code&gt;github-token&lt;/code&gt; and enable &lt;code&gt;create-issues&lt;/code&gt; and &lt;code&gt;auto-fix&lt;/code&gt;, the action does not just report findings -- it acts on them.&lt;/p&gt;

&lt;p&gt;For each vulnerability found:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is auto-fix enabled AND severity is in pr-severity list?
  +-- YES --&amp;gt; Generate fix with Claude
  |           +-- High/medium confidence --&amp;gt; Open fix PR
  |           +-- Low confidence --&amp;gt; Fall back to issue
  +-- NO  --&amp;gt; Create GitHub Issue (if create-issues enabled)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix PRs are created on &lt;code&gt;thr8/fix-{vuln-id}&lt;/code&gt; branches. Each PR includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The minimal code change needed&lt;/li&gt;
&lt;li&gt;An explanation of what was fixed&lt;/li&gt;
&lt;li&gt;Risk context (severity, business impact)&lt;/li&gt;
&lt;li&gt;A list of changed files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deduplication is built in. Each issue and PR body contains a hidden marker (&lt;code&gt;&amp;lt;!-- thr8:V-001 --&amp;gt;&lt;/code&gt;) that prevents duplicates on re-runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Threat Model&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;threat-model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate Threat Model&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cybrking/thr8@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;anthropic-api-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Upload Report&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;threat-model&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;threat-model/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fail Builds on Critical Findings
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate Threat Model&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cybrking/thr8@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;anthropic-api-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;
    &lt;span class="na"&gt;fail-on-high-risk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full Remediation Pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;threat-model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;issues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate Threat Model&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;threat-model&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cybrking/thr8@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;anthropic-api-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.ANTHROPIC_API_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;create-issues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
          &lt;span class="na"&gt;auto-fix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
          &lt;span class="na"&gt;pr-severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;critical,high'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Summary&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Threats found: ${{ steps.threat-model.outputs.threats-found }}"&lt;/span&gt;
          &lt;span class="s"&gt;echo "Critical: ${{ steps.threat-model.outputs.high-risk-count }}"&lt;/span&gt;
          &lt;span class="s"&gt;echo "Issues created: ${{ steps.threat-model.outputs.issues-created }}"&lt;/span&gt;
          &lt;span class="s"&gt;echo "Fix PRs created: ${{ steps.threat-model.outputs.prs-created }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Post Summary as PR Comment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Comment on PR&lt;/span&gt;
  &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.event_name == 'pull_request'&lt;/span&gt;
  &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/github-script@v7&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;const fs = require('fs');&lt;/span&gt;
      &lt;span class="s"&gt;const report = fs.readFileSync('threat-model/THREAT_MODEL.md', 'utf8');&lt;/span&gt;
      &lt;span class="s"&gt;github.rest.issues.createComment({&lt;/span&gt;
        &lt;span class="s"&gt;issue_number: context.issue.number,&lt;/span&gt;
        &lt;span class="s"&gt;owner: context.repo.owner,&lt;/span&gt;
        &lt;span class="s"&gt;repo: context.repo.repo,&lt;/span&gt;
        &lt;span class="s"&gt;body: report&lt;/span&gt;
      &lt;span class="s"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Supported Tech Stacks
&lt;/h2&gt;

&lt;p&gt;The codebase scanner automatically detects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Languages&lt;/td&gt;
&lt;td&gt;JavaScript, TypeScript, Python, Go, Java, Ruby&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frameworks&lt;/td&gt;
&lt;td&gt;Express, Django, Rails, FastAPI, Spring Boot, Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Databases&lt;/td&gt;
&lt;td&gt;PostgreSQL, MySQL, MongoDB, Redis, DynamoDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Terraform, Docker, Docker Compose, Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;JWT, OAuth, session-based, API keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;AWS, GCP, Azure resource detection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cost Transparency
&lt;/h2&gt;

&lt;p&gt;Three Claude API calls per run using &lt;code&gt;claude-sonnet-4-6&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typical input: ~2-5K tokens per call&lt;/li&gt;
&lt;li&gt;Typical output: ~3-8K tokens per call&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estimated cost: $0.05-0.15 per run&lt;/strong&gt; (analysis only)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;code&gt;auto-fix&lt;/code&gt; enabled, add ~$0.02-0.06 per run for fix generation.&lt;/p&gt;

&lt;p&gt;For a team running this on 50 repos with weekly pushes to main, that is roughly $10-30/month for continuous threat modeling across your entire portfolio.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Does Not Do
&lt;/h2&gt;

&lt;p&gt;Transparency matters. thr8 is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A DAST scanner.&lt;/strong&gt; It does not make HTTP requests to your running application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A replacement for penetration testing.&lt;/strong&gt; It identifies architectural threats, not runtime vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A compliance certification tool.&lt;/strong&gt; It produces documentation that supports compliance, but does not certify anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic.&lt;/strong&gt; Claude's analysis may vary between runs. The static discovery is deterministic, but the threat reasoning is probabilistic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The repo is open source (MIT): &lt;a href="https://github.com/cybrking/thr8" rel="noopener noreferrer"&gt;github.com/cybrking/thr8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Marketplace: &lt;a href="https://github.com/marketplace/actions/pasta-threat-model-generator" rel="noopener noreferrer"&gt;PASTA Threat Model Generator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add it to a repo, run it, and open an issue with feedback. The whole setup takes less than 5 minutes.&lt;/p&gt;

</description>
      <category>security</category>
      <category>devsecops</category>
      <category>ai</category>
      <category>github</category>
    </item>
  </channel>
</rss>
