> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semgrep.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Semgrep Malware Firewall exceptions

> Request an exception for a package version that the Semgrep Malware Firewall blocks, and approve, deny, or revoke requests as an admin.

> [!NOTE]
>
> Semgrep Malware Firewall is in **private beta**.

If the [Semgrep Malware Firewall](https://docs.semgrep.dev/semgrep-supply-chain/malware-firewall.md) blocks a package version you need, use the `mfw` CLI to request an exception for your organization's deployment. Admins use the same CLI to review, approve, or deny requests and revoke approved exceptions.

## How exceptions work

An exception request goes through the following steps:

1. The firewall blocks a package version during an install.
2. A requester runs `mfw exception request` and explains why they need that version.
3. If an admin set up notifications for your deployment, Semgrep posts the request to a Slack channel or webhook. For more information, see [Get notified about new requests](#get-notified-about-new-requests).
4. A deployment admin approves or denies the request with `mfw exception review`.
5. After approval, the firewall allows that version on every machine in the deployment.

Keep the following in mind:

* **An exception covers one exact version.** It applies to one ecosystem, package name, and version, such as `npm/example-package@1.2.3`. It doesn't cover version ranges, and every other version of the package stays blocked.
* **An exception applies to your whole deployment.** It isn't limited to the requester, or to one machine or project.
* **The package stays blocked until an admin approves the request.** Requesting an exception doesn't change anything on your machine. If you retry the install while the request is waiting, the firewall blocks it again.
* **Approvals and revocations take up to 5 minutes to apply.** To apply a change on your own machine right away, run `mfw restart`.

### When an approval stops applying

An approval covers the advisories that matched the package when the requester asked for the exception. If those advisories change later, the firewall stops applying the approval and blocks the package again. The request's status stays `approved`, but `mfw exception list` notes that it's no longer applied, and `mfw exception review` labels it `STALE`. An admin must revoke the approval before anyone can request an exception for that version again.

## Request an exception or review a request

Open the tab for the task you want to finish. An admin can request an exception and review requests.

> [tab] Request an exception
>
> > [!NOTE]
> >
> > **Prerequisites**
> >
> > To request an exception:
> >
> > * The Malware Firewall is installed on your machine and turned on for your deployment. For more information, see [Install and verify](https://docs.semgrep.dev/semgrep-supply-chain/malware-firewall.md#install-and-verify).
> > * You're signed in to the firewall with your own Semgrep account through `mfw login`. API tokens, such as one set in `SEMGREP_APP_TOKEN`, can't request exceptions yet.
>
> ## Request an exception
>
> To request an exception for a blocked package, follow these steps:
>
> **Step 1**
>
> Find the blocked package in the install output. The firewall lists each package that it blocked, with a link to each advisory that matched.
>
> **Step 2**
>
> Request an exception for that exact version:
>
> ```bash theme={null}
> mfw exception request ECOSYSTEM NAME@VERSION --reason "REASON"
> ```
>
> Replace the following:
>
> * `ECOSYSTEM`: The package's ecosystem, such as `npm` or `pypi`. See [Ecosystems and package names](#ecosystems-and-package-names).
> * `NAME@VERSION`: The exact package version from the install output, such as `example-package@1.2.3`.
> * `REASON`: Why you need this version. Admins see it when they review the request.
>
> For example:
>
> ```bash theme={null}
> mfw exception request npm example-package@1.2.3 --reason "We vendor a patched fork of this version"
> ```
>
> If you leave out `--reason`, `mfw` asks for one, then asks you to confirm before it sends the request.
>
> **Step 3**
>
> Confirm that `mfw` sent the request. The output looks like this:
>
> ```text theme={null}
> ✓ Exception requested for npm/example-package@1.2.3.
>   Advisories: ssc-1a2b3c4d https://semgrep.dev/orgs/-/advisories/ssc-1a2b3c4d
>   An org admin will review this request.
>   Check status with `mfw exception list`.
> ```
>
> If you belong to more than one deployment, `mfw` files a separate request in each deployment that has the firewall turned on. An admin of each deployment reviews it. If a request for the same version already exists, `mfw` tells you its status instead of filing another one.
>
> ### Ecosystems and package names
>
> Use one of the following ecosystem names:
>
> | Ecosystem | Example |
> | :- | :- |
> | `npm` | `mfw exception request npm @scope/example-package@1.2.3` |
> | `pypi` | `mfw exception request pypi example-package@1.2.3` |
> | `maven` | `mfw exception request maven com.example:example-artifact@1.2.3` |
> | `cargo` | `mfw exception request cargo example-crate@1.2.3` |
> | `gomod` | `mfw exception request gomod example.com/example/module@v1.2.3` |
>
> For Maven and Gradle projects, the ecosystem is `maven` and the package name is the `groupId:artifactId` coordinate. Maven `SNAPSHOT` versions can't have exceptions, because a snapshot refers to a series of builds that keeps changing. Request the exact release instead.
>
> ### Request options
>
> | Option | Description |
> | :- | :- |
> | `-r`, `--reason REASON` | Why you need the package. Required, up to 2,000 characters. If you omit it in an interactive terminal, `mfw` asks for it. |
> | `-y`, `--yes` | Send the request without asking for confirmation. |
> | `--json` | Print the response as JSON. |
>
> ## Check the status of your requests
>
> To see every exception request you've made, run:
>
> ```bash theme={null}
> mfw exception list
> ```
>
> Each line shows the request ID, the package, the deployment, and the request's status:
>
> ```text theme={null}
> 42  npm/example-package@1.2.3  Example Org  awaiting review (requested 5m ago)
> 37  pypi/example-tool@0.4.1    Example Org  approved 2h ago by an-admin: "Checked the fork"
> ```
>
> A request has one of the following statuses:
>
> | Status | Meaning |
> | :- | :- |
> | `awaiting review` | An admin hasn't reviewed the request yet. The package is still blocked. |
> | `approved` | The package is allowed across the deployment. A request approved in the last 5 minutes might not apply yet. |
> | `denied` | An admin turned down the request. The package is still blocked. |
> | `revoked` | An admin approved the request, then took the approval back. The package is blocked again. |
>
> To narrow the list, pass a package, a status, or both. To include more than one status, repeat `--state`:
>
> ```bash theme={null}
> mfw exception list npm example-package@1.2.3
> mfw exception list --state requested --state approved
> ```
>
> | Option | Description |
> | :- | :- |
> | `ECOSYSTEM NAME@VERSION` | Only show requests for this exact package version. |
> | `--state STATE` | Only show requests with this status: `requested`, `approved`, `denied`, or `revoked`. |
> | `--json` | Print the response as JSON. |
> | `--page-token TOKEN` | Continue a long `--json` listing from its `nextPageToken`. |
>
> ## Install a package after approval
>
> After an admin approves your request, the firewall allows the package on every machine in your deployment within about 5 minutes. To apply the approval on your own machine right away, run:
>
> ```bash theme={null}
> mfw restart
> ```
>
> Then run your install again. The install succeeds, and the firewall prints a line like the following for each package that an exception allowed:
>
> ```text theme={null}
> ⚠ npm/example-package@1.2.3 was allowed by an approved exception
> ```
>
> This line means that Semgrep still flags the package as malicious. The firewall let it through only because an admin approved an exception for it. If the package matched advisories, a link to each one follows the line.
>
> ## Troubleshoot a request
>
> To fix a failed request or install, match the message or symptom in the following table:
>
> | Message | Likely cause | Suggested fix |
> | :- | :- | :- |
> | `Exception requests need a user login.` | `mfw` is signed in with an API token | Run `mfw login` to sign in with your Semgrep account |
> | `Not signed in to Semgrep.` | You haven't signed in, or your session expired | Run `mfw login` |
> | `<package> is not blocked by the malware firewall, so it doesn't need an exception.` | The firewall doesn't block that version | Check the ecosystem, name, and version against the install output |
> | `A specified version is required. Exceptions apply to one exact version.` | The package has no version, or uses a range such as `^1.2.0` | Request the exact version, such as `example-package@1.2.3` |
> | `The malware firewall isn't turned on for any of your orgs` | The firewall isn't turned on for your deployment | Ask your Semgrep admin |
> | An approved package is still blocked | The approval hasn't reached your machine yet | Wait up to 5 minutes, or run `mfw restart` |

> [tab] Review requests (admins)
>
> > [!NOTE]
> >
> > **Prerequisites**
> >
> > To review exception requests:
> >
> > * The Malware Firewall is installed on your machine and turned on for your deployment. For more information, see [Install and verify](https://docs.semgrep.dev/semgrep-supply-chain/malware-firewall.md#install-and-verify).
> > * You're signed in to the firewall with your own Semgrep account through `mfw login`. API tokens, such as one set in `SEMGREP_APP_TOKEN`, can't review exceptions yet.
> > * You're an admin of the deployment.
>
> ## Review exception requests
>
> Only admins of the deployment can review exception requests. Reviews happen in the `mfw` CLI.
>
> ### Review requests interactively
>
> In a terminal, run:
>
> ```bash theme={null}
> mfw exception review
> ```
>
> `mfw` walks through your deployment's queue one request at a time. It shows requests awaiting review first, oldest first, then approved requests that you can revoke. For each request, it shows the package, who asked for it and when, and their reason:
>
> ```text theme={null}
> Reviewing 1 of 2
>   npm/example-package@1.2.3, requested by a-developer 12m ago
>   Reason: "We vendor a patched fork of this version"
> [a] approve  [d] deny  [s] skip  [v] view advisory info  [q] quit
> >
> ```
>
> | Key | Action |
> | :- | :- |
> | `a` | Approve the request. This allows the package across the deployment. |
> | `d` | Deny the request. |
> | `r` | Revoke an approved request. This blocks the package again across the deployment. Shown only for approved requests. |
> | `s` | Skip to the next request. |
> | `v` | Show the advisories that matched the package, with links. |
> | `q` | Stop reviewing. |
>
> After you choose an action, `mfw` asks for an optional comment for the requester, then asks you to confirm. When you finish or quit, it prints a summary of what you approved, denied, revoked, and skipped.
>
> If you belong to more than one deployment, `mfw` asks which one to review. To skip the question, pass `--deployment` with the deployment's ID or name.
>
> If an approved request is labeled `STALE`, the approval no longer applies. Revoke it before anyone can request that version again. For more information, see [When an approval stops applying](#when-an-approval-stops-applying).
>
> ### List the queue
>
> To print the whole queue instead of walking through it, run:
>
> ```bash theme={null}
> mfw exception review --list
> ```
>
> The list groups requests by status: awaiting review, approved, denied, and revoked. Each request shows the ID that you need to act on it by ID. The denied and revoked sections show the 10 most recent requests. To show all of them, add `--all`.
>
> ### Approve, deny, or revoke a request by ID
>
> &#x20;To act on one request without the interactive walkthrough, pass its ID:
>
> ```bash theme={null}
> mfw exception review --approve 42 --comment "Checked the fork"
> mfw exception review --deny 42 --comment "Use version 1.2.4 instead"
> mfw exception review --revoke 42 --comment "No longer needed"
> ```
>
> `mfw` shows the request and asks you to confirm before it changes anything. To skip the confirmation, for example in a script, add `--yes`.
>
> You can approve or deny a request only while it's awaiting review. You can revoke a request only after it's approved. To turn down a request that hasn't been approved, deny it instead.
>
> ### Review options
>
> | Option | Description |
> | :- | :- |
> | `--list` | Print the queue instead of walking through it. |
> | `--all` | With `--list`, show every denied and revoked request, one line each. |
> | `--approve REQUEST_ID` | Approve the request with this ID. This allows the package across the deployment. |
> | `--deny REQUEST_ID` | Deny the request with this ID. |
> | `--revoke REQUEST_ID` | Revoke the approved request with this ID, so the package is blocked again. |
> | `--comment COMMENT` | A comment for the requester, recorded with `--approve`, `--deny`, or `--revoke`. Up to 2,000 characters. |
> | `--deployment DEPLOYMENT` | The ID or name of the deployment to review. Required when you belong to more than one deployment and aren't in an interactive terminal. |
> | `-y`, `--yes` | Act on `--approve`, `--deny`, or `--revoke` without asking for confirmation. The interactive walkthrough asks before every action. |
> | `--json` | Print the response as JSON. |
> | `--page-token TOKEN` | Continue a long `--json` listing from its `nextPageToken`. |
>
> ## Get notified about new requests
>
> Semgrep can post a message to Slack, or call a webhook, each time someone requests an exception. Semgrep creates a policy for this, named **Malware firewall exception request notifications**, for each deployment that has the Malware Firewall turned on. The policy is off until an admin adds an action and enables it.
>
> > [!NOTE]
> >
> > **Prerequisites**
> >
> > To set up notifications for new requests:
> >
> > * You have set up Slack notifications or webhooks. For more information, see [Receive Slack notifications](https://docs.semgrep.dev/semgrep-appsec-platform/slack-notifications.md) or [Enable webhooks](https://docs.semgrep.dev/semgrep-appsec-platform/webhooks.md).
> > * Your deployment uses [Unified Policies](https://docs.semgrep.dev/semgrep-appsec-platform/unified-policies/overview).
>
> ### Set up notifications
>
> To send new requests to Slack or a webhook, follow these steps:
>
> **Step 1**
>
> In Semgrep AppSec Platform, go to [**Rules & Policies > Policies**](https://semgrep.dev/orgs/-/policies), and click the **Remediation** tab.
>
> **Step 2**
>
> Find the policy named **Malware firewall exception request notifications**. On its banner, click **Set up**. You can also click its \*\* icon\*\* and select **Edit policy**.
>
> **Step 3**
>
> Click **Add action**, then choose one or both of the following actions:
>
> > [card] [Send a Slack message](https://docs.semgrep.dev/semgrep-appsec-platform/slack-notifications.md)
>
> > [card] [Call a webhook](https://docs.semgrep.dev/semgrep-appsec-platform/webhooks.md)
>
> For **Send a Slack message**, select the channel where you want admins to see new requests.
>
> **Step 4**
>
> Click **Update and enable**.
>
> **Step 5**
>
> Confirm that the policy is on. On the **Remediation** tab, the policy no longer shows the **Disabled** label, and its **Then** column lists the action that you added.
>
> The policy's name, scope, and trigger are fixed, and it doesn't support conditions. You can't delete it. To stop notifications, turn off the policy. The Malware Firewall settings in **Settings > General** also link to this policy.
>
> ### What the Slack message shows
>
> Each message describes one request:
>
> * The package version, such as `npm/example-package@1.2.3`.
> * Why the firewall blocks it: the number of matching advisories, with a link to each one, or **Flagged by inline scanning** when no advisory matched.
> * Who requested the exception, with their email address when they're a current member of the deployment.
> * The reason the requester gave for the request.
> * The CLI commands to act on the request: `mfw exception review` to review the queue, and `mfw exception review --approve` with the request's ID to approve it directly.
>
> Slack and Semgrep AppSec Platform don't have an approve button. Admins act on requests from the CLI.
>
> ## Troubleshoot a review
>
> To fix a failed review, match the message in the following table:
>
> | Message | Likely cause | Suggested fix |
> | :- | :- | :- |
> | `Exception requests need a user login.` | `mfw` is signed in with an API token | Run `mfw login` to sign in with your Semgrep account |
> | `Not signed in to Semgrep.` | You haven't signed in, or your session expired | Run `mfw login` |
> | `Only org admins can review exception requests, and Semgrep couldn't confirm you're one.` | You aren't an admin of the deployment, or Semgrep couldn't check your role | Ask a deployment admin to review the request. If you're an admin, try again in a few minutes |
> | `The malware firewall isn't turned on for any of your orgs` | The firewall isn't turned on for your deployment | Ask your Semgrep admin |
> | `You belong to several orgs. Pick one with --deployment <id or name>` | You belong to more than one deployment and aren't in an interactive terminal | Pass `--deployment` with the deployment's ID or name |

## Limitations

Exceptions have the following limitations:

* **User sign-in only.** API tokens can't request or review exceptions yet. Sign in with `mfw login`.
* **Review happens in the CLI.** You can't approve, deny, or revoke requests in Semgrep AppSec Platform or Slack.
* **Exact versions only.** An exception can't cover a version range or a Maven `SNAPSHOT` version.
* **Packages flagged by inline scanning have no advisory.** Semgrep's inline scanning flags some packages without a published advisory. For these requests, `mfw` shows `Advisories: none; flagged by inline scanning`, and the Slack message shows **Flagged by inline scanning**.
