إخفاء الهوية

استخدم واجهة إخفاء الهوية في قُبة لحماية البيانات الحساسة في النص بأساليب متعددة، منها الاستبدال والتقنيع والتجزئة والتشفير.

import {
  Configuration,
  SensitiveDataProtectionApi,
} from "@quba/sensitive-data-protection"

const text = `Patient John Smith (SSN: 123-45-6789) was admitted to
  Dubai General Hospital on 2024-01-15. Contact: john.smith@email.com`

async function protectData(text: string) {
  // Pass your API key on every request via the x-api-key header.
  const api = new SensitiveDataProtectionApi(
    new Configuration({ headers: { "x-api-key": "quba_..." } }),
  )

  return await api.anonymizeText({
    text,
    rules: [
      {
        type: "replace",
        entities: [{ type: "model", value: "person" }],
        replacement: "[PATIENT]",
      },
      {
        type: "mask",
        entities: [{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }],
        masking_char: "*",
        chars_to_mask: 7,
        from_end: true,
      },
      {
        type: "redact",
        entities: [{ type: "model", value: "address" }],
      },
      {
        type: "sha256",
        entities: [{ type: "model", value: "email" }],
      },
    ],
  })
}

const response = await protectData(text)
console.log(response.text)
// Output: Patient [PATIENT] (SSN: ***-**-6789) was admitted to
// [REDACTED] on 2024-01-15. Contact: a1b2c3d4...
from quba_sdp import Client, models
from quba_sdp.api import anonymize_text

text = """Patient John Smith (SSN: 123-45-6789) was admitted to
  Dubai General Hospital on 2024-01-15. Contact: john.smith@email.com"""

# base_url defaults to the production API; pass your key via headers.
client = Client(headers={"x-api-key": "quba_..."})

response = anonymize_text.sync(
    client=client,
    body=models.AnonymizeRequestBody(
        text=text,
        rules=[
            models.ReplaceRule(
                entities=[models.ModelEntity(value="person")],
                replacement="[PATIENT]",
            ),
            models.MaskRule(
                entities=[models.RegexEntity(value=r"\d{3}-\d{2}-\d{4}")],
                masking_char="*",
                chars_to_mask=7,
                from_end=True,
            ),
            models.RedactRule(entities=[models.ModelEntity(value="address")]),
            models.SHA256Rule(entities=[models.ModelEntity(value="email")]),
        ],
    ),
)

print(response.text)
# Output: Patient [PATIENT] (SSN: ***-**-6789) was admitted to
# [REDACTED] on 2024-01-15. Contact: a1b2c3d4...

استخدم model لتترك للذكاء الاصطناعي كشف أنواع الكيانات تلقائياً، واستخدم regex لاستهداف نمط محدد، مثل صيغة رقم تعريفي أو صيغة تاريخ.

// Model-based: AI finds the entity type
{ type: "model", value: "person" }

// Regex-based: matches your exact pattern
{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }
# Model-based: AI finds the entity type
models.ModelEntity(value="person")

# Regex-based: matches your exact pattern
models.RegexEntity(value=r"\d{3}-\d{2}-\d{4}")

القواعد

تحدّد القاعدة للواجهة أمرين: ما الذي تكشفه، وكيف تعالجه لإخفاء الهوية. ولكل قاعدة جزآن إلزاميان:

  • type: عملية إخفاء الهوية المطبَّقة (replace أو redact أو mask أو sha256 أو sha512 أو encrypt)
  • entities: كيان مستهدف واحد أو أكثر، يُحدَّد كلٌّ منها بالنموذج أو بتعبير نمطي (regex)
{
  type: "replace",                                    // what to do
  entities: [{ type: "model", value: "person" }],     // what to find
  replacement: "[PATIENT]"                            // anonymization option
}

تمرّر القواعد في مصفوفة. تُقيَّم كل قاعدة على النص كاملاً بمعزل عن غيرها، لذا قد تطابق عدة قواعد مقاطع مختلفة وتعالجها، حتى لو تداخلت هذه المقاطع. وتُطبَّق القواعد بترتيب ورودها.

الكيانات المستهدفة

يُحدَّد كل كيان في entities إمّا بالنموذج أو بتعبير نمطي:

النوعالوصفمثال
modelيكشف الذكاء الاصطناعي نوع الكيان{ type: "model", value: "person" }
regexيُطابَق النص بالنمط الذي تحدده{ type: "regex", value: "\\d{3}-\\d{2}-\\d{4}" }

ويمكن أن تجمع القاعدة الواحدة بين الطريقتين:

{
  type: "redact",
  entities: [
    { type: "model", value: "email" },
    { type: "regex", value: "[A-Z]{2}\\d{6}" },  // custom ID format
  ]
}
models.RedactRule(
    entities=[
        models.ModelEntity(value="email"),
        models.RegexEntity(value=r"[A-Z]{2}\d{6}"),  # custom ID format
    ]
)

تسميات النموذج

كيانات النموذج تسميات بصيغة snake_case، مثل person وemail وphone_number وaddress وcard_number وapi_key. تُكشف تسميات البيانات الشخصية الشائعة بأعلى دقة، وتعمل أي تسمية أخرى أيضًا بدقة أقل.

القواعد الافتراضية والسياسات المُسندة

الحقل rules اختياري، والقواعد التي تُطبَّق تعتمد على المُستدعي:

  1. سياسة مُسندة. يستطيع المسؤول إسناد سياسة إلى مفتاح API أو إلى عضو في الفريق من لوحة التحكم، فتُطبَّق على كل استدعاء بذلك المفتاح أو من إضافة المتصفح، ويُرفض بالرمز 403 أي طلب يرسل rules أو confidence_threshold معها. ويبقى بإمكان ساحة التجارب في لوحة التحكم تجربة قواعد أخرى.

  2. قواعد الطلب rules، إن لم تُسند سياسة.

  3. القواعد الافتراضية، إن لم يوجد أيٌّ منهما: المُعرِّفات الشخصية والصحية والمالية وبيانات الاعتماد، ويُستبدل كلٌّ منها باسم تسميته بأحرف كبيرة بين قوسين معقوفين، فيصبح John Smith هو [PERSON]. ويكشف /scan التسميات نفسها إن لم تُرسل entities. وتشمل القواعد الافتراضية:

    • مُعرِّفات HIPAA Safe Harbor الواردة في النص: الأسماء والعناوين والتواريخ والأعمار وأرقام الهاتف والفاكس والبريد الإلكتروني وعناوين IP والروابط، وأرقام الهويات والحسابات والرخص والشهادات والسجلات الطبية والتأمين الصحي، ومُعرِّفات المركبات والأجهزة والمُعرِّفات الحيوية؛
    • أرقام جوازات السفر والأرقام الضريبية؛
    • أرقام البطاقات ورموز التحقق وتواريخ انتهائها، وأرقام IBAN والحسابات المصرفية وأرقام التوجيه؛
    • كلمات المرور ومفاتيح API ورموز الوصول والأسرار ورموز الاسترداد.

حد الثقة

يرفق النموذج بكل كيان يكشفه درجة score (من 0.0 إلى 1.0) تعبّر عن ثقته في صحة الكشف. ويستبعد المعامل confidence_threshold الكيانات التي تقل درجة ثقتها عن الحد المطلوب.

await api.anonymizeText({
  text: "...",
  rules: [...],
  confidence_threshold: 0.8, // only apply rules to high-confidence detections
})
anonymize_text.sync(
    client=client,
    body=models.AnonymizeRequestBody(
        text="...",
        rules=[...],
        confidence_threshold=0.8,  # only apply rules to high-confidence detections
    ),
)
  • القيمة الافتراضية: 0.5
  • تُطبَّق القواعد دائماً على مطابقات التعابير النمطية، فحد الثقة لا يؤثر فيها
  • ارفع الحد (مثل 0.8) لتقليل الكشف الخاطئ، أو اخفضه لكشف عدد أكبر من الكيانات

عمليات إخفاء الهوية

الاستبدال

استبدل الكيانات المكتشَفة بنص تحدده:

{
  type: "replace",
  entities: [{ type: "model", value: "person" }],
  replacement: "[REDACTED]"   // default: "****"
}
models.ReplaceRule(
    entities=[models.ModelEntity(value="person")],
    replacement="[REDACTED]",  # default: "****"
)

الحجب

أزِل الكيانات المكتشَفة من النص كلياً:

{
  type: "redact",
  entities: [{ type: "model", value: "email" }]
}
models.RedactRule(entities=[models.ModelEntity(value="email")])

التقنيع

غطِّ جزءاً من الكيان المكتشَف بحرف التقنيع:

{
  type: "mask",
  entities: [{ type: "model", value: "phone_number" }],
  masking_char: "*",     // default: "*"
  chars_to_mask: 8,      // null = mask all characters
  from_end: true         // false = mask from start
}
// +1-555-123-4567 → +1-555-***-****
models.MaskRule(
    entities=[models.ModelEntity(value="phone_number")],
    masking_char="*",      # default: "*"
    chars_to_mask=8,       # None = mask all characters
    from_end=True,         # False = mask from start
)
# +1-555-123-4567 → +1-555-***-****

SHA256 / SHA512

حوّل الكيانات المكتشَفة إلى قيم مُجزّأة:

{
  type: "sha256",
  entities: [{ type: "model", value: "government_id" }]
}
models.SHA256Rule(entities=[models.ModelEntity(value="government_id")])
# or models.SHA512Rule(...)

التشفير

شفّر الكيانات المكتشَفة بمفتاح تحدده:

{
  type: "encrypt",
  entities: [{ type: "model", value: "person" }],
  key: "your-encryption-key"   // default: ""
}
models.EncryptRule(
    entities=[models.ModelEntity(value="person")],
    key="your-encryption-key",  # default: ""
)

التعابير النمطية

يمكنك أيضاً استهداف أجزاء من النص بتعابير نمطية (regex):

{
  type: "replace",
  entities: [{ type: "regex", value: "\\d{4}-\\d{2}-\\d{2}" }],
  replacement: "[DATE]"
}
models.ReplaceRule(
    entities=[models.RegexEntity(value=r"\d{4}-\d{2}-\d{2}")],
    replacement="[DATE]",
)

نتائج تطبيق القواعد

عند تنفيذ إخفاء الهوية، يُنشأ سجل نتيجة لكل كيان كُشف وعولج. وتُعاد هذه السجلات في response.results سجلَّ تدقيق مرتباً، بعنصر واحد لكل مقطع مطابق.

const response = await api.anonymizeText({ text, rules })

console.log(response.text) // the anonymized string
console.log(response.results) // one record per anonymization applied
response = anonymize_text.sync(
    client=client,
    body=models.AnonymizeRequestBody(text=text, rules=rules),
)

print(response.text)     # the anonymized string
print(response.results)  # one record per anonymization applied

تبيّن لك كل نتيجة:

  • القاعدة المطبَّقة (rule)
  • ما كُشف (value: نوع الكيان أو التعبير النمطي)
  • موضعه في النص الأصلي (input)
  • موضعه الجديد في النص الناتج (output)

والنتيجة إمّا نتيجة نموذج (كيان كشفه الذكاء الاصطناعي) أو نتيجة تعبير نمطي (مقطع طابق نمطاً)، ويحدد الحقل type نوعها:

نتيجة النموذج

{
  type: "model",
  rule: "replace",            // rule type that was applied
  value: "PERSON",            // entity type the model detected
  score: 0.94,                // AI confidence (0.0–1.0)
  input:  { start: 8, end: 18, value: "John Smith" },   // position in original text
  output: { start: 8, end: 17, value: "[PATIENT]"  },   // position in result text
}

نتيجة التعبير النمطي

{
  type: "regex",
  rule: "mask",                                          // rule type that was applied
  value: "\\d{3}-\\d{2}-\\d{4}",                        // pattern that matched
  input:  { start: 20, end: 31, value: "123-45-6789" }, // position in original text
  output: { start: 20, end: 31, value: "***-**-6789" }, // position in result text
}

حقول TextRange

الحقلالنوعالوصف
startnumberموضع بداية المقطع (مشمول)
endnumberموضع نهاية المقطع (غير مشمول)
valuestringالمقطع الواقع في النطاق [start, end)

تُرتَّب النتائج حسب موضعها في النص الناتج. استخدم مواضع input لتحديد كل مقطع في النص الأصلي، ومواضع output لإبراز المقاطع في النص الناتج.

© 2026 قُبة