Sections in this lesson
Resource, Cost & Availability Abuse
Limit input size, model steps, tool attempts and fan-out before launching work.
Reviewed: · Content owner: Interview Preparator
What you will learn
- Bound work before admission
- Keep one deadline across recovery
- Report cost uncertainty honestly
Before you start
The flow
- 1.Identify scope
- 2.Inspect evidence
- 3.Apply host control
- 4.Run negative cases
- 5.Compare benign behavior
- 6.Review remaining risks
Bound work before admission
Limit input size, model steps, tool attempts and fan-out before launching work. A per-request bound alone cannot protect a shared service from many parallel requests; apply tenant quotas and downstream concurrency controls as well.
The teaching host reserves positive integer tokens and counts executed calls. A replayed receipt does not repeat the mutation. This models local accounting and duplicate protection, not a real provider token meter.
Keep one deadline across recovery
An absolute run deadline should survive retry and restart. Resetting a timeout on every attempt can create an effectively unbounded workflow. Reads may have classified limited retries; writes require target-aware reconciliation.
The Node host checks a supplied trusted time against its deadline. The existing Java bounded agent provides per-operation cancellation and persistent run counters; neither guarantees rollback of an external effect.
Report cost uncertainty honestly
A local token estimate may differ from provider usage, and disconnecting a stream may not stop all billing. Record estimates, observed usage, cancellation results and unobserved work separately.
The budget fixtures demonstrate denial after a local cap. They do not load-test shared infrastructure, implement a production scheduler or prove a currency ceiling. Those need provider integration and measured admission/queue behavior.
Try it
import { authorize, payloadDigest } from './policy.mjs';// Teaching host: no shell, network, or arbitrary-file tools are exposed.export class TeachingHost { constructor({ scope, resource, grant, maxCalls = 3, maxTokens = 100, deadline = 1000, epoch = 1 }) { if (!Number.isSafeInteger(maxCalls) || maxCalls < 1 || !Number.isSafeInteger(maxTokens) || maxTokens < 1 || !Number.isFinite(deadline)) throw new Error('Invalid budget'); this.scope = Object.freeze({ ...scope }); this.resource = structuredClone(resource); this.grant = grant ? structuredClone(grant) : null; this.maxCalls = maxCalls; this.maxTokens = maxTokens; this.deadline = deadline; this.epoch = epoch; this.calls = 0; this.tokens = 0; this.mutations = 0; this.receipts = new Map(); this.trace = []; } execute(call, callId, reservedTokens, now) { if (!Number.isSafeInteger(reservedTokens) || reservedTokens < 1 || !Number.isFinite(now) || !/^[a-z0-9-]{1,80}$/.test(callId)) throw new Error('Invalid operation'); if (now >= this.deadline) return this.record('TIMEOUT'); const permission = authorize(this.scope,call,this.resource,this.grant,now,this.epoch); if (permission !== 'ALLOW') return this.record(permission); const digest = payloadDigest(call); const cached = this.receipts.get(callId); if (cached) return this.record(cached.digest === digest ? 'REPLAY' : 'PAYLOAD_MISMATCH'); if (this.calls >= this.maxCalls || reservedTokens > this.maxTokens - this.tokens) return this.record('BUDGET_EXCEEDED'); this.calls++; this.tokens += reservedTokens; if (call.action === 'completePlan') this.mutations++; this.receipts.set(callId,{ digest }); return this.record('EXECUTED'); } record(status) { this.trace.push({ status, calls:this.calls, tokens:this.tokens, mutations:this.mutations }); return status; } stopAndRevoke() { this.epoch++; this.grant = null; }}// Cache keys include authorization scope and corpus version; cache values still// require current authorization at read time (revocation/deletion can change).export function cacheKey(scope, corpusVersion, question) { return JSON.stringify([scope.tenant,scope.user,corpusVersion,question]); }export function memoryRead(record, scope, version) { return record.tenant === scope.tenant && record.user === scope.user && record.conversation === scope.conversation && record.trusted === true && record.version === version ? record.text : null;}Run npm run examples:security and npm run eval:security. This source is a deterministic teaching fixture; it does not prove live model safety, NLI, production auth or OS/network isolation.
Interview questions
Does a request limit protect all parallel traffic?
The teaching host reserves positive integer tokens and counts executed calls. A replayed receipt does not repeat the mutation. This models local accounting and duplicate protection, not a real provider token meter.
Why preserve an absolute deadline?
The Node host checks a supplied trusted time against its deadline. The existing Java bounded agent provides per-operation cancellation and persistent run counters; neither guarantees rollback of an external effect.
Does local token reservation bound provider billing?
The budget fixtures demonstrate denial after a local cap. They do not load-test shared infrastructure, implement a production scheduler or prove a currency ceiling. Those need provider integration and measured admission/queue behavior.
Practice
Extend one negative scenario and its authorized positive counterexample for Resource, Cost & Availability Abuse.
Check your solution
- State the trusted input and effect boundary.
- Assert the expected status and observed effect.
- Report coverage and limitations without claiming production readiness.
Official references
Continue learning
Category sequence
AI Security
Lesson 7 / 14
Was this lesson useful?
Change notes: 2026-10-31: security/reliability curriculum and source-bound fixture.