{"id":51952290,"url":"https://github.com/benjitrapp/purpleskjaldborg","last_synced_at":"2026-07-29T07:00:57.699Z","repository":{"id":366550596,"uuid":"1276693020","full_name":"BenjiTrapp/PurpleSkjaldborg","owner":"BenjiTrapp","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-22T09:07:11.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-22T11:08:18.956Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BenjiTrapp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-22T07:55:06.000Z","updated_at":"2026-06-22T09:07:16.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/BenjiTrapp/PurpleSkjaldborg","commit_stats":null,"previous_names":["benjitrapp/purpleskjaldborg"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/BenjiTrapp/PurpleSkjaldborg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjiTrapp%2FPurpleSkjaldborg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjiTrapp%2FPurpleSkjaldborg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjiTrapp%2FPurpleSkjaldborg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjiTrapp%2FPurpleSkjaldborg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BenjiTrapp","download_url":"https://codeload.github.com/BenjiTrapp/PurpleSkjaldborg/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenjiTrapp%2FPurpleSkjaldborg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36022278,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-29T02:00:04.910Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-29T07:00:56.830Z","updated_at":"2026-07-29T07:00:57.686Z","avatar_url":"https://github.com/BenjiTrapp.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PurpleSkjaldborg\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"static/logo.png\" alt=\"PurpleSkjaldborg Logo\" width=\"280\"\u003e\n\u003c/p\u003e\n\n**Purple-team threat modeling in the browser.** Zero dependencies. One HTML file. Offense *and* defense on one canvas.\n\n\u003e *Skjaldborg* (Old Norse) — a **shield wall** formation where defenders interlock shields against attackers.\n\u003e This tool helps you build that digital shield wall.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"static/demo.gif\" alt=\"PurpleSkjaldborg Demo\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n---\n\n## What Is This?\n\nPurpleSkjaldborg is a visual threat modeling tool that combines **red team attack paths** with **blue team defensive controls** in a single diagram. It integrates four industry-standard frameworks:\n\n| Framework | Role in Skjaldborg |\n|-----------|-------------------|\n| **STRIDE** | Threat categorization per element (Spoofing, Tampering, Repudiation, Info Disclosure, DoS, EoP) |\n| **PASTA** | 7-stage risk-centric methodology mapped to canvas constructs |\n| **MITRE ATT\u0026CK** | Adversary techniques auto-mapped to Red Team nodes and attack edges — IDs link directly to official MITRE pages |\n| **MITRE D3FEND** | Defensive countermeasures auto-mapped to Blue Team shields and boundaries — IDs link directly to official MITRE pages |\n\n---\n\n## Quick Start\n\n```bash\n# No build. No install. Just open it.\nopen index.html\n\n# Or serve locally:\npython -m http.server 8765\n# then navigate to http://localhost:8765\n```\n\nThe app loads an **AD Attack Chain** sample by default. Click **Sample** in the toolbar to explore all 7 built-in scenarios.\n\n---\n\n## Features\n\n### Red Team Arsenal\n\n- **C2 Frameworks** — Cobalt Strike, Brute Ratel, Sliver, Havoc, ArachneC2, AdaptixC2\n- **Phishing Infra** — EvilGinx2, GoPhish, Tangled, PhishingClub\n- **Pivoting \u0026 Tunneling** — Ligolo-ng, Chisel, SSH tunnels, SOCKS proxies, dnscat2, iodine\n- **Living off the Land** — LOLBins, LOLDrivers, file transfer utilities\n- **Auto ATT\u0026CK** — Every Red Team node ships with pre-mapped MITRE technique IDs\n- **OpSec Ratings** — Each tool gets an intrinsic OpSec level (1 Loud → 5 Very Quiet), visible in the inspector and on the canvas bust% badge\n\n### Blue Team Shields\n\n- **EDR/XDR** — CrowdStrike Falcon, Microsoft Defender, Elastic Security, SentinelOne and 15+ more\n- **NDR** — Darktrace, Vectra AI, ExtraHop, Corelight and more\n- **Network Security** — pfSense/OPNsense, Suricata, Squid, WAF, NAC\n- **Cloud Security** — Wiz, Prisma Cloud, CNAPP, CSPM, CASB, DLP\n- **Hardening \u0026 Deception** — ASR/GPO, Kyverno, HoneyPots/Decoys\n\n\u003e Blue tools attach as **shields on assets** (force-ring + D3FEND coverage), not floating boxes.\n\n### Personas \u0026 Human Actors\n\nModel the **people** in your threat story — not just infrastructure. Persona nodes render as stick figures (not boxes) and carry human-centric properties instead of STRIDE/MITRE assessments:\n\n- **Actor types** — Employee, IT Admin, Developer, Executive, Vendor / Contractor, plus security roles (Red Teamer, Blue Teamer) and a generic Threat Actor\n- **Attacker profile** *(Threat Actor \u0026 Red Teamer only)* — alias/handle, motto/quote, **Intent** (4 CIA-impact dimensions: 🕵️ Espionage · 💥 Destructive · ⚡ Disruptive · 💰 Cyber-Crime), **Capability** level (Script Kiddie → Nation-State), motivation, sophistication, free-text **Needs** (goals) and **Obstacles** (where defenders can intervene)\n- **Human risk profile** *(non-attacker personas)* — 🎣 **Social Engineering Susceptibility**, 🧠 **Security Awareness Level**, and 💸 **Fraud Exposure** (Critical → Minimal, e.g. BEC / CEO-fraud payment authority)\n- **⭐ VIP / High-Value Target** flag for Executives and IT Admins — surfaces whaling / BEC priority targets, shown with a gold star badge on the node\n- **🎭 Impersonated** flag for non-attacker personas — marks an identity spoofed by an attacker (e.g. the \"CEO\" in a BEC lure); the persona **glows red** on the canvas\n- **🔑 MFA** toggle on auth-capable personas — auto-syncs a D3FEND `D3-MFA` mapping\n- **Reworked context menu** — persona right-click menus adapt per type: intent quick-toggles for attackers; MFA, VIP, impersonated, and fraud-exposure cycling for human personas; free-movement toggle for all\n\n### Canvas \u0026 Visualization\n\n- **Animated tunnel edges** — Red glow for offensive pivots, blue glow for defensive VPN/encrypted channels\n- **Green glow on encrypted flows** — Data flows with *Encrypted in Transit* enabled pulse with a green glow and dashed overlay\n- **Freehand Trust Boundary** — Click vertices on the canvas to draw any polygon; press Esc to finalize. Rendered with smooth Catmull-Rom curves, classical threat-model style\n- **Rectangular boundaries** — Trust (blue), Privacy/PII (green), Cloud (gradient), Network (dashed), Red Team, Grey Zone, K8s Namespace, NetworkPolicy\n- **Semantic Auto-arrange** — One click organises nodes into 10 semantic zones: External · Network/DMZ · Corporate · Kubernetes · Cloud · IAM · Blue Team · Red Team · Grey Zone · Pivot/Tunneling\n- **Semantic context menus** — Right-click items adapt to the component type: PII/classification for data stores, STRIDE flags per process type, privilege flag for K8s pods, OpSec for red team, internet exposure for assets, and human-actor actions (intent, MFA, VIP, fraud exposure) for personas\n- **Clickable MITRE IDs** — Every ATT\u0026CK and D3FEND chip opens the official MITRE technique page in a new tab\n- **Zoom \u0026 pan** — Scroll to zoom, drag background to pan\n\n### Node Badges (Canvas indicators)\n\nEach node carries corner badges so you can read the threat posture at a glance without opening the inspector:\n\n| Badge | Position | Meaning |\n|-------|----------|---------|\n| 🌐 Globe | Top-center | Asset is **internet-exposed** |\n| Count pill | Top-right | ATT\u0026CK / STRIDE technique count |\n| 🔒 / 🛡️ | Bottom-left | PII lock · Red sword · Blue shield |\n| ⚡ Ease score | Bottom-right | Ease of Attack score (0–100, color-coded) |\n| % Bust ring | Bottom-right | **Red team only** — detection bust likelihood |\n| Dashed ring | Outer ring | Red team detection risk color (green → red) |\n| 🔑 Key | Bottom-center | **MFA** enabled on an auth-capable node |\n| ⭐ Star | Top-right | **Persona only** — VIP / High-Value Target |\n| 💸 Cash | Bottom-left | **Persona only** — Fraud Exposure (color-coded by severity) |\n| 🎭 Red glow | Whole node | **Persona only** — identity is **impersonated** by an attacker |\n\n### Red Team OpSec \u0026 Detection\n\nEvery red team node gets a live **bust likelihood** score that reflects how detectable it is by the blue team on the same canvas:\n\n- **Intrinsic OpSec level** (1–5) is assigned per tool type: LOLBins and CDN-fronted C2 are quiet (5), default Cobalt Strike profiles are loud (1–2)\n- **D3FEND coverage** is computed by scanning all blue team nodes and controls on the canvas for techniques that match the red team node's detection surface\n- **Bust risk** = detection coverage × OpSec dampener `[1.0, 0.82, 0.65, 0.50, 0.40]`\n- Canvas shows a **color-coded dashed ring** and a **bust % badge** (bottom-right)\n- Inspector panel shows the full breakdown: OpSec level pips, bust likelihood bar, detected-by list, and uncovered detection gaps\n\n### Ease of Attack\n\nEvery non-red-team node gets an automatically computed **Ease of Attack score** (0–100):\n\n| Score | Label | Color |\n|-------|-------|-------|\n| 0–19 | Very Hard | 🟢 Green |\n| 20–37 | Hard | 🟡 Yellow-green |\n| 38–54 | Medium | 🟡 Yellow |\n| 55–71 | Easy | 🟠 Orange |\n| 72–100 | Critical | 🔴 Red |\n\nThe score starts from a base value per node type and is adjusted automatically by:\n\n- Number of attack edges pointing at the node\n- Active STRIDE threat flags\n- Privileged container flag\n- Security controls attached\n- D3FEND countermeasures mapped\n- Encrypted at Rest / Encrypted in Transit flows\n- ±5 manual fine-tuning buttons in the inspector\n\n### Data Classification (Stores \u0026 Databases)\n\nClick any data-holding node (Store, Bucket, DB, Cache, Secret, ConfigMap, Queue…) to access:\n\n- **Classification level** — Unclassified / 🟢 Public / 🔵 Internal / 🟡 Confidential / 🟠 Restricted / 🔴 Secret\n- **Data categories** — tag Personal (PII), Health (PHI), Financial (PCI), Biometric, Communications, Legal\n- **🔐 Encrypted at Rest** toggle\n\nAll settings are accessible from both the inspector panel and the right-click context menu.\n\n### Internet Exposure\n\nFlag any asset as reachable from the public internet:\n\n- **🌐 Globe badge** appears on the node at 12 o'clock position (blue, distinct from all other badges)\n- **Inspector toggle** — `🌐 Exposed to Internet` switch on every node\n- **Context menu** — `Mark as internet-exposed` / `Remove internet exposure` for all non-red-team, non-blue-team nodes\n- The built-in scenarios pre-annotate the correct nodes (firewalls, VPN gateways, email gateways, reverse proxies, phishing infra, cloud APIs, CI/CD platforms, ingress controllers…)\n\n### Multi-Factor Authentication (MFA)\n\nFlag MFA on any auth-capable asset or human persona:\n\n- **🔑 Key badge** at the node's 6 o'clock position (emerald, non-overlapping with other badges)\n- **Inspector toggle** and **context-menu** action on supported types (external, API, cloud, IAM, web app, AD, SIEM, firewall, and most personas)\n- Enabling MFA **auto-maps the D3FEND `D3-MFA` countermeasure** and **lowers the Ease of Attack score**; a missing MFA on an auth-capable node raises it\n\n### Analysis \u0026 Reporting\n\n- **Per-boundary risk scoring** — Attack surface vs. countermeasure coverage\n- **STRIDE matrix** — Visual applicability grid for all elements\n- **PASTA stages** — 7-stage methodology walkthrough mapped to your diagram\n- **Markdown report export** — Full threat model document including STRIDE assessment, ATT\u0026CK/D3FEND lists, PII assets, and data classification metadata\n- **SVG export** — Rich self-contained image with:\n  - Node annotations (ease score, classification level, ATT\u0026CK count, STRIDE flags, encryption status)\n  - Right-side **Analysis Panel** with summary metrics, STRIDE bar chart, ATT\u0026CK technique list, D3FEND coverage, data classification breakdown, red team OpSec assessment, and per-node ease breakdown\n  - Embedded font, resolved CSS variables, grid removed\n  - **Zoom \u0026 pan** — scroll to zoom, drag to pan, `+` / `−` / `fit` buttons\n- **JSON import/export** — Save and share full models with your team\n\n---\n\n## Built-in Scenarios\n\n| Scenario | Kill Chain | Key Techniques |\n|----------|-----------|----------------|\n| **AD Attack Chain** | Phishing → LOLBins → Ligolo-ng pivot → Kerberoasting → ADCS abuse | DCSync, Golden Ticket, EvilGinx2 AiTM, WireGuard VPN |\n| **Cobalt Strike Beacon Drop** | GoPhish campaign → Macro payload → Beacon C2 → Lateral movement | Malleable C2, DNS fallback, Kerberoasting, HTTPS egress |\n| **K8s Cluster Compromise** | RCE in pod → SA token theft → etcd dump → Cloud exfil | RBAC abuse, container escape, IRSA pivot, supply chain |\n| **Cloud Identity Breach (Azure)** | Consent phishing → OAuth token → Graph API → Key Vault | Entra ID takeover, MFA bypass, Managed Identity abuse |\n| **Supply Chain Attack (CI/CD)** | Malicious NPM dep → Runner RCE → Backdoored image → Prod | IRSA credential theft, ECR poisoning, ArgoCD deploy |\n| **Ransomware (Double Extortion)** | RDP brute-force → Cobalt Strike → DCSync → Exfil → GPO deploy | BYOVD EDR kill, rclone exfil, VSS/Veeam deletion |\n| **Phishing \u0026 CEO Fraud (BEC)** | OSINT → lookalike domain → spoofed \"CEO\" email → AP clerk → fraudulent wire → mule account | Impersonation (T1656), Financial Theft (T1657), DMARC/SPF bypass — *malware-free, human-centric* |\n\nAll scenarios are pre-annotated with internet-exposed assets, STRIDE flags, ATT\u0026CK/D3FEND techniques, PII zones, and security controls. The **CEO Fraud** scenario showcases the persona system — human actors with fraud exposure, social-engineering susceptibility, awareness levels, and a VIP-flagged executive.\n\n---\n\n## Keyboard Shortcuts \u0026 Interactions\n\n| Action | Result |\n|--------|--------|\n| `?` | Open Help panel |\n| `Esc` | Stop drawing flows · finalize freehand boundary · cancel tool · deselect |\n| `Shift` + click | Keep node/boundary tool armed (place multiple) |\n| `Delete` / `Backspace` | Delete selected element |\n| `F2` | Rename selected element |\n| Double-click edge | Toggle attack vector ↔ data flow |\n| Right-click anything | Semantic context menu |\n| Scroll | Zoom |\n| Drag background | Pan |\n| Click flow tool → source → target | Draw edge; tool stays armed — keep wiring or press Esc |\n| Click Freehand Boundary → vertices → Esc | Draw and save a polygon trust boundary |\n| Click MITRE ID chip | Open official MITRE technique page in new tab |\n\n---\n\n## Architecture\n\n```\nindex.html (single file)\n├── \u003cstyle\u003e       — CSS: dark theme, animations, modal/overlay, help panel\n├── \u003cbody\u003e        — HTML: toolbar, palette, SVG canvas, inspector, overlays\n└── \u003cscript\u003e      — JS: state, rendering, interactions, samples\n    ├── COMPONENTS[]              — Node type definitions (icon, role, ATT\u0026CK/D3FEND defaults)\n    ├── BND{}                     — Boundary visual config (color, dash, animation, MITRE mapping)\n    ├── STRIDE / PASTA            — Framework data structures + per-type applicability\n    ├── CLASSIFICATION_LEVELS / DATA_CATEGORIES — Data classification metadata\n    ├── OPSEC_RATINGS             — Per-tool intrinsic OpSec levels (1–5)\n    ├── BASE_EASE / computeEaseOfAttack() — Ease of Attack scoring engine\n    ├── computeRedTeamDetection() — Bust risk: D3FEND coverage × OpSec dampener\n    ├── Render pipeline           — SVG: boundaries → edges → nodes (layered)\n    ├── Freehand polygon          — Catmull-Rom → cubic Bézier smooth open path\n    ├── Auto-arrange              — 10 semantic zone layout\n    ├── SVG export                — Canvas clone + node annotations + analysis panel + zoom script\n    ├── Interaction               — Drag, select, arm tools, context menus, continuous flow drawing\n    ├── Persona system            — Human-actor nodes (stick figures), intent/capability, fraud exposure, VIP, MFA\n    ├── Sample library            — 7 pre-built scenarios with spatial layout and internet exposure flags\n    └── Help system               — Full-screen tabbed help (Tutorial / Metamodels / Workflow / Shortcuts / About)\n```\n\n**Zero dependencies.** No React, no D3, no build step. Opens in any modern browser, works offline.\n\n---\n\n## Philosophy\n\nMost threat modeling tools make you choose: either you model the attacker *or* you model the defenses. PurpleSkjaldborg lets you do both on the same canvas because **purple teams need both perspectives simultaneously**.\n\n- Attack paths and defenses rendered together expose gaps visually\n- Residual risk scoring quantifies where you're under-defended\n- Auto-mapped ATT\u0026CK/D3FEND means you don't need encyclopedic MITRE knowledge\n- OpSec ratings and bust likelihood make red team detectability tangible\n- Ease of Attack scores give defenders a prioritized target list\n- Data classification surfaces which stores are highest-value targets\n- Internet exposure flags make the attack surface boundary explicit\n- Personas put the **human attack surface** on the canvas — social engineering, fraud exposure, and awareness alongside the technical kill chain\n- Sample kill chains let you start from realistic scenarios and adapt\n\n---\n\n## Further Reading\n\n- [Threat Modeling — Culture \u0026 Practice](https://benjitrapp.github.io/cultures/2022-06-11-threat-modeling/) — Foundational concepts on STRIDE, PASTA, and integrating threat modeling into engineering workflows\n- [MITRE ATT\u0026CK](https://attack.mitre.org/) — Adversary tactics \u0026 techniques knowledge base\n- [MITRE D3FEND](https://d3fend.mitre.org/) — Defensive countermeasure taxonomy\n- [Incident Response Playbooks](https://github.com/BenjiTrapp/incident-response-playbooks) — Companion IR visualization project\n\n---\n\n## License\n\nMIT\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003ePurpleSkjaldborg\u003c/b\u003e — Build your digital shield wall.\u003cbr\u003e\n  \u003csub\u003ePurple-Team Threat Modeling \u0026middot; STRIDE \u0026middot; PASTA \u0026middot; ATT\u0026CK \u0026middot; D3FEND \u0026middot; Personas \u0026middot; OpSec \u0026middot; Ease of Attack\u003c/sub\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenjitrapp%2Fpurpleskjaldborg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenjitrapp%2Fpurpleskjaldborg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenjitrapp%2Fpurpleskjaldborg/lists"}