AUTH4D-334 device authorization budgets
The device flow endpoints spend a per-IP budget first, so one caller cannot use up the budget of a whole application or of a player’s code. Client-wide and tenant-wide budgets remain as backstops sized for real traffic. The routes, request shapes and success responses are unchanged.
Budgets
Budgets are spent in the order listed. The first one that is exhausted refuses the request.
| Endpoint | Budgets, in order |
|---|---|
POST /device/authorization |
60 an hour per IP; then 1,000 an hour per application |
POST /oauth/token (device code grant) |
240 a minute per IP; then 12 a minute per device code; then, only for a live device code, 3,000 a minute per application |
GET /device/verify (JSON) |
60 an hour per IP; then 10,000 an hour per tenant, shared with approve and deny; then 5 an hour per user code |
POST /device/approval, POST /device/denial |
30 an hour per IP, after the signed-in session and CSRF checks; then the same tenant and per-user-code budgets as verify |
- IP addresses come from
CF-Connecting-IPand are HMAC-pseudonymised before they reach the Durable Object, like every other per-IP budget. A request with no resolved address shares one bucket instead of skipping the limit. - The application poll budget is spent only after the device code has been found, belongs to this
tenant and application, and has not expired. Polls with unknown or expired codes never count
towards it, so they cannot cause
slow_downfor real codes. - The application start budget is a backstop for many addresses at once. About 1,000 codes an hour, each live for up to 10 minutes and polled 12 times a minute, stays under the poll backstop.
Responses
A refused request returns the same error as before:
HTTP/1.1 429 Too Many Requests
Cache-Control: no-store, max-age=0
Content-Type: application/json
{ "error": "slow_down" }
When the application poll backstop refuses a poll, the device code is left exactly as it was, so the next poll after the window resets continues normally.
RFC 8628 slow_down for real codes is unchanged: a poll before the current interval has passed
returns 400 slow_down and adds 5 seconds to the code’s interval.
Configuration
The defaults are DEVICE_ABUSE_BUDGETS in apps/api/src/modules/device/index.ts.
DeviceFeatureOptions.budgets overrides any of them, for deployments that need different limits
and for tests.
Tests: tests/integration/auth4d-334.device-budgets.test.ts.
Source: docs/api-spec/auth4d-334.md