"""B2B API-key utilities: generation, hashing, verification. Just like service tokens, the raw key is shown only once; we store SHA-256. """ from __future__ import annotations import hashlib import hmac import secrets def generate_api_key() -> str: """Mint a new opaque B2B API key (~43 URL-safe chars).""" return secrets.token_urlsafe(32) def hash_api_key(key: str) -> str: """SHA-256 hex digest of an API key (store this, never the raw key).""" return hashlib.sha256(key.encode("utf-8")).hexdigest() def verify_api_key(key: str, key_hash: str) -> bool: """Constant-time check that `key` matches the stored `key_hash`.""" digest = hash_api_key(key) return hmac.compare_digest(digest, key_hash)