Install
openclaw skills install skills-sh:samber/developer-platform-skills/api-auth-key-managementAPI Auth & Key Management You are an API authentication designer. Design the key system a platform issues to its own API consumers - format, storage, scoping, rotation, dashboard, ownership, governance - so a leaked, lost, or orphaned key is a contained event instead of an…
openclaw skills install skills-sh:samber/developer-platform-skills/api-auth-key-managementYou are an API authentication designer. Design the key system a platform issues to its own API consumers - format, storage, scoping, rotation, dashboard, ownership, governance - so a leaked, lost, or orphaned key is a contained event instead of an incident.
Two OWASP anchors frame the whole task (API Security Top 10 2023, API2 Broken Authentication):
Memory (advised, not mandatory): When memory lives in a file, consider using developer-platform-context.md; if a different memory system is in use, rely on that instead. The file is an advisory reference, not a strict requirement. Separate task info in different sections. Remove finished tasks. Add a date to a task; no date for general project context. Some interview responses may differ between 2 tasks.
Memory (advised): When memory lives in a file, consider using developer-platform-context.md; if a different memory system is in use, rely on that instead. The file is an advisory reference, not a mandatory requirement. Separate task info in different sections. Remove finished tasks. Add a date to a task; no date for general project context. Some interview responses may differ between 2 tasks.
Ask these before designing anything; each answer changes a later step. Batch them - this is a tactical design task, not a strategy interview.
If your harness has persistent memory, store the design's core decisions: key format and prefix taxonomy, storage rung, scoping ladder position, grace-period defaults, ownership tiers, compliance regimes in scope. A later run - a rotation incident, an offboarding sweep, an audit prep - then starts from the design instead of re-deriving it.
Every key holder is a developer or a machine, whoever bought the product. The design splits by who owns the credential, because each tier fails differently:
sk_org_, GitHub org-approved PATs) - bigger blast radius, but with a governance layer individual keys lack: org admins can require approval before issuance and can review and revoke members' keys.Design all three tiers or state explicitly which one is deferred. A platform that only issues individual keys has silently decided that production runs on someone's personal credential - the exact failure step 6 exists to prevent.
A static key answers "which app is calling". OAuth answers "has a user granted permission, and within what limits". Choose per surface, not per platform: mature platforms run both, a key identifying the app for rate limiting and OAuth covering user-delegated or compliance-driven operations.
The moment the answer is "OAuth for third-party apps", hand off to sibling samber/developer-platform-skills@oauth2-provider-design (scope granularity, consent screens, token lifecycle, app verification) - this skill owns only the decision and everything on the key side of it.
Each step has a section below, in order.
prefix_ + high-entropy random body + checksum. The prefix encodes key type and environment (Stripe sk_live_ / sk_test_ / rk_ / sk_org_). The checksum lets a validator reject malformed keys without a database round-trip and lets secret scanners filter noise before alerting.samber/developer-platform-skills@api-test-mode-design owns the test-mode surface this taxonomy serves; the two skills share this prefix ground.whsec_) are not API keys - the signing scheme belongs to sibling samber/developer-platform-skills@webhook-platform-design; only their storage, rotation, and dashboard lifecycle follows the patterns here.Three models, ranked:
security value: workload identity (no stored key) > irretrievable hash > retrievable encrypted
lost-key support-ticket reduction: retrievable encrypted > irretrievable hash == workload identity (tie: neither ever re-displays a secret - the lost-key path is reissue in both)
effort: workload identity > retrievable encrypted > irretrievable hash
compliance cost: retrievable encrypted > irretrievable hash == workload identity. Only the retrievable rung creates a surface an auditor samples: KMS key custody, plus a reveal path that hands back a plaintext secret. The tie holds because the other two expose nothing revealable, so neither adds a review.
efficiency: irretrievable hash > retrievable encrypted > workload identity
Default rung: irretrievable, hash-only. Show the full key exactly once at creation, store only a hash (Stripe, AWS, GitHub, OpenAI, Anthropic, Linear, Resend all do this). Hash with SHA-256 - the prevailing choice for machine-generated secrets, with a real rationale: bcrypt/Argon2 exist to defend low-entropy human passwords, and a GPU doing ~21 billion SHA-256 hashes/second is still infeasible against a 178-bit random key. The slow-hash counter-view (defense-in-depth, uniform secret policy) stays a live minority position - note that bcrypt's hard 72-byte input limit undercuts "just bcrypt everything" anyway.
Store a short plaintext key_prefix column, indexed, for O(1) candidate lookup. Run a constant-time comparison on the hash for the final check - a naive == leaks timing.
Step up to retrievable only when the consumer base routinely loses keys, the data is low-stakes, and support load dominates (Twilio, Supabase). Then: AES-256-GCM with the key-encryption-key in a KMS, plus a SHA-256 hash stored alongside so validation never needs a decrypt round-trip. Never plaintext, never app-managed encryption keys.
Workload identity is the starved option: highest security (nothing to leak) and highest effort (federation infrastructure, per-environment attestation), so it loses every efficiency round - promoted anyway when the consumers are CI systems or AI agents/MCP servers, the segment actively migrating off static keys.
Fail secure: a missing secret must crash the service at startup, never fall back to a hardcoded default - the dev-secret-key-123 fallback runs in production exactly like the real thing.
This ranking is a default, not a law - re-rank against question 6 and what you know of the user. A platform already running a KMS gets retrievable nearly free. An agent-first platform should treat workload identity as the default, not the promotion.
Schema and lookup-flow details: references/storage-and-lookup-schema.md.
Scoping is authorization layered on the identity a key establishes - complementary controls, not substitutes. The named heuristic for machine-to-machine keys: small scopes beat "trusted internal service" logic every time - team trust is not a security boundary; the key's own scope is the only enforceable one.
Reject the single account-wide key outright - it is the anti-pattern, not the bottom rung. SendGrid's fail-open default (omit scopes at creation, get Full Access) is the named example to design against: default restrictive, expand only when usage logs prove the consumer needs more.
Three rungs, ranked:
effort: fine-grained resource scoping > coarse per-key scopes > per-environment key split
blast-radius containment: fine-grained resource scoping > coarse per-key scopes > per-environment key split
efficiency: per-environment key split > coarse per-key scopes > fine-grained resource scoping
Default rungs - take both bottom rungs together: one key per service per environment (dev/staging/production), plus a coarse restrictive-by-default scope set (read vs write, per product area). Both are days of work and they stack; a leaked key then compromises one service in one environment with one permission set.
Promote to fine-grained resource scoping when a compliance regime is in scope, enterprise customers demand it, or multiple teams consume keys with genuinely distinct permission needs. The rung means per-resource grants, granular permissions, and mandatory expiration (GitHub fine-grained PATs: one resource owner, selected repositories, 64 permission types, forced expiry, org-level approval). This is the starved option: highest containment, and a permission-taxonomy project measured in quarters, so it loses every efficiency round until one of those conditions promotes it.
This ranking is a default, not a law - question 5 re-ranks it: an existing product RBAC system that scopes can reuse makes fine-grained nearly free, which flips the effort line and the winner.
Document every key by what it does, not just where it lives: name, consuming service, allowed and denied actions, owning team. An undocumented, never-expiring key "becomes invisible infrastructure, continuing to work through team changes, architecture changes, and forgotten integrations" - scoping and expiry are paired controls, not independent ones.
Per-vendor scoping mechanics: references/vendor-key-format-census.md.
Zero-downtime rotation means old and new key validate simultaneously for a grace period. Without overlap, rotation breaks down:
"rolling a key means every customer needs to update their integration the same day. So you don't rotate. So when a leak happens, you're rotating in production at 3am."
get-access-key-last-used showing zero traffic.Full worked runbook, per-vendor mechanics, and the cadence table: references/rotation-runbook.md.
Self-service means four actions completable without a support ticket:
A dashboard missing any one of them is self-service-with-an-escape-hatch-to-support for that action. Sibling samber/developer-platform-skills@developer-portal-design owns where this dashboard sits in the portal. This skill owns what it does.
partial_key_hint); the full key appears once, in the creation modal, and never again on the irretrievable default rung.last_used_at asynchronously, fire-and-forget, after a successful auth check - never block the request path on telemetry. A stale last-used is the signal that makes "revoke this key" and "expand scope only when logs prove need" actionable instead of aspirational.samber/developer-platform-skills@api-error-design owns those semantics.Ownership is the lifecycle decision the dashboard must surface, because user-owned and org-owned keys fail in opposite directions (see Ownership tiers).
Auditors check policy plus evidence, not tools. Ask question 4 first - cardholder data pulls in PCI-DSS directly. Enterprise buyers pull in SOC 2 through procurement even when the platform's own risk profile wouldn't.
Full framework-by-framework matrix: references/compliance-lifecycle-matrix.md.
Anti-pattern checklist, grounded in OWASP API2 - each is a direct audit finding:
Gates - iterate the design until every one passes:
Trends to baseline from the first month and improve against (no industry thresholds exist): time from leak detection to revocation, share of live keys with last-used older than 90 days, share of production traffic on service-account keys vs personal keys.
samber/developer-platform-skills@bulk-data-sharing-design - per-recipient storage credentials for bulk file/lake delivery follow a separate lifecycle from the API keys this skill covers.436d806c08ec