وثائق المصادقة في SingleFax

مفاتيح API وOAuth لاتصالات MCP وتفويض Agent Auth.

دليل المصادقة لوكلاء الذكاء الاصطناعي والمطورين.

كيفية مصادقة الوكلاء لدى SingleFax. التثبيت عبر HTML: https://singlefax.com/agents

هذا الملف هو الهدف agent_auth.skill المُعلن في البيانات الوصفية RFC 8414 على /.well-known/oauth-authorization-server.

يدعم SingleFax التسجيل عبر Auth.md باستخدام anonymous وservice_auth، مع موافقة المستخدم وإثباتات هوية موقعة من الخدمة. لا تتيح بيانات الاعتماد المجهولة الوصول إلى أي حساب قبل الموافقة. لا تُقبل ID-JAG الصادرة عن مزود خارجي. يُوثق مسار JWT الأقدم للمضيف والوكيل في Better Auth بشكل منفصل ضمن المسار C.

التسجيل عبر Auth.md ومبادلة الرموز

الجمهور المستهدف: وكلاء الذكاء الاصطناعي الذين يسجلون للعمل نيابةً عن حساب SingleFax قائم. يلزم تسجيل صادر عن المالك لكل طرق التسجيل. تُرفض الطلبات العامة التي لا تتضمن رمز تسجيل صالحًا قبل إنشاء التسجيل. جهة إصدار OAuth هي https://api.singlefax.com/api/auth؛ والمورد هو https://singlefax.com/mcp. لا يؤدي التسجيل إلى إرسال بريد أو فاكس أو تحصيل مبلغ.

طرق التسجيل المدعومة: anonymous وservice_auth. بيانات الاعتماد: identity_assertion وBearer ‏access_token. يسجل صاحب الحساب الدخول إلى SingleFax، ويراجع الأذونات المطلوبة، ويدخل الرمز المكوّن من ستة أرقام الذي يعرضه وكيله. النطاقات المدعومة هي fax:read وfax:draft وfax:send وinbox:read وcredits:read وcredits:checkout. الأذونات الافتراضية هي fax:read وcredits:read؛ اطلب النطاقات الإضافية صراحةً.

  1. يسجل المالك الدخول على https://singlefax.com/dashboard/agent-access، ويختار اسم الوكيل والصلاحيات المسموح بها، ثم يُنشئ صراحةً رمز تسجيل. يُعرض هذا السر قصير الأجل مرة واحدة، وتنتهي صلاحيته بعد عشر دقائق، ولا يسجل إلا وكيلًا واحدًا. أعطه للوكيل. يستخدم التجهيز عبر API جلسة متصفح المالك المباشرة على POST https://singlefax.com/api/auth/agent/identity/manage مع { "action": "enroll", "name": "My agent", "scopes": ["fax:read", "credits:read"] }. لا تُشارك ملفات تعريف ارتباط المتصفح مع الوكيل مطلقًا. يمكن للمالك إلغاء الرموز غير المستخدمة من الصفحة نفسها.
  2. سجّل باستخدام POST https://api.singlefax.com/api/auth/agent/identity مع Content-Type: application/json و{ "type": "service_auth", "enrollment_token": "<owner-issued token>", "login_hint": "<enrolling owner email>" }. يُرجع ذلك registration_id وclaim_token سريًا وموعد انتهاء الصلاحية وclaim مع user_code وverification_uri وفاصل استعلام خمس ثوانٍ. لا يصدر أي إثبات قبل الموافقة.
  3. أو سجّل باستخدام { "type": "anonymous", "enrollment_token": "<owner-issued token>" }. المقصود بالمجهول هنا بيانات الاعتماد قبل ربطها بالحساب، وليس التسجيل العام المفتوح. يُرجع ذلك فورًا identity_assertion موقّعًا وclaim_token. تؤدي مبادلة الإثبات قبل الربط إلى رمز بلا نطاقات لا يتيح الوصول إلى أي حساب. ابدأ موافقته باستخدام POST https://api.singlefax.com/api/auth/agent/identity/claim مع { "claim_token": "<secret>", "email": "<account email>" }، واقرأ claim_attempt المُرجع.
  4. اعرض الرمز منفصلًا وافتح verification_uri للمستخدم. يحتوي الرابط على رمز سري لمحاولة الربط؛ فلا تُدرج الرمز المعروض في هذا الرابط. لا يمكن الموافقة إلا للحساب المتحقق الذي أصدر التسجيل. يحدد المالك الاسم؛ ويمكن تضييق النطاقات المطلوبة دون تجاوز أذونات التسجيل. يجب أن يتطابق تلميح البريد وبريد الربط مع المالك المُسجِّل. للمستخدم حق الرفض. تنتهي صلاحية محاولات الربط بعد عشر دقائق؛ وتبطل كل محاولة جديدة الرابط القديم. لا يُنشأ أي حساب تلقائيًا.
  5. استعلم دوريًا من POST https://api.singlefax.com/api/auth/oauth2/token مع Content-Type: application/x-www-form-urlencoded وgrant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<secret>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. تعامل مع authorization_pending وslow_down (زد الفاصل خمس ثوانٍ) وexpired_token وaccess_denied. تُرجع الموافقة access_token معتمًا وtoken_type وexpires_in وscope وidentity_assertion وassertion_expires. تُبطل الرموز والإثباتات السابقة للربط عند الموافقة.
  6. استخدم Authorization: Bearer <access_token> على MCP أو A2A بالنطاقات الممنوحة. لا تتجاوز صلاحية الرموز ساعة واحدة. للتجديد، استخدم نقطة نهاية الرموز نفسها مع grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. لا يصدر رمز تحديث. تظل الإثباتات قابلة للمبادلة مجددًا حتى 30 يومًا ما لم يُلغَ التسجيل. تستخدم توقيعات EdDSA فيها /jwks لجهة الإصدار؛ وtyp يساوي oauth-id-jag+jwt، ويساوي كل من iss/aud جهة الإصدار.
  7. ألغِ رمزًا واحدًا باستخدام POST https://api.singlefax.com/api/auth/oauth2/revoke وجسم نموذج token=<access_token>&token_type_hint=access_token. يمكن تكرار ذلك دون أثر إضافي ويظل الإثبات صالحًا للاستخدام. ألغِ التسجيل باستخدام POST https://api.singlefax.com/api/auth/agent/identity/revoke وJSON ‏{ "identity_assertion": "<identity_assertion>" }؛ فتتوقف جميع رموز الوصول والمبادلات اللاحقة.

يمكن لصاحب الحساب مراجعة الأذونات وإلغاؤها على https://singlefax.com/dashboard/agent-access. يؤدي إلغاء التسجيل إلى إيقاف جميع رموز الوصول المرتبطة به وتجديد الإثباتات.

ردود الربط والموافقة خاصة ولا يجوز تخزينها مؤقتًا. حافظ على سرية رموز الربط والإثباتات ورموز الوصول. يخضع إصدار رموز التسجيل لحد لكل مالك عبر نسخ API، مع خمسة رموز نشطة غير مستخدمة كحد أقصى. لا تستهلك الطلبات العامة غير المسجلة حصة تسجيل المالك. يُرجع الرمز المفقود enrollment_required؛ وتُرجع الرموز المنتهية أو الملغاة أو المستخدمة invalid_enrollment. لا تستهلك محاولة التسجيل الفاشلة رمز التسجيل. لا تختبر نقاط نهاية التسجيل خلال فحوص الجاهزية السلبية.

الاكتشاف

خادم الموارد (MCP وAPI BFF): ‏https://singlefax.com

GET https://singlefax.com/.well-known/oauth-protected-resource
GET https://singlefax.com/.well-known/oauth-protected-resource/mcp

البيانات الوصفية للمورد المحمي (RFC 9728): يصف المستند الجذري الأصل (resource ‏https://singlefax.com)؛ ويصف /.well-known/oauth-protected-resource/mcp خادم MCP ‏(resource ‏https://singlefax.com/mcp، الذي يشير إليه الرابط WWW-Authenticate). يدرج كلاهما authorization_servers (جهة الإصدار https://api.singlefax.com/api/auth) وscopes_supported. اطلب الرموز للمورد https://singlefax.com/mcp.

GET https://singlefax.com/.well-known/oauth-authorization-server
GET https://singlefax.com/.well-known/oauth-authorization-server/api/auth

تتضمن البيانات الوصفية لخادم التفويض issuer وauthorization_endpoint وtoken_endpoint وregistration_endpoint وjwks_uri وscopes_supported وagent_auth (ويشير skill إلى هنا).

يقدم أصل API ‏https://api.singlefax.com وثائق well-known نفسها.

المسار A. ‏MCP OAuth (تطبيقات الدردشة)

استخدم هذا مع Cursor وClaude وChatGPT وCodex وVS Code.

  1. أضف MCP ‏https://singlefax.com/mcp (Streamable HTTP).
  2. عند 401، اقرأ WWW-Authenticate واجلب PRM أعلاه.
  3. تسجيل العميل الديناميكي: POST {issuer}/oauth2/register ‏(PKCE S256 وtoken_endpoint_auth_method=none للعملاء العامين).
  4. رمز تفويض مع PKCE على {issuer}/oauth2/authorize.
  5. الرمز على {issuer}/oauth2/token.
  6. استخدم POST /mcp مع Authorization: Bearer. للمستند المعتاد، استدعِ create_upload وأعطِ المستخدم uploadPageUrl، ثم create_fax_draft مع to وuploadToken. ‏base64 للملفات الصغيرة جدًا فقط. يستخدم PUT إلى uploadUrl رمز HMAC في المسار دون ترويسة OAuth. أرسل ملف Word أو Excel أو PDF أو الصورة الأصلي؛ ولا تحوّله إلى PDF أولًا.

النطاقات: openid وprofile وemail وoffline_access وfax:read وfax:draft وfax:send وinbox:read وcredits:read وcredits:checkout. اطلب credits:checkout صراحةً لشراء الرصيد عبر AP2؛ وتظل كل عملية تحصيل بحاجة إلى موافقة منفصلة بمفتاح مرور.

يقبل POST /mcp دون مصادقة server/discover فقط. تتطلب initialize وtools/list وtools/call استخدام OAuth.

المسار A2. ‏A2A (من وكيل إلى وكيل)

بطاقة الوكيل: GET https://singlefax.com/.well-known/agent-card.json ‏(A2A 1.0). نقطة النهاية: POST https://singlefax.com/a2a ‏(JSON-RPC: ‏SendMessage وGetTask وCancelTask؛ وتعمل أيضًا أسماء الإصدار 0.3 ‏message/send وtasks/get وtasks/cancel).

  1. استخدم خادم OAuth والنطاقات والرموز نفسها في المسار A (اطلب المورد https://singlefax.com/mcp). أرسل Authorization: Bearer. لا تُقبل الرموز المرتبطة بـDPoP على /a2a.
  2. أرسل جزء بيانات واحدًا: { "skill": "<skill id from the card>", "arguments": { ... } }. لا يُفسر النص الحر.
  3. تُرجع مهارات الفاكس والأرقام رابط Stripe Checkout ‏(checkoutUrl). لا يستخدم A2A رصيد الحساب أو صفحات الخطة مطلقًا. تكون حالة مهمة المسودة المنتظرة للدفع input-required. استعلم دوريًا باستخدام GetTask.

لشراء الرصيد عبر AP2، اطلب credits:checkout واتفق على إضافة التاجر. تُوثق تفويضات السلة والدفع الموقّعة، وموافقة المالك المنفصلة بمفتاح مرور، واستبدال Stripe Shared Payment Token، والإيصالات المؤكدة في دفتر الحسابات على https://singlefax.com/ap2.md.

يتابع GetTask مع fax:read تسليم الفاكس لمسودات الفاكس، والدفع والتجهيز لشراء الأرقام. تكتمل مهمة الرقم عند تفعيله. لا تتضمن عملية شراء حزمة الرصيد مهمة مرتبطة بطلب للاستعلام عنها؛ تحقق من الرصيد بعد الدفع.

المسار B. مفتاح API (الأنظمة الخلفية وCLI)

  1. أنشئ مفتاحًا على https://singlefax.com/dashboard/api-keys ‏(sf_live_…).
  2. اشترِ رصيدًا مدفوعًا مقدمًا.
  3. استخدم Authorization: Bearer sf_live_… على https://singlefax.com/api/v1/… (أو https://api.singlefax.com/api/v1/…).
  4. CLI: استخدم npx @singlefax/cli send FILE --to +E164 مع SINGLEFAX_API_KEY. مرّر ملف Word أو Excel أو PDF أو الصورة الأصلي؛ ولا تحوّله إلى PDF أولًا.

أمثلة لغات البرمجة (curl وNode وPython وGo وPHP): https://singlefax.com/developers.md

OpenAPI: https://singlefax.com/openapi.json

المسار C. رموز JWT المفوّضة للمضيف والوكيل عبر Better Auth

تستخدم الصلاحيات المفوّضة (validate_fax وsend_fax وget_fax_status وget_credits وcreate_credit_checkout) الموافقة عبر الجهاز.

  1. اقرأ GET https://api.singlefax.com/.well-known/agent-configuration لمعرفة الخوارزميات ونقاط النهاية والأوضاع وطرق الموافقة. جهة إصدار Agent Auth هي https://api.singlefax.com، وتختلف عن جهة إصدار OAuth التي ينتهي عنوانها بـ/api/auth. استخدم هذا الأصل جمهورًا مستهدفًا لـJWT. أنشئ مفتاحي توقيع منفصلين للمضيف والوكيل بخوارزمية مدعومة، وحافظ على سرية المفاتيح الخاصة.
  2. جهّز المضيف أولًا. التسجيل الديناميكي للمضيف معطل. يجب على صاحب الحساب تسجيل الدخول إلى SingleFax واستدعاء POST https://singlefax.com/api/auth/host/create (المكافئ على أصل API: https://api.singlefax.com/api/auth/host/create) باستخدام جلسة متصفحه المباشرة. قدّم { "name": "My agent host", "public_key": <host public JWK>, "default_capabilities": [] }. يحدد hostId في الرد المضيف المسجل. تضمن الإعدادات الافتراضية الفارغة أن كل صلاحية تتطلب موافقة منفصلة. أو احذف public_key لتلقي enrollmentToken محدود الصلاحية ويُستخدم مرة واحدة؛ ثم يستدعي المضيف POST https://api.singlefax.com/api/auth/host/enroll مع { "token": <enrollment token>, "public_key": <host public JWK>, "name": "My agent host" }. لا تشارك ملفات تعريف ارتباط المتصفح أو مفاتيح التوقيع الخاصة مع الوكيل مطلقًا.
  3. سجّل عبر POST https://api.singlefax.com/api/auth/agent/register. أرسل Authorization: Bearer <signed host+jwt> وJSON ‏{ "name": "My agent", "mode": "delegated", "capabilities": ["validate_fax", "get_fax_status", "get_credits"], "preferred_method": "device_authorization", "force_approval": true }. تستخدم ترويسة JWT ‏typ: "host+jwt" وalg مدعومًا (وkid من JWK التوقيع إن وُجد). تتضمن المطالبات iss: <registered hostId> وaud: "https://api.singlefax.com" وjti جديدًا وiat حاليًا وexp ضمن 60 ثانية وagent_public_key: <agent public JWK>. وقّع بمفتاح المضيف المجهّز. تُرفض معرّفات JWT المعاد استخدامها.
  4. يُرجع التسجيل agent_id وhost_id والحالة والصلاحيات الممنوحة وكائن approval عند الحاجة. اعرض رمز الجهاز وافتح verification_uri_complete على موقع SingleFax. يسجل المستخدم الدخول ويوافق عبر رابط التحقق المُرجع. يغيّر التسجيل والتجهيز والموافقة حالة الحساب؛ لذا يجب على أدوات الفحص السلبي قراءة وثائق الاكتشاف فقط.
  5. استعلم دوريًا من GET https://api.singlefax.com/api/auth/agent/status?agent_id=<registered id> باستخدام JWT جديد للمضيف (iss: <host_id>). بعد الموافقة، وقّع JWT الوكيل بمفتاحه الخاص: الترويسة typ: "agent+jwt"، وalg/kid المدعومان؛ والمطالبات iss: <host_id> وsub: <agent_id> وaud: "https://api.singlefax.com" وiat حاليًا وexp ضمن 60 ثانية وjti جديدًا. استدعِ POST https://api.singlefax.com/api/auth/capability/execute مع Authorization: Bearer <signed agent+jwt> و{ "capability": "get_credits", "arguments": {} }، أو صلاحية ممنوحة أخرى بمعاملاتها الموثقة. بيانات الاعتماد هذه إثباتات موقّعة وليست مفاتيح API أو رموز وصول OAuth.
  6. للحصول على رمز جهاز جديد لوكيل مسجل، استخدم POST https://api.singlefax.com/api/auth/agent/device/code مع { "agent_id": "<registered id>" } وJWT موقّع للمضيف. لا تسجّل نقطة النهاية هذه وكيلًا. للإلغاء، استخدم POST https://api.singlefax.com/api/auth/agent/revoke مع { "agent_id": "<registered id>" } وJWT المضيف المالك أو جلسة المالك. يتطلب send_fax تحقق المستخدم بمفتاح مرور؛ ولا يعمل بصورة مستقلة.

لا ترسل ID-JAG أو { "type": "anonymous" } إلى هنا عبر POST. أنواع الهوية هذه غير مدعومة.

مدفوعات الآلة (ليست OAuth)

الدفع المستقل يستخدم MPP HTTP 402 على POST /api/v1/machine/faxes مع Stripe Shared Payment Token أو Tempo USDC. راجع https://singlefax.com/mpp.md. لا يستطيع Cursor إنشاء SPT؛ استخدم Stripe Link CLI مع رابط REST هذا، وليس /mcp. تسدد محافظ Tempo تحدي Tempo على الرابط نفسه.

HIPAA

لا ترسل معلومات صحية محمية عبر MCP أو MPP أو API العامة. تستخدم الجهات المشمولة وضع HIPAA Secure على الموقع مع اتفاقية BAA إلكترونية.