Exception model

An exception lets a specific package bypass one firewall rule. Developers can request one, and the team that owns your policy decides.

Sometimes a package that a rule blocks is needed anyway. It might be a security patch newer than your delay window allows, or a vulnerable version whose vulnerable code your project never calls. An exception lets that package bypass that rule, and the rule keeps blocking everything else.

For the steps, see Manage exceptions.

Each exception applies to one rule

An exception belongs to a single rule. When the rule matches a request and one of its exceptions matches too, the firewall skips that rule for the request. Every other rule still runs, so an exception on the vulnerability rule does not get a package past the malware rule, or past a rule you add later.

What an exception covers

An exception names its packages the same way a rule does: by package name and version, and optionally by upstream. This is called its selector.

Keep it narrow. An exception for lodash version 4.17.20 covers one version. One for lodash with no version covers every version, including versions published later, and keeps applying after the reason for it is gone.

Exceptions can expire

After its expiry date, an exception stops matching and the rule blocks the package again. Nobody has to remove it.

If the package is still needed, someone renews the exception and checks the decision again. An exception without an expiry stays until someone deletes it, so prefer short expiries.

Every exception records a reason

Each exception has a reason from a fixed list, such as not_exploitable or no_upgrade_path (see the full list), and optional notes, such as a ticket link. With logging on, the log entry for a request the exception allowed includes the exception's ID.

When someone later asks why a blocked package got through, the log entry leads to the exception, and the exception shows the rule, the reason, and the expiry.

Who can grant an exception

Adding an exception needs the fw:update:exception permission on the firewall, and you choose which team has it.

If every developer has it, blocks get resolved quickly, but each developer decides for the whole organization. If only the team that owns the policy has it, developers have to ask that team outside the firewall, and the reasons end up in chat instead of with the exception.

Exception requests let developers ask inside the firewall. A developer requests the exception they need and writes a justification. A reviewer with fw:update:exception approves it, which adds the exception, or denies it with a comment. The request stays linked to the exception, so you can see who asked, who decided, and why. Other tools call this a waiver workflow.

From a blocked install to an exception

With exception requests turned on, a block goes through these steps:

Approved
Rule blocks a packagedeveloper sees a request ID
Developer requests an exceptionwith a justification
Reviewer decides
Exception addedselector, reason, expiry
Next install passeslogged with exception ID
Expiry passesblock returns unless renewed
Block standscomment sent to the developer

Choose direct exceptions or requests

Two questions decide which one fits a firewall:

  1. Are the people who hit blocks the same people who are responsible for the policy?
  2. Does each exception need sign-off from a team such as security or compliance?
Your situationUse
One team installs packages and owns the policyDirect exceptions. Give that team fw:update:exception. See Manage exceptions
Developers hit blocks, and a security or platform team owns the policyException requests. Keep fw:update:exception with the policy owners and turn requests on. See Set up an exception workflow
Exceptions are managed as code by automationDirect exceptions through config import. A request needs a person, so service access tokens cannot make one. See Manage config as code

Both can run on one firewall. Users who can add exceptions are offered Create exception, and users who can only ask are offered Request exception.