12-tenant-rate-limit

Usage limit, enforced and recorded

Rate limit per tenant: limit + 1 requests in one minute

Tenant rl-test has an explicit per-minute limit. In one fresh one-minute window the runner sends <limit> requests for a model the tenant may not use (refused before any provider call, but counted), then one request for its allowed model. The rate check runs last, so that request would otherwise be allowed: it gets 429 rate.tenant_limit with retry-after, and its decision is a signed record in Shield.

rate-limitdenyevidence
FIXTURE
tenant_id"rl-test"
home_region"tst"
scopes
ai.chat.write
sub"rl-scenario-<run id>"

Defaults: iss = http://localhost/tst-issuer, aud = edge, exp = now+1h, kid = tester-rs256

EXPECTED OUTCOME
HTTP STATUS429
X-POLICY-DECISIONdeny
X-POLICY-REASONrate.tenant_limit
What this demonstrates

A team exceeds the request volume its organization agreed to. The extra request is refused, and the refusal is signed evidence an auditor can open, so usage limits are a control you can prove, not a setting you hope is applied.

Usage & cost controlsEU AI Act Art. 12 (record-keeping)
RUNNER

Execute scenario

Checks the test tenant, waits for a fresh one-minute window if needed, then sends the tenant's limit in refused requests and one more for its allowed model, which the policy must refuse with 429. No request reaches an AI provider.

One run at a time: it uses up the test tenant's quota for that minute.

WHY THIS MATTERS

Proves per-tenant limits are enforced by the policy, count every request including denied ones, and leave per-request signed evidence. A run never reaches a provider: the one allowed-model request is only sent once it is certain to be refused.