Skip to content

قم بتخزين واسترجاع بيانات الاعتماد الحساسة بشكل آمن باستخدام واجهات برمجة التطبيقات الأصلية لنظام التشغيل لتخزين بيانات الاعتماد.

typescript
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)

استرجاع بيانات اعتماد مخزنة.

typescript
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)

تخزين أو تحديث بيانات الاعتماد.

typescript
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)

حذف بيانات اعتماد مخزنة.

typescript
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

javascript
// تخزين رمز 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}`,
    },
  });
}

الترحيل من ملفات التكوين النصية العادية

javascript
// بدلاً من التخزين في ~/.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/الإنتاج

معالجة الأخطاء

javascript
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("لم يتم العثور على بيانات الاعتماد");
}

تحديث بيانات الاعتماد

javascript
// كلمة المرور الأولية
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

اعتبارات الأمان

  1. التشفير: يتم تشفير بيانات الاعتماد بواسطة مدير بيانات الاعتماد لنظام التشغيل
  2. التحكم في الوصول: فقط المستخدم الذي قام بتخزين بيانات الاعتماد يمكنه استرجاعه
  3. لا نص عادي: لا يتم تخزين كلمات المرور أبدًا كنص عادي
  4. أمان الذاكرة: يمسح Bun ذاكرة كلمة المرور بعد الاستخدام
  5. عزل العملية: يتم عزل بيانات الاعتماد لكل حساب مستخدم

القيود

  • يختلف الحد الأقصى لطول كلمة المرور حسب المنصة (عادةً 2048-4096 بايت)
  • يجب أن تكون أسماء service و name بأطوال معقولة (< 256 حرفًا)
  • قد تحتاج بعض الأحرف الخاصة إلى هروب اعتمادًا على المنصة
  • يتطلب خدمات النظام المناسبة:
    • Linux: يجب أن يكون daemon خدمة الأسرار قيد التشغيل
    • macOS: يجب أن يكون الوصول إلى Keychain متاحًا
    • Windows: يجب تمكين خدمة مدير بيانات الاعتماد

المقارنة مع متغيرات البيئة

على عكس متغيرات البيئة، Bun.secrets:

  • ✅ يشفر بيانات الاعتماد في حالة السكون (بفضل نظام التشغيل)
  • ✅ يتجنب كشف الأسرار في تفريغ ذاكرة العملية (يتم مسح الذاكرة بعد عدم الحاجة إليها)
  • ✅ يبقى بعد إعادة تشغيل التطبيق
  • ✅ يمكن تحديثه بدون إعادة تشغيل التطبيق
  • ✅ يوفر تحكم وصول على مستوى المستخدم
  • ❌ يتطلب خدمة بيانات الاعتماد لنظام التشغيل
  • ❌ ليس مفيدًا جدًا لأسرار النشر (استخدم متغيرات البيئة في الإنتاج)

أفضل الممارسات

  1. استخدم أسماء خدمة وصفية: طابق اسم التطبيق أو الأداة إذا كنت تبني CLI للاستخدام الخارجي، فربما يجب استخدام UTI (معرّف النوع الموحد) لاسم الخدمة.

    javascript
    // جيد - يطابق الأداة الفعلية
    { service: "com.docker.hub", name: "username" }
    { service: "com.vercel.cli", name: "team-name" }
    
    // تجنب - عام جدًا
    { service: "api", name: "key" }
  2. بيانات الاعتماد فقط: لا تخزن تكوين التطبيق في هذه الواجهة هذه الواجهة بطيئة، ربما لا تزال بحاجة إلى استخدام ملف تكوين لبعض الأشياء.

  3. استخدم لأدوات التطوير المحلية:

    • ✅ أدوات CLI (gh و npm و docker و kubectl)
    • ✅ خوادم التطوير المحلية
    • ✅ مفاتيح API شخصية للاختبار
    • ❌ خوادم الإنتاج (استخدم إدارة الأسرار المناسبة)

TypeScript

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;
}

Bun بواسطة www.bunjs.com.cn تحرير