pock://docs
Documentation
Pock encrypts your secrets on your device and never sees the plaintext. Here's how to share files, manage your vault, drive the CLI, and what's happening under the hood.
60 seconds
Quickstart
- Install the CLI:
$ curl -fsSL pock.sh/install | sh
- Authenticate -
pock loginopens your browser and waits for you to approve the device. - Share a file:
pock share .env.production --ttl 1h. Pock prints a link and copies the key to your clipboard. - Send the link and the key through different channels. The recipient runs
pock receive <id> <key>or drags the saved key onto the web receive page.
one line
Install
The pock binary installs to ~/.pock/bin. Add that directory to your PATH if the installer can't do it for you.
Linux & macOS
$ curl -fsSL pock.sh/install | sh pock installing… ✓ downloaded pock 0.5.0 (darwin/arm64) ✓ installed → ~/.pock/bin/pock → add ~/.pock/bin to your PATH, then run: pock login
Windows (PowerShell)
> irm pock.sh/install.ps1 | iex
device flow
Authenticate
pock login opens your browser and starts a device approval flow - confirm in the browser and the CLI stores a token under ~/.pock. No keys or passwords are typed into the terminal.
$ pock login → opening https://pock.sh/cli-auth?code=JABS-X9F2 waiting for approval in your browser… ✓ approved - logged in as alice@acme.dev
Check who you are, or sign out and wipe the local token:
$ pock whoami alice@acme.dev · acme.dev · token expires in 29d $ pock logout ✓ signed out - local token removed
decrypt
Receiving
The recipient runs pock receive <id> <key>. Pock fetches the envelope, decrypts it locally, and writes the files out - the key never leaves their machine either.
$ pock receive 3kPq8vN2 pk_aQ7x9…Lr2 --out ./secrets ✓ fetched envelope · 1 file ✓ decrypted → ./secrets/.env.production
On the web, navigate to the share link and drag the saved .key file onto the receive page - no clipboard needed, decryption runs in your browser via WASM.
--out <DIR>- Directory to write decrypted files into. Defaults to the current directory.
--force- Overwrite existing files in the output directory instead of aborting.
secret manager
Vault
The vault stores key/value secrets grouped into projects. Each value is encrypted to your own key ("encrypt-to-self") and stored as an opaque blob - Pock never sees the plaintext.
Web (/vault)
- Create - keygen runs in WASM; your Secret Key and recovery code are shown once (copy and download them).
- Unlock - enter your passphrase + Secret Key, or use a passkey (Face ID, Touch ID, Windows Hello) for one-touch unlock.
- Manage - reveal, copy, and edit secrets; add projects; reset the vault to start over.
CLI
# Create a new vault (generates Secret Key + recovery code) $ pock vault init # Write secrets $ pock vault set app DATABASE_URL=postgres://db/prod API_KEY=abc123 set app/DATABASE_URL set app/API_KEY # List projects or keys $ pock vault ls app $ pock vault ls app API_KEY DATABASE_URL # Read secrets (prompts for passphrase) $ pock vault get app DATABASE_URL=postgres://db/prod API_KEY=abc123 $ pock vault get app API_KEY abc123 # Inject secrets into a process (never written to disk) $ pock run -p app -- printenv DATABASE_URL postgres://db/prod
pock run -p <project> -- <cmd> injects the project's secrets as environment variables into the child process. They are never written to disk or exposed in the shell's history.
WebAuthn PRF
Touch ID / Passkeys
When you register a passkey - Face ID, Touch ID, Windows Hello, or a hardware security key - on the vault unlock page, Pock uses the WebAuthn PRF extension to derive a deterministic key from your authenticator. That key is never sent to the server - it's derived on-device, used to unwrap your Account Unlock Key, then discarded.
The PRF output never leaves the authenticator. Pock's server sees only the wrapped Account Unlock Key blob.
A server breach cannot recover vault plaintext. The key material required to decrypt lives only on your device.
If biometrics are unavailable, unlock with your passphrase + Secret Key or the printed recovery code.
under the hood
Crypto core
One audited Rust core (pock-core) compiled to native and WebAssembly powers every surface - CLI and web are byte-compatible.
Key derivation - 2SKD
Argon2id with a two-secret derivation (2SKD): your passphrase is combined with a machine-generated 128-bit Secret Key. A server breach cannot brute-force vault ciphertext without the Secret Key, and a stolen Secret Key is useless without the passphrase.
Ciphers
- X-Wing (X25519 + ML-KEM-768)default
Post-quantum hybrid KEM. Secure if either classical (X25519) or post-quantum (ML-KEM-768) stays unbroken. Used for multi-recipient and asymmetric envelope encryption.
- XChaCha20-Poly1305
AEAD with a 24-byte random nonce. Constant-time, no AES-NI required. Used for symmetric encryption and as the inner AEAD inside envelope encryption.
- Ed25519
Signatures and identity. Used for CLI token signing and authenticating CLI-to-server requests.
Envelope encryption
HPKE-style: KEM encapsulate produces a shared secret - HKDF expands it to a per-item data key - XChaCha20-Poly1305 encrypts the payload. The data key is wrapped to each recipient's public key so multi-recipient shares require only one ciphertext copy.
The server stores ciphertext and metadata. It never holds plaintext, passphrase, or any key material required to decrypt.
X-Wing is the default for sharing. Even if a quantum computer breaks X25519 today, ML-KEM-768 keeps the ciphertext secure.
pock-core is open-source Rust. The same binary is used by the CLI and compiled to WASM for the browser - one target to audit.
portability & compromise recovery
Backup & rotation
Two independent safety nets live in account menu → Vault: an encrypted file backup, and self-service key rotation. Both run entirely on your device.
Encrypted backup (.pockvault)
Export decrypts every secret you can read, serializes them, and seals the result under a passphrase you choose. Argon2id (46 MiB, memory-hard) derives the key and XChaCha20-Poly1305 seals the body. The file is deliberately standalone: it is not bound to your Secret Key or account, so it restores even if you lose everything else. The trade-off is that the backup passphrase is the only thing protecting it, so use a long, unique one.
.pockvault layout ┌───────────┬──────────┬─────────────────┬────────────────────────┐ │ MAGIC (8) │ salt(16) │ argon2 params │ XChaCha20-Poly1305 body │ │ POCKVLT\x01│ │ m_kib,t,p (12) │ nonce(24) ‖ ct ‖ tag │ └───────────┴──────────┴─────────────────┴────────────────────────┘ Import re-derives the key; the auth tag rejects a wrong passphrase or any tampering (no partial decrypt).
Key rotation
Change passphrase, Rotate Secret Key, and Regenerate recovery code are cheap: they re-wrap your account key (AUK) under the new factor, so no secrets are re-encrypted. Rotated values are shown once; save them.
Rotate identity keys is the deep option for a suspected compromise: a fresh keypair is minted and every secret is re-encrypted to it in one atomic operation. Old-key artifacts (item history, trash) are cleared because they can't be carried across, and team secrets are re-keyed separately by a team admin. Unlock protected namespaces first, or rotation aborts before changing anything.
A plaintext JSON export is also available for migrating to another tool. Treat that file like any password-manager export, since it is unencrypted.
commands
CLI reference
All commands accept --help for full flag listings.
pock login- Device-flow authentication. Opens a browser tab and waits for approval. Stores a token under
~/.pock. pock logout- Sign out and delete the local token.
pock whoami- Print the authenticated email, org, and token expiry.
pock share <file…> [flags]- Encrypt and upload one or more files. See the Secure sharing section for the full flag list.
pock receive <id> <key> [--out DIR]- Fetch and decrypt a share by ID and key.
pock vault init- Create a new vault. Generates your Secret Key and recovery code (shown once).
pock vault set <project> KEY=VALUE…- Write one or more secrets into a project, encrypted to your key.
pock vault get <project> [KEY]- Decrypt and print secrets for a project, or a single key. Prompts for passphrase.
pock vault ls [project]- List projects, or the keys within a project.
pock vault rm <project> <key>- Delete a secret. Use
pock vault mvto rename or move one (--to-projectto move across namespaces). pock vault ns rename|rm- Rename a namespace and its whole subtree, or delete a namespace and its contents.
pock vault env ls|create|add|export- Manage environments.
exportdecrypts the referenced secrets to a.env(stdout or--file). pock vault import <file>- Import a
.envas standalone secrets plus an environment (--env,--folder). pock gen [-l N | -p -w N]- Generate a strong password or passphrase.
pock vault link- Attach a new machine to your existing vault (Secret Key + passphrase, once). The device-setup / recovery flow.
pock vault machine create <scope> [--github owner/repo]- Mint a scoped machine key for CI (re-encrypts
<scope>to a new keypair; decrypts only that subtree).--githubwrites it straight to a repo's secrets. Alsomachine ls/machine rm. pock run -p <project> -- <cmd>- Inject a project's secrets as env vars into a child process (item names become var names). Never written to disk.
pock run -e <environment> -- <cmd>- Inject an environment's secrets (export keys become var names).
env: POCK_TOKEN / POCK_MACHINE_KEY / POCK_SECRET_KEY / POCK_PASSPHRASE- Drive Pock non-interactively in CI - auth with
POCK_TOKEN, unlock with a scopedPOCK_MACHINE_KEY(best) or yourPOCK_SECRET_KEY+POCK_PASSPHRASE. See Guides. pock version- Print the running build and check for a newer release.
pock update- Upgrade the binary in place under
~/.pock/bin.
staying current
Maintenance
pock version prints the build you're running and checks for a newer release. pock update upgrades the binary in place under ~/.pock/bin.
$ pock version pock 0.5.0 (darwin/arm64) ↑ 0.5.1 available - run `pock update` $ pock update ↓ updating 0.5.0 → 0.5.1… ✓ pock is now 0.5.1