@lacspace/apikey
v1.1.1
Published
Issue & verify API keys the right way — prefixed high-entropy keys, store only the SHA-256 hash, constant-time verify, last-4 display. Isomorphic over Web Crypto.
Maintainers
Readme
@lacspace/apikey
Issue & verify API keys the right way — show once, store only the hash.
Generate prefixed, high-entropy keys (e.g.
lac_live_…), return the SHA-256 hash to store and the last 4 to display, and verify in constant time. You never persist the raw key — exactly how Stripe/GitHub-style keys work.
- 🔑
generateApiKey→{ key, hash, prefix, last4 } - ✅
verifyApiKey(constant-time) ·hashApiKey·parseApiKey - ⚡ Zero deps (bar
@lacspace/crypto) · 🌍 isomorphic · fully typed
Install
npm install @lacspace/apikeyUsage
import { generateApiKey, verifyApiKey } from "@lacspace/apikey";
// on create — show `key` to the user ONCE, store the rest
const { key, hash, prefix, last4 } = await generateApiKey({ prefix: "lac_live" });
// key: "lac_live_9f8a…" (return to user, never store)
// hash: "3b2c…" (store this), prefix, last4 for display
// on each request
const presented = req.headers["x-api-key"];
if (await verifyApiKey(presented, storedHash)) { /* authorized */ }API
| Export | Description |
| --- | --- |
| generateApiKey(opts?) | { key, hash, prefix, last4 } — prefix, bytes |
| verifyApiKey(key, storedHash) | constant-time verify |
| hashApiKey(key) | SHA-256 for lookup/storage |
| parseApiKey(key) | { prefix, last4 } |
The Lacspace Security Kit
| Package | For |
| --- | --- |
| @lacspace/crypto | AES encryption & hashing |
| @lacspace/password | Password hashing |
| @lacspace/jwt | JWTs & tokens |
| @lacspace/apikey | API keys (this package) |
| @lacspace/otp | TOTP/HOTP 2FA |
| @lacspace/webauthn | Passkeys / biometric |
| @lacspace/mfa | 2FA/3FA orchestration |
| @lacspace/lock | Account lockout |
| @lacspace/headers | Secure headers / CSP |
| @lacspace/redact | Log redaction |
New in 1.1 — request adapters
import { extractApiKey, authenticateApiKey, expressApiKey, isValidKeyFormat } from "@lacspace/apikey";
// Pull the key from x-api-key or Authorization: Bearer
const key = extractApiKey(req);
// Verify (constant-time) against your store, with expiry + scope checks
const record = await authenticateApiKey(key ?? "", {
resolve: ({ prefix }) => db.apiKeys.findByPrefix(prefix), // returns { hash, scopes, expiresAt }
scopes: ["read"],
});
// Express: verifies → req.apiKey, else 401
app.use("/api", expressApiKey({ resolve: ({ prefix }) => db.apiKeys.findByPrefix(prefix) }));
isValidKeyFormat("lac_live_xxxxxxxxxxxxxxxx"); // cheap offline reject before hitting the DBLicensing
This package is free under the Lacspace Free Licence — MIT-equivalent freedoms. Use it in personal and commercial projects at no cost; just keep the notice.
Not every Lacspace package is free. We also offer Commercial (paid), Client-specific, and Private (proprietary) packages under separate terms. See the full Lacspace Licence Centre.
Part of the Lacspace ecosystem — 35 zero-dependency, isomorphic TypeScript packages.
