An exception request for an unapproved package should fit on one page and answer seven questions: what it is, why it is needed, who owns it, what it can access, what the alternatives are, how long the exception lasts, and how to remove it. Give every exception an expiry date, or it quietly becomes policy.
Why a template beats a chat message
Without a form, requests arrive as chat messages with half the facts. The reviewer spends the first day asking questions, the developer waits, and the developer then installs the package anyway. A short template makes the fast answer possible.
The goal is not to make saying yes hard. It is to make a good yes cheap and a bad yes visible.
The template
| Field | What to ask | Why it matters |
|---|---|---|
| Package and version | Name, ecosystem, exact version, source URL | You can only review a specific thing |
| Need | What job does it do, and what happens if we do not use it? | Separates need from habit |
| Owner | Named engineer and team | Someone to call when an advisory lands |
| Where it runs | Production, build, test or developer machine only | Sets the review depth |
| Access | Network, secrets, user data, file system | Drives the risk call |
| Alternatives | Approved packages considered, and why they fall short | Often ends the request |
| Duration | One sprint, one release, or permanent with review | Sets the expiry |
| Exit plan | How to replace or remove it | Makes removal realistic |
Add a line for the license, noted from the package's own metadata, and a line for transitive packages it brings in.
A fast decision rule
Use tiers so low-risk requests do not queue behind high-risk ones.
- Build or test only, no secrets: approve by the team lead within one working day.
- Runs in production, no sensitive data: security review within three working days.
- Handles secrets, user data or network calls: full review, with the owner present.
Write the target times down, and measure them. If decisions take longer than the targets, people route around you. For who should approve at each tier, see who approves a new dependency: risk tiers and fast lanes.
Make exceptions expire
Every approved exception gets an expiry date and an owner reminder. At expiry, one of three things happens: it is promoted to the approved list, it is replaced, or it is renewed with a new reason. Nothing renews silently.
Keep exceptions in one place, with the request attached. At audit time, an expiry log is easy evidence that the process works. For the audit angle, see SOC 2 audit exceptions: what they are and how to avoid them.
What to check before approving
Look at the package's source repository, its maintainers, how recently it was updated, whether it has known advisories, and what it pulls in. Pin the version, and add it to your inventory so you hear about future advisories.
Quick check
Who should sign off on an exception?
The owner's team lead for low-risk cases, and security for anything that touches production, secrets or user data.
How long should an exception last?
Short by default. One release cycle is a good start, with an explicit renewal if it is still needed.
Safeguard offers policies, gates and guardrails, SBOM and dependency scanning, and a free scan at gold.safeguard.sh/scan.
Last reviewed: 19 October 2026.