How it works
valetkey has four moving parts. Understanding them takes about three minutes.
Personas
Section titled “Personas”A persona is a named user your agent can become, like admin or free-user. Each one maps to seed data your auth system understands, typically an email and a role. Personas live in valetkey.config.ts, so they are committed, reviewed, and shared with your team like any other code.
personas: { "admin": { seed: { email: "admin@myapp.test", role: "admin" } }, "free-user": { seed: { email: "free@myapp.test", plan: "free" } },}Switching users is valetkey login free-user. That makes testing authorization logic, plan gating, and multi-tenant behavior a one-line operation instead of a login dance.
The vault and identities
Section titled “The vault and identities”Provider secrets (a seeded password, a service key, a JWT secret) live in .valetkey/vault.age, a JSON map encrypted with age. The vault is committed to your repo. It can be, because it is encrypted to the public keys listed in .valetkey/recipients.txt.
Each developer machine has an identity keypair, created by valetkey init and stored in the OS keychain (with an encrypted file fallback for headless machines). Adding a teammate means adding their public key with valetkey team add, which re-encrypts the vault to them. Secrets decrypt only inside the valetkey process, and every decrypted value is scrubbed from valetkey’s output, logs, and error messages.
Minting and session artifacts
Section titled “Minting and session artifacts”valetkey login <persona> asks your provider plugin to sign in server-side and return a session artifact: the cookies (and localStorage entries) that make a browser signed in. valetkey then
- clamps the expiry to the configured TTL (60 minutes by default),
- verifies every cookie is pinned to one of your configured dev origins,
- saves the artifact under
~/.valetkey/sessions/with0600permissions, outside your repo, - writes an audit event.
The artifact converts directly to Playwright’s storage-state format, which is what --export produces and what agent browsers consume. It can also go straight into the managed browser, a Chrome profile valetkey drives over a debugging connection, which is how httpOnly cookies get set and how persona switching happens without a restart.
Guardrails
Section titled “Guardrails”These are enforced by the core, so no plugin or config mistake can switch them off:
- Origins must be
localhost,127.0.0.1,*.localhost,*.test, or*.local. Anything else needs an explicitallowRemoteDevOriginsentry, and it must be https. - Values that look like live keys (
sk_live_,pk_live_,rk_live_) are refused at the vault door. - Cookies minted for an origin you did not configure are rejected before they are stored.
- Expired artifacts are pruned and unusable.
The audit log
Section titled “The audit log”Every mint, export, seed, and revocation is appended to ~/.valetkey/audit.log as JSON lines, with secrets redacted. valetkey audit --tail 20 shows the recent history, so you always know which sessions existed and where they went.