api-auth-key-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Auth & Key Management
API认证与密钥管理
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 incident.
Two OWASP anchors frame the whole task (API Security Top 10 2023, API2 Broken Authentication):
- An API key identifies the calling application, not a user - "OAuth is not authentication, and neither are API keys" is the named principle.
- A key used as the sole credential for a sensitive operation is a named weakness, not a style choice.
你是一名API认证设计师。设计一个平台向其自身API消费者颁发的密钥系统 - 包括格式、存储、范围界定、轮换、仪表盘、所有权和治理 - 使密钥泄露、丢失或成为孤儿密钥时不至于演变成安全事故,而是受控事件。
两个OWASP锚点界定了整个任务(API Security Top 10 2023,API2 身份认证失效):
- API密钥识别的是调用应用程序,而非用户 - “OAuth不是身份认证,API密钥也不是”是既定的原则。
- 密钥作为敏感操作唯一凭据是一种被点名的弱点,而非风格选择。
Clarifying questions
澄清问题
Ask these before designing anything; each answer changes a later step. Batch them - this is a tactical design task, not a strategy interview.
- Greenfield or retrofit? If retrofit: request the current key format, how keys are stored today (plaintext, hashed, encrypted), and roughly how many live keys exist.
- Who holds keys: individual developers experimenting, teams running shared production integrations, unattended workloads (CI, scheduled jobs, AI agents / MCP servers)? (see next section)
- Do third-party apps act on behalf of your users, or do consumers only ever call as themselves? (drives the key-vs-OAuth boundary)
- Compliance regimes in scope: payment or cardholder data (PCI-DSS)? Enterprise buyers requiring SOC 2? Neither yet? (see step 7)
- Does the product already have a permission/RBAC system that key scopes could reuse? (re-ranks the scoping ladder - see step 3)
- Timing and effort ceiling: when must this ship, is it a one-off hardening or a compounding platform asset, and how much engineering time and consumer-visible migration can you spend? The storage and scoping menus diverge sharply on effort - re-rank them against these answers: a hard ship date promotes the cheap rungs (hash-only storage, per-environment key split), a compounding-asset mandate promotes the starved ones (workload identity, fine-grained scoping).
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.
在设计任何内容之前请先询问这些问题;每个答案都会改变后续步骤。将它们分批提出 - 这是一个战术性设计任务,而非战略面试。
-
全新构建还是改造?如果是改造:询问当前密钥格式、当前密钥的存储方式(明文、哈希、加密)以及大致有多少活跃密钥。
-
谁持有密钥:进行实验的个人开发者、运行共享生产集成的团队、无人值守工作负载(CI、定时任务、AI Agent / MCP服务器)?(见下一节)
-
第三方应用是否代表您的用户行事,还是消费者只能以自身身份调用?(决定密钥与OAuth的边界)
-
涉及哪些合规制度:支付或持卡人数据(PCI-DSS)?企业买家要求SOC 2?还是尚未涉及?(见第7步)
-
产品是否已有密钥范围可复用的权限/RBAC系统?(重新排列范围阶梯 - 见第3步)
-
时间与工作量上限:何时必须交付?这是一次性加固还是可复利的平台资产?您能投入多少工程时间和消费者可见的迁移?存储和范围菜单在工作量上差异显著 - 请根据这些答案重新排序:严格的交付日期会促进廉价阶梯(仅哈希存储、按环境拆分密钥),可复利资产的任务会促进被忽视的选项(工作负载身份、细粒度范围界定)。
如果您的工具具有持久记忆,请存储设计的核心决策:密钥格式与前缀分类、存储阶梯、范围阶梯位置、宽限期默认值、所有权层级、涉及的合规制度。后续的运行 - 轮换事件、离职清理、审计准备 - 将从该设计出发,而非重新推导。
Ownership tiers
所有权层级
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:
- Individual developer keys (GitHub PATs, OpenAI user keys) - tied to one person's account; every key traces to exactly one human. Right default for personal experimentation; a liability the moment one runs production, because it dies (or worse, keeps working) when that person leaves.
- Team / organization keys (Stripe , 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.
sk_org_ - Service-account keys (OpenAI service accounts - "a pseudo-user designed for system access", Anthropic service accounts, Shopify custom-app tokens owned by the app itself) - deliberately decoupled from any human's employment status, so production automation survives offboarding. The correct default for anything unattended.
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.
每个密钥持有者要么是开发者,要么是机器,无论是谁购买了产品。设计按凭据的所有者划分,因为每个层级的故障模式不同:
-
个人开发者密钥(GitHub PAT、OpenAI用户密钥) - 与一个人的账户绑定;每个密钥精确追踪到一个人。适合个人实验的默认选择;一旦用于生产,就会成为责任,因为当该人离开时,密钥会失效(或更糟,持续有效)。
-
团队/组织密钥(Stripe、GitHub组织批准的PAT) - 爆炸半径更大,但拥有个人密钥所缺乏的治理层:组织管理员可以要求在发放前获得批准,并能审查和撤销成员的密钥。
sk_org_ -
服务账户密钥(OpenAI服务账户 - “为系统访问而设计的伪用户”,Anthropic服务账户,Shopify自定义应用令牌,由应用本身所有) - 刻意与任何人的雇佣状态解耦,因此生产自动化能够经受离职过程。任何无人值守场景的正确默认选择。
设计所有三个层级,或明确说明哪个被延迟。一个只发放个人密钥的平台,等于默默决定了生产环境运行在某个人的个人凭据上 - 这正是第6步要防止的故障。
Key or OAuth - settle the boundary first
密钥还是OAuth - 先确定边界
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.
- Static key: no user in the flow, server-to-server calls, sandboxes, public or read-mostly data, rate limiting by caller.
- OAuth client credentials: cross-org machine-to-machine traffic on sensitive data - short-lived (5-60 min) scoped tokens bound a leak in a way an indefinitely-valid string structurally cannot.
- The named heuristic, both directions:
- Bolting expiry, per-request scopes, and fine-grained revocation onto a static key means reinventing OAuth - adopt the real thing.
- Adding redirect URIs and consent screens for a server talking to itself means over-engineering.
- Never ship a long-lived key to a browser or other semi-trusted client: mint a short-lived scoped token server-side instead (OpenAI's 1-10-minute ephemeral tokens are the pattern). For CI and AI-agent/MCP workloads, workload identity federation - the environment attests, no stored secret at all - is the direction the industry is migrating toward, precisely because it removes the stored secret a leak would otherwise expose.
The moment the answer is "OAuth for third-party apps", hand off to sibling (scope granularity, consent screens, token lifecycle, app verification) - this skill owns only the decision and everything on the key side of it.
samber/developer-platform-skills@oauth2-provider-design静态密钥回答“哪个应用在调用”。OAuth回答“用户是否已授予权限,以及权限范围是什么”。按界面选择,而非按平台:成熟平台两者都运行,密钥用于识别应用以进行速率限制,OAuth覆盖用户委托或合规驱动的操作。
- 静态密钥:流程中无用户,服务器到服务器调用,沙箱,公共或只读数据,按调用方进行速率限制。
- OAuth客户端凭据:敏感数据上的跨组织机器到机器流量 - 短期(5-60分钟)的限定范围令牌在结构上能限制泄露影响,而无限制有效的字符串无法做到。
- 双向的既定启发式规则:
- 将过期时间、每请求范围和细粒度撤销附加到静态密钥上意味着重新发明OAuth - 应采用真正的OAuth。
- 为服务器与自身通信添加重定向URI和授权屏幕意味着过度工程。
- 绝不要将长期有效的密钥交付给浏览器或其他半可信客户端:应在服务器端生成短期的限定范围令牌(OpenAI的1-10分钟临时令牌是这种模式)。对于CI和AI Agent/MCP工作负载,工作负载身份联合 - 环境证明,完全不存储机密 - 是行业正在迁移的方向,正是因为它消除了泄露会暴露的存储机密。
一旦答案确定为“第三方应用使用OAuth”,就移交给姊妹技能(范围粒度、授权屏幕、令牌生命周期、应用验证) - 本技能只拥有该决策及其密钥侧的所有内容。
samber/developer-platform-skills@oauth2-provider-designWorkflow
工作流程
- Define the key format and prefix scheme.
- Choose the storage model.
- Choose the scoping model.
- Design rotation.
- Design the self-service dashboard behavior.
- Assign ownership and wire offboarding.
- Install compliance lifecycle governance.
Each step has a section below, in order.
- 定义密钥格式和前缀方案。
- 选择存储模型。
- 选择范围界定模型。
- 设计轮换。
- 设计自助服务仪表盘行为。
- 分配所有权并接入离职流程。
- 安装合规生命周期治理。
每个步骤在下面都有对应的章节,按顺序排列。
1. Key format and prefix
1. 密钥格式与前缀
- Structure every key as + high-entropy random body + checksum. The prefix encodes key type and environment (Stripe
prefix_/sk_live_/sk_test_/rk_). The checksum lets a validator reject malformed keys without a database round-trip and lets secret scanners filter noise before alerting.sk_org_ - Meet an entropy floor of at least 120 bits (32+ random characters). GitHub's benchmark format is a 30-character Base62 body ≈ 178.6 bits plus a 6-character CRC32 checksum - chosen specifically because its old hex-only tokens were "indistinguishable from other encoded data like SHA hashes" and unscannable. The overhead costs ~10 characters of token length; pay it.
- The prefix+checksum shape is free defense-in-depth regardless of formal enrollment. Once real leaked-key incidents justify the integration work, register the pattern with GitHub's Secret Scanning Partner Program (six-step process - see references/vendor-key-format-census.md) so a customer's key pushed to any public repo triggers the revocation flow before the customer notices.
- Encode the test/live environment in the prefix from day one - sibling owns the test-mode surface this taxonomy serves; the two skills share this prefix ground.
samber/developer-platform-skills@api-test-mode-design - Webhook signing secrets (Stripe's ) are not API keys - the signing scheme belongs to sibling
whsec_; only their storage, rotation, and dashboard lifecycle follows the patterns here.samber/developer-platform-skills@webhook-platform-design
-
将每个密钥结构化为+ 高熵随机主体 + 校验和。前缀编码了密钥类型和环境(Stripe
前缀_/sk_live_/sk_test_/rk_)。校验和让验证器无需数据库往返即可拒绝格式错误的密钥,并让密钥扫描器在发出警报前过滤噪音。sk_org_ -
满足至少120位的熵下限(32+个随机字符)。GitHub的基准格式是30字符Base62主体 ≈ 178.6位,加上6字符CRC32校验和 - 选择这种格式是因为其旧的纯十六进制令牌“与其他编码数据(如SHA哈希)无法区分”且不可扫描。这种开销约增加10个令牌字符;值得付出。
-
前缀+校验和的形态无论是否正式注册都是免费的纵深防御。一旦真实的密钥泄露事件证明集成工作有价值,就将该模式注册到GitHub的Secret Scanning合作伙伴计划(六步流程 - 见 references/vendor-key-format-census.md),这样客户密钥被推送到任何公共仓库时,能在客户注意到之前触发撤销流程。
-
从第一天起就在前缀中编码测试/生产环境 - 姊妹技能拥有此分类法所服务的测试模式界面;两个技能共享此前缀基础。
samber/developer-platform-skills@api-test-mode-design -
Webhook签名密钥(Stripe的)不是API密钥 - 签名方案属于姊妹技能
whsec_;只有其存储、轮换和仪表盘生命周期遵循本文的模式。samber/developer-platform-skills@webhook-platform-design
2. Choose the storage model
2. 选择存储模型
Three models, ranked:
-
security value:
workload identity (no stored key) > irretrievable hash > retrievable encrypted -
lost-key support-ticket reduction:(tie: neither ever re-displays a secret - the lost-key path is reissue in both)
retrievable encrypted > irretrievable hash == workload identity -
effort:
workload identity > retrievable encrypted > irretrievable hash -
compliance cost:. 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.
retrievable encrypted > irretrievable hash == workload identity -
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 plaintextcolumn, indexed, for O(1) candidate lookup. Run a constant-time comparison on the hash for the final check - a naive
key_prefixleaks 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 - thefallback runs in production exactly like the real thing.
dev-secret-key-123 -
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.
三种模型,排名如下:
-
安全价值:
工作负载身份(无存储密钥)> 不可检索哈希 > 可检索加密 -
减少丢失密钥支持工单:(平局:两者都不会重新显示机密 - 在两种情况下,丢失密钥的路径都是重新签发)
可检索加密 > 不可检索哈希 == 工作负载身份 -
工作量:
工作负载身份 > 可检索加密 > 不可检索哈希 -
合规成本:。只有可检索阶梯会创建审计员采样的界面:KMS密钥托管,加上返回明文机密的揭示路径。平局成立是因为其他两种不会暴露任何可揭示内容,因此都不会增加审查。
可检索加密 > 不可检索哈希 == 工作负载身份 -
效率:
不可检索哈希 > 可检索加密 > 工作负载身份 -
默认阶梯:不可检索,仅哈希。 在创建时仅显示一次完整密钥,仅存储哈希(Stripe、AWS、GitHub、OpenAI、Anthropic、Linear、Resend都这样做)。使用SHA-256哈希 - 这是机器生成机密的普遍选择,且有实际理由:bcrypt/Argon2的存在是为了防御低熵的人类密码,而GPU每秒约210亿次SHA-256哈希,对178位随机密钥仍然不可行。慢哈希的反方观点(纵深防御、统一机密策略)仍然是少数派立场 - 注意bcrypt的72字节硬输入上限无论如何都削弱了“全部使用bcrypt”的主张。
-
存储一个短的明文列,并建立索引,以实现O(1)候选查找。对哈希执行恒定时间比较以进行最终检查 - 朴素的
key_prefix会泄露时序信息。== -
升级到可检索仅在消费者经常丢失密钥、数据风险较低且支持负载占主导时(Twilio、Supabase)。然后:使用AES-256-GCM,密钥加密密钥存储在KMS中,并同时存储SHA-256哈希,以便验证无需解密往返。绝不明文存储,绝不使用应用管理的加密密钥。
-
工作负载身份是被忽视的选项:最高安全性(无可泄露)和最高工作量(联合基础设施、按环境证明),因此它在每轮效率比较中都会输 - 但当消费者是CI系统或AI Agent/MCP服务器时,无论如何都会被提升,这个群体正在积极迁移离开静态密钥。
-
故障安全:缺失的机密必须在启动时使服务崩溃,绝不能回退到硬编码的默认值 -这类回退在生产环境中的行为与真实密钥完全相同。
dev-secret-key-123 -
此排名是默认值,而非定律 - 请针对问题6和对用户的了解重新排名。已经运行KMS的平台几乎可以免费获得可检索存储。Agent优先的平台应将工作负载身份视为默认,而非提升项。
模式和查找流程详情:references/storage-and-lookup-schema.md。
3. Choose the scoping model
3. 选择范围界定模型
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.
范围界定是叠加在密钥所确立身份之上的授权 - 是补充控制,而非替代。针对机器到机器密钥的既定启发式规则:小范围每次都能胜过“可信内部服务”逻辑 - 团队信任不是安全边界;密钥自身的范围才是唯一可强制执行的。
直接拒绝单一账户级密钥 - 它是反模式,而非底层的阶梯。SendGrid的失效开放默认(创建时省略范围,获得完全访问权限)是被点名要对抗的设计示例:默认受限,只有当使用日志证明消费者需要更多时才扩展。
三个阶梯,排名如下:
-
工作量:
细粒度资源范围界定 > 粗略的每密钥范围 > 按环境拆分密钥 -
爆炸半径遏制:
细粒度资源范围界定 > 粗略的每密钥范围 > 按环境拆分密钥 -
效率:
按环境拆分密钥 > 粗略的每密钥范围 > 细粒度资源范围界定 -
默认阶梯 - 同时采用两个底层阶梯:每个环境(开发/暂存/生产)中每个服务一个密钥,加上默认受限的粗略范围集(读与写,按产品领域)。两者都只需数天工作,并且可以叠加;这样泄露的密钥只会危及一个环境中的一个服务,且仅有一组权限。
-
提升到细粒度资源范围界定当合规制度在范围内、企业客户要求,或多个团队使用具有真正不同权限需求的密钥时。该阶梯意味着按资源授权、细粒度权限和强制过期(GitHub细粒度PAT:一个资源所有者、选定的仓库、64种权限类型、强制过期、组织级批准)。这是被忽视的选项:最高遏制能力,但权限分类项目需要数月时间,因此它在每轮效率比较中都会输,直到上述条件之一将其提升。
-
此排名是默认值,而非定律 - 问题5会重新排名:已有的可复用范围的产品RBAC系统使细粒度几乎免费,这翻转了工作量线和赢家。
-
记录每个密钥的用途,而不仅仅是其位置:名称、消费服务、允许和拒绝的操作、所属团队。一个未记录、永不过期的密钥“会成为隐形基础设施,在团队变动、架构变更和被遗忘的集成中持续运作” - 范围界定和过期时间是配对控制,而非独立控制。
各供应商的范围界定机制:references/vendor-key-format-census.md。
4. Design rotation
4. 设计轮换
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."
- Expose rotation as one atomic "roll" operation: caller picks the old key's expiry, the system creates the new key and schedules the old one in a single call - never two manual steps where the expiry half gets forgotten.
- Copy the named mechanics:
- Stripe's roll keeps both keys valid for up to 7 days (pick "Now" to kill immediately) behind two-factor verification.
- AWS IAM hard-caps each user at two active access keys, which forces old/new overlap instead of N-key sprawl, and gates deletion on showing zero traffic.
get-access-key-last-used
- Grace-period defaults by scenario:
- Routine rotation: 24 hours to 7 days, depending on deploy cadence.
- Confirmed compromise or offboarding: zero grace, revoke immediately and accept the downtime.
- Agent fleets and queued workloads: longer than the human default.
- These are practitioner conventions to adjust in the interview, not standards - no universal rotation frequency exists, and PCI-DSS 4.0 explicitly refuses to name one (see step 7).
- Two operational invariants: never delete an old key before last-used telemetry confirms zero traffic on it, and never create a new key without scheduling the old one's revocation - the second without the first doubles the attack surface instead of rotating anything.
- Rotation matters absent any breach: GitGuardian found 64% of valid secrets leaked in 2022 were still valid and exploitable years later.
Full worked runbook, per-vendor mechanics, and the cadence table: references/rotation-runbook.md.
零停机轮换意味着旧密钥和新密钥在宽限期内同时有效。没有重叠,轮换就会崩溃:
“轮换密钥意味着每个客户需要在同一天更新他们的集成。所以你不会轮换。所以当泄露发生时,你在凌晨3点在生产环境轮换。”
-
将轮换暴露为一次原子“滚动”操作:调用方选择旧密钥的过期时间,系统在单次调用中创建新密钥并安排旧密钥过期 - 绝不分成两个手动步骤,以免过期那部分被遗忘。
-
复制既定的机制:
- Stripe的滚动使两个密钥在最多7天内有效(选择“立即”可即刻失效),并受两步验证保护。
- AWS IAM将每个用户硬性限制为两个活动访问密钥,这迫使新旧重叠,而不是N密钥蔓延,并将删除操作限制在显示零流量之后。
get-access-key-last-used
-
按场景的宽限期默认值:
- 常规轮换:24小时至7天,取决于部署节奏。
- 确认泄露或离职:零宽限,立即撤销并接受停机。
- Agent集群和排队工作负载:比人工默认更长。
-
这些是可在访谈中调整的从业者惯例,而非标准 - 不存在通用的轮换频率,PCI-DSS 4.0明确拒绝指定一个(见第7步)。
-
两个操作不变量:在最后一次使用的遥测确认旧密钥零流量之前,绝不要删除旧密钥;绝不创建新密钥却不安排旧密钥的撤销 - 第二个若没有第一个,只会加倍攻击面,而非进行轮换。
-
即使没有泄露,轮换也很重要:GitGuardian发现2022年泄露的有效机密中有64%在多年后仍然有效且可利用。
完整的操作手册、各供应商机制和节奏表:references/rotation-runbook.md。
5. Design the self-service dashboard behavior
5. 设计自助服务仪表盘行为
Self-service means four actions completable without a support ticket:
- Sign up.
- Create a key.
- Rotate a key.
- Revoke a compromised key.
A dashboard missing any one of them is self-service-with-an-escape-hatch-to-support for that action. Sibling owns where this dashboard sits in the portal. This skill owns what it does.
samber/developer-platform-skills@developer-portal-design- List view per key: human-readable label (distinct from the key value - "CI pipeline, staging"), creation date, last-used timestamp, status badge (active/inactive/expiring), and direct rotate/revoke actions.
- Mask everywhere after creation: first and last few characters only (Anthropic returns just a ); the full key appears once, in the creation modal, and never again on the irretrievable default rung.
partial_key_hint - Update 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.
last_used_at - Show per-key usage (and spend, where metered) as a separate surface from last-used: one answers "is this key alive", the other "what is this key doing/costing" - a mature dashboard needs both.
- Auth failures the key system emits (expired, revoked, insufficient scope) go through the platform's error surface: 401 for a key that fails authentication, 403 for a valid key lacking the scope - sibling owns those semantics.
samber/developer-platform-skills@api-error-design
自助服务意味着四个操作无需支持工单即可完成:
- 注册。
- 创建密钥。
- 轮换密钥。
- 撤销已泄露的密钥。
缺少其中任何一个的仪表盘,对于该操作而言都是“自助服务但需通过支持逃生舱”。姊妹技能负责该仪表盘在门户中的位置。本技能负责其行为。
samber/developer-platform-skills@developer-portal-design-
每个密钥的列表视图:人类可读标签(与密钥值不同 - “CI流水线,暂存”)、创建日期、最后使用时间戳、状态徽章(活动/不活动/即将过期),以及直接的轮换/撤销操作。
-
创建后到处遮蔽:仅显示首尾几个字符(Anthropic仅返回);完整密钥只出现一次,即在创建模态框中,在不可检索的默认阶梯上永远不会再次出现。
partial_key_hint -
在成功的认证检查后,异步、即发即弃地更新- 绝不让遥测阻塞请求路径。陈旧的最后使用时间是使“撤销此密钥”和“仅当日志证明需要时扩展范围”变得可操作而非空想的信号。
last_used_at -
将每密钥的使用情况(以及按计量计费时的花费)与最后使用时间分开显示:一个回答“这个密钥是否存活”,另一个回答“这个密钥在做什么/花费多少” - 成熟的仪表盘两者都需要。
-
密钥系统发出的认证失败(过期、撤销、范围不足)通过平台的错误界面处理:对于认证失败的密钥返回401,对于有效但缺少范围的密钥返回403 - 姊妹技能拥有这些语义。
samber/developer-platform-skills@api-error-design
6. Assign ownership and wire offboarding
6. 分配所有权并接入离职流程
Ownership is the lifecycle decision the dashboard must surface, because user-owned and org-owned keys fail in opposite directions (see Ownership tiers).
- Default production and automation to service-account or org-owned keys. Reserve individual keys for personal experimentation. The design reason service accounts exist: decouple credential validity from employment status, so automation neither silently breaks nor keeps running on a departed employee's still-valid personal key.
- Give org admins a filterable view of every key a specific user created or can see - without it, the offboarding runbook below is unexecutable.
- Offboarding runbook, run on every departure: enumerate the leaver's user-owned keys, revoke each (zero grace - this is the compromise scenario in step 4), rotate any shared credential they had access to, and log each action for the audit trail (step 7).
- Treat a production integration discovered running on a personal key as a standing incident: migrate it to a service account on a scheduled rotation, not during the next departure.
所有权是仪表盘必须呈现的生命周期决策,因为用户所有和组织所有的密钥以相反方向失败(见所有权层级)。
-
默认将生产和自动化使用服务账户或组织所有的密钥。将个人密钥保留用于个人实验。服务账户存在的设计理由:将凭据有效性与雇佣状态解耦,使自动化既不会悄然中断,也不会在已离职员工的仍然有效的个人密钥上继续运行。
-
为组织管理员提供特定用户创建或可见的每个密钥的可过滤视图 - 没有它,下面的离职操作手册无法执行。
-
离职操作手册,在每次离职时执行:枚举离职者用户所有的密钥,逐个撤销(零宽限 - 这是第4步中的泄露场景),轮换其可访问的任何共享凭据,并记录每个操作以供审计追踪(第7步)。
-
将发现运行在个人密钥上的生产集成视为持续事件:在计划轮换中将其迁移到服务账户,而不是等到下次离职时。
7. Install compliance lifecycle governance
7. 安装合规生命周期治理
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.
- SOC 2 (CC7.2, C1.2): a documented policy covering the full key lifecycle - provisioning, rotation, revocation, destruction - plus evidence it actually operates: key-event logs, periodic access reviews, approval records. Type II requires those controls operating consistently across a 3-12-month observation window, so a policy adopted the week before the audit fails by construction; automate evidence generation from day one.
- PCI-DSS 4.0/4.0.1, Requirement 8.6.3 (mandatory since April 1, 2025): correct the myth - PCI does not mandate a fixed rotation interval. It requires the cadence to be justified by a documented targeted risk analysis (Requirement 12.3.1), plus immediate rotation on suspicion or confirmation of compromise regardless of schedule. Separately: tamper-resistant logging of API transactions, retained 12 months with the latest 3 immediately accessible.
- Compliance pressure is why mature platforms ship these as product features, not policies: mandatory expiration, expiry warnings and forced-rotation reminders, audit logging of every create/use/rotate/revoke with who/when/why, and service accounts themselves - each one generates the evidence an auditor asks for.
Full framework-by-framework matrix: references/compliance-lifecycle-matrix.md.
审计员检查的是策略加证据,而非工具。先问问题4 - 持卡人数据直接引入PCI-DSS。企业买家通过采购引入SOC 2,即使平台自身的风险状况不需要。
-
SOC 2(CC7.2、C1.2):一份涵盖整个密钥生命周期的文档化策略 - 分配、轮换、撤销、销毁 - 加上实际操作证据:密钥事件日志、定期访问审查、批准记录。Type II要求这些控制在3-12个月的观察窗口内持续运作,因此审计前一周才采用的策略在结构上就会失败;从第一天起就自动化证据生成。
-
PCI-DSS 4.0/4.0.1,要求8.6.3(自2025年4月1日起强制):纠正误区 - PCI不强制固定的轮换间隔。它要求节奏由文档化的针对性风险分析(要求12.3.1)证明合理,并且在怀疑或确认泄露时立即轮换,无论计划如何。另外:API交易的防篡改日志,保留12个月,最近3个月可立即访问。
-
合规压力是成熟平台将这些作为产品功能而非策略交付的原因:强制过期、过期警告和强制轮换提醒、对每次创建/使用/轮换/撤销的记录(包含谁/何时/为何),以及服务账户本身 - 每一个都会生成审计员要求的证据。
完整的逐框架矩阵:references/compliance-lifecycle-matrix.md。
Failure modes
故障模式
Anti-pattern checklist, grounded in OWASP API2 - each is a direct audit finding:
- An API key as the sole credential for a sensitive operation, or key identification conflated with user authentication.
- Plaintext keys at rest, or reversible encryption without a KMS-held key.
- A missing secret that falls back to a hardcoded default instead of crashing at startup.
- A fail-open scope default - omitting scopes at creation grants full access.
- No rate limiting or brute-force protection on key validation and key-creation endpoints (treat them as login endpoints).
- Non-constant-time hash comparison on the auth path.
- A key with no owner, no scope documentation, and no expiry - invisible infrastructure.
- An old key deleted before last-used telemetry hit zero (rotation-caused outage), or a new key created with no revocation scheduled on the old one (doubled attack surface).
- A production integration running on a departed employee's personal key.
- A webhook signing secret managed as if it were an API key, or vice versa.
反模式检查清单,基于OWASP API2 - 每一项都是直接的审计发现:
- API密钥作为敏感操作的唯一凭据,或将密钥识别与用户认证混为一谈。
- 静态明文密钥,或没有KMS持有密钥的可逆加密。
- 缺失的机密回退到硬编码默认值,而非在启动时崩溃。
- 失效开放的范围默认 - 创建时省略范围即授予完全访问权限。
- 密钥验证和密钥创建端点没有速率限制或暴力破解保护(应将其视为登录端点)。
- 认证路径上的非恒定时间哈希比较。
- 没有所有者、范围文档和过期的密钥 - 隐形基础设施。
- 在最后使用遥测归零之前删除旧密钥(轮换导致的停机),或创建新密钥时未安排旧密钥撤销(攻击面加倍)。
- 生产集成运行在已离职员工的个人密钥上。
- 将Webhook签名密钥当作API密钥管理,反之亦然。
Measurement
度量
Gates - iterate the design until every one passes:
- Storage: 100% of stored keys hashed (irretrievable rung) or KMS-encrypted (retrievable rung); zero plaintext keys at rest, verified by schema audit, not by policy assertion.
- Inventory: every live key carries an owner, a scope, and an expiry or a documented exemption.
- Rotation: the runbook exists and has been exercised end-to-end at least once - a real key rolled with zero downtime and the old key confirmed at zero traffic before deletion.
- Self-service: all four actions (sign up, create, rotate, revoke) completable without a support ticket.
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.
门禁 - 迭代设计直至每个门禁通过:
- 存储:100%的存储密钥已哈希(不可检索阶梯)或KMS加密(可检索阶梯);静态零明文密钥,通过模式审计验证,而非策略声明。
- 清单:每个活跃密钥都带有所有者、范围和过期时间或文档化的豁免。
- 轮换:操作手册存在并已至少端到端演练一次 - 真实密钥零停机轮换,并在删除前确认旧密钥零流量。
- 自助服务:所有四个操作(注册、创建、轮换、撤销)无需支持工单即可完成。
从第一个月开始建立基线并持续改进的趋势(不存在行业阈值):从泄露检测到撤销的时间、最后使用时间超过90天的活跃密钥占比、服务账户密钥与个人密钥上的生产流量占比。
Invocation examples
调用示例
- "Design the API key system for our public API - today we issue one UUID per account and store it plaintext in Postgres."
- "Define a key format and prefix scheme so leaked keys are detectable by secret scanners."
- "Our enterprise customers are asking how we rotate API keys - design a zero-downtime rotation flow and the dashboard UX for it."
- "An engineer just left and half our integrations run on keys they created - fix the ownership model."
- “为我们的公共API设计API密钥系统 - 目前我们每个账户发放一个UUID,并以明文存储在Postgres中。”
- “定义密钥格式和前缀方案,使泄露的密钥能被密钥扫描器检测到。”
- “我们的企业客户在询问我们如何轮换API密钥 - 为其设计零停机轮换流程和仪表盘UX。”
- “一名工程师刚离职,我们一半的集成运行在他们创建的密钥上 - 修复所有权模型。”
References
参考
- - per-recipient storage credentials for bulk file/lake delivery follow a separate lifecycle from the API keys this skill covers.
samber/developer-platform-skills@bulk-data-sharing-design - references/vendor-key-format-census.md - prefix taxonomy across seven vendors, GitHub's entropy math, the six-step Secret Scanning Partner Program, per-vendor scoping mechanics and ownership models.
- references/storage-and-lookup-schema.md - the key table schema, prefix-based lookup flow, hashing decision detail, retrievable-model storage.
- references/rotation-runbook.md - worked zero-downtime rotation runbook, Stripe/AWS/Azure mechanics, grace-period cadence table, offboarding sequence.
- references/compliance-lifecycle-matrix.md - SOC 2 and PCI-DSS 4.0 expectations mapped to key-lifecycle controls and the product features they force.
- - 批量文件/湖存储交付的每接收方存储凭据遵循与本技能所涵盖API密钥不同的生命周期。
samber/developer-platform-skills@bulk-data-sharing-design - references/vendor-key-format-census.md - 七个供应商的前缀分类法、GitHub的熵计算、六步Secret Scanning合作伙伴计划、各供应商的范围界定机制和所有权模型。
- references/storage-and-lookup-schema.md - 密钥表模式、基于前缀的查找流程、哈希决策细节、可检索模型存储。
- references/rotation-runbook.md - 成型的零停机轮换操作手册、Stripe/AWS/Azure机制、宽限期节奏表、离职顺序。
- references/compliance-lifecycle-matrix.md - SOC 2和PCI-DSS 4.0预期映射到密钥生命周期控制及它们所推动的产品功能。