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@nQ4 over 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:

  1. A random key is generated locally on your machine
  2. Your secret is encrypted with AES-256-GCM using a key derived via HKDF-SHA256
  3. Only the encrypted ciphertext is sent to the server
  4. 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 send

Read a secret someone sent you

$ 1time read 'https://1time.io/v/#eyJpZCI6...'
postgres://admin:s3cret@db.prod.internal:5432/myapp

The 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.com

Data 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 stdin over arguments: Use printf 'secret' | 1time send instead of 1time send 'secret'. Command-line arguments are visible in ps output and shell history.
  • Environment variable input: For CI/CD pipelines, you can also use 1TIME_SECRET as 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 crypto module. 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 install and 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/cli

Requires 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.