
مشاركة آمنة ومؤقتة للأسرار للمطورين.
مشاركة سرية مؤقتة وآمنة للمطورين.
توقف عن لصق الأسرار في 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
### الملفات الثنائية المبنية مسبقاً
قم بالتنزيل من [GitHub Releases](https://github.com/FlerAlex/enseal/releases) لأنظمة Linux (x86_64, aarch64)، macOS (Intel, Apple Silicon)، وWindows.
## بداية سريعة
### الوضع المجهول (بدون إعداد)
شارك الأسرار باستخدام رمز لمرة واحدة. لا مفاتيح، لا حسابات — يعمل فوراً.```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
يجب أن يكون كلا الطرفين مفتوحين في نفس الوقت — ينتظر المرسل حتى يتصل المستلم.
### Identity mode (key-based, no codes)
للفرق التي لديها ثقة مفاتيح راسخة. شفر إلى اسم، لا حاجة للتنسيق.```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
الأسرار توجد فقط في ذاكرة العملية الفرعية. عند خروجها، تختفي.
## الميزات
### ثلاثة أوضاع للمشاركة
**الوضع المجهول** (الافتراضي) — قائم على ثقب دودي، بدون إعداد. كل ما تحتاجه هو رمز مفهوم للبشر. المصادقة المتبادلة SPAKE2 تمنع هجمات الوسيط (MITM).```bash
enseal share .env # generates wormhole code
enseal receive 7-guitarist-revenge # uses code
مع --relay، يتجاوز الوضع المجهول wormhole ويستخدم نقل الترحيل enseal بدلاً من ذلك. يجب على كلا الجانبين استخدام نفس الترحيل:```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)، ليعيد رابطًا ذاتي التدمير يفتحه المستلم في المتصفح. لا حاجة لـ 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)
يفتح المستلم الرابط في أي متصفح — لا حاجة لتثبيت enseal. أضف --passphrase لتشفير من جهة العميل قبل الرفع (يرى الخادم نصًا مشفرًا فقط):```bash
enseal share .env --upload --passphrase # prompts for passphrase
enseal share .env --upload --ttl 4 # 4-hour TTL (max 24)
يتطلب الوصول إلى واجهة برمجة التطبيقات (API) خطة Pro أو Team على burnurl.dev. اضبط `BURNURL_API_KEY` على مفتاحك. تجاوز عنوان URL الأساسي للنسخ المستضافة ذاتيًا: `BURNURL_URL=https://burnurl.internal`.
**وضع الهوية** — تشفير بالمفتاح العام لأعضاء الفريق المعروفين. تشفير إلى اسم.```bash
enseal keys init # one-time setup
enseal share .env --to sarah # encrypt to sarah's public key
وضع الهوية يدعم ثلاثة خيارات للنقل:```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} تشير مراجع ${VAR} إلى القيم الموسعة بالكامل قبل الإرسال، لذا يتلقى المستلمون تلك القيم:```env
DB_HOST=postgres.internal
DB_PORT=5432
DATABASE_URL=postgres://user:pass@${DB_HOST}:${DB_PORT}/myapp
يدعم صيغة الاسترجاع `${VAR:-default}`. يتم اكتشاف المراجع الدائرية والمستقبلية ورفضها. استخدم `--no-interpolate` لإرسال صيغة `${VAR}` الخام.
### التصفية
التحكم في أي المتغيرات يتم إرسالها:```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
### تشفير البيانات في وضع السكون
قم بتشفير ملفات `.env` للتخزين الآمن في git باستخدام تشفير age:```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
### المرحّل المستضاف ذاتيًا
احتفظ بكل شيء داخل شبكتك. المرحّل عديم الحالة — فهو يرى فقط النص المشفر.```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
وضع الهوية مع مرحّل مستضاف ذاتيًا هو بدون كود بالكامل:```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
## كيف يعمل
### الوضع المجهول
**Wormhole (افتراضي، بدون `--relay`):**
1. يقوم المرسل بتشفير الحمولة باستخدام `age`
2. تبادل مفتاح SPAKE2 ينشئ سرًا مشتركًا عبر مرحّل wormhole العام
3. تنتقل الحمولة المشفّرة عبر المرحّل
4. يقوم المستلم بفك التشفير باستخدام المفتاح المتفاوض عليه
5. يتم تدمير القناة — استخدام واحد، محدود زمنيًا
لا يرى المرحّل النص العادي. يوفر رمز wormhole المصادقة المتبادلة.
**مرحّل Enseal (`--relay`):**
1. يقوم المرسل بتشفير الحمولة باستخدام `age` وإرسالها إلى مرحّل enseal تحت رمز قناة مولّد
2. يتصل المستلم بنفس المرحّل بنفس الرمز ويتلقى الحمولة
3. يتم استهلاك القناة عند أول استلام
لا يوجد SPAKE2 في هذا الوضع — رمز القناة هو المُعتمد الوحيد.
### الرفع غير المتزامن (`--upload`)
1. يقوم المرسل بتسلسل الحمولة إلى `Envelope` (JSON، التحقق من سلامة SHA-256)
2. اختياريًا يقوم بتشفيرها من جهة العميل باستخدام عبارة مرور age scrypt (`--passphrase`)
3. يُرسل الحمولة عبر POST إلى `burnurl.dev/api/secret` عبر HTTPS
4. يخزنها burnurl.dev مع تشفير AES-256-GCM من جانب الخادم ويعيد رابط تدمير ذاتي
5. الرابط صالح لمدة TTL المكوّنة (حتى 24 ساعة في الطبقة المجانية)، قراءة واحدة فقط
يشارك المرسل الرابط. يفتحه المستلم في أي متصفح — لا حاجة لـ enseal. مع `--passphrase`، يجب مشاركة عبارة المرور بشكل منفصل؛ لا يرى الخادم النص العادي أبدًا.
**الطبقات:** يتطلب الوصول إلى API خطة Pro أو Team على burnurl.dev. قم بتعيين `BURNURL_API_KEY` إلى مفتاحك — الطبقة المجانية ليس لديها وصول API.
قم بتجاوز `BURNURL_URL` للإشارة إلى مثيل burnurl مستضاف ذاتيًا.
### وضع الهوية (المفتاح العام)
1. يقوم المرسل بتشفير البيانات باستخدام المفتاح العام `age` للمستلم
2. يقوم المرسل بالتوقيع باستخدام مفتاح `ed25519` الخاص به
3. تنتقل الحمولة عبر مرحّل، أو إسقاط ملف، أو wormhole
4. يقوم المستلم بفك التشفير باستخدام مفتاحه الخاص
5. يتحقق المستلم من توقيع المرسل
تعتمد الثقة على المفاتيح التي قمت باستيرادها.
**خيارات النقل في وضع الهوية:**
| النقل | العلامة | كيف يعمل |
|---|---|---|
| Wormhole (افتراضي) | `--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