Skip to main content

User Risk Score

User Risk Score attaches a number from 0 to 100 to every user, where a higher number means a riskier identity. Once users are scored you can target guards at just the risky ones, and refuse tool calls outright from users above a line you set.

The score is deliberately a single number rather than a category, so that policies read the way admins state them — "block above 80", "run the DLP guard on anyone over 70".

Beta feature

This page appears only when the User Risk Score flag is on under Beta Features. With the flag off, scores can still be written through the API but nothing reads them.

Where scores come from

SourceRecorded asHow it gets set
An admin editing a user in the dashboardManualSet a score by hand
The Admin APIAdmin APIPATCH /api/users
A bulk push from any external systemYour own labelPOST /api/users/risk-scores
CrowdStrike Falcon Identity ProtectionCrowdStrikeThe built-in sync

A user who has never been scored is unscored, which is not the same as a user scored 0. Unscored users are excluded from the distribution chart and from the average, they are never blocked, and by default they do not match a guard's risk filter. This is what keeps a failed or half-finished sync from locking your organization out.

Score bands

The bands below are used for badge colors and chart colors throughout the dashboard. They are presentational — thresholds you configure are exact numbers, not bands.

BandRange
Low0–39
Medium40–69
High70–89
Critical90–100

Open the page

Go to SettingsSecurity SettingsUser Risk Score, then select Manage User Risk Score. The card itself carries badges reporting whether the CrowdStrike sync is on and what threshold, if any, is blocking.

The page opens with four tiles — how many users are scored, the average score, the highest score, and how many users the block policy currently catches — above a histogram of how many users fall in each ten-point band. If a block threshold is set, the chart draws a line at it, so you can see how many people a change would affect before you make it.

Set a score by hand

  1. Go to ManageUsers.
  2. Select a user to open the edit dialog.
  3. Enter a whole number from 0 to 100 in Risk score, or clear the field to make the user unscored again.
  4. Select Save.

A score set here is recorded as Manual. Provider syncs skip users whose score is manual, so a deliberate override survives the next import — unless you turn on Overwrite manual scores.

The users table gains a Risk column while the beta flag is on, showing each user's score and, on hover, what set it.

Import scores from CrowdStrike

Willow can pull identity risk scores from CrowdStrike Falcon Identity Protection and match them to your users by email address.

Falcon reports risk on a 0–1 scale; Willow multiplies by 100 so a Falcon score of 0.72 is stored as 72. Both scales run the same direction — higher is riskier — so the ordering is preserved.

note

Netskope's Cloud Exchange plugin for the same data source inverts the scale, where 0 is maximum risk. Willow does not. A number that looks alarming in one product may be benign in the other.

Create Falcon API credentials

  1. In the Falcon console, go to SupportResourcesAPI Clients and Keys.
  2. Select Add New API Client and grant these scopes:
ScopeAccess
Identity Protection GraphQLWrite
Identity Protection EntitiesRead
Identity Protection TimelineRead
  1. Copy the Base URL, Client ID, and Client Secret. The secret is shown once.

Configure the sync

On the User Risk Score page, in the CrowdStrike Falcon Identity Protection card:

  1. Turn the card's switch on.
  2. Pick your API region — this is the Falcon cloud your tenant lives in (api.crowdstrike.com, api.us-2.crowdstrike.com, api.eu-1.crowdstrike.com, or GovCloud). Using the wrong region fails authentication.
  3. Enter the Client ID and Client secret.
  4. Decide whether to Overwrite manual scores. Off by default, so a scheduled import cannot undo an admin's deliberate override.
  5. Select Test connection to confirm the credentials and region before saving, then Save.

Once saved, Willow syncs once a day. Select Sync now to run one immediately. The card reports when the last sync ran, how many users it updated, and the error if it failed.

Identities whose email matches no Willow user are counted as skipped rather than failing the run, so you do not need to reconcile the Falcon export against your user list first.

Block high-risk users

The Block high-risk users card refuses MCP tool calls from users at or above a threshold. The call is rejected at the gateway before any tool runs, and the rejection is written to the audit log with the error code USER_RISK_BLOCKED, the user's score, and the threshold that caught them.

  1. Turn the card's switch on.
  2. Set the Threshold. The helper text tells you how many users are currently at or above it.
  3. Optionally set the Message shown to the user, for example pointing them at your IT helpdesk.
  4. Select Save.

The comparison is inclusive: a threshold of 80 blocks a user scored exactly 80. Unscored users are never blocked.

caution

Check the distribution chart before turning this on. Blocking is organization-wide and immediate — every affected user loses MCP access on their next call.

Apply a guard to a score range

Rather than blocking outright, you can narrow an existing guard to risky users, so that everyone keeps working while the risky few get extra scrutiny.

  1. Open a guard and go to its Filters tab.
  2. Turn on Filter by User Risk Score.
  3. Set a Minimum score, a Maximum score, or both. Both bounds are inclusive, and either can be left empty for an open-ended range.
  4. Choose whether to Also apply to users with no risk score. Off by default.

A guard filtered to 70–100 runs only for high and critical users. One filtered to 0–39 runs only for low-risk users, which is useful for a warn-only guard you want to keep off your riskiest population while a stricter guard covers them.

Risk filters apply to runtime guards — the ones that inspect tool calls. Build-time guards are evaluated without a user in context and ignore the filter.

Update scores through the API

The API is the intended path for any risk source other than CrowdStrike, such as your own SIEM, an identity provider, or a scheduled export from another risk product. Both endpoints need an API token with the admin:write scope. See the Admin API reference for full schemas.

Update one user

curl -X PATCH 'https://your-org.mcp-s.com/api/users?email=john.doe@example.com' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"risk_score": 72}'

Send "risk_score": null to clear the score back to unscored. The score is recorded as Admin API, which does overwrite a manual score.

Push scores in bulk

Use this for scheduled imports. Up to 5,000 users per request, matched by email.

curl -X POST 'https://your-org.mcp-s.com/api/users/risk-scores' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"source": "okta-risk",
"overwrite_manual": false,
"scores": [
{ "email": "john.doe@example.com", "risk_score": 72 },
{ "email": "jane.smith@example.com", "risk_score": 15 }
]
}'
{ "data": { "updated": 2, "skipped": 0 } }

source is a free-form label recorded on each updated user and shown in the dashboard, so you can tell at a glance which system set a score. The value manual is reserved for dashboard edits and is rejected. overwrite_manual defaults to false.

skipped counts entries that matched no user, plus users left alone because their score was set manually.

If your source uses a different scale, convert before calling. Willow validates that every score is a whole number from 0 to 100 and rejects the whole request otherwise, rather than silently clamping.