Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
sandbox-runtime — أداة عزل (sandboxing) خفيفة الوزن لفرض قيود على نظام الملفات والشبكة على أي عملية على مستوى نظام التشغيل، دون الحاجة إلى حاوية (container). | Kitploit
أدوات/GitHubGitHub/anthropic-experimental/sandbox-runtime
أدوات دفاعيةأمن الحاوياتالتحليل الديناميكي (عزل)تدقيق التكوينالمحاكاة الافتراضية للأمانأمن الشبكاتالاستجابة للحوادث
GitHub

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
anthropic-experimental/sandbox-runtime

sandbox-runtime

أداة عزل (sandboxing) خفيفة الوزن لفرض قيود على نظام الملفات والشبكة على أي عملية على مستوى نظام التشغيل، دون الحاجة إلى حاوية (container).

عرض المستودع
4.9k399152منذ 2 أيامتمت المراجعة من قبل Kitploit
مشاركة
# بيئة تشغيل معزولة من Anthropic (srt)

أداة عزل خفيفة الوزن لفرض قيود على نظام الملفات والشبكة على عمليات اعتباطية على مستوى نظام التشغيل، دون الحاجة إلى حاوية.

يستخدم `srt` أوليات العزل الأصلية في نظام التشغيل (`sandbox-exec` على macOS، و`bubblewrap` على Linux) وتصفية الشبكة القائمة على الوكيل. يمكن استخدامه لعزل سلوك الوكلاء وخوادم MCP المحلية وأوامر bash والعمليات الاعتباطية.

> **معاينة بحثية تجريبية (Beta)**
>
> بيئة التشغيل المعزولة هي معاينة بحثية طُوّرت لـ [Claude Code](https://www.claude.com/product/claude-code) لتمكين وكلاء ذكاء اصطناعي أكثر أمانًا. تُتاح الآن كمعاينة مفتوحة المصدر مبكرة لمساعدة المنظومة الأوسع على بناء أنظمة وكيلة أكثر أمانًا. وبما أن هذه معاينة بحثية مبكرة، فقد تتطور واجهات البرمجة (APIs) وصيغ الإعداد. نرحب بالملاحظات والمساهمات لجعل وكلاء الذكاء الاصطناعي أكثر أمانًا افتراضيًا!

## التثبيت

```bash
npm install -g @anthropic-ai/sandbox-runtime
```

## الاستخدام الأساسي

```bash
# Network restrictions
$ srt "curl anthropic.com"
Running: curl anthropic.com
<html>...</html>  # Request succeeds

$ srt "curl example.com"
Running: curl example.com
Connection blocked by network allowlist  # Request blocked

# Filesystem restrictions
$ srt "cat README.md"
Running: cat README.md
# Anthropic Sandb...  # Current directory access allowed

$ srt "cat ~/.ssh/id_rsa"
Running: cat ~/.ssh/id_rsa
cat: /Users/ollie/.ssh/id_rsa: Operation not permitted  # Specific file blocked
```

## نظرة عامة

توفر هذه الحزمة تنفيذًا مستقلًا لبيئة معزولة (sandbox) يمكن استخدامه كأداة سطر أوامر (CLI) ومكتبة برمجية في آنٍ واحد. وقد صُمم بفلسفة **آمن افتراضيًا** (secure-by-default) مُصممة خصيصًا لحالات الاستخدام الشائعة لدى المطورين: تبدأ العمليات بأقل قدر من الوصول، وتفتح أنت صراحةً فقط الثغرات التي تحتاجها.

**القدرات الرئيسية:**

- **قيود الشبكة**: التحكم في المضيفين/النطاقات التي يمكن الوصول إليها عبر HTTP/HTTPS وبروتوكولات أخرى
- **قيود نظام الملفات**: التحكم في الملفات/المجلدات التي يمكن قراءتها/كتابتها
- **قيود مقابس Unix**: التحكم في الوصول إلى مقابس IPC المحلية
- **مراقبة الانتهاكات**: على macOS، الاستفادة من مخزن سجلات انتهاكات بيئة العزل في النظام للحصول على تنبيهات فورية

### مثال على حالة الاستخدام: عزل خوادم MCP

من حالات الاستخدام الرئيسية عزل خوادم بروتوكول سياق النموذج (MCP) لتقييد قدراتها. على سبيل المثال، لعزل خادم MCP الخاص بنظام الملفات:

**بدون عزل** (`.mcp.json`):

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem"]
    }
  }
}
```

**مع العزل** (`.mcp.json`):

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "srt",
      "args": ["npx", "-y", "@modelcontextprotocol/server-filesystem"]
    }
  }
}
```

ثم قم بتكوين القيود في `~/.srt-settings.json`:

```json
{
  "filesystem": {
    "denyRead": [],
    "allowWrite": ["."],
    "denyWrite": ["~/sensitive-folder"]
  },
  "network": {
    "allowedDomains": [],
    "deniedDomains": []
  }
}
```

سيمنع الآن خادم MCP من الكتابة إلى المسار المرفوض:

```
> Write a file to ~/sensitive-folder
✗ Error: EPERM: operation not permitted, open '/Users/ollie/sensitive-folder/test.txt'
```

## كيف يعمل

تستخدم بيئة العزل (sandbox) عناصر أساسية على مستوى نظام التشغيل لفرض قيود تنطبق على شجرة العمليات بأكملها:

- **macOS**: يستخدم `sandbox-exec` مع ملفات تعريف [Seatbelt](https://reverse.put.as/wp-content/uploads/2011/09/Apple-Sandbox-Guide-v1.0.pdf) المُولَّدة ديناميكيًا
- **Linux**: يستخدم [bubblewrap](https://github.com/containers/bubblewrap) للحاويات مع عزل مساحة أسماء الشبكة
- **Windows**: يشغّل العملية المعزولة تحت حساب مستخدم محلي مخصص `srt-sandbox`، مع سياج خروج [Windows Filtering Platform](https://learn.microsoft.com/en-us/windows/win32/fwp/windows-filtering-platform-start-page) مرتبط بـ SID الخاص بذلك الحساب، ورمز مميز مقيّد بالكتابة، وACEs صريحة على شجرة العمل

0d1c612947c798aef48e6ab4beb7e8544da9d41a-4096x2305

### نموذج العزل المزدوج

يُعدّ عزل نظام الملفات وعزل الشبكة كلاهما ضروريًا لعزل فعّال. فبدون عزل الملفات، قد تتمكن عملية مخترقة من تسريب مفاتيح SSH أو ملفات حساسة أخرى. وبدون عزل الشبكة، قد تتمكن عملية من الهروب من بيئة العزل والحصول على وصول غير مقيّد إلى الشبكة.

**عزل نظام الملفات** يفرض قيود القراءة والكتابة:

- **القراءة** (نمط الرفض ثم السماح): افتراضيًا، يُسمح بالوصول للقراءة في كل مكان. يمكنك رفض مناطق واسعة (مثل `/Users`) ثم إعادة السماح بمسارات محددة داخلها (مثل `.`). `allowRead` لها الأولوية على `denyRead` — وهو عكس الكتابة، حيث `denyWrite` لها الأولوية على `allowWrite`. يبقى إدخال `denyRead` الأكثر تحديدًا من منطقة `allowRead` التي يقع داخلها (مثل `denyRead: ["**/.env"]` أو `["./secrets"]` مع `allowRead: ["."]`) مرفوضًا.
- **الكتابة** (نمط السماح فقط): افتراضيًا، يُرفض الوصول للكتابة في كل مكان. يجب عليك السماح بالمسارات صراحةً (مثل `.`، `/tmp`). قائمة السماح الفارغة تعني عدم وجود وصول للكتابة.

**عزل الشبكة** (نمط السماح فقط): افتراضيًا، يُرفض كل الوصول إلى الشبكة. يجب عليك السماح بالنطاقات صراحةً. قائمة allowedDomains الفارغة تعني عدم وجود وصول إلى الشبكة. تُوجَّه حركة الشبكة عبر خوادم وكيلة (proxies) تعمل على المضيف:

- **Linux**: تُوجَّه الطلبات عبر نظام الملفات من خلال مقبس نطاق Unix. تُزال مساحة أسماء الشبكة للعملية المعزولة بالكامل، لذا يجب أن تمر كل حركة الشبكة عبر الخوادم الوكيلة التي تعمل على المضيف (تستمع على مقابس Unix المثبَّتة (bind-mounted) داخل بيئة العزل)

- **macOS**: يسمح ملف تعريف Seatbelt بالاتصال فقط بمنفذ localhost محدد. تستمع الخوادم الوكيلة على هذا المنفذ، مما ينشئ قناة مُتحكَّمًا بها لكل الوصول إلى الشبكة

- **Windows**: تحجب مجموعة مرشحات WFP على مستوى الجهاز الاتصالات الصادرة التي تُجريها العمليات التي تعمل بحساب `srt-sandbox` باستثناء loopback إلى نطاق منافذ الوكيل. تستمع الخوادم الوكيلة داخل ذلك النطاق، مما ينشئ قناة مُتحكَّمًا بها لكل الوصول إلى الشبكة. لا تتبع المرشحات عملية معزولة تضع رمزًا مميزًا مختلفًا على خيط (thread) قبل إنشاء مقبس، ولا حركة المرور التي تنقلها خدمة نظام نيابةً عنها؛ راجع [القيود المعروفة](#known-limitations) الخاصة بـ Windows

تتوسط هذه الخوادم الوكيلة في كل من HTTP/HTTPS (عبر وكيل HTTP) وحركة TCP الأخرى (عبر وكيل SOCKS5)، وهي التي تفرض قوائم السماح والحظر الخاصة بنطاقاتك.

لمزيد من التفاصيل حول العزل في Claude Code، راجع:

- [وثائق عزل Claude Code](https://docs.claude.com/en/docs/claude-code/sandboxing)
- [ما وراء مطالبات الأذونات: جعل Claude Code أكثر أمانًا واستقلالية](https://www.anthropic.com/engineering/claude-code-sandboxing)

## البنية

```
src/
├── index.ts                  # Library exports
├── cli.ts                    # CLI entrypoint (srt command)
├── utils/                    # Shared utilities
│   ├── debug.ts             # Debug logging
│   ├── settings.ts          # Settings reader (permissions + sandbox config)
│   ├── platform.ts          # Platform detection
│   └── exec.ts              # Command execution utilities
└── sandbox/                  # Sandbox implementation
    ├── sandbox-manager.ts    # Main sandbox manager
    ├── sandbox-schemas.ts    # Zod schemas for validation
    ├── sandbox-violation-store.ts # Violation tracking
    ├── sandbox-utils.ts      # Shared sandbox utilities
    ├── http-proxy.ts         # HTTP/HTTPS proxy for network filtering
    ├── socks-proxy.ts        # SOCKS5 proxy for network filtering
    ├── linux-sandbox-utils.ts # Linux bubblewrap sandboxing
    ├── macos-sandbox-utils.ts # macOS sandbox-exec sandboxing
    └── windows-sandbox-utils.ts # Windows srt-win sandboxing
```

## الاستخدام

### كأداة CLI

يلفّ أمر `srt` (Anthropic Sandbox Runtime) أي أمر بحدود أمنية:

```bash
# Run a command in the sandbox
srt echo "hello world"

# With debug logging
srt --debug curl https://example.com

# Specify custom settings file
srt --settings /path/to/srt-settings.json npm install
```

ملف الإعدادات اختياري — فبدون وجود ملف في `~/.srt-settings.json`، يعمل `srt`
بالإعدادات الافتراضية المدمجة: لا وصول إلى الشبكة، ولا كتابة خارج مسارات
الكتابة الافتراضية، وقراءات غير مقيّدة. أما ملف الإعدادات الموجود فعليًا لكنه
فارغ، أو يتعذّر قراءته، أو لا يجتاز التحقق، فهو خطأ: يُبلّغ `srt` بذلك
ويخرج بدلًا من الرجوع إلى تلك الإعدادات الافتراضية، فهي إعدادات مختلفة
وليست أضعف منها — فالرجوع إليها سيُسقط قواعد `denyRead` و`allowRead` وقواعد
بيانات الاعتماد الخاصة بالملف مع كل ما نصّ عليه سواه. وينطبق الأمر ذاته على
ملف يُحدَّد باسم عبر `--settings`، والذي يجب أن يكون موجودًا أيضًا.

#### تحديث الإعدادات أثناء تشغيل الأمر: `--control-fd`

يقرأ `--control-fd <fd>` تحديثات الإعدادات من واصف (descriptor) سبق أن فتحه
المستدعي، كائن JSON واحد لكل سطر بالشكل نفسه الذي يتخذه ملف الإعدادات. ويحلّ
كل سطر محل الإعدادات بأكملها ويُتحقَّق منه وفق المخطط نفسه، لذا فالسطر
إعدادات كاملة وليس رقعة تعديل: إذ يُشترط وجود `network` و`filesystem`، وأي
مفتاح يغفله السطر يعود إلى قيمته الافتراضية.

```bash
# fd 3 is the read end of a pipe the caller writes lines to
srt --control-fd 3 -- npm test
```

ما الذي تغيّره السطر المقبول بمجرد تشغيل الأمر:

- قوائم الشبكة — `network.allowedDomains` و`deniedDomains` (مع
  `deniedDomainReasons`) و`deniedResolvedAddresses` — تدخل حيّز التنفيذ عند
  الاتصال التالي، على كل المنصات: يستشيرها الوكيل عند كل طلب،
  ويُعاد بناء فحص العنوان المُحلَّل من السطر نفسه. وينطبق الأمر ذاته على
  `network.mitmProxy` و`network.tlsTerminate.excludeDomains`، اللذين يقرأهما
  عند كل طلب أيضًا.
- يدخل `credentials.sigv4` حيّز التنفيذ عند الطلب التالي، بشرط أن يكون srt
  قد بدأ بكتلة `credentials`: فخطاف التوقيع لا يُثبَّت إلا حينها، ويقرأ
  السياسات عند كل طلب بدلًا من التقاطها.
- لا يتغيّر أي شيء آخر. فقواعد نظام الملفات موجودة أصلًا في ملف تعريف seatbelt،
  أو في وسائط bubblewrap، أو في قوائم ACEs على Windows، وأقنعة بيانات الاعتماد
  بُنيت عند تغليف الأمر، وخوادم الوكيل العاملة التقطت `network.parentProxy`،
  وما إذا كان TLS يُنهى أصلًا، عند بدئها.
- على Windows، يلاحظ srt سطرًا تختلف فيه مجموعة الوصول إلى الملفات (`filesystem.*`
  مع `credentials.files`) عن تلك المطبَّقة عند بدء التشغيل، ولا يذكر ذلك إلا تحت
  `SRT_DEBUG`: فمنح ACL على مستوى الجلسة، لذا تبقى المجموعة المطبَّقة عند بدء
  التشغيل سارية. ويُطبَّق باقي السطر كما هو موضح أعلاه.

كيف يقرأ srt القناة، وما الذي يرفضه:

- يجب أن يكون الواصف عددًا صحيحًا **قيمته 3 أو أكثر** وقابلًا للقراءة — إذ إن
  `0`-`2` هي التدفقات القياسية. يخرج srt بخطأ بدلًا من تشغيل الأمر عندما
  يتعذّر عليه قراءة الواصف المعطى له، لذا لا تمرّ قناة ميتة أبدًا على أنها
  حيّة. والقناة التي تموت قبل أن تسلّم تحديثًا واحدًا تُسقط الأمر معها؛ أما التي
  تموت بعد ذلك فتُعلن ذلك وتترك الأمر يعمل وفق الإعداد المطبَّق آخر مرة.
- يُبلَّغ عن السطر غير الصالح كإعداد صحيح على stderr ويُهمَل؛ ويبقى الإعداد
  السابق ساريًا. ويُرسَل السطر نفسه إلى سجل التصحيح بدلًا من الطرفية، ويُتجاهَل
  السطر الفارغ بصمت.
- لا يبدأ srt القراءة إلا بعد أن تصبح البيئة المعزولة جاهزة، لذا ينتظر تحديث
  كُتب قبل ذلك في القناة بدلًا من أن يضيع — ولا يمكن أن يطمسه الإعداد الذي تبدأ
  به البيئة المعزولة. وقد يُقرأ هذا السطر بينما لا يزال الأمر قيد التغليف،
  فيكون حينها هو الإعداد الذي يُغلَّف به، بما في ذلك قواعد نظام الملفات. ويعتمد
  ما إذا كان يُقرأ بهذه البكرة على مدة التغليف (على Linux، يكفي نمط glob للحظر
  على شجرة كبيرة لذلك)، لذا فإن قاعدة يجب أن يبدأ الأمر في ظلها تنتمي إلى ملف
  الإعدادات.
- **يخرج srt مع الأمر المغلَّف** ولا ينتظر الكاتب ليغلق الواصف. ونهاية الإدخال
  ليست خطأً أيضًا: يستمر الأمر في العمل وفق الإعداد المطبَّق آخر مرة.
- أعطِ srt **طرفًا مخصصًا للقراءة فقط**. يضع srt أنبوبًا أو مقبسًا في الوضع
  غير الحاجز، وهذا العلم يعيش على وصف الملف المفتوح، لذا فإن أي شيء آخر يحمل
  الوصف نفسه — مثل `exec 3<fifo` في صدفة، أو `pass_fds` لواصف يواصل الأصل
  استخدامه — يتلقى `EAGAIN` من قراءاته الحاجزة هو من ذلك الحين فصاعدًا.
- على macOS وLinux لا يحصل الأمر المعزول على الواصف: يوجّه srt تلك الخانة إلى
  `/dev/null` للأمر، فلا يستطيع أي شيء داخل البيئة المعزولة قراءة التحديثات أو
  كتابة إعداد خاص به. أما على Windows فيُولَّد الأمر بالتدفقات القياسية الثلاثة
  وحدها، لذا لا يكون واصف التحكم بين الواصفات التي تُسلَّم له.

### كخادم وكيل مستقل مع مُقرِّر خارجي: `srt proxy`

يشغّل `srt proxy` (أو الملف التنفيذي الأحادي `srt-proxy` الذي يبنيه `bun run build:srt-proxy`) وكيل HTTP الخاص بـ SRT فقط، دون عملية فرعية معزولة، لمضيف يشغّل عبء العمل في مكان آخر. يستقبل على مقبس استماع يسلّمه له المضيف، ويُنهي كل CONNECT داخل العملية، ولا يمرّر طلبًا إلا عندما يسمح به عملية مُقرِّرة منفصلة، يُوصَل إليها عبر واصف موروث آخر. راجع [docs/srt-proxy.md](https://github.com/anthropic-experimental/sandbox-runtime/blob/main/docs/srt-proxy.md) للاطلاع على سطر الأوامر وبروتوكول المُقرِّر ونموذج الأمان.

### كمكتبة

```typescript
import {
  SandboxManager,
  type SandboxRuntimeConfig,
} from '@anthropic-ai/sandbox-runtime'
import { spawn } from 'child_process'

// Define your sandbox configuration
const config: SandboxRuntimeConfig = {
  network: {
    allowedDomains: ['example.com', 'api.github.com'],
    deniedDomains: [],
  },
  filesystem: {
    denyRead: ['~/.ssh'],
    allowWrite: ['.', '/tmp'],
    denyWrite: ['.env'],
  },
}

// Initialize the sandbox (starts proxy servers, etc.)
await SandboxManager.initialize(config)

// Wrap a command with sandbox restrictions
const sandboxedCommand = await SandboxManager.wrapWithSandbox(
  'curl https://example.com',
)

// Execute the sandboxed command
const child = spawn(sandboxedCommand, { shell: true, stdio: 'inherit' })

// Handle exit and cleanup after child process completes
child.on('exit', async code => {
  console.log(`Command exited with code ${code}`)
  // Cleanup when done (optional, happens automatically on process exit)
  await SandboxManager.reset()
})
```

**إسناد الانتهاكات (`commandId` / `commandText`).** تُخزَّن الانتهاكات المرصودة أثناء تشغيل أمر مُغلَّف (أسطر سجل seatbelt، وأحداث seccomp، وعمليات الرفض من الوسيط) تحت مفتاح إسناد، ويبحث `annotateStderrWithSandboxFailures(key, stderr)` / `getViolationsForCommand(key)` عنها بذلك المفتاح نفسه. افتراضيًا يكون المفتاح هو السلسلة المُغلَّفة نفسها. مرِّر `commandId` معتمًا لكل استدعاء (مثل معرّف استخدام أداة) لتكون المفاتيح به بدلًا من ذلك — وهو الموصى به: تُقارَن المفاتيح بأول 100 حرف منها، لذا فإن الأوامر الطويلة التي تشترك في بادئة قد تُنسب خطأً إلى بعضها البعض، كما أن إعادة تشغيل النص نفسه ستَرِث أحداث التشغيل السابق. إذا كانت السلسلة التي _تنفّذها_ ليست الأمر الذي _يمثّله_ الاستدعاء (مثلًا عندما تُغلِّف `source <snapshot> && eval '<cmd>'` المُجمَّعة)، فمرِّر أيضًا `commandText: '<cmd>'`: فهو ما تُطابَق به أنماط أوامر `ignoreViolations` وما يُبلِّغ به كل انتهاك عن `command` الخاص به. يجب أن يكون `commandId` الذي تمرره إلى `wrapWithSandbox` هو السلسلة غير الفارغة نفسها التي تمررها بعد ذلك إلى `annotateStderrWithSandboxFailures` / `getViolationsForCommand`؛ إذ يُعامَل المفتاح الفارغ كأنه لا `commandId` على الإطلاق، فيكون المفتاح هو الأمر.

يُقتَص المفتاح فقط إلى 100 حرف. اعتبارًا من الإصدار v0.0.76، يكون `command` المُبلَّغ عنه — والنص الذي تُطابَق به أنماط أوامر `ignoreViolations` — هو الأمر كاملًا للاستدعاء المُغلَّف دون `commandId`، وليس أول 100 حرف منه؛ لذا لا يمكن لنمط أن يكبت إلا أكثر مما كان يفعل سابقًا، وليس أقل أبدًا. أي مفتاح إسناد لم يسجّله أي استدعاء في هذه العملية (فالحاملات قابلة للكتابة من داخل الـ sandbox) يُبلَّغ عنه بعد تنقيته واقتطاعه إلى طول المفتاح نفسه.

```typescript
const wrapped = await SandboxManager.wrapWithSandbox(
  assembledCommand, // what actually runs
  undefined,
  undefined,
  undefined,
  { commandId: invocationId, commandText: rawCommand },
)
// ... run it ...
const annotated = SandboxManager.annotateStderrWithSandboxFailures(
  invocationId,
  stderr,
)
```

**السؤال عن مضيف لا تقرره أي قاعدة (استدعاء ask).** الوسيط الثاني لـ `SandboxManager.initialize` هو `SandboxAskCallback` اختياري. يُسأل عن وجهة لم تقررها `network.deniedDomains` ولا `network.allowedDomains` ولا قائمة السماح الخاصة بكل أمر (القسم التالي)، ولا يُسأل أبدًا في ظل `network.strictAllowlist`. وبدون استدعاء، تُرفض هذه الوجهة. يُحل الاستدعاء إلى أحد الخيارات التالية:

- `true` - السماح بالاتصال. القيمة `true` وحدها هي التي تسمح.
- `false` - رفضه. يُبلّغ سطر الانتهاك عن السبب العام `user denied`.
- `{ allow: false, reason: '...' }` - رفضه، والإبلاغ عن `reason` في سطر الانتهاك بدلًا من النص العام، حتى يعرف من يقرأ كتلة `<sandbox_violations>` (بما في ذلك النموذج) السبب وما يجب فعله بدلًا من ذلك. يقرأه العميل المعزول أيضًا، كعبارة الحالة الخاصة بـ `403` التي تجيب على CONNECT الخاص به.

أي إجابة أخرى ترفض، سواء كانت صادقة أم لا، وتُبلّغ عن السبب العام. ويشمل ذلك كائنًا يحمل `reason` دون أن ينص على `allow: false`، مثل `{ allow: true, reason: '...' }`: فلا يُبلّغ عن سببه.

يُعقَّم السبب قبل تخزينه، على غرار بقية سطر الانتهاك. كل سلسلة من المحارف التحكمية (بما في ذلك فواصل الأسطر وعلامات الجدولة) أو من المحارف غير المرئية (المحارف ذات العرض الصفري، ومنها الواصل، ومحارف التحكم ثنائية الاتجاه) تصبح مسافة واحدة؛ وتُزال `<` و `>`، لذا يُخزَّن `re-run with <host> listed` على هيئة `re-run with host listed`؛ وتُشذَّب الأطراف. وتُقتطع النتيجة إلى 500 محرف، تُحسب كوحدات شفرة UTF-16 بالطريقة التي تعدّها `String.prototype.length`. والسبب الذي لا يتبقى منه شيء بعد ذلك يعود إلى `user denied`. اكتبه كسطر واحد من نص عادي.

**تغيير في السلوك في الإصدار الأول بعد 0.0.79:** كان المرشّح سابقًا يسمح بأي إجابة صادقة، لذا فإن استدعاءً يُحل إلى قيمة صادقة غير `true` (`1`، أو سلسلة، أو أي كائن) كان يسمح بالاتصال. أما الآن فيرفض. وللسبب نفسه، فإن `{ allow: false, reason }` المُعاد إلى إصدار أقدم سيُقرأ هناك على أنه سماح، لأن الكائن صادق. `SandboxManager.askCallbackDenyReason` هي `true` على إصدار يفهم الكائن: تحقق منها قبل إرجاع واحد، وارفض بـ `false` صريحة حيث تكون غائبة.

```typescript
const deny = (reason: string) =>
  SandboxManager.askCallbackDenyReason
    ? { allow: false as const, reason }
    : false

await SandboxManager.initialize(config, async ({ host, port }) => {
  if (await userApproves(host, port)) return true
  return deny(`${host} was not approved for this session`)
})
```

**قوائم السماح للشبكة لكل أمر (`registerCommandNetworkLists`).** يمكن لاستدعاء واحد أن يحمل قائمة سماح خاصة به، بالإضافة إلى القائمة المُهيّأة، طوال مدة تشغيله:

```typescript
import { randomBytes } from 'node:crypto'

// 128 bits of randomness, 22 characters. See below for why nothing less will do.
const commandId = randomBytes(16).toString('base64url')
const wrapped = await SandboxManager.wrapWithSandbox(
  command,
  undefined,
  undefined,
  undefined,
  { commandId },
)

SandboxManager.registerCommandNetworkLists(commandId, {
  allowedDomains: ['registry.example.org', '*.cdn.example.org:443'],
})
const child = spawn(wrapped, { shell: true })
const unregister = () => SandboxManager.unregisterCommandNetworkLists(commandId)
child.once('exit', unregister)
child.once('error', unregister) // the child never started
```

تُستخدم الإدخالات بقواعد ومطابق `network.allowedDomains` وتحصل على التحقق نفسه. يرمي `registerCommandNetworkLists` عند إدخال غير صالح، وعند `commandId` أقصر من 22 حرفًا (لا يُحتسب البديل غير المزاوج). إعادة تسجيل معرّف تستبدل قائمته؛ و`unregisterCommandNetworkLists` عملية لا أثر لها لمعرّف لا يملك أي قائمة؛ و`reset()` يزيل كل تسجيل.

ترتيب التقييم لاتصال ما هو:

1. تطابق `network.deniedDomains` يرفض؛
2. تطابق `network.allowedDomains` يسمح؛
3. `network.strictAllowlist` يرفض؛
4. تطابق في القائمة المسجّلة للمعرّف الذي يقدّمه الاتصال يسمح؛
5. يقرّر رد نداء السؤال إن وُجد، وإلا يُرفض الاتصال.

لذا فإن إدخالًا لكل أمر لا يتجاوز أبدًا إدخال `deniedDomains` المُهيّأ، ويُتجاهل كليًا تحت `strictAllowlist`. ولا يدخل أبدًا في `network.*` أيضًا: لا يُظهره `getConfig()` و`getNetworkRestrictionConfig()`، ولا ينمو نطاق `injectHosts` الافتراضي لبيانات اعتماد مقنّعة، وهو `network.allowedDomains`. والمضيف المسموح بهذه الطريقة يمرّ مع ذلك بفحص العنوان المُحلَّل عند الاتصال به، ولا يضيف حرفي IP في قائمة لكل أمر أي إعفاء هناك.

ما يجب أن يكون عليه المعرّف، وما ليست هذه الميزة: يتعلّم الوكيل إلى أي استدعاء ينتمي الاتصال من اسم مستخدم الوكيل، واسم المستخدم يقدّمه العميل داخل العزل. لذا فإن المعرّف هو **الشيء الوحيد** الذي يربط الاتصال بقائمة سماح. **يجب** أن يكون غير قابل للتخمين: 128 بتًا من العشوائية على الأقل، وألا يكون أبدًا عدّادًا أو طابعًا زمنيًا أو أي شيء مشتق من الأمر. عملية معزولة تقدّم معرّف استدعاء حيّ آخر تحصل على سماحات ذلك الاستدعاء، لذا فهذا إسناد، وليس حدًا فاصلًا بين أوامر متزامنة في جلسة واحدة. سجّل قبل إنشاء الأمر المُغلَّف مباشرةً، وألغِ التسجيل عند خروج الابن أو إذا لم يبدأ أبدًا: فالتسجيل الذي يعيش أطول من أمره يوسّع النافذة التي يكون فيها معرّفه جديرًا بالتقديم. وكما هو الحال مع كل مفتاح إسناد، لا يشارك سوى أول 100 حرف من المعرّف. أبقِ المعرّفات ASCII: فقائمة تحت معرّف غير ASCII لا يتسع شكله المُرمَّز في اسم مستخدم الوكيل (255 بايت) تُسجَّل ولا تُطبَّق أبدًا.

لا تُطبَّق أي قائمة بينما يسمّي `network.httpProxyPort` وكيلًا خارجيًا: فالغلاف لا يمنح ذلك الوكيل اسم مستخدم، لذا لا يحمل أي اتصال معرّفًا. ينجح `registerCommandNetworkLists` مع ذلك (ويقول ذلك في سطر واحد تحت `SRT_DEBUG`)، ويُقرَّر كل اتصال كما لو لم توجد أي قائمة.

#### الصادرات المتاحة

```typescript
// Main sandbox manager
export { SandboxManager } from '@anthropic-ai/sandbox-runtime'

// Violation tracking
export { SandboxViolationStore } from '@anthropic-ai/sandbox-runtime'

// TypeScript types
export type {
  SandboxRuntimeConfig,
  NetworkConfig,
  FilesystemConfig,
  IgnoreViolationsConfig,
  SandboxAskCallback,
  FsReadRestrictionConfig,
  FsWriteRestrictionConfig,
  NetworkRestrictionConfig,
} from '@anthropic-ai/sandbox-runtime'
```

## الإعدادات

### موقع ملف الإعدادات

بشكل افتراضي، يبحث وقت تشغيل بيئة العزل عن الإعدادات في `~/.srt-settings.json`. يمكنك تحديد مسار مخصص باستخدام العلامة `--settings`:

```bash
srt --settings /path/to/srt-settings.json <command>
```

### مثال تكوين كامل

```json
{
  "network": {
    "allowedDomains": [
      "github.com",
      "*.github.com",
      "lfs.github.com",
      "api.github.com",
      "npmjs.org",
      "*.npmjs.org"
    ],
    "deniedDomains": ["malicious.com"],
    "allowUnixSockets": ["/var/run/docker.sock"],
    "allowLocalBinding": false
  },
  "filesystem": {
    "denyRead": ["~/.ssh"],
    "allowRead": [],
    "allowWrite": [".", "src/", "test/", "/tmp"],
    "denyWrite": [".env", "config/production.json"]
  },
  "ignoreViolations": {
    "*": ["/usr/bin", "/System"],
    "git push": ["/usr/bin/nc"],
    "npm": ["/private/tmp"]
  },
  "enableWeakerNestedSandbox": false,
  "allowNestedUserNamespaces": false,
  "enableWeakerNetworkIsolation": false,
  "allowAppleEvents": false
}
```

### خيارات التكوين

#### تكوين الشبكة

يستخدم **نمط السماح فقط** - يتم رفض جميع الوصول إلى الشبكة افتراضيًا.

- `network.allowedDomains` - مصفوفة من النطاقات المسموح بها (تدعم أحرف البدل مثل `*.example.com`). مصفوفة فارغة = لا يوجد وصول إلى الشبكة. لاحقة `:port` الاختيارية (`api.example.com:443`، `*.example.com:8443`) تقيّد الإدخال بمنفذ الوجهة ذلك؛ الإدخالات التي لا تحتوي على منفذ تطابق أي منفذ.

---

[Read more](https://github.com/anthropic-experimental/sandbox-runtime)
تنزيل الأداة