CORS & throttling
CORS & throttling
CORS
Cross-origin browser access is deny-by-default. config/cors.php builds its
allow-list from an explicit, env-driven list — never the * wildcard.
CORS_ALLOWED_ORIGINS=https://app.acme.com,https://dashboard.acme.com
# CORS_ALLOWED_ORIGINS_PATTERNS=
# CORS_SUPPORTS_CREDENTIALS=false
- With
CORS_ALLOWED_ORIGINSunset, no cross-origin browser request is allowed. - The allow-list applies to the
api/*,billing/*, andwebhooks/*paths. - Allowed methods:
GET, POST, DELETE, OPTIONS. - Allowed headers include
Authorization,Content-Type, andIdempotency-Key(so a browser can send the idempotency header on mutating management calls).
Server-to-server SDK traffic (the enforcement API) carries a bearer token and is not subject to CORS at all — CORS only governs browser origins, e.g. a product's own dashboard embedding the payment element.
Rate limiting
Per-token API rate limits are defined in config/billing.php → rate_limits and
registered as named limiters in AppServiceProvider, applied as throttle:cbox-*
on the route groups. There are two tiers plus the webhook:
| Limiter | Applies to | Env | Default (req/min) |
|---|---|---|---|
cbox-enforcement |
The hot path: reserve, commit, usage, leases, entitlements. Runs on every metered operation, so the higher ceiling. |
CBOX_BILLING_THROTTLE_ENFORCEMENT |
600 |
cbox-management |
The self-service surface: subscriptions, payment intents, invoices, licenses. Human-paced and mutating, so the lower ceiling. | CBOX_BILLING_THROTTLE_MANAGEMENT |
60 |
cbox-webhook |
Inbound settlement callbacks from the gateway. | CBOX_BILLING_THROTTLE_WEBHOOK |
120 |
How the key is derived
Each limiter is keyed per bearer token (token:<sha256>), so one tenant's
traffic can never exhaust another's budget. A token-less request falls back to the
client IP (ip:<addr>). The webhook limiter keys on the source IP, since the
callback carries no bearer token — its authenticity is the gateway signature.
The activation heartbeat has its own limiter
The unauthenticated license-activation heartbeat (GET /api/v1/license/activate)
keeps its own inline throttle:30,1 so it cannot be probed. See
API → License activation.