The CLI Manual
opake is the reference client. Everything the web app does maps back to a command here, and
a few things only the CLI does today: shell completions, the background maintenance daemon,
and the scripting hooks you'd want for pipelines and cron jobs.
Installing #
The CLI is written in Rust. For now it only ships as source; pre-built binaries and a crates.io release are on the roadmap. Needs Rust 1.75 or later and Git.
git clone https://github.com/Opake-at/Opakecd opake && cargo install --path apps/clicargo install drops the binary at ~/.cargo/bin/opake. Confirm with opake --version.
Shell completions #
Every modern shell gets tab-completion for commands, flags, and subcommands. Pick yours:
opake completions bash > ~/.local/share/bash-completion/completions/opakeopake completions zsh > ~/.zfunc/_opakeopake completions fish > ~/.config/fish/completions/opake.fishHow the CLI thinks #
Three concepts orient the rest of this page.
Paths look like file paths: report.pdf, projects/Q4/notes.md, /. Internally Opake
identifies records by AT-URI (at://did:plc:xxx/at.opake.document/yyy), and most commands
accept either — the friendly path when you're at a prompt, the URI when you're piping URIs
around between commands.
Workspaces are a separate namespace from your personal cabinet. A bare opake ls lists
the cabinet; opake ls --workspace family-photos lists that workspace. Every file-touching
command takes the same --workspace flag.
Accounts stack. opake account login adds one; opake account list shows the stack;
--as alice.bsky.social runs a single command against a specific account without flipping
the default. Useful when you keep a personal account and a work account side by side and
don't want to remember which is currently primary.
Two more globals worth knowing up front: -v increases log verbosity (-vv debug, -vvv
trace), and --help works on every subcommand.
1. Signing in #
OAuth through your PDS is the default. The first opake account login on a fresh machine also
generates your identity keys and prints a 24-word seed phrase — write it down before you
close the window. It's the only thing that can bring your identity back if you lose every
device you're signed in on.
opake account login alice.bsky.socialIf your PDS is somewhere other than the Bluesky cluster, point at it:
opake account login alice.example.com --pds https://pds.example.comFor PDSes that don't speak OAuth, fall back to app-password auth:
opake account login alice.example.com --legacyComing back to an existing identity #
Two ways to sign in on a new machine without generating a fresh identity: pair off an existing device, or restore from the seed phrase.
opake pair request # on the new deviceopake pair approve # on the existing devicePairing hands the new device a wrapped copy of your identity keys through your PDS. Both sides delete their half of the handshake as soon as the transfer is complete.
The other way back in is the seed phrase, in case no paired device is available:
opake recover # interactive; prompts for all 24 wordsopake recover -f seed-backup.txtManaging the account stack #
opake account listopake account set-default bob.other.comopake ls --as alice.bsky.social--as accepts a handle or a DID. Handles get resolved fresh on each invocation, so if someone
moved providers recently the CLI still finds them.
2. Files #
opake upload puts a file in your cabinet. Destination paths are optional; omit them and the
file lands at the root.
opake upload report.pdfopake upload report.pdf --dir projects/Q4opake upload report.pdf --description "Quarterly financial summary"opake upload report.pdf --workspace teamReading them back #
opake lsopake ls projects/Q4 -l # long format, sizes + mime typesopake ls --tag financeopake treeopake download report.pdf -o ~/Downloads/opake cat notes.md # decrypts to stdout, pipe-friendlyopake cat is opake download --stdout with a shorter name, and it composes with the rest of
your shell:
opake cat grocery-list.txt | grep -i breadMoving, renaming, deleting #
Rename is a metadata change. Move is structural.
opake metadata rename report.pdf quarterly-report.pdfopake move report.pdf projects/Q4/opake mkdir archiveopake rm old-draft.mdopake rm -r archive/Editing metadata #
Document metadata is the part Opake still lets you see in the clear — locally. Names, tags, and descriptions are encrypted on the wire but rendered in your terminal.
opake metadata show report.pdfopake metadata describe report.pdf "Q4 financial summary"opake metadata tag add report.pdf financeopake metadata tag remove report.pdf draft3. Sharing #
One file, one person #
opake share new secret.pdf bob.bsky.socialOpake resolves the handle, fetches Bob's public key from his PDS, wraps the file's content key against it, and publishes a grant record. Bob sees the file appear in his inbox the next time his client syncs.
opake share list # grants you've issuedopake share inbox # grants issued to youopake share revoke at://did:plc:123/at.opake.grant/tid456Revoking deletes the grant record. It doesn't un-decrypt any copy Bob has already downloaded — that ship sailed the moment he opened the file. What revocation does buy you is: Bob can't re-fetch, can't get future updates, and anyone else browsing his repo won't see the grant.
Grab the URI of a specific grant from opake share list.
A group of people #
Workspaces are shared folders with a shared encryption key. Adding someone to the workspace gives them access to every file in it; removing them doesn't re-encrypt history, but it does cut them off from future changes.
opake workspace create family-photosopake workspace add-member family-photos alice.bsky.socialopake workspace ls -lopake upload vacation.jpg --workspace family-photosopake workspace remove-member family-photos alice.bsky.socialopake workspace leave family-photos4. Looking someone up #
Before you ship a grant to a handle you got over email or Signal, it's sometimes worth verifying who's on the other end:
opake resolve bob.bsky.socialPrints Bob's DID, his PDS, and his X25519 encryption public key. Ask Bob to read his key
fingerprint to you out-of-band; if it matches what opake resolve shows, you've confirmed the
identity the grant will actually target.
5. Background sync #
The daemon runs maintenance tasks that don't need to be interactive: the SSE subscription for live updates, proactive token refresh, and re-encryption passes after a key rotation. You don't strictly need it for day-to-day use — every interactive command triggers the minimum sync it needs before running. The daemon just means you don't eat that latency each time.
opake daemon run # foreground, for systemd / launchd unitsopake daemon list-tasks # what's queued and what's runningopake daemon install # generate + install a launchd or systemd unitopake daemon uninstallopake daemon install picks the right service format for your platform (launchd on macOS,
systemd on Linux) and writes the unit file where the service manager expects it. The service
starts automatically on login.
6. Starting over #
Three escalating levels of clean slate.
opake account logout alice.bsky.socialDrops local session credentials for one account. Your encrypted files stay on your PDS untouched; signing back in picks them right up.
opake rm -r /Empties your cabinet of every document and directory but keeps your identity, keys, and workspace memberships intact. Good for when you want to repopulate from scratch without re-pairing or regenerating anything.
opake purge --dry-runopake purge --forceThe real nuke. Deletes every at.opake.* record from your PDS — files, grants, workspaces,
published encryption key, the lot. Your atproto identity itself survives (that belongs to the
PDS, not Opake), but every trace of Opake having been there is gone. --dry-run lists what
would go without touching anything.