ypcli
CI / agents / team-first CLI for sharing end-to-end-encrypted one-time secrets via yopass
ypcli publishes text and files to a yopass server as end-to-end-encrypted, self-expiring one-time secrets. Encryption happens client-side with OpenPGP — the decryption key never reaches the server.
It is a CI / agents / team-first superset of the official yopass CLI: bearer-token authentication, machine-readable JSON output, strict exit codes, and multiple server profiles — while staying byte-for-byte interoperable with the yopass web frontend (openpgp.js v6).
- Works with locked-down instances. Bearer-token auth (
--token,YPCLI_TOKEN, or a per-profiletoken_command) reachesREQUIRE_AUTH/ OIDC-gated servers non-interactively — the official CLI cannot. - Built for automation.
--jsonon every command and stable exit codes (auth vs not-found vs decrypt failures are distinguishable) make it safe to script in CI and agents. - Multiple servers, one tool. Named profiles target different yopass
instances without repeating
--api/--url; tokens are sourced from a command, never stored in plaintext. - Interoperable and minimal. The crypto is a vendored ~150-line surface over
ProtonMail/go-crypto; interoperability with upstream is proven by a test-only dependency that never links into the shipped binary. - Everywhere. Static, CGO-free binaries for macOS, Linux, and Windows on amd64 and arm64.
# Homebrew (macOS)
brew install dantte-lp/tap/ypcli
# Scoop (Windows)
scoop bucket add dantte-lp https://github.com/dantte-lp/scoop-bucket
scoop install ypcli
# Go
go install github.com/dantte-lp/ypcli/cmd/ypcli@latestPrebuilt archives are on the Releases page.
# Encrypt text from stdin, print a one-time share URL
printf 'my secret' | ypcli send
# Encrypt a file, valid for one day
ypcli send --file ./db.env --expiration 1d
# Receive and decrypt (text to stdout)
ypcli receive 'https://yopass.se/#/s/ID/KEY'
# CI-friendly: machine-readable output
url=$(printf "$PASSWORD" | ypcli send --json --one-time | jq -r .url)graph TB
subgraph ypcli["ypcli binary"]
CLI["cli<br/>cobra commands"]
API["api<br/>HTTP + bearer auth"]
CRY["crypto<br/>OpenPGP (vendored)"]
CFG["config<br/>profiles + token"]
OUT["output<br/>text / json / qr"]
end
USER(["stdin / --file / --text"]) --> CLI
CLI --> CFG
CLI --> CRY
CLI --> API
CLI --> OUT
API -->|"HTTPS + Bearer"| SRV["yopass server<br/>/create /secret /file /config /version"]
style CRY fill:#1a73e8,color:#fff
The random key never leaves the client — it lives only in the URL fragment
(#/…), which browsers never send to the server.
sequenceDiagram
participant U as User / CI
participant Y as ypcli
participant S as yopass server
U->>Y: send (plaintext)
Y->>Y: generate key (crypto/rand)
Y->>S: GET /config (Argon2?)
Y->>Y: OpenPGP encrypt (AES-256 / GCM)
Y->>S: POST /create/secret (ciphertext)
S-->>Y: { id }
Y-->>U: https://…/#/s/{id}/{key}
Full documentation lives in docs/. English is canonical;
a Russian mirror is in docs/ru/.
| # | Document (EN) | RU | Description |
|---|---|---|---|
| 01 | Architecture | ru | Packages, layers, data flow |
| 02 | Installation | ru | Homebrew, Scoop, winget, Go, binaries |
| 03 | Usage | ru | send / receive walkthroughs |
| 04 | CLI Reference | ru | Every command and flag |
| 05 | Configuration | ru | Profiles, precedence, tokens |
| 06 | Automation | ru | CI/agents, JSON, exit codes |
| 07 | Security | ru | Crypto model, interoperability |
| 08 | Development | ru | Build, test, lint, release |
| 09 | MCP server | ru | Expose ypcli to AI agents (Claude/Codex/Gemini) |
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | generic error |
| 2 | usage / bad flags |
| 3 | configuration error |
| 4 | network / timeout |
| 5 | auth failure (401/403) |
| 6 | not found / one-time already consumed (404/410) |
| 7 | decryption / crypto failure |
Repository participation is governed by CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, SUPPORT.md, GOVERNANCE.md, and MAINTAINERS.md.
make verify # build + test (-race) + lint + vuln
make e2e # end-to-end suite: drives the binary against a live yopass containerTesting has three layers: Go unit tests, a byte-level interop gate against
upstream yopass, and a Python end-to-end suite (uv + ruff + ty) that drives
the compiled binary against a live yopass server — see
Development.
MIT © Pavel Lavrukhin