# معماری MCP مرکزی AdminJump

یک سرور HTTP مشترک Laravel MCP 1.0.2 همهٔ اتصال‌ها را سرویس می‌دهد؛ هر UUID پردازش مستقل ندارد. مسیر `POST /mcp/connections/{uuid}`، resource و audience همان آدرس کامل هستند. UUID عمومی به‌تنهایی مجوز نیست. این adapter به API Key مگاشاپ دسترسی مستقیم کلاینت نمی‌دهد.

```mermaid
flowchart LR
 Client[AI Client] --> OAuth[OAuth code + PKCE]
 Client --> MCP[Central MCP / Bearer]
 OAuth --> Grant[Connection / Grant / Session]
 MCP --> Auth[Current effective permissions]
 Auth --> Tools[AiToolService]
 Tools --> Articles[ArticleService / HistoryService / SyncService]
 Articles --> Queue[Durable operation + queue]
 Queue --> CMS[ConnectorManager / CMS API]
```

OAuth با League OAuth2 Server 9.4.1، JWT با Lcobucci و رمزنگاری کد/توکن تمدید با Defuse انجام می‌شود. رمزنگاری اختصاصی نداریم. Opis JSON Schema ورودی ابزار را بررسی می‌کند. UI انسانی و AI از سرویس‌های مشترک استفاده می‌کنند. اصل مقاله، کنترل version و idempotency نهایی همچنان در CMS است.

چهار مفهوم مجزا:

| مفهوم | مسئولیت |
|---|---|
| OAuthClient | هویت نرم‌افزار، metadata و callbackهای دقیق |
| AiConnection | یک سایت، سازنده، نام و سقف مجوزهای قابل کاهش |
| AiAuthorizationGrant | تأیید یک کاربر برای client، connection، resource و scopes |
| AiSession | خانوادهٔ توکن‌ها، scopes جاری، انقضا و لغو مستقل |

جداول جدید در migration `2026_10_14_000016_create_ai_oauth_tables.php` هستند. PK/FK و index و UUID عمومی مستقل حفظ شده‌اند. grant و token جدول‌های جدا دارند؛ نصب Passport انجام نشده و جدول‌های آن شبیه‌سازی نشده‌اند. هر operation موجود فقط metadata هویت AI، hash ورودی و UUID درخواست می‌گیرد؛ محتوای مقاله همچنان فایل خصوصی است.

Transport واقعی SDK از 2026-07-28 با server/discover و نسخه‌های legacy 2025-11-25 و 2025-06-18 با initialize پشتیبانی می‌کند. Stateless است؛ نشست پنل، خانوادهٔ OAuth است و `Mcp-Session-Id` نیست. JSON-RPC، پاسخ JSON و خطای استاندارد بر عهدهٔ SDK است. GET stream و DELETE protocol session پشتیبانی نمی‌شوند و 405 می‌دهند؛ polling وضعیت operation ابزار استاندارد این برنامه است.

اعمال مجوز و لغو/محدودسازی/صدور توکن و ارسال صف با قفل مشترک connection هماهنگ‌اند. در چند instance، cache lock باید مشترک باشد؛ cache database فعلی یا Redis مناسب است، cache array مناسب deployment نیست. عملیاتی که ارسالش پیش از لغو شروع شده، ممکن است در CMS پایان یابد؛ لغو تغییر انجام‌شده را rollback نمی‌کند. CMS باید هنگام write هم مجوز و version را اتمیک کنترل کند.

محصولات MCP، agent اختصاصی خارج از مجوز کاربر، منابع/prompts اختصاصی، SSE بلندمدت و انتقال grant بین سایت‌ها در این نسخه فعال نیستند. افزودن Connector جدید منطق OAuth را تکثیر نمی‌کند.


---

# OAuth و Discovery

issuer ثابت از APP_URL می‌آید؛ باید دقیقاً با دامنهٔ عمومی نصب برابر باشد. Resource هر اتصال آدرس کامل `/mcp/connections/UUID` است. Token برای همین audience صادر می‌شود؛ اشتراک token بین UUIDها، سایت‌ها یا CMS ممنوع است.

## مسیرها

| مسیر | کاربرد |
|---|---|
| GET /.well-known/oauth-authorization-server | RFC 8414؛ issuer، endpoints، S256، CIMD و iss |
| GET /.well-known/oauth-protected-resource/mcp/connections/UUID | RFC 9728؛ resource و authorization_servers |
| GET /oauth/authorize | ورود وب موجود و نمایش Consent |
| POST /oauth/authorize | CSRF، nonce یک‌بارمصرف و تأیید/رد |
| POST /oauth/token | code یا refresh_token، با resource اجباری |
| POST /oauth/revoke | RFC 7009؛ لغو خانوادهٔ متعلق به client |
| POST /oauth/register | DCR عمومی محدود، قابل غیرفعال‌کردن |

در نبود Bearer معتبر، MCP پاسخ401 با `WWW-Authenticate: Bearer resource_metadata="https://HOST/.well-known/oauth-protected-resource/mcp/connections/UUID", error="invalid_token"` می‌دهد. discovery کلید یا token ندارد. Issuer در redirect هم با `iss` مطابق RFC9207 بازگردانده می‌شود.

## Authorization Code

```text
GET /oauth/authorize?
 response_type=code&client_id=CLIENT_ID
 &redirect_uri=EXACT_REGISTERED_CALLBACK
 &resource=https://HOST/mcp/connections/UUID
 &scope=articles.read%20articles.create
 &state=CLIENT_RANDOM_STATE
 &code_challenge=BASE64URL_SHA256_VERIFIER
 &code_challenge_method=S256
```

فقط S256؛ challenge دقیقاً43 کاراکتر base64url. رمز/implicit/client_credentials/password grant پشتیبانی نمی‌شود. client موظف است state تصادفی و پاسخ آن و issuer را اعتبارسنجی کند؛ سرور state را بدون تغییر برمی‌گرداند و nonce مستقل Consent را به حساب وب، پارامترهای اصلی و پنج دقیقه محدود می‌کند. تغییر body هنگام تأیید نمی‌تواند resource، scopes یا callback را عوض کند.

پس از تأیید، code پنج‌دقیقه‌ای و یک‌بارمصرف است. client با فرم URL-encoded و `grant_type=authorization_code`، `client_id`، `redirect_uri`، `resource`، `code` و `code_verifier` آن را مبادله می‌کند. public client روش none و confidential client از پیش ثبت‌شده client_secret_basic دارد. PKCE برای هر دو الزامی است.

Access Token پانزده دقیقه و خانوادهٔ نشست سی روز است. JWT امضاشده شامل iss، aud=resource، sub=user، client_id، scopes و jti است. raw JWT در DB ذخیره نمی‌شود. کد و refresh token توسط کتابخانه رمز می‌شوند؛ DB شناسه و زمان انقضا/لغو را دارد. تغییر APP_KEY کد/refresh را نامعتبر می‌کند؛ آن را دوباره تولید نکنید.

## تمدید و لغو

```text
POST /oauth/token
grant_type=refresh_token&client_id=CLIENT_ID
&resource=EXACT_RESOURCE&refresh_token=ENCRYPTED_REFRESH
```

scope اختیاری فقط می‌تواند کاهش یابد. refresh rotation توکن قدیمی را مصرف می‌کند. reuse توکن قدیمی، کل خانوادهٔ نشست را لغو می‌کند، حتی بعد از rollback تراکنش ناموفق. هر client باید تمدید را serialize کند و refresh token تازه را اتمیک جایگزین کند. طبیعی است reuse هم‌زمان یک refresh موجب قطع خانواده شود.

Revocation با client_id و token مرتبط، کل خانوادهٔ access/refresh را لغو می‌کند. توکن ناشناخته مطابق RFC7009 پاسخ200 دارد؛ به معنی معتبر بودن آن نیست. خطای عملیاتی لغو نباید موفقیت کاذب گزارش شود.

## ثبت client

CIMD: client_id یک URL عمومی HTTPS غیرریشه‌ای است. document باید client_id دقیقاً برابر همان URL، client_name، redirect_uris و auth none داشته باشد. دریافت DNS امن، IP pin، TLS verify، سقف64KB، timeout و منع redirect دارد؛ مقصد داخلی و userinfo ممنوع‌اند. cache ده دقیقه است و تغییر metadata بعداً دوباره بررسی می‌شود.

DCR: client_name و redirect_uris لازم‌اند؛ public none، code/refresh و response code. callback باید عضو دقیق MCP_REDIRECT_URIS باشد؛ wildcard و callback انتخابی دلخواه وجود ندارد. http loopback تنها در local/testing با MCP_LOCAL_REDIRECTS=true مجاز است. client metadata URL برخلاف callback اجازهٔ خودکار HTTP داخلی نمی‌دهد. ثبت محدود به پنج درخواست در دقیقه است.

تنظیمات Production: HTTPS واقعی، APP_DEBUG=false، proxy مورد اعتماد درست، APP_URL ثابت، SESSION_SECURE_COOKIE=true و redirect/origin دقیق. تغییر نام نرم‌افزار در CIMD دلیل اعتماد به آن نیست؛ صفحه Consent شناسهٔ client را هم نشان می‌دهد.


---

# مجوز مؤثر AI

ایجاد/مدیریت اتصال `ai.connections.manage` دارد. Owner می‌تواند همهٔ اتصال‌های همان سایت را مدیریت کند؛ Manager فقط با permission صریح و برای اتصال‌های خودش. نام role به‌تنهایی مجوز نمی‌دهد. creator و تأییدکننده هر دو باید هنوز عضو مجاز سایت و دارای مجوز مدیریت AI باشند.

مجوز مؤثر اشتراک این موارد است:

1. مجوز فعلی creator و کاربر grant در AdminJump؛
2. allowed_permissions فعلی Connection؛
3. scopes تأییدشدهٔ Grant؛
4. scopes همان token و وضعیت/انقضای Session؛
5. قابلیت Connector و sync فعال؛
6. scope واقعی کلید CMS، authenticated، site.owner و هویت ثابت site_id؛
7. متصل بودن سایت و لغو نشده بودن client، grant و connection.

سایت/کاربر/connection در Schema ورودی ابزار وجود ندارند. tenant از token و resource معتبر تعیین می‌شود. هر ابزار حتی خواندن، کلید زندهٔ CMS را بررسی می‌کند؛ UI سریع مقالات همچنان از snapshot محلی استفاده می‌کند. UUID منبع یا operation سایت دیگر به خروجی نمی‌رسد.

| عملیات | مجوز لازم |
|---|---|
| list/get/versions | articles.read |
| create draft | articles.create |
| update draft | articles.update |
| publish | articles.update + articles.publish |
| create published / edit published | create یا update + articles.publish |
| delete | articles.delete |
| restore | articles.read + articles.update؛ در صورت حذف create، در صورت انتشار publish نیز |
| status | نشست معتبر، فقط operation/approval همان نشست |

انتشار، حذف، ویرایش مقالهٔ منتشرشده و بازگردانی منتشرشده نیازمند Approval وب مجزا، CSRF و User معتبرند. درخواست AI صرفاً approval_required برمی‌گرداند و Job ساخته نمی‌شود. Approval پانزده دقیقه فرصت دارد، payload فایل خصوصی تغییرناپذیر است و در همان connection قفل می‌شود. کاهش مجوز یا لغو پیش از تأیید، جلوی ارسال را می‌گیرد. Worker مجوز فعلی تأییدکننده را هم دوباره می‌سنجد.

صف مجوزها را هنگام اجرا دوباره از DB و API می‌خواند. refresh معمولی نباید نوشتهٔ durable را از دست بدهد: worker به خانوادهٔ فعال، scopes جاری کاهش‌یافتهٔ آن، scopes token اصلی و grant فعلی متکی است؛ انقضای عادی access15دقیقه‌ای به‌تنهایی Job را از بین نمی‌برد. عملیات AI پس از24ساعت بدون اجرای موفق متوقف می‌شود. لغو خانواده یا کاهش scopes فوراً Job اجرا‌نشده را رد می‌کند.

مالک سایت در AdminJump همهٔ Permissionهای تعریف‌شدهٔ سایت خودش را دارد. در جزئیات اتصال AI می‌تواند مجوزهای قابل اجرای همین سایت را هم افزایش و هم کاهش دهد؛ ساخت اتصال دوباره لازم نیست. افزایش، تمام Grant/Session/Access/Refreshهای قبلی همان اتصال را لغو می‌کند و OAuth و Consent تازه لازم دارد. فرم نسخهٔ مجوزها را می‌فرستد؛ زیر قفل اتصال، نسخهٔ کهنه رد می‌شود تا نتواند کاهش هم‌زمان را بازگرداند. Manager تنها اتصال خودش را مدیریت می‌کند و همچنان فقط کاهش مجاز است. مجوز مربوط به ابزار پیاده‌سازی‌نشده یا API پشتیبانی‌نشده، عملیات اجرایی ایجاد نمی‌کند.

حذف عضویت grantها/نشست‌های وابسته را لغو می‌کند. قطع CMS همهٔ خانواده‌های سایت را لغو می‌کند و اتصال دوباره نیازمند OAuth تازه است. کلید CMS لغوشده نیز در call و worker رد می‌شود. محتوای HTML/Markdown از CMS دادهٔ غیرقابل اعتماد است و دستور اجرایی AI محسوب نمی‌شود.


---

# قرارداد ابزارهای MCP

Schema دقیق در پاسخ tools/list و App\Mcp\ToolCatalog موجود است. additionalProperties=false؛ input خارج Schema به صورت isError با پیام امن رد می‌شود، ابزار ناشناخته خطای JSON-RPC دارد. هر ابزار خروجی موفق structuredContent با status دارد و نسخه متنی همان خروجی هم توسط SDK ارائه می‌شود. خطاهای ابزار result.isError=true دارند؛ کلاینت باید هر دو سطح JSON-RPC و isError را بررسی کند.

| ابزار | ورودی |
|---|---|
| list_articles | q<=200، status=draft/published/archived، page>=1، per_page=1..100؛ همه اختیاری |
| get_article | article_id رشتهٔ شناسهٔ CMS |
| get_article_versions | article_id، version_id اختیاری UUID برای دریافت محتوای نسخه |
| get_article_operation_status | دقیقاً یکی از operation_id یا approval_id UUID |
| create_article | request_id UUID، title، content؛ content_format، status، featured_image اختیاری |
| update_article | همان create به‌علاوه article_id و version فعلی |
| publish_article | request_id، article_id، version |
| delete_article | request_id، article_id، version |
| restore_article_version | request_id، version_id UUID، version فعلی مقاله |

title حداکثر250، content حداکثر100000 نویسه. content_format پیش‌فرض markdown و html نیز مجاز و پاک‌سازی‌شده است؛ status پیش‌فرض draft برای create و وضعیت فعلی برای update. featured_image رشتهٔ URL یا null؛ نبود آن هنگام update تصویر فعلی را حفظ می‌کند. تصاویر داخل Markdown با `![متن](https://HOST/image.jpg)` ممکن‌اند؛ دریافت/ذخیره/upload از سرویس امن موجود در worker می‌گذرد، با سقف20تصویر و محدودیت مقصد/اندازه/نوع. ابزار upload باینری اختصاصی نداریم.

version یک رشته عددی مثبت از پاسخ get_article است؛ انتظار CAS سرور CMS است. article_id حداکثر120 کاراکتر از حروف/عدد/underscore/dash است. `request_id` نقش Idempotency-Key adapter را دارد؛ آن را برای retry همان عملیات حفظ کنید و برای تغییر واقعی UUID تازه بسازید. هدر اختیاری Idempotency-Key باید همان UUID request_id باشد؛ اختلاف رد می‌شود. dedupe در سطح خانوادهٔ نشست است و hash tool+payload باید یکسان بماند. UUID operation مشترک در CMS هم به‌عنوان idempotency key ارسال می‌شود. بازگردانی مقالهٔ حذف‌شده یک مقالهٔ تازه با شناسهٔ تازه ایجاد می‌کند؛ undelete فیزیکی CMS نیست.

```json
{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/call",
  "params": {
    "name": "create_article",
    "arguments": {
      "request_id": "c058e184-3d16-45fb-ae51-107e37d1e2a6",
      "title": "مقالهٔ تازه",
      "content": "## مقدمه\nمتن مقاله",
      "content_format": "markdown",
      "status": "draft"
    }
  }
}
```

خروجی structuredContent نمونه:

```json
{"status":"pending","operation_id":"UUID","article_id":null,"cms_confirmed":false,"error":null}
```

| status | معنی |
|---|---|
| ok | خواندن موفق؛ ادعای انتشار نیست |
| pending | durable محلی، هنوز در CMS تأیید نشده؛ یا نیاز به approval |
| processing | worker در حال ارسال |
| confirmed | CMS پاسخ معتبر داده و snapshot اعمال شده |
| conflict | version هم‌زمان تغییر کرده؛ بازخوانی و تصمیم تازه لازم است |
| failed | مجوز/شبکه پس از retry/اعتبارسنجی/approval نامعتبر |

در عملیات حساس خروجی `approval_required=true`، `approval_id` و `approval_url` نیز دارد. لینک را برای تأیید انسانی باز کنید؛ AI نمی‌تواند با پارامتر bypass آن را تأیید کند. تأیید دوباره همان approval Job جدید نمی‌سازد. statuspoll فقط operation همان نشست را می‌پذیرد. تاریخچه پنج نسخه متفاوتِ محتوای تأییدشده با متن/عکس فایل خصوصی است؛ restore نوشتن تازهٔ صفی است، rollback مستقیم CMS نیست.

2025 legacy: initialize سپس notifications/initialized و tools/* با Accept: application/json,text/event-stream و MCP-Protocol-Version. در 2026-07-28: server/discover، سپس هر درخواست params._meta["io.modelcontextprotocol/protocolVersion"] و هدرهای MCP-Protocol-Version، Mcp-Method و Mcp-Name (برای toolcall). از SDK استاندارد برای negotiation استفاده کنید. هیچ API Key مقصد یا مسیر فایل خصوصی در نتیجهٔ ابزار وجود ندارد.


---

# اتصال، نشست و نگهداری داده

در سایت → «همکاران و هوش مصنوعی» → تب AI، ساخت اتصال سه مرحله دارد: مشخصات، scope، تأیید ساخت. endpoint UUID فقط یک نشانی عمومی است؛ وضعیت pending تا OAuth کامل شود. چند خانوادهٔ نشست می‌توانند متعلق به یک connection باشند.

جزئیات اتصال شامل endpoint قابل کپی، سقف مجوزها، تأییدهای عملیات حساس، نام client، کاربر grant، scopes جاری، زمان صدور/انقضا/آخرین استفاده، لغو یک نشست یا همه، و Audit صفحه‌بندی‌شده است. API Key و raw Access/Refresh Token در صفحه نمایش داده نمی‌شوند.

لغو نشست، access tokenهای همان خانواده و refresh tokenهای مرتبط را لغو می‌کند. «قطع تمام نشست‌ها» grantهای قبلی را هم لغو می‌کند، ولی endpoint برای OAuth تازه باقی می‌ماند. «حذف اتصال» soft revoke است؛ UUID دیگر قابل احراز هویت نیست، اطلاعات audit و metadata عملیات حفظ می‌شوند.

فعال بودن badge نشست یعنی انقضای زمانی و لغو صریح؛ موفقیت call همچنین به CMS و مجوزهای جاری بستگی دارد. یک client می‌تواند هنگام refresh scope کمتری بگیرد؛ scopes جاری در پنل و worker به‌روز می‌شوند. کاهش دائمی Connection روی tokenهای موجود هم اعمال می‌شود.

مدیر اصلی می‌تواند در همان اتصال مجوز جدید اضافه کند؛ در این حالت همهٔ نشست‌ها و Grantها و توکن‌های قبلی اتصال لغو می‌شوند، endpoint حفظ می‌شود و کلاینت باید OAuth تازه را تکمیل کند. مدیر عادی فقط می‌تواند مجوز اتصال خودش را کم کند. فرم کهنه اجازهٔ بازگرداندن مجوزهای تغییرکرده را ندارد.

دادهٔ سنگین درخواست حساس فقط در فایل خصوصی ذخیره می‌شود:

```text
storage/app/private/sites/SITE_ID/ai/CONNECTION_UUID/approvals/APPROVAL_UUID/request.json
```

نوشتهٔ queued از همان پوشه‌بندی ArticleOperation و تاریخچهٔ پنج‌نسخه‌ای موجود استفاده می‌کند. Daily `adminjump:cleanup` پس از هفت روز فایل approval منقضی/بسته و payload عملیات confirmed را پاک می‌کند؛ UUID/hash/status کوچک AI برای جلوگیری از replay حفظ می‌شوند. نوشتهٔ pending/conflict خودکار حذف نمی‌شود. تغییر/حذف فایل approval در دسترس وب یا ابزار AI نیست.

Metadata قدیمی توکن/نشست و audit در این MVP خودکار پاک نمی‌شوند تا refresh replay و سابقه قابل پیگیری بمانند؛ retention audit/token برای سرویس بزرگ باید با سیاست و آرشیو جدا طراحی شود. حذف دستی سراسری جدول‌ها، حفاظت dedupe و audit را از بین می‌برد. تاریخچهٔ محتوای مقاله مستقل از تاریخچهٔ فعالیت AI است.


---

# امنیت MCP

نصب محلی فعلی SQLite و PHP8.2 دارد. transaction_mode=IMMEDIATE در Laravel این نسخه فقط روی PHP8.4+ اجرا می‌شود؛ چند Worker هم‌زمان در بررسی واقعی خطای قفل SQLite ایجاد کردند. launcher محلی اکنون یک Worker اولویت‌دار دارد. این کاهش تداخل جایگزین DB مناسب چند نویسنده در deployment نیست؛ برای چند process/instance پرترافیک از MySQL/PostgreSQL و cache lock مشترک استفاده کنید. دادهٔ pending و idempotency مستقل از عمر process حفظ می‌شوند.

## مرز ورودی و شبکه

- Production فقط HTTPS واقعی، issuer HTTPS و debug خاموش؛ host باید دامنهٔ APP_URL باشد.
- Origin فقط issuer و MCP_ALLOWED_ORIGINS دقیق؛ نبود Origin برای client سروری مجاز است. CORS wildcard نداریم.
- Bearer فقط Authorization header؛ query access_token/api_key ممنوع.
- سقف body MCP256KB و OAuth32KB؛ JSON برای POST ابزار، Accept هر دو JSON و SSE.
- OAuth metadata fetch و media از SSRF محافظت دارند: مقصد عمومی، بررسی همه A/AAAA، IP pin، TLS verify، بدون redirect/proxy، اندازه و timeout محدود.
- OAuth token/register/revoke ماشین CSRF وب ندارند و به OAuth/PKCE/client/auth متکی‌اند؛ Consent و Approval وب CSRF و session معتبر دارند.
- rate limit ثبت5، authorize20، token/revoke30 و MCP120 در دقیقه، با store مشترک. quota مالی/تولید محتوا در MVP نیست.

## Credential و مجوز

JWT RS256 با کلید3072بیتی کتابخانه، iss/aud/resource ثابت، جداول revocation و خانوادهٔ نشست بررسی می‌شوند. هیچ tokenِ CMS یا tokenِ resource دیگر پذیرفته یا passthrough نمی‌شود. کد یک‌بارمصرف، PKCE S256، callback دقیق، nonce consent و refresh rotation/reuse detection فعال‌اند. تمام writeها UUID ثابت و CAS دارند.

DB فقط jti/شناسه refresh/code و metadata دارد؛ raw token client-side است. secret client از پیش ثبت‌شده باید hash باشد. کلید امضای خصوصی و APP_KEY فایل/secret deployment هستند؛ با DB و آرشیو محتوا backup امن شوند و در public/storage یا Git قرار نگیرند. command تولید کلید فایل موجود را بازنویسی نمی‌کند. روی Linux permission0600 و روی Windows ACL service account را اعمال کنید؛ این task ACL سراسری سیستم را عوض نمی‌کند.

مجوز فعلی در هر call و هر worker، نقش محدود و grant محدود، لغو فوری، idempotency و قفل connection اعمال می‌شوند. برای چند ماشین cache locks مشترک و timeout هماهنگ با worker ضروری است. رقابت لغو با عملیاتی که قبلاً به CMS ارسال شده، rollback توزیع‌شده ندارد؛ CMS باید revocation خودش را روی endpoint اتمیک کنترل کند.

## عملیات حساس و دادهٔ غیرقابل اعتماد

انتشار/حذف/edit published/restore published approval انسانی پنل دارد. payload غیرقابل تغییر و پانزده‌دقیقه‌ای است، هنگام اجرای job حق کاربر grant و تأییدکننده دوباره بررسی می‌شود. درخواست AI بدون approval به CMS نمی‌رود. مکالمه AI جای CSRF/تأیید وب نیست.

HTML/Markdown پاک‌سازی می‌شود و metadata content_is_untrusted=true است. دستورهای داخل مقاله/data دستور اجرایی محسوب نمی‌شوند. این محدودیت سرور جلوی دسترسی اضافی را می‌گیرد؛ رفتار خود مدل در برابر prompt injection باید توسط client نیز کنترل شود. محتوا، token و API Key در ActivityLog ثبت نمی‌شوند؛ فقط شناسه، tool، نتیجه، issuer-user و operation.

Bearer token ذاتاً در بازهٔ اعتبار قابل replay است؛ DPoP، mTLS و token binding پیاده نشده‌اند. claims محدود، انقضای کوتاه، revoke online، PKCE و کنترل خانواده کاهش ریسک‌اند و به معنی حذف همهٔ replayها نیستند. ادعای ممیزی مستقل امنیت یا conformance certification نداریم. خطای حساس بدون جزئیات فنی به client برمی‌گردد؛ در monitoring بیرونی Authorization، code، verifier و refresh باید redact شوند.
