API الخاص بك يزيل بيانات C2PA الوصفية: كيفية كشف ذلك بالاختبار

كلود، وجيميني، وأوبن إيه آي يرفقون الآن بيانات C2PA وصفية موقّعة بالملفات المولّدة، لذا فإن الأصالة الحقيقية تصل إلى نقطة نهاية التحميل الخاصة بك، ومن المحتمل أن يقوم مسار عملك بحذفها. أمر "curl" يستغرق دقيقتين يثبت ذلك، واختبار من ثلاث طبقات يصحّح الوضع.

Ashley Innocent

Ashley Innocent

12 أغسطس 2026

API الخاص بك يزيل بيانات C2PA الوصفية: كيفية كشف ذلك بالاختبار

Apidog للمؤسسات

النشر على الخوادم المحلية

SSO و RBAC

متوافق مع SOC 2

استكشف Apidog للمؤسسات

يقوم Claude الآن بإرفاق بيانات تعريف العزو (provenance metadata) المشفرة من C2PA بالملفات التي يقوم بإنشائها. وكذلك تفعل نماذج صور OpenAI، وكذلك Gemini. وهذا يعني أن إشارة عزو حقيقية تصل إلى نقطة تحميلك لأول مرة، وهناك احتمال كبير أن تقوم سلسلة المعالجة الخاصة بك بحذفها قبل أن يراها أحد.

ليس بقصد سيء. بل بشكل افتراضي. تنتج الدالة sharp().resize() ملفًا نظيفًا بدون بيانات تعريف ما لم تطلب غير ذلك. وكذلك ImageMagick. وكذلك Pillow. وكذلك معظم شبكات توصيل المحتوى (CDNs) للصور. يدخل البيان، ويخرج ملف JPEG أصغر، ولا يذكر سجلاتك أي شيء عن ذلك.

هذا فشل قابل للاختبار، والاختبار ليس معقدًا. إليك كيفية موت بيانات التعريف في سلسلة معالجة عادية، وكيفية إثبات حدوث ذلك، وكيفية ربط فحص ذهاب وعودة في CI بحيث لا يعود. تتولى Apidog التنسيق؛ ويتولى c2patool التحقق على مستوى البايت.

زر

ما الذي يتم تدميره بالفعل

بيان C2PA هو كتلة موقعة تشفيريًا مدمجة في حاوية الملف. يسجل من قام بتوقيع الأصل وما تم الإدعاء به بشأنه، ولأنه موقع، فإن تغيير البايتات دون إعادة التوقيع يكسر التوقيع بطريقة يمكن لأي قارئ اكتشافها.

مستوى الحاوية هو العبارة الأساسية. أعد كتابة الحاوية وسيختفي البيان.

العملية هل يتبقى البيان افتراضيًا؟
نسخ أو نقل بايت ببايت نعم
sharp().resize().toBuffer() لا
ImageMagick convert / magick لا
Pillow Image.save() لا
PNG إلى WebP، JPEG إلى AVIF لا
تحسين تلقائي لـ CDN للصور عادةً لا
لقطة شاشة لا
إعادة حفظ من محرر صور لا
تحميل S3 بدون تحويل نعم

كل شيء في عمود "لا" هو أمر يفعله تطبيق ويب عادي لكل صورة يقبلها. صور مصغرة، متغيرات سريعة الاستجابة، تفاوض التنسيق، مسح بيانات EXIF للخصوصية. كل منها معقول بشكل منفصل، وكل منها ينهي سلسلة العزو بصمت.

تجدر الإشارة: غالبًا ما تكون عادة -strip التي تحركها الخصوصية متعمدة، لأن EXIF يحمل إحداثيات GPS وأرقام تسلسل الكاميرا. يؤدي تجريد جميع البيانات الوصفية لإزالة بيانات الموقع إلى إزالة بيان العزو أيضًا. تتعارض هذه الأهداف الآن، وحلها يعني أن تكون انتقائيًا بدلاً من تدمير الكتلة بأكملها.

أثبت ذلك في دقيقتين

قبل بناء أي شيء، تأكد من أن لديك المشكلة. تحتاج إلى ملف واحد ببيان صالح. أي صورة ينشئها Claude تعمل، أو احصل على عينة موقعة من مبادرة أصالة المحتوى (Content Authenticity Initiative).

قم بتثبيت واجهة سطر الأوامر المرجعية (CLI):

cargo install c2patool

تحقق من أن المُركب موقع بالفعل:

c2patool fixtures/signed-sample.png

يجب أن تحصل على تقرير JSON يذكر منشئ المطالبة وحالة التوقيع. الآن قم بتمريره عبر مكدسك الخاص وتحقق من الطرف الآخر:

# Upload through your real endpoint
curl -sS -X POST https://api.example.com/v1/assets \
  -H "Authorization: Bearer $API_TOKEN" \
  -F "file=@fixtures/signed-sample.png" \
  -o /tmp/upload.json

# Fetch it back through the URL your frontend would use
ASSET_URL=$(jq -r '.url' /tmp/upload.json)
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png

# Did the manifest survive?
c2patool /tmp/roundtrip.png

ثلاث نتائج محتملة، وهي تعني أشياء مختلفة:

النتيجة الثالثة هي التي يجب البحث عنها. عادة ما تعني أن مكتبة التحويل احتفظت بكتلة البيانات الوصفية أثناء إعادة كتابة البكسلات.

ابحث عن الخطوة التي تفعل ذلك

إذا فشلت الرحلة ذهابًا وإيابًا، قم بتقسيم خط الأنابيب. تحقق من البيان فورًا بعد كل مرحلة بدلاً من التخمين.

المشتبه بهم النموذجيون حسب ترتيب الاحتمال:

1. خطوة تغيير الحجم أو الصورة المصغرة. الجاني الأكثر احتمالاً. في sharp، يتم إسقاط البيانات الوصفية ما لم تحتفظ بها صراحة:

// Drops the C2PA manifest
await sharp(input).resize(1200).toFile(output);

// Preserves the metadata block
await sharp(input).resize(1200).keepMetadata().toFile(output);

الحفاظ على الكتلة ضروري ولكنه غير كافٍ. تغيرت البكسلات، لذا لم يعد التوقيع الأصلي صالحًا مقابل البايتات الجديدة. للحفاظ على سلسلة عزو عاملة، يجب عليك إعادة توقيع المخرجات وتسجيل التحويل كتأكيد إجراء، عادةً c2pa.resized. تدعم مكتبات c2pa لـ Rust و Python و JavaScript و C كل هذا.

2. تحويل التنسيق. يعني تقديم AVIF أو WebP حاوية جديدة. نفس القاعدة: حافظ وأعد التوقيع، أو اقبل أن السلسلة تنتهي هناك وصرح بذلك.

3. شبكة توصيل المحتوى (CDN). تعيد العديد من شبكات CDN للصور الكتابة عند التسليم. بعضها الآن يحافظ ويعيد توقيع Content Credentials بشكل أصلي؛ وقد قامت معظمها تاريخيًا بتجريدها. اختبر عبر عنوان URL التسليم الذي يصل إليه المستخدمون فعليًا، وليس عبر الأصل، وإلا ستحصل على نتيجة خضراء لا تعني شيئًا.

4. توحيد التحميل. الخدمات التي تعيد الترميز عند الاستيعاب لتوحيد التنسيقات من السهل نسيانها، لأن الكود موجود في مستودع بنية تحتية لا يقرأه أحد.

اجعله اختبارًا دائمًا

يُثبت أمر curl لمرة واحدة الحالة اليوم. ولكنه لا يمنع أي شخص من إضافة خطوة لتغيير الحجم في السبرنت التالي. يجب أن يعيش الفحص في CI.

قسّمه إلى طبقتين، لأن أداتين مختلفتين جيدتان في شيئين مختلفين.

الطبقة الأولى: الرحلة ذهابًا وإيابًا، في Apidog

التنسيق هو اختبار API متسلسل عادي: تحميل مُركب، التقاط عنوان URL المُعاد، جلب الأصل مرة أخرى عبر مسار التسليم الحقيقي، التأكيد على ما يتم إرجاعه.

في Apidog، هذا سيناريو اختبار بخطوتين.

الخطوة 1: POST /v1/assets

const body = pm.response.json();
pm.environment.set("ASSET_URL", body.url);
pm.test("upload returns a delivery URL", function () {
    pm.expect(body.url).to.be.a("string").and.to.include("https://");
});

الخطوة 2: GET {{ASSET_URL}}

const uploadedBytes = Number(pm.environment.get("FIXTURE_BYTES"));
const returnedBytes = pm.response.responseSize;
pm.test("asset was not silently re-encoded", function () {
    pm.expect(returnedBytes).to.be.above(uploadedBytes * 0.9);
});

الحجم هو تقدير، وليس إثباتًا. إنه يلتقط الإخفاقات الصارخة بتكلفة منخفضة ويعمل في نفس المجموعة مثل أي شيء آخر. يتم تغطية أنماط التأكيد القياسية في تأكيدات API.

الطبقة الثانية: التحقق على مستوى البايت، في CI

التحقق من التوقيع يعني تحليل الحاوية، وهي مهمة c2patool، وليست مهمة عميل HTTP. قم بتشغيلها كخطوة في خط الأنابيب مقابل الملف الذي تم جلبه في الرحلة ذهابًا وإيابًا:

# .github/workflows/provenance.yml
name: provenance
on: [pull_request]

jobs:
  c2pa-round-trip:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install c2patool
        run: cargo install c2patool

      - name: Install Apidog CLI
        run: npm install -g apidog-cli

      - name: Run the round-trip scenario
        run: |
          apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
            -t "$SCENARIO_ID" -e "$ENV_ID" -r cli,html --out-dir ./apidog-reports
        env:
          APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
          SCENARIO_ID: ${{ vars.PROVENANCE_SCENARIO_ID }}
          ENV_ID: ${{ vars.APIDOG_ENV_ID }}

      - name: Verify the manifest survived
        run: |
          set -euo pipefail
          curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
          c2patool /tmp/roundtrip.png > /tmp/report.json
          jq -e '.validation_status == null or (.validation_status | length) == 0' /tmp/report.json

يُعد set -euo pipefail مهمًا. بدونه، يؤدي فشل c2patool في ملف مُجرد إلى تحذير وبناء أخضر، وهو الفشل المحدد الذي كنت تحاول منعه. إذا كنت جديدًا في تشغيل سيناريوهات Apidog في خط أنابيب، فإن أتمتة اختبارات API في GitHub Actions تغطي الإعداد.

الطبقة الثالثة، اختيارية: نقطة نهاية للتحقق

إذا كانت بيانات العزو (provenance) ميزة في المنتج وليست فحصًا داخليًا، فإن أنظف تصميم هو نقطة نهاية صغيرة في خدمتك الخاصة تقوم بتشغيل مكتبة c2pa وتُرجع نتيجة منظمة. عندئذٍ يكون كل شيء قابلًا للاختبار كـ JSON عادي، وتحصل واجهة المستخدم الأمامية (frontend) الخاصة بك على إجابة حقيقية بدلاً من تخمين.

{
  "asset_id": "img_9f2c41",
  "provenance": {
    "status": "verified",
    "standard": "c2pa",
    "signer": "Anthropic",
    "signature_valid": true,
    "checked_at": "2026-08-11T09:14:22Z",
    "tool": "c2patool/0.9"
  }
}

احتفظ بثلاث حالات، لا اثنتين. تشير verified و absent و invalid إلى أشياء مختلفة تمامًا، ويؤدي دمج absent و invalid في قيمة منطقية واحدة إلى التخلص من الإشارة الأكثر إثارة للاهتمام التي لديك. أضف unchecked إذا كان المدقق الخاص بك غير متاح، بحيث لا يتنكر الانقطاع على أنه نتيجة نظيفة.

وثّق الشكل في تعريف OpenAPI الخاص بك وتحقق منه، حتى لا تختفي الحقول في عملية إعادة هيكلة. كيفية التحقق من مواصفات OpenAPI تغطي هذا الجانب.

التركيبات الأربعة التي تستحق الاحتفاظ بها

تحتاج مجموعة بيانات العزو (provenance) إلى مدخلات معيبة عمدًا، وليس فقط مسارًا سعيدًا.

  1. ملف موقع صالح. توقع verified. يلتقط التجريد المفرط الحماس.
  2. ملف مجرد. نفس الصورة، تم إزالة البيان باستخدام exiftool -all=. توقع absent، وليس خطأ وبالتأكيد ليس verified.
  3. ملف مُتلاعب به. ملف موقع مع تغيير بايت واحد بعد التوقيع. توقع invalid. هذا هو الذي يثبت أنك تتحقق من التوقيع بدلاً من مجرد التحقق من وجود كتلة.
  4. تنسيق غير مدعوم. شيء لا يدعم أي بيان على الإطلاق. توقع absent نظيف بدلاً من 500.

التزم بجميع الأربعة في المستودع بجوار سيناريو الاختبار. إنها صغيرة، ولا تتغير أبدًا، وهي الفرق بين اختبار يمر واختبار له معنى.

لماذا العناء

ثلاثة أسباب، بترتيب تصاعدي لتكلفة كل منها عليك.

ادعاء منتجك. إذا كانت واجهة المستخدم الخاصة بك تعرض شارة العزو (provenance)، وسلسلة المعالجة الخاصة بك تجرد البيانات، فإن الشارة ستكون خاطئة لكل أصل مر بتغيير حجم. هذه مشكلة ثقة ستكتشفها من مستخدم.

قصة الامتثال الخاصة بك. إذا كنت تعتمد على C2PA لأي شيء يتعلق بالمادة 50، فإن البيان المجرد هو عنصر تحكم لا يعمل. يوضح تقسيم الموفر والمستخدم في المادة 50 من قانون الاتحاد الأوروبي للذكاء الاصطناعي لمطوري API الواجبات التي تقع عليك بالفعل.

الإشارة نفسها. يعمل العزو (Provenance) فقط إذا استمرت السلسلة من البداية إلى النهاية. كل سلسلة معالجة تسقط البيانات بصمت تجعل النظام البيئي بأكمله أقل فائدة، بما في ذلك لك عندما تحاول التحقق من شيء ما.

قم بتنزيل Apidog لبناء سيناريو الرحلة ذهابًا وإيابًا مقابل نقاط النهاية الخاصة بك، ثم قم بربط خطوة c2patool خلفها.

الأسئلة الشائعة

هل يؤدي تغيير حجم الصورة إلى إزالة بيانات تعريف C2PA؟ نعم، بشكل افتراضي في كل مكتبة شائعة. يتطلب الحفاظ على كتلة البيانات التعريفية علامة صريحة، ويتطلب الحفاظ على توقيع صالح إعادة توقيع المخرج المحول.

كيف أتحقق مما إذا كان الملف يحتوي على بيانات تعريف C2PA؟ قم بتشغيل c2patool <file> من سطر الأوامر، أو قم بإسقاط الملف في صفحة التحقق من بيانات اعتماد المحتوى.

هل يمكنني الاحتفاظ ببيانات تعريف C2PA عند تغيير الحجم؟ نعم، ولكن ليس بمجرد الحفاظ عليها. احتفظ بالكتلة، ثم أعد توقيع المخرج بتأكيد إجراء مثل c2pa.resized باستخدام إحدى مكتبات c2pa. وإلا فلن يتطابق التوقيع القديم مع البايتات الجديدة.

هل تقوم شبكات توصيل المحتوى (CDNs) بتجريد بيانات اعتماد المحتوى؟ يفعل الكثير منها عند التحسين التلقائي. بعضها الآن يحافظ ويعيد التوقيع بشكل أصلي. اختبر عبر عنوان URL التسليم الذي يصل إليه المستخدمون، وليس عبر المصدر.

ما الفرق بين البيان المجرد والبيان غير الصالح؟ البيان المجرد يعني عدم العثور على بيان، وهذا لا يخبرك شيئًا عن أصل الملف. البيان غير الصالح يعني وجود بيان ولكن توقيعه لا يتطابق مع البايتات، مما يعني أن الملف تغير بعد التوقيع. احتفظ بهما كحالتين منفصلتين.

هل يمكن لـ Apidog التحقق من توقيع C2PA مباشرة؟ يقوم بتنسيق الرحلة ذهابًا وإيابًا ويؤكد على استجابات HTTP، بما في ذلك JSON الخاص بنقطة نهاية التحقق. تحليل التوقيع نفسه هو مهمة c2patool، يتم تشغيلها كخطوة CI أو داخل خدمتك الخاصة. استخدم كليهما معًا.

هل يجب علي تجريد EXIF للخصوصية ولكن الاحتفاظ بـ C2PA؟ هذا هو الهدف الصحيح ويتطلب نهجًا انتقائيًا. يزيل الأمر الشامل -strip كليهما. قم بإزالة كتل EXIF التي تهتم بها على وجه التحديد واترك بيان C2PA سليمًا.

الخلاصة

تصل بيانات تعريف العزو (provenance metadata) إلى واجهة برمجة التطبيقات الخاصة بك سليمة وعادة ما تغادر في أجزاء، ولن يخبرك أي شيء في مراقبتك بذلك. الحل هو مُركب، رحلة ذهاب وعودة عبر مسار التسليم الحقيقي، وفحص c2patool يفشل البناء.

عشرون دقيقة من الإعداد، وتحول ادعاء تقدمه في واجهة المستخدم الخاصة بك إلى ضمان تفرضه سلسلة المعالجة الخاصة بك بالفعل.

زر

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات