Skip to content

Commit 117be5a

Browse files
authored
Add Scamalytics free mode risk scoring (#746)
1 parent 547e061 commit 117be5a

17 files changed

Lines changed: 4362 additions & 36 deletions

File tree

common/src/types/freebuff-session.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,20 @@ export type FreebuffSpurStatus =
7171
| 'suspicious'
7272
| 'failed'
7373

74+
export type FreebuffScamalyticsStatus =
75+
| 'not_checked'
76+
| 'clean'
77+
| 'suspicious'
78+
| 'failed'
79+
7480
export type FreebuffPrivacyDecision =
7581
| 'allowed_clean'
7682
| 'ipinfo_suspicious_spur_clean'
7783
| 'corroborated_block'
7884
| 'cloudflare_tor_block'
7985
| 'spur_failed_limited'
86+
| 'scamalytics_failed_limited'
87+
| 'scamalytics_suspicious_limited'
8088
| 'ipinfo_failed_limited'
8189
| 'limited_other'
8290

@@ -87,6 +95,8 @@ export type FreebuffPrivacyProviderDecision =
8795
| 'ipinfo_failed'
8896
| 'ipinfo_only'
8997
| 'spur_failed'
98+
| 'scamalytics_failed'
99+
| 'scamalytics_only'
90100
| 'corroborated_soft'
91101
| 'corroborated_hard'
92102

docs/environment-variables.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
- Server secrets: validated in `packages/internal/src/env-schema.ts` (used via `@codebuff/internal/env`).
77
- Runtime/OS env: pass typed snapshots instead of reading `process.env` throughout the codebase.
88
- `IPINFO_TOKEN` is required; free-mode country gating uses it to check IPinfo privacy signals for VPN/proxy/Tor/relay/hosting traffic.
9-
- `SPUR_TOKEN` is required; VPN/proxy/Tor/residential-proxy privacy signals use Spur Context API corroboration. In allowlisted countries, a successful clean Spur result overrides IPinfo privacy signals back to full access, while suspicious or failed Spur lookups fall back to limited access. Cloudflare Tor country detection remains a hard block.
9+
- `SPUR_TOKEN` is required; VPN/proxy/Tor/residential-proxy privacy signals use Spur Context API corroboration.
10+
- `SCAMALYTICS_API_KEY` is required; when IPinfo reports privacy or hosting/service signals, free-mode gating also checks Scamalytics for a fraud score and proxy/Tor/VPN evidence. In allowlisted countries, full access requires both Spur and Scamalytics to return clean follow-up results. Provider failures, Scamalytics outages/API errors, ambiguous results, VPN/generic-proxy signals, and hosting/datacenter signals fall back to limited access. Residential proxy is blocked only when Scamalytics also reports residential/proxy evidence or a medium+ fraud score, as are Cloudflare Tor or Tor corroborated by another provider.
1011
- `CODEBUFF_FULL_TELEMETRY=true` or `CODEBUFF_FULL_TELEMETRY_IDS=user-id,email@example.com`
1112
disables client analytics sampling for targeted debugging. Use sparingly because it can send full CLI log payloads.
1213

docs/freebuff-waiting-room.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ All endpoints authenticate via the standard `Authorization: Bearer <api-key>` or
181181
- Existing active+unexpired row, **different model** → reject with `model_locked` (HTTP 409); `active_instance_id` is **not** rotated so the other CLI stays valid. Client must DELETE the session before switching.
182182
- Existing active+expired row → reset to queued with fresh `queued_at` and the requested `model` (re-queue at back).
183183

184-
Before any of those state transitions, the handler requires a resolved country and IPinfo/Spur privacy classification. Unsupported countries enter limited Freebuff access. In allowlisted countries, IPinfo privacy signals still receive full access when Spur returns clean context, and fall back to limited access when Spur reports suspicious context or lookup fails. IPinfo lookup failures fail closed into limited access. Cloudflare Tor country detection remains a hard block.
184+
Before any of those state transitions, the handler requires a resolved country and IPinfo privacy classification. Unsupported countries enter limited Freebuff access. In allowlisted countries, IPinfo privacy/hosting/service signals trigger paid follow-up checks with Spur and Scamalytics. Full access is restored when both follow-up providers return clean context; suspicious or failed follow-up checks fall back to limited access. A Scamalytics outage/API error is treated as a transient limited decision, not a hard block. The server records a 0-100 privacy risk score for observability/cache rows; named/recent IPinfo anonymizer observations raise that score, while generic Scamalytics third-party proxy labels do not override a low top-level Scamalytics score by themselves. VPN, generic proxy, and hosting/datacenter signals limit access when follow-up providers do not clear them. Residential proxy signals hard-block only when Scamalytics also reports residential/proxy evidence or a medium+ fraud score. Cloudflare Tor country detection or Tor corroborated by another provider is also hard-blocked by the IP-intelligence gate.
185185

186186
Response shapes:
187187

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE "free_mode_country_access_cache" ADD COLUMN "scamalytics_ip_privacy_signals" text[];--> statement-breakpoint
2+
ALTER TABLE "free_mode_country_access_cache" ADD COLUMN "scamalytics_status" text;--> statement-breakpoint
3+
ALTER TABLE "free_mode_country_access_cache" ADD COLUMN "scamalytics_score" integer;--> statement-breakpoint
4+
ALTER TABLE "free_mode_country_access_cache" ADD COLUMN "scamalytics_risk" text;--> statement-breakpoint
5+
ALTER TABLE "free_mode_country_access_cache" ADD COLUMN "risk_score" integer;

0 commit comments

Comments
 (0)