Lacspace talks about security in layers — and we wanted those layers to be something a developer can actually npm install, not just a diagram. So the Security Kit turns each layer into a small, focused package, all built on the Web Crypto API. We do not hand-roll cryptography; we make the standard primitives easy to use correctly.

The layers

1 · Encryption — @lacspace/crypto
Authenticated AES-256-GCM, PBKDF2 key derivation, SHA-2, HMAC, secure random and constant-time comparison. Encrypt a field before it touches your database:
import { encrypt, decrypt, generateKey } from "@lacspace/crypto";
const key = generateKey(); // 256-bit key, store it safely
const sealed = await encrypt("PAN: ABCDE1234F", key);
// "v1:<iv>:<ciphertext+tag>" — tampering is rejected on decrypt
const plain = await decrypt(sealed, key);
2 · Passwords — @lacspace/password
PBKDF2-HMAC-SHA256 at 600,000 iterations (per OWASP), in a portable PHC string, with constant-time verification and a strength estimator.
import { hash, verify } from "@lacspace/password";
const stored = await hash("correct horse battery staple");
await verify(input, stored); // true / false, constant-time
3 · Tokens & 4 · API keys — @lacspace/jwt, @lacspace/apikey
Sign and verify JWTs (HS256/384/512) with strict expiry and issuer/audience checks — on the edge, where the classic jsonwebtoken package cannot run. And issue API keys the right way: show the key once, store only its hash, verify in constant time.
import { sign, verify } from "@lacspace/jwt";
import { generateApiKey, verifyApiKey } from "@lacspace/apikey";
const token = await sign({ sub: "user_1" }, secret, { expiresIn: 3600 });
const { key, hash } = await generateApiKey({ prefix: "lac_live" }); // store 'hash', show 'key' once
5 · Two-factor — @lacspace/otp
Google Authenticator-compatible TOTP/HOTP, verified against the RFC 6238 test vectors, with an otpauth:// URI you can turn into a QR code.
import { generateSecret, verifyTotp, keyuri } from "@lacspace/otp";
const secret = generateSecret();
const uri = keyuri({ secret, label: "user@site.com", issuer: "Lacspace" }); // → QR
await verifyTotp(code, secret); // offset | null (tolerates clock drift)
6 · Biometric / passkeys — @lacspace/webauthn
Passwordless login with FaceID, fingerprint or a security key. Browser ceremony helpers, server challenge/options builders, and real ES256/RS256 assertion verification over Web Crypto — including the fiddly parts (DER signatures, a compact CBOR/COSE parser to extract the public key at registration).
7 · Multi-factor — @lacspace/mfa
The conductor. Combine a password, a TOTP code and a passkey into 2FA or 3FA step-up flows, and compute the NIST Authenticator Assurance Level (AAL1–3) so you can require stronger auth for sensitive actions.
import { mfaSession } from "@lacspace/mfa";
const session = mfaSession({ factors, policy: { minFactors: 2, minAAL: 2 } });
session.markVerified("password");
session.markVerified("totp");
session.satisfied; // true — AAL2
And two that quietly save you
@lacspace/lock adds account lockout with exponential backoff to stop brute-force and credential stuffing at the door. @lacspace/redact masks secrets and PII (JWTs, API keys, emails, cards) before they ever reach CloudWatch or your error tracker — the last line of defence against leaking a token into a log. And @lacspace/headers gives you a strict set of security response headers and a typed Content-Security-Policy builder.
Tested, not just typed
Security code has to be right, so we verify behaviour — not just that it compiles. AES-GCM rejects tampered ciphertext, SHA-256 matches the NIST vector, TOTP matches RFC 6238, JWT rejects expired and mis-signed tokens, and the full WebAuthn ceremony is verified end-to-end against a synthetic authenticator, before anything is published.
Every package uses the Lacspace Free Licence and is zero-dependency. Start with the packages page, or read the source in the open monorepo.
Frequently asked questions
Did Lacspace roll its own cryptography?
No. The Security Kit is a thin, correct layer over the Web Crypto API — AES-256-GCM, PBKDF2, HMAC and ECDSA/RSA verification. We do not invent crypto primitives; we make the standard ones easy to use correctly, and we test against known vectors (for example TOTP against RFC 6238 and SHA-256 against the NIST test vector) before every release.
What does the Security Kit include?
Ten packages: @lacspace/crypto (AES-256-GCM, hashing, HMAC), @lacspace/password (PBKDF2 hashing), @lacspace/jwt (tokens), @lacspace/apikey (API keys), @lacspace/otp (TOTP/HOTP 2FA), @lacspace/webauthn (passkeys/biometric), @lacspace/mfa (2FA/3FA orchestration), @lacspace/lock (account lockout), @lacspace/headers (secure headers + CSP) and @lacspace/redact (log redaction).
Does it work on the edge and in the browser?
Yes. Because it is built on Web Crypto, the same code runs on Node 18+, on edge runtimes and workers, in the browser and in React Native — so you can encrypt on a serverless function or verify a passkey assertion wherever your code runs.
How do the 2FA and passkey packages relate?
@lacspace/otp gives you authenticator-app 2FA (TOTP), @lacspace/webauthn gives you passkeys / biometric login (FaceID, fingerprint, security keys), and @lacspace/mfa is the conductor that combines a password, a TOTP code and a passkey into 2FA or 3FA step-up flows with NIST assurance levels.
Can I encrypt database fields or S3 objects with it?
Yes. @lacspace/crypto uses authenticated AES-256-GCM, so you can encrypt a field before it is written to MongoDB or an object body before it is put on S3, and decryption fails loudly if the ciphertext was tampered with. There is also a passphrase mode that derives the key with PBKDF2.
Is it free for commercial use?
Yes, all ten packages use the Lacspace Free Licence and are free for personal and commercial projects.

