Table of Contents
- Why generic threat modeling fails tech-aware users
- EFF SSD adapted: assets, adversaries, capabilities
- STRIDE for non-corporate profiles
- Risk matrix: solo dev on Mac, iPhone, GitHub, AWS
- Mitigations by tier
- Six profiles: assets, adversaries, priority mitigations
- Annual review: re-evaluation checklist
What is threat modeling for technical users?
Threat modeling is a step-by-step process. You list what assets you own, who might attack them, what they can do, and which fixes cut the biggest risks first. For technical users β developers, sysadmins, OSS maintainers β the asset list goes beyond personal accounts. It includes cloud credentials, CI/CD pipelines, and domain registrars. The goal is to make ranked, evidence-based security choices.
Why generic threat modeling fails tech-aware users
The NIST Cybersecurity Framework 2.0 (published February 2024) is a solid governance document. But it does not tell you what to do in one case. An OSS maintainer finds that a malicious PR just landed in a package with 40,000 weekly downloads. Generic consumer advice β "use a password manager, enable 2FA" β is needed but not enough. It falls short for anyone whose digital footprint looks like this: three GitHub organizations, an AWS root account, a CI pipeline with deploy keys, a public SSH endpoint, DNS run through Cloudflare, and a dev machine that also opens personal banking.
The gap is not about skill. It is about being specific. Consumer guides assume one threat: "account takeover by an opportunistic attacker." A developer or sysadmin faces more. The real threat list includes targeted supply-chain injection, CI/CD secrets theft, and SSH key theft from a hacked dotfiles repo. It also includes social engineering from someone who has read your commit history and knows your deployment stack.
EFF's Surveillance Self-Defense (ssd.eff.org) frames security the right way. It treats security as a function of your own situation β assets, adversaries, capabilities, likelihood, consequences. The consumer guides skip the first step. They never list, in detail, what you actually own that is worth attacking.
So the method below starts with an asset list built for technical users. Then it maps adversaries and what they can really do. Only after that does it touch any fixes.
See the pillar guide on browser privacy in 2026 for the broader privacy landscape this threat model sits within. Key terms used throughout this guide β STRIDE, threat model, supply chain attack, zero-day, sandboxing β are defined in the browser privacy & security glossary.
EFF SSD adapted: assets, adversaries, capabilities
Asset enumeration for technical practitioners
Before you sort threats, list what you actually own. For a typical indie developer or OSS maintainer in 2026, the asset list breaks into five groups:
Identity assets: GitHub/GitLab accounts (tied to a public reputation and org permissions), cloud provider root accounts (AWS, GCP, Azure), domain registrar accounts (the root of your web presence), and email accounts (the recovery path for everything else). Add package registry accounts (npm, PyPI, crates.io). The blast radius of a breach here reaches every downstream user.
Infrastructure assets: Production servers and containers, DNS zones, TLS certificates and CA configurations, SSH keys (especially deploy keys with write access to repositories), cloud IAM roles and service accounts, secrets stored in .env files or secret managers.
Code assets: Private repositories, CI/CD pipeline configurations, dependency lockfiles, signing keys for commit signing or package releases.
Financial assets: Stripe/payment processor accounts, domain renewal payment methods, cryptocurrency wallets if applicable.
Reputational assets: Your public commit history, your package publish access, your social accounts tied to your professional identity.
Adversary taxonomy
EFF SSD uses five adversary levels. Mapped to the tech user:
Opportunistic attackers scan the internet for exposed credentials, unpatched services, and reused passwords. They are automated, high-volume, and low-skill. If your EC2 instance has port 22 open on a residential IP range, they will find it within minutes of launch. This is the baseline threat that the security basics cover.
Targeted attackers (criminal or competitive) have picked you out as a target worth money. They craft spearphishing against your exact stack. They try supply chain injection into your dependencies. They watch your public activity for useful intel. To reach this tier, you need real revenue, custody of valuable data, or visibility in a space that pays.
Nation-state actors work with near-endless persistence and a wide set of zero-day tools. For most users, this tier needs rare conditions: you work on sensitive government infrastructure, you are a political dissident, or you are a journalist covering intelligence services. This tier still matters for calibration. Do not build every fix to survive a nation-state. For most cases, the cost and complexity are not worth it.
Insider threats are people with real access who act with bad intent or by mistake. For solo users this matters less. For OSS maintainers with many collaborators, it matters a lot. A hacked maintainer account, an angry contributor with merge rights, or an accidental secret commit from a trusted contributor all fall here.
Capabilities matrix β for each adversary type, judge what they have: credential databases, phishing infrastructure, zero-day exploits, legal force, physical access. Cross asset value against adversary capability. That gives you the real threat space you need to address.
How do you apply the STRIDE framework as an individual developer?
STRIDE categorizes threats into six classes applicable to personal infrastructure:
- Spoofing β account takeover via phishing or credential stuffing (mitigate with FIDO2 hardware keys)
- Tampering β malicious dependency or compromised CI pipeline (mitigate with Sigstore, pinned lockfiles)
- Repudiation β inability to prove commit authorship (mitigate with SSH/GPG commit signing)
- Information Disclosure β leaked .env files or API keys (mitigate with pre-commit secret scanning)
- Denial of Service β DDoS on your API or CI budget exhaustion (mitigate with Cloudflare, rate limits)
- Elevation of Privilege β CI pipeline with write access accepting untrusted PR code (mitigate with OIDC federation)
Microsoft's STRIDE framework (1999, Adam Shostack) sorts threats into six classes. Corporate security teams use it on data flow diagrams of app designs. As one person, use it on your own infrastructure layout.
Spoofing (account takeover). For a developer, the spoofing threat is mostly account takeover. Someone pretends to be you on GitHub, your cloud console, or your registrar, and acts under your identity. Attack paths include credential stuffing from breached databases and real-time phishing proxies (Evilginx2 can bypass TOTP 2FA). They also include SIM swapping (to grab SMS 2FA) and OAuth token theft through malicious GitHub Apps. The fix is phishing-resistant login β hardware FIDO2 keys β for accounts where a spoof has a high blast radius.
Tampering (supply chain). A tampered artifact means changed code reaches production or end users. For a developer this shows up in a few ways. A malicious PR is merged without enough review. A dependency bump adds a backdoor (xz utils, event-stream). A hacked build environment signs a changed binary. Or an npm publish token is stolen. The fix stack includes Sigstore/cosign for artifact signing, pinned lockfiles with hash checks, code review gates that do not trust automated bots, and SLSA provenance levels.
Repudiation (audit trails). Can you prove what happened and who did it? Git commit signing with SSH keys or GPG builds a tamper-evident record of code changes. Signed commits do not stop attacks. But they do prove accountability. That is vital if you must show downstream users that a given commit was not written by you. CloudTrail and similar audit logs for cloud actions do the same job.
Information disclosure (leaked secrets). This is the most common high-impact incident in the developer world. Think of a .env file committed to a public repo, an AWS key in a GitHub Actions log, a database connection string in an error message, or a private key baked into a Docker image layer. git-secrets, truffleHog, and GitHub's secret scanning catch committed secrets. Pre-commit hooks stop them before they land. After any suspected leak, you must rotate credentials at once.
Denial of Service (availability). For a solo developer hosting a SaaS product, a long DDoS can wipe out revenue. There are quieter forms too. Rate limits hit your GitHub API calls. Or a crafted dependency drags out build times and drains your CI/CD pipeline. At the baseline tier, the fix is Cloudflare or a similar CDN/DDoS shield in front of public endpoints. At the infrastructure level, make sure one hacked dependency cannot exhaust your CI budget.
Elevation of privilege (CI/CD pipelines). A CI pipeline that has write access to production and runs any code from pull requests is an EoP vector. An attacker submits a PR that steals deploy keys or writes malicious code to production. GitHub Actions softens this. By default the pull_request event has a read-only GITHUB_TOKEN. But many repos override that. The right design keeps untrusted PRs (read-only, no secrets) apart from trusted merges (deploy access). OIDC federation removes long-lived credentials in CI for good.
Risk matrix: solo dev on Mac, iPhone, GitHub, AWS
Here is a concrete example. A solo developer runs a SaaS product on Mac (main workstation), iPhone (2FA device and personal communication), GitHub (code and CI/CD), and AWS (production infrastructure). We score each vector on a simple 1β5 probability Γ impact scale:
| Threat vector | STRIDE class | Probability | Impact | Score | Priority |
|---|---|---|---|---|---|
| GitHub account takeover via phishing | Spoofing | 3 | 5 | 15 | Critical |
| AWS root credential leak (committed .env) | Information Disclosure | 3 | 5 | 15 | Critical |
| Malicious dependency in npm chain | Tampering | 4 | 3 | 12 | High |
| CI deploy key exfiltration | Elevation of Privilege | 2 | 5 | 10 | High |
| SSH key theft from Mac | Spoofing | 2 | 4 | 8 | High |
| SIM swap attacking phone 2FA | Spoofing | 2 | 4 | 8 | High |
| Cloudflare account takeover | Spoofing | 2 | 4 | 8 | High |
| DDoS on production API | Denial of Service | 3 | 2 | 6 | Medium |
| Leaked Stripe webhook secret | Information Disclosure | 2 | 3 | 6 | Medium |
| Unsigned commits enabling repudiation | Repudiation | 3 | 2 | 6 | Medium |
| S3 bucket misconfiguration | Information Disclosure | 2 | 3 | 6 | Medium |
| IAM over-permissioned service account | Elevation of Privilege | 3 | 2 | 6 | Medium |
This matrix tells you where to focus first: GitHub and AWS root account protection, plus .env leak prevention. The rest matters too, but it is not first in line.
You may want CVSS 3.1 scores for specific flaws in your dependencies. The NVD database (nvd.nist.gov) gives base scores for CVEs. Environmental and temporal modifiers let you tune those scores to your own deployment.
Mitigations by tier
Baseline (all tech practitioners, no exceptions)
Passkeys and FIDO2 hardware keys for GitHub, cloud consoles, domain registrars, and email. These are the accounts where takeover has the highest blast radius. A hacked registrar account lets an attacker take over every domain and its certificate. A hacked GitHub account lets them push malicious code and steal all repository secrets.
TOTP-based 2FA (Ente Auth, Aegis, 1Password TOTP) for every account that does not support passkeys. TOTP does not resist phishing, but it defeats credential stuffing at scale. For accounts tied to a known phone number, SMS 2FA is worse than TOTP. SIM swapping is a documented attack vector.
Password manager with a unique, random credential for every account. Bitwarden and 1Password both ship CLI tools for use in automation. See the password manager guide for engineers for CLI setup details.
Secret scanning pre-commit hook. Install truffleHog or git-secrets as a pre-commit hook. Run git log --all --full-history against your existing repos to check for past leaks.
AWS root account lockdown. AWS root credentials should have MFA on with a hardware key. The root account should have no access keys at all. All day-to-day access should use IAM roles with least-privilege policies.
Intermediate
Dedicated hardware security key (YubiKey 5 NFC or equivalent). The YubiKey 5 supports FIDO2, PIV, OpenPGP, and OTP in one device. For FIDO2, register two keys. Store the backup in a separate physical location.
Separate development machine or VM for your most sensitive work. Say your daily machine runs npm install from many projects. Any package that runs a malicious install script can then reach its credential store. A dedicated, hardened VM holds only the tools you need for financial accounts or sensitive infrastructure. That caps the blast radius of a workstation breach.
Commit signing. Set up SSH commit signing (supported by GitHub since 2022) or GPG signing for all commits. Turn on branch protection rules that require signed commits on main/release branches.
Audit cron. Run a weekly automated check. Use aws iam generate-credential-report to review IAM credentials. Use gh api /user/installations to audit GitHub App permissions. Use a dig axfr-style check for unauthorized DNS changes. These are visible signs of a breach that show up before an attacker hits their goal.
Dependency pinning with hash verification. Lock dependencies to specific commit SHAs or content-addressed hashes, not floating semantic version ranges. For npm, use npm ci with a committed package-lock.json. For Python, use pip-compile with hashed requirements. For Go, go.sum is already hash-based.
Advanced
Tailscale (or Headscale) for infrastructure access. Expose nothing on the public internet that does not need to be public. SSH, admin panels, monitoring dashboards, and staging belong on a Tailscale mesh. Add Tailscale ACLs to enforce least-privilege network access between devices. Headscale (a self-hosted coordination server) drops the dependency on Tailscale's coordination infrastructure.
Separate browser profiles per context. Run financial accounts, development work, general browsing, and social media in separate browser profiles or separate browser apps. Firefox with Multi-Account Containers gives container-level isolation inside one app. This stops cookies and sessions from being linked across contexts. See the network leak detection guide for detection methods. Use our browser fingerprint test tool to check how much of your canvas and WebGL identity carries across profile switches.
Isolated build environment. CI should run in throwaway environments with no stored credentials. For local builds, use a container or VM with no host credential mount. That way a malicious build script cannot grab the host's SSH agent, cloud credentials, or keychain.
VPN for sensitive network contexts. A no-log, audited VPN on untrusted networks (public Wi-Fi, hotel ethernet) stops passive snooping on unencrypted traffic and hides your IP from destination servers. The VPN guide for tech-aware users covers how to assess providers. Pair it with our HTTP security headers checker to audit the headers your own web services show to passive observers.
Six profiles: assets, adversaries, priority mitigations
| Profile | Primary assets | Realistic adversaries | Top 3 mitigations |
|---|---|---|---|
| Indie dev (SaaS) | GitHub account, AWS/Stripe credentials, domain registrar | Opportunistic credential stuffing, targeted phishing after revenue visible | 1. FIDO2 on GitHub + AWS root, 2. .env leak prevention, 3. separate browser for financial |
| OSS maintainer | npm/PyPI publish tokens, repository merge access, commit signing key | Supply chain attackers, account takeover for downstream poisoning | 1. Hardware key for package registry, 2. SLSA provenance, 3. audit cron for unexpected releases |
| Security researcher | Research environment, PoC code, vulnerability disclosure records | Targeted phishing (you hold pre-disclosure vulns), insider threats in coordinating vendors | 1. Air-gapped research VM, 2. encrypted disk for PoC storage, 3. hardware key on email |
| Journalist (technical) | Source communications, notes and documents, email | Nation-state surveillance, targeted device compromise | 1. Signal for sources, 2. Tor Browser for sensitive research, 3. separate device for source contact |
| Crypto holder | Hardware wallet seed phrase, exchange accounts, DeFi wallet keys | Targeted theft, SIM swap for exchange 2FA, $5 wrench attack | 1. Metal seed backup in secure location, 2. no SMS 2FA on exchanges, 3. Yubikey for exchange accounts |
| Sysadmin (MSP/solo) | Root SSH keys, client infrastructure access, monitoring dashboards | Targeted phishing via client impersonation, insider threat, ransomware operators | 1. Tailscale for all SSH access, 2. break-glass accounts with hardware key + offline MFA, 3. immutable backup strategy |
Worked example: a coherent configuration for an indie dev
To make the tiers above concrete, here is how the advice fits into one coherent setup for the "indie dev (SaaS)" profile. It is judged against an opportunistic-plus-targeted-phishing threat tier. Treat it as an example reference architecture, not a rule. Your asset list decides what actually applies.
Hardware security keys: two FIDO2 keys (for example, a YubiKey 5 NFC as primary and a 5C NFC as backup kept in a separate physical location). Register both on GitHub, Cloudflare, the domain registrar, and the email/workspace admin. TOTP (Ente Auth, Aegis, or 1Password) covers accounts that do not support hardware keys. Use an encrypted local backup rather than a cloud sync. Print the emergency recovery codes and store them offline.
Workstation compartmentalization: split browser profiles by context. For example dev (GitHub, cloud consoles, CI dashboards, npm), financial (bank, Stripe, payment processors, exchanges), editorial (CMS, analytics, social), and personal. Run the financial context in its own browser app on a separate OS user account for stronger isolation. You can use the browser fingerprint test to check how much of your canvas and WebGL identity carries across profiles versus across separate apps.
Secrets management: a password manager with CLI integration (for example op run --env-file) for app secrets. Broker AWS credentials through a tool like aws-vault with hardware MFA on session-token calls, so no long-lived access keys sit on disk. Add a pre-commit secret scanner (gitleaks detect --staged, truffleHog, or git-secrets) that blocks accidental key commits before they land.
Infrastructure access: a Tailscale (or Headscale) mesh with no port 22 exposed publicly. Keep admin panels, Grafana, and staging on the 100.x.x.x range only. Use ACL rules to limit which devices can reach production versus read-only monitoring.
Network: an audited no-log VPN on untrusted networks, DNS-level filtering (such as Pi-hole) on your home network, and a baseline tunnel on mobile to block passive snooping on cellular.
A common trap: a CI/CD pipeline keeps static cloud credentials in GitHub Actions secrets because OIDC federation is always "on the list." It is worth doing early. Short-lived OIDC tokens remove a standing secret that a hacked workflow could steal. The migration is usually a few hours of work across a handful of workflows. That is far less than people assume. The job feels complex, so it gets delayed far longer than the real work would justify.
Annual review: re-evaluation checklist
A threat model is not a document you write once and file away. The threat surface shifts as your activity shifts. Each of the events below calls for an immediate review:
Trigger events requiring immediate re-evaluation:
- A new project goes public (ProductHunt launch, GitHub stars crossing 1,000, press mention)
- You gain admin access to infrastructure you did not control before
- A security incident touches any account in your ecosystem, even indirectly
- Revenue crosses a level that makes a financial attack pay off
- You get a message that could be targeted social engineering
- Your name shows up in a context that raises doxxing risk
Annual re-evaluation checklist:
- List all assets again. What accounts exist now that did not six months ago? What services have you added to your stack?
- Audit access tokens. Run
gh auth list,aws iam list-access-keys --user-name <all users>,gcloud auth list. Revoke anything you no longer use. - Review 2FA methods. Have any accounts dropped from a hardware key to TOTP, or from TOTP to SMS? Fix those steps backward.
- Check for exposed secrets. Run truffleHog across all repos, including private ones. Run Grype or a similar tool against container images.
- Update dependency lockfiles. Pin to current known-good versions. Read the changelog for security-relevant changes.
- Review cloud IAM policies. Least privilege erodes over time, as permissions get added for convenience and never removed.
- Test backup restore. An untested backup is not a backup. Check that your encrypted disk images, database snapshots, and seed phrase backups are intact and can be restored.
- Reassess your adversary tier. Has anything in your professional or public profile changed that would make you a higher-value target?
The NIST CSF 2.0 Govern function sets up this kind of steady improvement loop at the org level. For individuals, the same thing is a calendar reminder, a clear checklist, and the discipline to run it even when nothing has gone wrong yet.
The EFF publishes updated guides at ssd.eff.org on a rolling basis. The MITRE ATT&CK Matrix (attack.mitre.org) is updated quarterly with new adversary techniques drawn from real incidents. That helps you check whether any new TTPs apply to your profile.
Building a reliable threat model is not a one-afternoon task. It is the habit of asking, for each big change in your attack surface: what could an adversary do with this? And is the cost of stopping it lower than the cost of the incident? The frameworks above β EFF SSD, STRIDE, CVSS 3.1 scoring β give you a shared language for that talk. You can use it with yourself, with your collaborators, or with a security professional you consult when the stakes are high enough to warrant outside review.

