بروتوكول البوابة
بروتوكول Gateway WS هو مستوى التحكم الوحيد + نقل العقدة لـ OpenClaw. جميع العملاء (CLI، واجهة الويب، تطبيق macOS، عقد iOS/Android، العقد بلا واجهة) يتصلون عبر WebSocket ويعلنون عن دورهم + نطاقهم في وقت المصافحة.
النقل
- WebSocket، إطارات نصية مع حمولات JSON.
- يجب أن تكون الإطارة الأولى طلب
connect.
المصافحة (connect)
البوابة → العميل (تحدي ما قبل الاتصال):
{
"type": "event",
"event": "connect.challenge",
"payload": { "nonce": "…", "ts": 1737264000000 }
}
العميل → البوابة:
{
"type": "req",
"id": "…",
"method": "connect",
"params": {
"minProtocol": 3,
"maxProtocol": 3,
"client": {
"id": "cli",
"version": "1.2.3",
"platform": "macos",
"mode": "operator"
},
"role": "operator",
"scopes": ["operator.read", "operator.write"],
"caps": [],
"commands": [],
"permissions": {},
"auth": { "token": "…" },
"locale": "en-US",
"userAgent": "openclaw-cli/1.2.3",
"device": {
"id": "device_fingerprint",
"publicKey": "…",
"signature": "…",
"signedAt": 1737264000000,
"nonce": "…"
}
}
}
البوابة → العميل:
{
"type": "res",
"id": "…",
"ok": true,
"payload": { "type": "hello-ok", "protocol": 3, "policy": { "tickIntervalMs": 15000 } }
}
عند إصدار رمز جهاز، يتضمن hello-ok أيضًا:
{
"auth": {
"deviceToken": "…",
"role": "operator",
"scopes": ["operator.read", "operator.write"]
}
}
مثال للعقدة
{
"type": "req",
"id": "…",
"method": "connect",
"params": {
"minProtocol": 3,
"maxProtocol": 3,
"client": {
"id": "ios-node",
"version": "1.2.3",
"platform": "ios",
"mode": "node"
},
"role": "node",
"scopes": [],
"caps": ["camera", "canvas", "screen", "location", "voice"],
"commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"],
"permissions": { "camera.capture": true, "screen.record": false },
"auth": { "token": "…" },
"locale": "en-US",
"userAgent": "openclaw-ios/1.2.3",
"device": {
"id": "device_fingerprint",
"publicKey": "…",
"signature": "…",
"signedAt": 1737264000000,
"nonce": "…"
}
}
}
التأطير
- الطلب:
{type:"req", id, method, params} - الاستجابة:
{type:"res", id, ok, payload|error} - الحدث:
{type:"event", event, payload, seq?, stateVersion?}
تتطلب الطرق ذات الأثر الجانبي مفاتيح عدم التكرار (انظر المخطط).
الأدوار + النطاقات
الأدوار
operator= عميل مستوى التحكم (CLI/UI/الأتمتة).node= مضيف القدرات (الكاميرا/الشاشة/اللوحة/system.run).
النطاقات (المشغل)
النطاقات الشائعة:
operator.readoperator.writeoperator.adminoperator.approvalsoperator.pairing
نطاق الطريقة هو البوابة الأولى فقط. بعض أوامر الشرطة المائلة التي يتم الوصول إليها عبر chat.send تطبق فحوصات أكثر صرامة على مستوى الأمر فوق ذلك. على سبيل المثال، تتطلب عمليات الكتابة المستمرة /config set و /config unset نطاق operator.admin.
القدرات/الأوامر/الأذونات (العقدة)
تعلن العقد عن مطالبات القدرات في وقت الاتصال:
caps: فئات القدرات عالية المستوى.commands: قائمة السماح بالأوامر للاستدعاء.permissions: مفاتيح تفصيلية (مثلscreen.record،camera.capture).
تعامل البوابة هذه على أنها مطالبات وتفرض قوائم السماح من جانب الخادم.
الحضور
system-presenceتُرجع إدخالات مفتاحها هوية الجهاز.- تتضمن إدخالات الحضور
deviceId، وroles، وscopesحتى تتمكن واجهات المستخدم من عرض صف واحد لكل جهاز حتى عندما يتصل كـ مشغل و عقدة معًا.
طرق المساعدة للعقدة
- قد تستدعي العقد
skills.binsلجلب القائمة الحالية للملفات القابلة للتنفيذ للمهارات لفحوصات السماح التلقائي.
طرق المساعدة للمشغل
- قد يستدعي المشغلون
tools.catalog(operator.read) لجلب كتالوج أدوات وقت التشغيل للوكيل. تتضمن الاستجابة الأدوات المجمعة وبيانات المصدر:source:coreأوpluginpluginId: مالك المكون الإضافي عندما يكونsource="plugin"optional: ما إذا كانت أداة المكون الإضافي اختيارية
موافقات التنفيذ
- عندما يحتاج طلب التنفيذ إلى موافقة، تبث البوابة
exec.approval.requested. - يحلها عملاء المشغل عن طريق استدعاء
exec.approval.resolve(يتطلب نطاقoperator.approvals). - بالنسبة لـ
host=node، يجب أن يتضمنexec.approval.requestsystemRunPlan(argv/cwd/rawCommand/بيانات جلسة العمل الأساسية). يتم رفض الطلبات التي تفتقدsystemRunPlan.
التحكم بالإصدارات
PROTOCOL_VERSIONموجود فيsrc/gateway/protocol/schema.ts.- يرسل العملاء
minProtocol+maxProtocol؛ يرفض الخادم التطابقات غير المتطابقة. - يتم إنشاء المخططات + النماذج من تعريفات TypeBox:
pnpm protocol:genpnpm protocol:gen:swiftpnpm protocol:check
المصادقة
- إذا تم تعيين
OPENCLAW_GATEWAY_TOKEN(أو--token)، يجب أن يتطابقconnect.params.auth.tokenأو يتم إغلاق المقبس. - بعد الاقتران، تصدر البوابة رمز جهاز محدد النطاق لدور الاتصال + النطاقات. يتم إرجاعه في
hello-ok.auth.deviceTokenويجب على العميل الاحتفاظ به لاتصالات مستقبلية. - يمكن تدوير/إلغاء رموز الجهاز عبر
device.token.rotateوdevice.token.revoke(يتطلب نطاقoperator.pairing).
هوية الجهاز + الاقتران
- يجب أن تتضمن العقد هوية جهاز مستقرة (
device.id) مشتقة من بصمة زوج المفاتيح. - تصدر البوابات رموزًا لكل جهاز + دور.
- مطلوب موافقات الاقتران لهويات الأجهزة الجديدة ما لم يتم تمكين الموافقة التلقائية المحلية.
- تتضمن الاتصالات المحلية loopback وعنوان tailnet الخاص بمضيف البوابة نفسه (حتى يمكن لربطات tailnet على نفس المضيف الموافقة تلقائيًا).
- يجب على جميع عملاء WS تضمين هوية
deviceأثناءconnect(المشغل + العقدة). يمكن لواجهة التحكم حذفها فقط عندما يتم تمكينgateway.controlUi.dangerouslyDisableDeviceAuthللاستخدام في حالات الطوارئ. - يجب على جميع الاتصالات توقيع nonce
connect.challengeالمقدم من الخادم.
تشخيصات ترقية مصادقة الجهاز
للعملاء القديمين الذين لا يزالون يستخدمون سلوك التوقيع السابق للتحدي، يُرجع connect الآن رموز تفاصيل DEVICE_AUTH_* تحت error.details.code مع error.details.reason ثابت. حالات الفشل الشائعة أثناء الترقية:
| الرسالة | details.code | details.reason | المعنى |
|---|---|---|---|
device nonce required | DEVICE_AUTH_NONCE_REQUIRED | device-nonce-missing | العميل حذف device.nonce (أو أرسل فارغًا). |
device nonce mismatch | DEVICE_AUTH_NONCE_MISMATCH | device-nonce-mismatch | وقع العميل باستخدام nonce قديم/خاطئ. |
device signature invalid | DEVICE_AUTH_SIGNATURE_INVALID | device-signature | الحمولة الموقعة لا تطابق حمولة v2. |
device signature expired | DEVICE_AUTH_SIGNATURE_EXPIRED | device-signature-stale | الطابع الزمني الموقع خارج النطاق المسموح به. |
device identity mismatch | DEVICE_AUTH_DEVICE_ID_MISMATCH | device-id-mismatch | device.id لا يطابق بصمة المفتاح العام. |
device public key invalid | DEVICE_AUTH_PUBLIC_KEY_INVALID | device-public-key | فشل تنسيق/توحيد المفتاح العام. |
هدف الترقية:
- انتظر دائمًا
connect.challenge. - وقع حمولة v2 التي تتضمن nonce الخادم.
- أرسل نفس nonce في
connect.params.device.nonce. - الحمولة الموقعة المفضلة هي
v3، والتي تربطplatformوdeviceFamilyبالإضافة إلى حقول الجهاز/العميل/الدور/النطاقات/الرمز/الـ nonce. - لا تزال تواقيع
v2القديمة مقبولة من أجل التوافق، لكن تثبيت بيانات الجهاز المقترن لا يزال يتحكم في سياسة الأمر عند إعادة الاتصال.
TLS + التثبيت
- TLS مدعوم لاتصالات WS.
- قد يثبت العملاء اختياريًا بصمة شهادة البوابة (انظر إعداد
gateway.tlsبالإضافة إلىgateway.remote.tlsFingerprintأو--tls-fingerprintفي CLI).
النطاق
يعرض هذا البروتوكول واجهة برمجة تطبيقات البوابة الكاملة (الحالة، القنوات، النماذج، الدردشة، الوكيل، الجلسات، العقد، الموافقات، إلخ). يتم تحديد السطح الدقيق بواسطة مخططات TypeBox في src/gateway/protocol/schema.ts.