The problem with sharing secrets in DevOps
Every DevOps engineer and sysadmin has been in this situation: you need to share a database connection string, an API key, or a root password with someone on your team. Right now.
The usual options are all bad:
- Slack / Teams: Persisted in message history, indexed, searchable. One compromised account exposes every secret ever shared.
- Email: Stored in multiple mailboxes, backed up to archives, often unencrypted at rest.
- Shared docs / wikis: Credentials rot in Confluence pages that nobody remembers to update or delete.
- Verbal / phone: Secure, but try dictating
xK9#mP2$vL7@nQ4over a call.
Secret managers like Vault and AWS Secrets Manager solve the storage problem, but not the ad-hoc sharing problem. When you are onboarding a contractor, debugging a production issue at 2 AM, or rotating credentials during an incident, you need something faster.
One-time links from the terminal
The 1time CLI lets you create encrypted, self-destructing links directly from your terminal:
$ npm install -g @1time/cli
$ printf '%s' "$DATABASE_URL" | 1time send
https://1time.io/v/#eyJpZCI6ImFiYzEyMyIsImtleSI6...That is it. You get a one-time link. Send it to your colleague over whatever channel you want — Slack, email, SMS. Once they open it, the secret is decrypted in their browser and permanently deleted from the server. If nobody opens it, it expires automatically.
How the encryption works
The CLI uses the same encryption protocol as the 1time.io web app:
- A random key is generated locally on your machine
- Your secret is encrypted with AES-256-GCM using a key derived via HKDF-SHA256
- Only the encrypted ciphertext is sent to the server
- The decryption key lives in the URL fragment (
#), which is never sent to the server
The server stores an encrypted blob it cannot decrypt. Even with full database access and server compromise, your secrets remain unreadable. This is zero-knowledge architecture — the same principle behind end-to-end encrypted messaging apps.
Real-world workflows
Pipe from any command
The CLI reads from stdin, so you can pipe output from any command:
# Share an environment variable
printf '%s' "$DATABASE_URL" | 1time send
# Share output from a secrets manager
vault kv get -field=password secret/prod/db | 1time send
# Share a generated password
openssl rand -base64 32 | 1time sendRead a secret someone sent you
$ 1time read 'https://1time.io/v/#eyJpZCI6...'
postgres://admin:s3cret@db.prod.internal:5432/myappThe secret is decrypted locally and printed to stdout. You can pipe it into another command, write it to a file, or use it in a script.
Self-hosted instances
If your team runs a self-hosted 1time instance, point the CLI at your own server:
printf 'secret' | 1time send --host https://secrets.yourcompany.comData never leaves your infrastructure. The CLI enforces HTTPS for remote hosts and only allows plain HTTP for loopback addresses during local development.
Security considerations
The CLI is designed for the security-conscious:
- Prefer
stdinover arguments: Useprintf 'secret' | 1time sendinstead of1time send 'secret'. Command-line arguments are visible inpsoutput and shell history. - Environment variable input: For CI/CD pipelines, you can also use
1TIME_SECRETas an environment variable. - No config files: The CLI does not write any files to disk. No credentials stored, no state files, no logs.
- Minimal dependencies: Uses Node.js built-in
cryptomodule. No third-party encryption libraries.
Compared to alternatives
There are other ways to share one-time secrets. Here is how the 1time CLI compares:
- Yopass CLI: Also end-to-end encrypted with a CLI. Requires a Go toolchain to install or pre-built binaries. 1time installs with a single
npm installand requires only Node.js, which most DevOps teams already have. - Password Pusher: Has a CLI, but the server-side encryption means the server can read your secrets. 1time uses client-side encryption — the server never sees plaintext.
- OneTimeSecret: No official CLI. Server-side encryption only. Ruby stack is heavier for self-hosting.
- GPG-encrypted email: Secure, but requires key exchange and is painful for one-off credential sharing.
- age / sops: Excellent for encrypting files and secrets at rest, but not designed for one-time sharing links.
Getting started
npm install -g @1time/cliRequires Node.js 20 or later. The CLI is open source (MIT license) and the full encryption implementation is about 200 lines of JavaScript you can audit yourself.
Or use the web version at 1time.io — same encryption, no install required.