قم بتخزين واسترجاع بيانات الاعتماد الحساسة بشكل آمن باستخدام واجهات برمجة التطبيقات الأصلية لنظام التشغيل لتخزين بيانات الاعتماد.
import { secrets } from "bun";
let githubToken: string | null = await secrets.get({
service: "my-cli-tool",
name: "github-token",
});
if (!githubToken) {
githubToken = prompt("الرجاء إدخال رمز GitHub الخاص بك");
await secrets.set({
service: "my-cli-tool",
name: "github-token",
value: githubToken,
});
console.log("تم تخزين رمز GitHub");
}
const response = await fetch("https://api.github.com/user", {
headers: { Authorization: `token ${githubToken}` },
});
console.log(`تم تسجيل الدخول باسم ${(await response.json()).login}`);نظرة عامة
يوفر Bun.secrets واجهة برمجة تطبيقات متعددة المنصات لإدارة بيانات الاعتماد الحساسة التي تخزنها عادةً أدوات CLI وتطبيقات التطوير في ملفات نصية عادية مثل ~/.npmrc أو ~/.aws/credentials أو ملفات .env. يستخدم:
- macOS: خدمات Keychain
- Linux: libsecret (GNOME Keyring و KWallet وغيرها)
- Windows: مدير بيانات اعتماد Windows
جميع العمليات غير متزامنة وغير محظورة، وتعمل على threadpool الخاص بـ Bun.
NOTE
في المستقبل، قد نضيف خيار `provider` إضافيًا لجعل هذا أفضل لأسرار نشر الإنتاج، لكن اليوم هذه الواجهة مفيدة في الغالب لأدوات التطوير المحلية.الواجهة
Bun.secrets.get(options)
استرجاع بيانات اعتماد مخزنة.
import { secrets } from "bun";
const password = await Bun.secrets.get({
service: "my-app",
name: "alice@example.com",
});
// يرجع: string | null
// أو إذا كنت تفضل بدون كائن
const password = await Bun.secrets.get("my-app", "alice@example.com");المعلمات:
options.service(string، مطلوب) - الخدمة أو اسم التطبيقoptions.name(string، مطلوب) - اسم المستخدم أو معرف الحساب
الإرجاع:
Promise<string | null>- كلمة المرور المخزنة، أوnullإذا لم يتم العثور عليها
Bun.secrets.set(options, value)
تخزين أو تحديث بيانات الاعتماد.
import { secrets } from "bun";
await secrets.set({
service: "my-app",
name: "alice@example.com",
value: "super-secret-password",
});المعلمات:
options.service(string، مطلوب) - الخدمة أو اسم التطبيقoptions.name(string، مطلوب) - اسم المستخدم أو معرف الحسابvalue(string، مطلوب) - كلمة المرور أو السر المراد تخزينه
ملاحظات:
- إذا كان بيانات الاعتماد موجودًا بالفعل لمجموعة service/name المعطاة، فسيتم استبداله
- القيمة المخزنة مشفرة بواسطة نظام التشغيل
Bun.secrets.delete(options)
حذف بيانات اعتماد مخزنة.
const deleted = await Bun.secrets.delete({
service: "my-app",
name: "alice@example.com",
value: "super-secret-password",
});
// يرجع: booleanالمعلمات:
options.service(string، مطلوب) - الخدمة أو اسم التطبيقoptions.name(string، مطلوب) - اسم المستخدم أو معرف الحساب
الإرجاع:
Promise<boolean>-trueإذا تم حذف بيانات الاعتماد،falseإذا لم يتم العثور عليه
أمثلة
تخزين بيانات اعتماد أداة CLI
// تخزين رمز GitHub CLI (بدلاً من ~/.config/gh/hosts.yml)
await Bun.secrets.set({
service: "my-app.com",
name: "github-token",
value: "ghp_xxxxxxxxxxxxxxxxxxxx",
});
// أو إذا كنت تفضل بدون كائن
await Bun.secrets.set("my-app.com", "github-token", "ghp_xxxxxxxxxxxxxxxxxxxx");
// تخزين رمز سجل npm (بدلاً من ~/.npmrc)
await Bun.secrets.set({
service: "npm-registry",
name: "https://registry.npmjs.org",
value: "npm_xxxxxxxxxxxxxxxxxxxx",
});
// استرجاع لاستدعاءات API
const token = await Bun.secrets.get({
service: "gh-cli",
name: "github.com",
});
if (token) {
const response = await fetch("https://api.github.com/name", {
headers: {
Authorization: `token ${token}`,
},
});
}الترحيل من ملفات التكوين النصية العادية
// بدلاً من التخزين في ~/.aws/credentials
await Bun.secrets.set({
service: "aws-cli",
name: "AWS_SECRET_ACCESS_KEY",
value: process.env.AWS_SECRET_ACCESS_KEY,
});
// بدلاً من ملفات .env مع بيانات حساسة
await Bun.secrets.set({
service: "my-app",
name: "api-key",
value: "sk_live_xxxxxxxxxxxxxxxxxxxx",
});
// التحميل في وقت التشغيل
const apiKey =
(await Bun.secrets.get({
service: "my-app",
name: "api-key",
})) || process.env.API_KEY; // احتياطي لـ CI/الإنتاجمعالجة الأخطاء
try {
await Bun.secrets.set({
service: "my-app",
name: "alice",
value: "password123",
});
} catch (error) {
console.error("فشل تخزين بيانات الاعتماد:", error.message);
}
// التحقق مما إذا كان بيانات الاعتماد موجودًا
const password = await Bun.secrets.get({
service: "my-app",
name: "alice",
});
if (password === null) {
console.log("لم يتم العثور على بيانات الاعتماد");
}تحديث بيانات الاعتماد
// كلمة المرور الأولية
await Bun.secrets.set({
service: "email-server",
name: "admin@example.com",
value: "old-password",
});
// التحديث إلى كلمة مرور جديدة
await Bun.secrets.set({
service: "email-server",
name: "admin@example.com",
value: "new-password",
});
// تم استبدال كلمة المرور القديمةسلوك المنصة
macOS (Keychain)
- يتم تخزين بيانات الاعتماد في سلسلة مفاتيح تسجيل الدخول
- قد يطلب الإذن للوصول عند الاستخدام الأول
- تستمر بيانات الاعتماد عبر إعادة تشغيل النظام
- يمكن الوصول إليها من قبل المستخدم الذي قام بتخزينها
Linux (libsecret)
- يتطلب daemon خدمة الأسرار (GNOME Keyring أو KWallet أو غيرها)
- يتم تخزين بيانات الاعتماد في المجموعة الافتراضية
- قد يطلب فتح القفل إذا كانت سلسلة المفاتيح مقفلة
- يجب أن تكون خدمة الأسرار قيد التشغيل
Windows (مدير بيانات الاعتماد)
- يتم تخزين بيانات الاعتماد في مدير بيانات اعتماد Windows
- مرئي في لوحة التحكم → مدير بيانات الاعتماد → بيانات اعتماد Windows
- تستمر مع العلم
CRED_PERSIST_ENTERPRISEلذا فهي محدودة لكل مستخدم - مشفرة باستخدام واجهة حماية بيانات Windows
اعتبارات الأمان
- التشفير: يتم تشفير بيانات الاعتماد بواسطة مدير بيانات الاعتماد لنظام التشغيل
- التحكم في الوصول: فقط المستخدم الذي قام بتخزين بيانات الاعتماد يمكنه استرجاعه
- لا نص عادي: لا يتم تخزين كلمات المرور أبدًا كنص عادي
- أمان الذاكرة: يمسح Bun ذاكرة كلمة المرور بعد الاستخدام
- عزل العملية: يتم عزل بيانات الاعتماد لكل حساب مستخدم
القيود
- يختلف الحد الأقصى لطول كلمة المرور حسب المنصة (عادةً 2048-4096 بايت)
- يجب أن تكون أسماء service و name بأطوال معقولة (< 256 حرفًا)
- قد تحتاج بعض الأحرف الخاصة إلى هروب اعتمادًا على المنصة
- يتطلب خدمات النظام المناسبة:
- Linux: يجب أن يكون daemon خدمة الأسرار قيد التشغيل
- macOS: يجب أن يكون الوصول إلى Keychain متاحًا
- Windows: يجب تمكين خدمة مدير بيانات الاعتماد
المقارنة مع متغيرات البيئة
على عكس متغيرات البيئة، Bun.secrets:
- ✅ يشفر بيانات الاعتماد في حالة السكون (بفضل نظام التشغيل)
- ✅ يتجنب كشف الأسرار في تفريغ ذاكرة العملية (يتم مسح الذاكرة بعد عدم الحاجة إليها)
- ✅ يبقى بعد إعادة تشغيل التطبيق
- ✅ يمكن تحديثه بدون إعادة تشغيل التطبيق
- ✅ يوفر تحكم وصول على مستوى المستخدم
- ❌ يتطلب خدمة بيانات الاعتماد لنظام التشغيل
- ❌ ليس مفيدًا جدًا لأسرار النشر (استخدم متغيرات البيئة في الإنتاج)
أفضل الممارسات
استخدم أسماء خدمة وصفية: طابق اسم التطبيق أو الأداة إذا كنت تبني CLI للاستخدام الخارجي، فربما يجب استخدام UTI (معرّف النوع الموحد) لاسم الخدمة.
javascript// جيد - يطابق الأداة الفعلية { service: "com.docker.hub", name: "username" } { service: "com.vercel.cli", name: "team-name" } // تجنب - عام جدًا { service: "api", name: "key" }بيانات الاعتماد فقط: لا تخزن تكوين التطبيق في هذه الواجهة هذه الواجهة بطيئة، ربما لا تزال بحاجة إلى استخدام ملف تكوين لبعض الأشياء.
استخدم لأدوات التطوير المحلية:
- ✅ أدوات CLI (gh و npm و docker و kubectl)
- ✅ خوادم التطوير المحلية
- ✅ مفاتيح API شخصية للاختبار
- ❌ خوادم الإنتاج (استخدم إدارة الأسرار المناسبة)
TypeScript
namespace Bun {
interface SecretsOptions {
service: string;
name: string;
}
interface Secrets {
get(options: SecretsOptions): Promise<string | null>;
set(options: SecretsOptions, value: string): Promise<void>;
delete(options: SecretsOptions): Promise<boolean>;
}
const secrets: Secrets;
}