Policy config

Decide what the firewall blocks. The firewall reads your Socket policy, so there is nothing to configure on the firewall itself.

The firewall does not hold its own rules. For every download it asks Socket for a verdict, and Socket answers from your organization's policy. Change the policy and every firewall pointed at that organization follows, with no restart.

ActionEffect at the firewall
Block (error in the API)403, install fails
WarnAllowed, X-Socket-Warn-Reason header added
MonitorAllowed silently, recorded
IgnoreAllowed, no record

Which policy system do you have?

Socket is migrating every organization from Security Policy + Alert Triage to Policies. Check the dashboard: if you see a Policies page, use the Policies steps. If you see Settings → Security Policy, use the legacy steps.

🚧

After migration, legacy API writes fail

Once an organization switches to Policies, writes to the old security-policy and triage endpoints are rejected (POST returns 409, PUT and DELETE return 405). Reads still work but show a frozen copy. Move any scripts before you confirm the migration.

Least-work setup

Policies

  1. Open Policies → Default. The firewall always uses the Default policy, because installs are not tied to a repository.
  2. Pick a baseline preset. Balanced (the default) blocks malware and covers common supply chain risks. Comprehensive also blocks critical vulnerabilities.
  3. Add custom rules only for what the preset doesn't do the way you want. Custom rules sit above the baseline, and the first match wins.

Security Policy (legacy)

Dashboard → Settings → Security Policy, set an action per alert type.

Block or allow one package

Policies: in the Default policy, add a custom rule matching the package (and version), with action Block to deny or Ignore to allow. Place it above broader rules. See Rule Conditions.

Security Policy (legacy): Settings → Security Policy → Alert Triage, add an entry for the package, version, and an alert type the package actually carries. Block denies, Ignore allows.

🚧

Legacy triage attaches to an alert type

A legacy triage entry changes how one alert type is treated for that package. If the package doesn't carry that alert type, the entry silently does nothing. Check first with the verdict call below. Policies rules don't have this limitation: a rule can match the package alone.

Verify

Ask Socket what it would decide, then confirm the firewall agrees. This example assumes a deny rule for [email protected].

# Socket's verdict (works on both policy systems)
curl -s -X POST "https://api.socket.dev/v0/purl?alerts=true" \
  -H "Authorization: Bearer $SOCKET_API_KEY" -H 'Content-Type: application/json' \
  -d '{"components":[{"purl":"pkg:npm/[email protected]"},{"purl":"pkg:npm/[email protected]"}]}' \
  | jq -c 'select(.name!=null)|{p:"\(.name)@\(.version)",actions:([.alerts[]?|{t:.type,a:.action}]|unique)}'

# The firewall's decision
for v in 3.0.1 2.0.0; do
  printf 'is-odd@%s -> ' "$v"
  curl -sk -D- -o /dev/null "https://sfw.example.com/npm/is-odd/-/is-odd-$v.tgz" \
    | grep -iE '^HTTP/|^x-socket-block-reason' | tr '\n' ' '; echo
done

Expected on Policies. The rule adds a policy entry with error; the package's own alerts keep their original action:

{"p":"[email protected]","actions":[{"t":"unmaintained","a":"warn"}]}
{"p":"[email protected]","actions":[{"t":"policy","a":"error"},{"t":"unmaintained","a":"warn"}]}

[email protected] -> HTTP/2 403 x-socket-block-reason: Blocked by security policy
[email protected] -> HTTP/2 200

Expected on Security Policy (legacy), with a triage entry on unmaintained. The alert itself changes to error:

{"p":"[email protected]","actions":[{"t":"unmaintained","a":"warn"}]}
{"p":"[email protected]","actions":[{"t":"unmaintained","a":"error"}]}

[email protected] -> HTTP/2 403 x-socket-block-reason: Unmaintained
[email protected] -> HTTP/2 200
  • The verdict call shows the action you set
  • The firewall returns 403 for Block and 200 otherwise
  • The change is in the audit log with your user

Notes

  • Cache: the firewall caches verdicts for cache.ttl (600 s). A package fetched just before a change keeps its old decision until then. Test with a package the firewall hasn't seen recently, or clear the cache: restart the container, or run FLUSHDB if you use Redis, where verdicts survive restarts.
  • Same org: the firewall's API token must belong to the organization whose policy you edited.
  • Not a policy setting: blocking packages Socket hasn't scanned yet is a firewall switch, socket.fail_open_unscanned: false.
  • Not a policy file: a repository's socket.yml with issueRules: does not set firewall policy. The firewall's socket.yml is a different file with a different schema.

Automate it

Everything above can be scripted. The token needs alert-policy:list, alert-policy:create, alert-policy:update, alert-policy:delete (Policies) or the legacy policy and triage scopes. The firewall's own token does not have these, so use a separate admin token.

Policies

ORG=your-org

# 1. Find the Default policy (the one that applies to unlabeled repos and the firewall)
DEFAULT_ID=$(curl -s -H "Authorization: Bearer $SOCKET_API_KEY" \
  "https://api.socket.dev/v0/orgs/$ORG/alert-policies" \
  | jq -r '.. | objects | select(.apply_method? == "unlabeled_repos") | .id' | head -1)

# 2. Dry-run a deny rule, then create it. New rules are placed first.
for q in "?dry_run=true" ""; do
  curl -s -X POST -H "Authorization: Bearer $SOCKET_API_KEY" -H 'Content-Type: application/json' \
    "https://api.socket.dev/v0/orgs/$ORG/alert-policies/$DEFAULT_ID/rules$q" \
    -d '{"name":"Deny is-odd 3.0.1",
         "vigil_selector":{"artifact.type":"npm","artifact.name":"is-odd","artifact.version":"3.0.1"},
         "action":"error",
         "note":"Deny list: superseded internally"}'
  echo
done

Use "action":"ignore" for an allow rule. Rules are written as Vigil selectors. To list, update, or delete rules, see the policy rule API reference.

Security Policy (legacy)

Set actions per alert type. POST merges, so send only what you're changing:

curl -s -X POST -H "Authorization: Bearer $SOCKET_API_KEY" \
  -H 'Content-Type: application/json' \
  https://api.socket.dev/v0/orgs/your-org/settings/security-policy \
  -d '{"policyRules":{"malware":{"action":"error"},"criticalCVE":{"action":"error"}}}'

Deny one package version with a triage entry (state: block; use ignore to allow):

curl -s -X POST -H "Authorization: Bearer $SOCKET_API_KEY" -H 'Content-Type: application/json' \
  https://api.socket.dev/v0/orgs/your-org/triage/alerts \
  -d '{"alertTriage":[{"packageType":"npm","packageNamespace":"*","packageName":"is-odd",
       "packageVersion":"3.0.1","alertType":"unmaintained","state":"block",
       "note":"Deny list: superseded internally"}]}'
📘

Legacy API quirks

The write method is POST (PUT returns 405). The body key is policyRules, but GET returns securityPolicyRules. Triage returns {"result":"success"}.

Reference


Did this page help you?