Freshness budget
Maximum accepted age or minimum remaining lifetime.
Chapter 15 of 16 · Application/workload user · orders-api
Design a bounded state machine for fresh, renewing, stale-but-valid, terminal, and recovered secret states.
Shared local lab running for the outage drill and Chapters 8-10 understood.
orders-api follows a bounded fresh, stale, expired, and recovered lifecycle during a Vault outage.
| Owner | Consumer-facing responsibility |
|---|---|
| You own | States the consumer contract and proves reload and degraded behavior. |
| Platform team owns | Owns runtime identity, integration components, rollout, and operational health. |
| Vault owns | Owns server-side trust, policy, engines, audit, and Vault service health. |
Maximum accepted age or minimum remaining lifetime.
Bounded attempts with backoff and jitter.
Deliberate continued use of still-valid material.
Stop sensitive work before using invalid material.
cd learn-vault/labs/failure-drill
python3 state_machine.py --self-test
./run-drill.sh
jq '{state,lease_remaining_seconds,render_age_seconds,reload_generation}' ../../.runtime/drill-status.json| Symptom | Vault is unavailable during renewal. |
|---|---|
| Likely causes | Network, DNS, trust, Vault leader or storage event, rate limit, or client retry storm. |
| Inspect safely | Track last success, TTL remaining, attempt count, error class, circuit state, and request ID. |
| Do not print | Cached data, tokens, renewal payloads, renders, or exceptions containing headers. |
Break it: Pause Vault during the simulated renewal window.
Fix it: Use bounded retry and still-valid material only until hard expiry; validate replacement before recovery.
Escalate with time, endpoint, auth path, role, mount, namespace when relevant, status code, request ID, and sanitized error class. Never attach a credential or response body.
labs/bootstrap owns the disposable server, auth mounts, policies, roles, and engines; learner actions begin after setup.
$0; local containers only
Run labs/bootstrap/setup.sh and source .runtime/learner.env unless the chapter lab says AppRole alone is sufficient.
Run the deterministic state-machine test, pause Vault, observe bounded stale behavior, resume it, and verify recovery.
cd learn-vault/labs/failure-drill
python3 state_machine.py --self-test
./run-drill.sh
jq -e '.transitions|index("STALE") and index("RECOVERED")' ../../.runtime/drill-result.json
./cleanup.sh
Complete every item in the Verify section using metadata-only evidence; no secret value appears in terminal output or tracked files.
Use the Failure drill and Break it / fix it evidence fields. Stop before broadening policy, weakening identity or TLS checks, or copying secret-bearing diagnostics.
The drill resumes Vault through a trap. Cleanup removes results and confirms shared service status.
Readiness requires auth validity, DB lease margin, cert margin, render freshness, and accepted reload generation.
Not always; still-valid material may have bounded grace based on risk.
Use of expired or invalid material.
It prevents synchronized retry and renewal storms.
Acquire, validate, install, then declare healthy.
Resilience is a timed state machine with a hard security boundary, not an infinite retry loop.