
개발자를 위한 안전하고 일시적인 비밀 공유.
개발자를 위한 안전하고 일회성인 비밀 공유.
Slack에 비밀을 붙여넣는 것을 중단하세요. enseal은 안전하지 않은 경로보다 안전한 경로를 더 빠르게 만듭니다 — 암호화된 일회용 채널을 통해 .env 파일과 비밀을 명령 하나로, 설정 없이 공유하세요.```bash
$ enseal share .env Share code: 7-guitarist-revenge Secrets: 14 variables (staging) Expires: on first receive
$ enseal receive 7-guitarist-revenge ok: 14 secrets written to .env
## 설치
### crates.io에서```bash
cargo install enseal
git clone https://github.com/FlerAlex/enseal.git cd enseal cargo build --release
### 사전 빌드된 바이너리
Linux (x86_64, aarch64), macOS (Intel, Apple Silicon), Windows용 [GitHub Releases](https://github.com/FlerAlex/enseal/releases)에서 다운로드하세요.
## 빠른 시작
### 익명 모드 (설정 불필요)
일회용 코드를 사용하여 비밀을 공유하세요. 키도, 계정도 필요 없습니다 — 즉시 작동합니다.```bash
# terminal 1 (sender)
enseal share .env
Share code: 7-guitarist-revenge
Secrets: 14 variables
Expires: on first receive
# terminal 2 (recipient) — enter the code
enseal receive 7-guitarist-revenge
ok: 14 secrets written to .env
단일 비밀에도 작동합니다:```bash
echo "my-api-token" | enseal share --label "API key" Share code: 4-orbital-hammock
enseal receive 4-orbital-hammock my-api-token
두 터미널이 동시에 열려 있어야 합니다 — 보내는 쪽은 받는 쪽이 연결될 때까지 기다립니다.
### 신원 모드 (키 기반, 코드 없음)
키 신뢰가 확립된 팀을 위한 기능입니다. 이름으로 암호화하며, 추가 조정이 필요하지 않습니다.```bash
# one-time setup
enseal keys init
enseal keys export > my-key.pub # share this with teammates
enseal keys import teammate-key.pub # import theirs
# sender encrypts to recipient by name
enseal share .env --to sarah
# or push through the public relay (no codes at all)
enseal share .env --to sarah --relay wss://relay.enseal.dev
# or produce an encrypted file (no network)
enseal share .env --to sarah --output ./drop/
enseal inject 7-guitarist-revenge -- npm start
enseal inject --listen --relay wss://relay.enseal.dev -- docker compose up
enseal inject ./staging.env.age -- python manage.py runserver
비밀은 자식 프로세스의 메모리에만 존재합니다. 프로세스가 종료되면 사라집니다.
## 기능
### 세 가지 공유 모드
**익명 모드** (기본값) — wormhole 기반, 설정 불필요. 사람이 읽을 수 있는 코드만 있으면 됩니다. SPAKE2 상호 인증이 MITM 공격을 방지합니다.```bash
enseal share .env # generates wormhole code
enseal receive 7-guitarist-revenge # uses code
With --relay, anonymous mode bypasses wormhole and uses the enseal relay transport instead. Both sides must use the same relay:```bash
enseal share .env --relay ws://relay.internal:4443 # generates channel code
enseal receive 3421-amber-frost --relay ws://relay.internal:4443
**비동기 업로드 (`--upload`)** — 발신자 전용. 로컬에서 암호화하여 [burnurl.dev](https://burnurl.dev)에 게시하며, 수신자가 브라우저에서 열 수 있는 자체 파괴 URL을 반환합니다. 수신자 측에서 CLI가 필요하지 않습니다.```bash
enseal share .env --upload
# Secret URL: https://burnurl.dev/s/a3f9c2e1...
# Expires: 2026-03-08 19:42:00 UTC (24h)
# Reads: 1 (self-destructs on first open)
수신자는 브라우저에서 URL을 열 수 있습니다 — enseal 설치가 필요하지 않습니다. --passphrase를 추가하여 업로드 전에 클라이언트 측에서 암호화합니다 (서버는 암호문만 확인합니다):```bash
enseal share .env --upload --passphrase # prompts for passphrase
enseal share .env --upload --ttl 4 # 4-hour TTL (max 24)
API 접근은 burnurl.dev에서 Pro 또는 Team 플랜이 필요합니다. `BURNURL_API_KEY`를 키로 설정하세요. 자체 호스팅 인스턴스의 기본 URL을 재정의하려면: `BURNURL_URL=https://burnurl.internal`.
**Identity 모드** — 알려진 팀원을 위한 공개 키 암호화. 이름으로 암호화합니다.```bash
enseal keys init # one-time setup
enseal share .env --to sarah # encrypt to sarah's public key
Identity mode는 세 가지 전송 옵션을 지원합니다:```bash
enseal share .env --to sarah
enseal share .env --to sarah --relay wss://relay.enseal.dev
enseal share .env --to sarah --output ./drop/
### 유연한 입력
enseal은 여러 소스로부터 비밀을 수락합니다:```bash
# .env file (default)
enseal share .env
enseal share staging.env
# environment profile
enseal share --env staging # resolves to .env.staging
# pipe from stdin
echo "sk_live_abc123" | enseal share
cat secrets.env | enseal share
pass show stripe/key | enseal share --to sarah
# inline (careful — visible in shell history)
enseal share --secret "API_KEY=sk_live_abc123"
# wrap raw string as KEY=VALUE
echo "sk_live_abc123" | enseal share --as STRIPE_KEY
${VAR} 참조는 전송 전에 해결되므로 수신자는 완전히 확장된 값을 받습니다:```env
DB_HOST=postgres.internal
DB_PORT=5432
DATABASE_URL=postgres://user:pass@${DB_HOST}:${DB_PORT}/myapp
Supports `${VAR:-default}` fallback syntax. Circular and forward references are detected and rejected. Use `--no-interpolate` to send raw `${VAR}` syntax.
### 필터링
전송할 변수를 제어합니다:```bash
# exclude public/non-secret vars
enseal share .env --exclude "^PUBLIC_|^NEXT_PUBLIC_"
# send only matching vars
enseal share .env --include "^DB_|^API_"
# skip .env parsing entirely (send raw file)
enseal share .env --no-filter
출력이 전송된 내용에 맞게 조정됩니다:```bash
enseal receive CODE ok: 14 secrets written to .env
enseal receive CODE --output staging.env
enseal receive CODE sk_live_abc123
enseal receive CODE --clipboard ok: copied to clipboard
enseal receive CODE --no-write
enseal receive ./staging.env.age ok: signature verified, file decrypted ok: 14 secrets written to .env
### Inject
비밀을 수신하여 자식 프로세스에 환경 변수로 직접 주입합니다. 비밀은 파일 시스템에 닿지 않습니다.```bash
# anonymous mode: inject via wormhole code
enseal inject 7-guitarist-revenge -- npm start
# identity mode: listen for incoming transfer on relay
enseal inject --listen --relay wss://relay.enseal.dev -- docker compose up
# from encrypted file drop
enseal inject ./staging.env.age -- python manage.py runserver
--listen을 사용하면 수신자가 릴레이에 연결하여 대기합니다. 송신자는 enseal share .env --to alex --relay wss://relay.enseal.dev로 푸시합니다 — 코드 교환이 없고, 조정이 전혀 필요하지 않습니다.
공유 외에도, enseal은 완전한 .env 보안 툴킷입니다:```bash
enseal check error: missing from .env (present in .env.example): JWT_SECRET, REDIS_URL
enseal diff .env.development .env.staging
enseal redact .env DATABASE_URL= API_KEY= PORT=
enseal validate .env error: missing required: JWT_SECRET error: PORT value "abc" is not an integer ok: 11/14 variables passed validation
enseal template .env
### 저장 데이터 암호화
안전한 git 저장을 위해 age 암호화를 사용하여 `.env` 파일을 암호화합니다:```bash
# whole-file encryption
enseal encrypt .env
ok: .env encrypted in-place (14 variables, age key)
enseal decrypt .env
# per-variable: keys visible for diffing, values encrypted
enseal encrypt .env --per-var
# DB_HOST=ENC[age:abc123...]
# DB_PORT=ENC[age:def456...]
# multi-recipient: anyone on the team can decrypt
enseal encrypt .env --to sarah --to alex
enseal keys init
enseal keys export > my-key.pub
enseal keys import sarah.pub
enseal keys list
enseal keys fingerprint
enseal keys remove [email protected]
enseal keys alias sarah [email protected]
enseal keys group create backend-team enseal keys group add backend-team sarah enseal keys group add backend-team alex enseal keys group list backend-team enseal share .env --to backend-team
enseal keys group delete backend-team
### 공용 릴레이
무료 공용 릴레이가 `wss://relay.enseal.dev`에서 제공됩니다. 빠른 테스트나 개인 릴레이가 필요하지 않을 때 사용하세요.```bash
# check relay health
curl https://relay.enseal.dev/health
# use it for identity-mode transfers
enseal share .env --to sarah --relay wss://relay.enseal.dev
enseal inject --listen --relay wss://relay.enseal.dev -- npm start
# or set it globally
export ENSEAL_RELAY=wss://relay.enseal.dev
enseal keys init
enseal keys export > /tmp/mykey.pub enseal keys import /tmp/mykey.pub
enseal share --secret "TEST=works" --to mykey --output /tmp/ enseal receive /tmp/mykey.env.age
enseal inject --listen --relay wss://relay.enseal.dev -- env | grep TEST
enseal share --secret "TEST=relay_works" --to mykey --relay wss://relay.enseal.dev
### 자체 호스팅 릴레이
네트워크 내 모든 것을 유지하세요. 릴레이는 상태 비저장(stateless)입니다 — 오직 암호문만 볼 수 있습니다.```bash
# Docker (one command)
docker run -d -p 4443:4443 enseal/relay
# Or as a binary
enseal serve --port 4443
# Check relay health
curl http://localhost:4443/health
enseal serve는 일반 WebSocket (ws://)을 사용합니다. TLS를 사용하려면 리버스 프록시(Caddy, nginx)를 앞에 두고 wss://로 연결하세요.
--relay가 설정되면 모든 모드가 릴레이를 통해 라우팅됩니다:```bash
enseal share .env --relay ws://relay.internal:4443
enseal receive 3421-amber-frost --relay ws://relay.internal:4443
export ENSEAL_RELAY=ws://relay.internal:4443 enseal share .env
자체 호스팅 릴레이를 사용한 Identity mode는 완전히 코드가 필요 없습니다:```bash
# receiver listens on the relay
enseal inject --listen --relay ws://relay.internal:4443 -- npm start
# sender pushes directly — no code generated
enseal share .env --to alex --relay ws://relay.internal:4443
ok: pushed to alex
프로젝트 루트에 있는 .enseal.toml에 규칙을 정의하세요:```toml
[schema]
required = ["DATABASE_URL", "API_KEY", "JWT_SECRET"]
[schema.rules.DATABASE_URL] pattern = "^postgres://" description = "PostgreSQL connection string"
[schema.rules.PORT] type = "integer" range = [1024, 65535]
[schema.rules.API_KEY] min_length = 32
그런 다음 검증하십시오:```bash
enseal validate .env
검증은 .env 파일을 수신할 때 자동으로 실행되어, 혼란을 초래하기 전에 잘못된 구성을 잡아냅니다.
enseal share --env staging # shares .env.staging enseal validate --env production # validates .env.production enseal diff .env.development .env.production
## 작동 방식
### 익명 모드
**웜홀 (기본값, `--relay` 없음):**
1. 발신자가 `age`로 페이로드 암호화
2. SPAKE2 키 교환을 통해 공개 웜홀 중계기를 경유하여 공유 비밀 설정
3. 암호화된 페이로드가 중계기를 통과
4. 수신자가 협상된 키로 복호화
5. 채널 소멸 — 단일 사용, 시간 제한
중계기는 평문을 볼 수 없습니다. 웜홀 코드는 상호 인증을 제공합니다.
**Enseal 중계기 (`--relay`):**
1. 발신자가 `age`로 페이로드를 암호화하고 생성된 채널 코드와 함께 enseal 중계기로 전송
2. 수신자가 동일한 코드로 같은 중계기에 연결하고 페이로드 수신
3. 최초 수신 시 채널 소모
이 모드에서는 SPAKE2가 없습니다. 채널 코드가 유일한 자격 증명입니다.
### 비동기 업로드 (`--upload`)
1. 발신자가 페이로드를 `Envelope`(JSON, SHA-256 무결성 검사)로 직렬화
2. 선택적으로 age scrypt 패스프레이즈를 사용하여 클라이언트 측에서 암호화 (`--passphrase`)
3. HTTPS를 통해 페이로드를 `burnurl.dev/api/secret`에 POST
4. burnurl.dev가 저장 시 서버 측 AES-256-GCM으로 저장하고 자동 삭제 URL 반환
5. URL은 설정된 TTL(무료 티어에서 최대 24시간) 동안 유효하며, 단일 읽기 전용
발신자가 URL을 공유합니다. 수신자는 모든 브라우저에서 URL을 열 수 있으며 enseal이 필요하지 않습니다. `--passphrase`를 사용하면 패스프레이즈를 별도로 공유해야 하며 서버는 평문을 볼 수 없습니다.
**티어:** API 액세스에는 burnurl.dev의 Pro 또는 Team 플랜이 필요합니다. `BURNURL_API_KEY`를 키로 설정하십시오. 무료 티어에는 API 액세스가 없습니다.
`BURNURL_URL`을 재정의하여 자체 호스팅 burnurl 인스턴스를 가리킬 수 있습니다.
### 신원 모드 (공개 키)
1. 발신자가 수신자의 `age` 공개 키로 암호화
2. 발신자가 자신의 `ed25519` 키로 서명
3. 페이로드가 중계기, 파일 드롭 또는 웜홀을 통해 전송
4. 수신자가 자신의 개인 키로 복호화
5. 수신자가 발신자의 서명 확인
신뢰는 가져온 키에 기반합니다.
**신원 모드의 전송 옵션:**
| 전송 방식 | 플래그 | 작동 방식 |
|---|---|---|
| 웜홀 (기본값) | `--to sarah` | 코드 생성, 서명이 포함된 익명 모드와 유사 |
| 중계기 푸시 | `--to sarah --relay URL` | 수신자의 결정적 채널로 푸시, 코드 없음 |
| 파일 드롭 | `--to sarah --output ./dir/` | 암호화된 `.env.age` 파일 생성, 네트워크 없음 |
중계기 푸시를 사용하면 수신자가 `enseal inject --listen --relay URL -- cmd`로 수신 대기하거나 `enseal receive ./file.env.age`로 파일 드롭을 수신합니다.
## 보안 모델
**보호 대상:**
- 전송 중 비밀 (암호화된 채널)
- Slack/이메일 기록 내 비밀 (일시적, 지속성 없음)
- MITM 공격 (SPAKE2 / 공개 키 인증)
- 악성 중계기 (종단 간 암호화, 중계기는 암호문만 봄)
- 발신자 사칭 (신원 모드: ed25519 서명)
- 디스크 상의 비밀 (주입 모드: 프로세스 메모리만)
- Git 내 비밀 (암호화: 저장 시 암호화)
**보호되지 않는 대상:**
- 손상된 엔드포인트 (기기가 장악되면 아무것도 도움이 되지 않음)
- 키 배포 (가져온 키를 신뢰함 — PKI, CA 없음)
## 설정
프로젝트 루트에 선택적 `.enseal.toml`:```toml
[defaults]
relay = "wss://relay.enseal.dev" # public relay (identity mode)
# relay = "ws://relay.internal:4443" # self-hosted without TLS
# relay = "wss://relay.internal:4443" # self-hosted with TLS reverse proxy
[filter]
exclude = ["^PUBLIC_", "^NEXT_PUBLIC_", "^REACT_APP_"]
[identity]
default_recipient = "devops-team"
[schema]
required = ["DATABASE_URL", "API_KEY", "JWT_SECRET"]
CORE
enseal share [] Send secrets (file, pipe, or --secret)
enseal receive [<code|file>] Receive secrets
enseal inject [] -- Inject secrets into a process
enseal keys Manage identity keys and aliases
enseal serve Run self-hosted relay server
.ENV TOOLKIT enseal check [file] Verify .env has all vars from .env.example enseal diff Compare .env files (keys only) enseal redact Replace values with enseal validate Validate against schema rules enseal template Generate .env.example with type hints
ENCRYPTION enseal encrypt Encrypt .env for git storage enseal decrypt Decrypt an encrypted .env
### `share` 플래그```
--to <name> Identity mode: encrypt to recipient (alias, group, or identity)
--output <dir> File drop: write encrypted file (identity mode, no network)
--upload Post to burnurl.dev (async, browser-readable, no CLI on recipient side)
--ttl <hours> Secret TTL for --upload (1-24, default: 24)
--passphrase Encrypt client-side before --upload (prompts; server never sees plaintext)
--secret <value> Inline secret (raw string or KEY=VALUE)
--label <name> Human label for raw/piped secrets
--as <KEY> Wrap raw input as KEY=<value>
--relay <url> Route through relay server. Anonymous mode: uses enseal relay transport
(generates channel code, bypasses wormhole). Identity mode: push to
recipient's channel. Also: ENSEAL_RELAY env var.
--env <profile> Environment profile (resolves to .env.<profile>)
--exclude <pattern> Regex to exclude vars
--include <pattern> Regex to include only matching vars
--no-filter Send raw file, skip .env parsing
--no-interpolate Don't resolve ${VAR} references before sending
--words <n> Words in wormhole code (2-5, default: 2). Wormhole mode only (no --relay).
--quiet / -q Minimal output
receive 플래그```--output Write to specific file --clipboard Copy to clipboard instead of stdout/file --no-write Print to stdout even for .env payloads --relay Use specific relay server --quiet / -q Minimal output
### `inject` 플래그```
--listen Listen for incoming identity-mode transfer (requires --relay)
--relay <url> Use specific relay server (also: ENSEAL_RELAY)
--quiet / -q Minimal output
keys 서브커맨드```enseal keys init Generate your keypair enseal keys export Print your public key bundle enseal keys import Import a colleague's public key enseal keys list Show all trusted keys and aliases enseal keys remove Remove a trusted key enseal keys fingerprint Show your key fingerprint enseal keys alias Map short name to identity enseal keys group create Create a named group enseal keys group add Add identity to group enseal keys group remove Remove identity from group enseal keys group list [name] List groups or group members enseal keys group delete Delete a group
### `serve` 플래그```
--port <port> Listen port (default: 4443)
--bind <addr> Bind address (default: 0.0.0.0)
--max-mailboxes <n> Max concurrent channels (default: 100)
--channel-ttl <seconds> Idle channel lifetime (default: 300)
--max-payload <bytes> Max WebSocket message size (default: 1048576)
--rate-limit <n> Max connections per minute per IP (default: 10)
--health Print server health check and exit
encrypt / decrypt 플래그```--per-var Per-variable encryption (keys visible, values encrypted) --to Encrypt to specific recipients (multi-key)
### 전역 플래그```
--verbose / -v Debug output (never prints secret values)
--quiet / -q Minimal output (for scripting)
| enseal | Slack DM | 1Password Share | dotenvx | croc | |
|---|---|---|---|---|---|
| 제로 설정 | 예 | 예 | 아니오 | 아니오 | 예 |
| 종단간 암호화 | 예 | 아니오 | 예 | 해당 없음 | 예 |
| 일시적 (기록 없음) | 예 | 아니오 | 예 | 해당 없음 | 예 |
| .env 인식 | 예 | 아니오 | 아니오 | 예 | 아니오 |
| 프로세스 주입 | 예 | 아니오 | 아니오 | 예 | 아니오 |
| 스키마 검증 | 예 | 아니오 | 아니오 | 아니오 | 아니오 |
| 저장 시 암호화 | 예 | 해당 없음 | 해당 없음 | 예 | 아니오 |
| 자체 호스팅 릴레이 | 예 | 아니오 | 아니오 | 해당 없음 | 예 |
| 원시 문자열/파이프 지원 | 예 | 예 | 아니오 | 아니오 | 예 |
--to 플래그 (완료)--upload) (현재)MIT