Ask five questions: who can reach it, what does it hold, what can it change, what input does it trust, and how would you know if it was misused. Answer them in 30 minutes with the people who built and use the tool, and you will find most of the serious gaps in an internal tool.
Definition
A threat model is a structured way of asking what could go wrong with a system, before it does. For internal tools such as portals, CLIs, bots and dashboards, it does not need diagrams or a framework. It needs honest answers about access, data, power and trust, written down.
The five questions
| Question | What to write down | Typical finding |
|---|---|---|
| Who can reach it? | Networks, identities, roles, service accounts | Open to anyone on the network, or one shared login |
| What does it hold? | Credentials, tokens, customer data, config | A broad token created for a demo |
| What can it change? | Repos, pipelines, cloud resources, access | Write access nobody needs |
| What input does it trust? | Config files, catalog entries, user text, plugin output | Untrusted values reaching commands or queries |
| How would you know? | Logs, alerts, audit trail | No record of who ran what |
How to run the session
- Invite the owner, one regular user and one person who did not build it. The outsider asks the questions the builders stopped noticing.
- Draw the tool as a simple list: users, the tool, what it talks to. Five boxes are enough.
- Go through the five questions in order and write one line per answer.
- For each answer, ask the follow up: if this were wrong, what is the worst plausible result?
- Pick the top three issues and give each an owner and a date. Do not try to fix everything.
- Store the page next to the code, and review it when the tool changes materially.
Examples of what comes up
For a developer portal, the documentation's own defaults are instructive: endpoints are not protected and all actions are available to anyone until you configure authentication and permissions. That answers the first question in an uncomfortable way, and the fix is clear.
For a CLI run by developers, the second and fourth questions surface fast. It holds a token, and it reads a config file from whatever directory the user is in. For an editor extension or plugin, the VS Code documentation notes that extensions run with the same permissions as the editor, which answers question three before you ask it.
For a chatops bot or a build helper, question four is where the findings are: message text or branch names flowing into shell commands.
Rank by blast radius, not by likelihood
Teams argue about whether an attack is likely. For internal tools that debate wastes time. Rank by what happens if the tool is controlled by someone hostile. A tool that can deploy to production outranks a tool that reads a dashboard, whatever the odds.
Keep it alive
A threat model that sits in a folder helps nobody. Add one line to your tool template: "Threat model reviewed on this date." Link it from the README. Refresh it when you add an integration, a new credential or a new way for users to supply input.
Where Safeguard fits
Safeguard's asset discovery and SBOM and dependency scanning help with the "what does it hold and depend on" answers, and policies and gates can enforce fixes. Try the free scan at gold.safeguard.sh/scan.
Quick check
Do I need a framework to do this?
No. Five questions, thirty minutes and a written page are enough for most internal tools. Use a framework later if you need more depth.
How often should it be reviewed?
Whenever the tool gains a new credential, integration or input path, and at least once a year for tools that can change production.
Sources
- Permissions overview, Backstage documentation
- Extension runtime security, Visual Studio Code documentation
Last reviewed: 19 October 2026.