Summary
Implement secure API key generation, hashing, and validation utilities for the Campus Audit Service.
Requirements
- Add
generate_audit_api_key() -> str - Generate audit service API key
- Format:
audit_v1_<22-char-base64url> (31 total characters)
- Example:
audit_v1_kXj9mP2nQ5vR8sT7uV3wY4zX5cV6bN7m
- Use
secrets.token_urlsafe(16) for ~132-bit entropy
- Database ID format:
uid-apikey-<16-hex-chars>
2. Hashing Functions
hash_api_key(api_key: str) -> str - SHA-256 hash of raw key
verify_api_key_hash(raw_key: str, stored_hash: str) -> bool - Constant-time comparison
- Use
hmac.compare_digest() for timing-safe comparison
3. Validation Logic
- Validate key format (prefix, length, character set)
- Check against revoked/expired status
- Scope validation with wildcard support
- Rate limit bucket extraction from key metadata
4. Security Requirements
- Never log raw API keys
- Use constant-time comparison to prevent timing attacks
- Hash must use SHA-256 with optional per-key salt
- Key hash must be stored as hex string (64 chars)
- 132-bit entropy provides strong security margin
5. Key Format Specification
Public ID (database):
uid-apikey-ab12cd34ef567890 # 16 hex chars
Secret value (authentication):
audit_v1_kXj9mP2nQ5vR8sT7uV3wY4zX5cV6bN7m # 31 total chars
- Prefix:
audit_v1_ (9 chars) - version identification
- Random: 22 base64url chars - URL-safe, case-sensitive
- Entropy: ~132 bits - strong security margin
- Comparison: Stripe uses ~130+ bits, GitHub uses 160 bits
6. Testing
- Unit tests for key generation uniqueness
- Tests for hash verification edge cases
- Security tests for timing attack resistance
- Tests for expired/revoked key detection
- Format validation tests (prefix, length, character set)
Acceptance Criteria
Related
Summary
Implement secure API key generation, hashing, and validation utilities for the Campus Audit Service.
Requirements
1. Key Generation (extend
campus/common/utils/secret.py)generate_audit_api_key() -> str- Generate audit service API keyaudit_v1_<22-char-base64url>(31 total characters)audit_v1_kXj9mP2nQ5vR8sT7uV3wY4zX5cV6bN7msecrets.token_urlsafe(16)for ~132-bit entropyuid-apikey-<16-hex-chars>2. Hashing Functions
hash_api_key(api_key: str) -> str- SHA-256 hash of raw keyverify_api_key_hash(raw_key: str, stored_hash: str) -> bool- Constant-time comparisonhmac.compare_digest()for timing-safe comparison3. Validation Logic
4. Security Requirements
5. Key Format Specification
Public ID (database):
Secret value (authentication):
audit_v1_(9 chars) - version identification6. Testing
Acceptance Criteria
audit_v1_prefixuid-apikey-prefix with 16 hex charsRelated
campus/common/utils/secret.pycampus/model/audit.py(APIKey already exists)