Files
hub/docs/decisions/ADR-010-api-keys-vs-client-secrets-direction-matters.md
glm-5.1 2b63cda1c7 Setup repo: migrate architecture specs, code stubs, and tasks from alkhub_ts
Copy architecture docs, ADRs, storage domain specs, research, reviews,
and 56 storage architecture tasks from the alkhub_ts monorepo. Adapt for
standalone @alkdev/hub repo structure (src/ not packages/hub/).

Sanitize all sensitive information:
- Replace private IPs (10.0.0.1) with localhost defaults
- Remove internal server hostnames (dev1, ns528096)
- Replace /workspace/ private paths with npm package references
- Remove hardcoded credentials from examples
- Rewrite infrastructure.md without private network details

Add Deno project scaffolding: deno.json (pinned deps), .gitignore,
AGENTS.md, entry point. Migrate existing code stubs (crypto, config
types, logger) with updated import paths.
2026-05-25 10:56:32 +00:00

1.7 KiB

ADR-010: API keys vs client secrets — direction matters

  • Status: Accepted
  • Date: 2026-04-19
  • Deciders: alkdev

Context

Both api_keys and client_secrets store authentication credentials, but they serve opposite directions.

Decision

Keep as separate tables with different security models. api_keys: keys WE issue so others can call US (hub auth). Managed by keypal. Stored as SHA-256 hashes. client_secrets: keys OTHERS issue so we can call THEM (outbound auth). Managed by us. Stored as AES-256-GCM encrypted values. Never mix — a hashed client secret is useless (we can't send it), an encryptable API key defeats the purpose of hashing.

SHA-256 vs KDF trade-off

API keys are hashed with SHA-256, not a deliberately slow KDF (bcrypt, Argon2). This is acceptable because:

  1. API keys are high-entropy machine-generated strings (128-bit+). With 2^128 key space, brute-force is infeasible regardless of hash speed — there are not enough keys to make a dictionary attack viable.
  2. SHA-256 provides O(1) verification latency at high throughput, which matters for every API request.
  3. Slow KDFs exist to protect low-entropy human passwords (where rate-limiting cannot compensate for small key space). Machine-generated keys do not have this weakness.

If the database is compromised, the attacker has the SHA-256 hashes but cannot reverse them without enumerating the key space — which is computationally infeasible for 128-bit+ random keys.

Consequences

Positive: clear security model per direction, appropriate crypto per use case, no confusion about how credentials are stored. Negative: two tables instead of one, but the security models are fundamentally incompatible so merging would be wrong.