Since Authentication is always on, Fraud Protection is on. There is no independent toggle.
Available signals
Every sign-up attempt is scored with the following fields. They’re always available in the CEL condition builder alongsideemail, emailDomain, authMethod, and oauthProvider. The Operators column lists the choices shown in the builder’s dropdown; under the hood each rule is stored as a CEL expression, so equals becomes ==, in_list becomes in [...], greater_or_equal becomes >=, and so on:
These fields evaluate together with the rest of the sign-up context, so a single rule can combine them freely.
Using signals in rules
Open Authentication → Sign-up Rules → Add rule. The rule builder is the same one documented in Sign-up Rules - the fraud-specific fields just appear in the field dropdown.Block obvious bots
- Condition:
riskScores.bot >= 80 - Action: Reject
Restrict suspected free-trial abuse for manual review
Send borderline accounts to a restricted state instead of blocking outright, so support can review them:- Condition:
riskScores.free_trial_abuse >= 60 - Action: Restrict
isRestricted). Hexclave treats restricted users like unauthenticated users in most SDK calls until an admin clears the restriction or they finish whatever verification is required. See Restricted Users for SDK handling and JWT claims, and Sign-up Rules → Restrict for how the action behaves in the rule engine.
Combine signals with email and geo
Allow sign-ups from a known corporate domain, but still hard-block anything that smells like automation:- Rule 1:
emailDomain == "company.com" && riskScores.bot < 70→ Allow - Rule 2:
riskScores.bot >= 70→ Reject - Rule 3:
countryCode in ["CN", "RU"] && riskScores.free_trial_abuse >= 40→ Restrict - Default: Allow
Restrict rule is attributed to the user). Place explicit allows above broader blocks if you want allow-lists to short-circuit.
Log first, enforce later
When you start tuning thresholds, set the action to Log instead ofReject / Restrict. The rule will trigger and show up in the per-rule sparkline + trigger history, but the sign-up flow is unaffected. Once you’re confident, switch the action to Reject or Restrict.
Testing fraud signals
The Sign-up Rules rule tester (button Open tester at the bottom of the page) has a dedicated Risk overrides section for the fraud fields:- Country - override the resolved country code (any ISO-3166-1 alpha-2).
- Bot score - 0–100. Must be provided together with Free-trial abuse or both must be blank.
- Free-trial abuse - 0–100. Same pairing rule as Bot score.
- Outcome - allow / reject and whether it came from a rule or the default action.
- Triggered rules - which rules matched, plus which one was the decision.
- Evaluation trace - every rule’s status (
Matched/No match/Disabled/No condition/Error). - Normalized context - the exact values the engine used, so you can sanity-check your overrides against the rendered context.
Trigger history & analytics
Each rule row on the Sign-up Rules page shows a sparkline with the count of triggers in the recent analytics window (typically last 48h). Click the sparkline to open the trigger history dialog, which shows:- All-time and recent counts.
- A per-rule activity chart.
- A paginated list of every individual trigger (timestamp + email when captured).
riskScores.* thresholds.
On the user page
The fraud signals also surface per-user. Open any user from Users → <user>, switch to the Authentication tab, and scroll to the Fraud section. It shows a 2-column grid with four fields:
These are the same values the Sign-up Rules engine saw at sign-up time. Editing them is useful for back-filling test data, fixing a miscalibrated score, or overriding the country before re-running a downstream flow.
Restricting a user
A Restrict user button sits in the section header (and the action also lives in the user’s top-right⋮ menu). It’s red (destructive) while the user has no manual restriction, and switches to an outline style once one is in place. It opens the User Restriction dialog with two fields:
- Public reason - shown to the user when they try to access your app.
- Private details - admin-only notes (e.g. internal ticket links).
restrictedByAdmin: true. The action label reflects the user’s current state: Restrict user when they’re unrestricted, Add manual restriction when they’re already restricted for another reason (e.g. unverified email), and Edit or remove manual restriction once a manual restriction exists - in which case the dialog also gains a Remove manual restriction action.
A Restrict outcome from your sign-up rules also lands users here - but with restrictedReason.type === "restricted_by_administrator" you can tell the difference between a rule-driven restriction (which carries a rule ID in analytics) and a hand-picked manual one.
Restriction banner
If a user is restricted for any reason, a destructive banner shows at the top of their page explaining why:anonymous- Anonymous users must sign up with credentials to remove this restriction.email_not_verified- The user needs to verify their email address.restricted_by_administrator- Shows the public reason and private details if set.
Related
- Authentication Overview - parent app.
- Sign-up Rules - the enforcement layer that consumes these signals.
- Restricted Users - what restricted accounts can and can’t do.
- JWT Tokens - how the
Restrictaction surfaces in user tokens.