Documentation
¶
Overview ¶
Package apikey provides the security-sensitive primitives for issuing and verifying API keys: cryptographically-random key generation, hashing, and constant-time verification.
This is the reusable, get-it-wrong-and-you're-breached part. Everything ELSE about API keys is application code you own: the api_keys table (add it with `forge scaffold entity`), the store that reads/writes it, and the auth.KeyValidator that turns a validated key into claims. The auth skill's "API keys" recipe shows the full wiring; the short version is:
// issuing a key (in your store's Create):
plaintext, err := apikey.Generate() // "fk_..." — show once
prefix, _ := apikey.LookupPrefix(plaintext) // indexed lookup handle
hash := apikey.Hash(plaintext) // store this, never the key
// verifying (in your auth.KeyValidator.ValidateKey):
prefix, err := apikey.LookupPrefix(presented) // reject malformed early
row := store.findByPrefix(ctx, prefix) // one indexed read
if !apikey.Verify(presented, row.Hash) { ...unauthenticated... }
Keys are high-entropy random tokens (~190 bits), so a fast cryptographic hash (SHA-256) is the correct choice — the slow password hashes (bcrypt, argon2) exist to defend LOW-entropy secrets against brute force and buy nothing here while costing a lookup's worth of CPU per request.
Index ¶
Constants ¶
const ( // KeyPrefix is prepended to every generated key. It makes keys // recognizable in logs and lets secret scanners match on "fk_". KeyPrefix = "fk_" // LookupPrefixLen is the number of post-KeyPrefix characters stored in // cleartext as an indexed lookup handle, so verification is a single // indexed row read rather than a full-table hash scan. LookupPrefixLen = 8 )
Variables ¶
This section is empty.
Functions ¶
func Generate ¶
Generate returns a new random API key of the form "fk_<32 base62 chars>". The plaintext is returned once; store only its Hash and LookupPrefix.
func LookupPrefix ¶
LookupPrefix returns the indexed lookup handle for key (the LookupPrefixLen characters following KeyPrefix). It doubles as a cheap format check: malformed input is rejected before any DB work.
Types ¶
This section is empty.