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. 1.Identify scope
  2. 2.Inspect evidence
  3. 3.Apply host control
  4. 4.Run negative cases
  5. 5.Compare benign behavior
  6. 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

host.mjs
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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.