Identity tables were derived from hub's PostgreSQL schema but simplified without documenting what was removed or why. This restructures them for the current auth landscape (API key + wraith SSH/cert-authority): - ADR-049: Separate api_keys and peer_credentials tables (different lookup patterns, columns, lifecycles), remove Gitea columns, map hub data→metadata - ADR-050: Extract SHA-256 vs KDF decision from inline spec text - Add peer_credentials table for SSH key and cert-authority auth - Specify all FK cascade behaviors within system DB (RESTRICT, CASCADE, SET NULL) - Complete index specifications for all identity tables - Add scope boundary section (storage owns schemas, not auth/authorization) - Update audit_logs with credentialId+credentialType polymorphic reference - Add 3 new open questions (OQ-33/34/35) for credential type expansion
1.9 KiB
ADR-050: SHA-256 for Machine-Generated API Keys
Status
Accepted
Context
API key hashing has two common approaches:
- Fast hash (SHA-256): O(1) verification at high throughput. Standard for machine-generated tokens.
- Slow KDF (bcrypt, Argon2): Intentionally expensive to slow brute-force attacks. Standard for human-chosen passwords.
The choice depends on the input entropy. Human passwords are low-entropy
(maybe 30-40 bits of actual randomness even with complexity requirements), so
brute-force is feasible unless the hash is slow. Machine-generated keys are
high-entropy (128-bit+ randomness from crypto.randomUUID() or equivalent),
making brute-force computationally infeasible even with a fast hash.
Decision
Use SHA-256 for API key hashing. Do not use bcrypt or Argon2.
The API keys in @alkdev/storage are machine-generated secrets with 128-bit+
entropy. An attacker attempting to brute-force a SHA-256 hash of such a key
faces 2^128 possible inputs — infeasible regardless of hash speed. Slow KDFs
add latency (50-200ms per verification) without meaningful security
improvement for high-entropy inputs.
Consequences
Positive:
- Fast O(1) verification — critical for high-throughput API authentication
- Widely supported — every language/runtime has SHA-256 built in
- Simple implementation — no salt generation, no cost parameter tuning
Negative:
- If a consumer generates low-entropy keys (short, predictable patterns), SHA-256 provides less protection against brute-force than a slow KDF. This is a consumer responsibility — the storage table schema cannot enforce key generation quality.
- SHA-256 is not post-quantum resistant. This is acceptable for API keys, which can be rotated, unlike passwords which are often long-lived.
References
api_keys.keyHashin sqlite-host.md- Hub ADR-010: SHA-256 for API key hashing (same decision, provenance)