الامتثال والسياسات ككود

الضوابط والأدلة

18 دقيقة الدرس 2 من 27

الضوابط والأدلة

لا يثق المدققون في الادعاءات — بل يثقون في الأدلة. حين يسأل مدقق SOC 2 أو محقق PCI أو فريق الأمن الداخلي "كيف تعلم أن أنظمتك ملتزمة؟"، لا يمكن أن تكون الإجابة "نتبع أفضل الممارسات." يجب أن تكون مُخرَجاً مُوَقَّتاً وغير قابل للتلاعب يُثبت أن ضابطاً بعينه عمل بشكل صحيح في وقت محدد. يعلّمك هذا الدرس التفكير كذلك المدقق، وتصميم أطر ضوابط قابلة للتدقيق بطبيعتها، وأتمتة خط سير الأدلة حتى لا يقع عبء الامتثال كله على فريقك في الأسبوع الذي يسبق كل مراجعة.

ما هو الضابط؟

الضابط control هو إجراء وقائي أو تعويضي يعالج خطراً بعينه. كل إطار امتثال رئيسي — SOC 2 وISO 27001 وPCI DSS وHIPAA وFedRAMP — هو في نهاية المطاف كتالوج من الضوابط، ولكل منها هدف ضابط control objective: عبارة تصف الحالة المرغوبة التي يسعى الضابط إلى الحفاظ عليها. فهم هذه المصطلحات شرط مسبق لأتمتة أعمال الامتثال.

  • هدف الضابط — النتيجة التي يجب أن يحققها الضابط. مثال: "يجب أن يستلزم كل وصول إداري إلى قواعد بيانات الإنتاج المصادقة متعددة العوامل." هذا هو الماذا.
  • نشاط الضابط — الإجراء أو الإعداد المحدد الذي يحقق الهدف. مثال: "تقع مجموعة RDS في VPC دون نقطة نهاية عامة، والوصول يمر عبر بروكسي bastion مصادَق عليه بـIAM ويُطبّق MFA عبر رمز صلب." هذا هو الكيف.
  • الأدلة — المُخرَج الذي يُثبت أن الضابط عمل كما صُمّم خلال فترة معينة. مثال: سجلات CloudTrail تُثبت أن كل اتصال بقاعدة البيانات جاء من ARN البروكسي، وتقرير IAM Access Analyzer يؤكد غياب الوصول العام، وسجل إصدارات سياسة تطبيق MFA على البروكسي.

عملياً، تُصنَّف الضوابط حسب طبيعتها. الضوابط الوقائية تمنع حدوث الأشياء السيئة (سياسة IAM ترفض تعيين s3:PutBucketPublicAccessBlock إلى false). الضوابط الكاشفة تُلاحظ حين يسوء الأمر (تنبيه CloudWatch عند إضافة قاعدة security group بـ0.0.0.0/0). الضوابط التصحيحية تُصلح الضرر تلقائياً (إزالة ACL الدلو العام خلال ثوانٍ). يستلزم برنامج الامتثال الناضج تطبيق الأنواع الثلاثة بصورة متداخلة.

تصنيف الضوابط مهم للمدققين: حين تعرض الأدلة، نظّمها حسب نوع الضابط. يتحقق المدققون من أن كل هدف ضابط يحتوي على ضابط وقائي أو كاشف واحد على الأقل، مدعوم بأدلة تغطي كامل فترة التدقيق (عادةً 12 شهراً لـSOC 2 Type II). أي فجوة في تغطية الأدلة — حتى لو كانت أسبوعاً واحداً — قد تستلزم إعادة الاختبار أو رأياً مشروطاً.

أهداف الضوابط بمفاهيم هندسية

الفجوة بين اللغة المجردة لأُطر الامتثال وما يُهيّئه المهندس فعلاً هي المكان الذي يتراكم فيه الدَّيْن التقني للامتثال. لنتتبع تعييناً ملموساً لضابط SOC 2 شائع هو CC6.6، الذي يستلزم إزالة الوصول المنطقي في الوقت المناسب عند انتهاء التفويض:

  • الهدف: إلغاء الوصول خلال 24 ساعة من إنهاء الخدمة.
  • الضابط الهندسي: مزامنة SCIM بين نظام الموارد البشرية (Workday أو BambooHR) وموفر الهوية (Okta أو Azure AD). يُعطّل Okta الحساب فور تلقّي webhook إنهاء الخدمة من نظام HR. Okta متحدة مع AWS وGCP وجميع أدوات SaaS عبر SAML/OIDC — تعطيل حساب Okta يُزيل الوصول في كل مكان تلقائياً.
  • مُخرَجات الأدلة: (1) تصدير سجل نظام Okta يُظهر حدث التعطيل والوقت، (2) CloudTrail يُظهر آخر دخول إلى وحدة التحكم قبل التعطيل، (3) تقرير شهري للمستخدمين غير النشطين يُثبت غياب حسابات نشطة للموظفين المنتهية خدمتهم، (4) لقطة شاشة إعداد SCIM تُثبت أن التكامل فعّال.

هذا هو عمل الترجمة. كل ضابط في إطارك يحتاج إلى نفس التفكيك: الهدف، والتطبيق الهندسي، وقائمة مُخرَجات الأدلة التي تُثبت أنه عمل بشكل صحيح خلال فترة التدقيق.

أتمتة جمع الأدلة

جمع الأدلة يدوياً هو التكلفة الخفية للامتثال. الفرق التي تجمع الأدلة بالطريقة اليدوية — تصدير ملفات CSV والتقاط لقطات الشاشة وكتابة نصوص برمجية لمرة واحدة — تقضي أسابيع قبل كل مراجعة في حالة طوارئ. على مقياس Google، البديل هو خط سير أدلة مستمر: بنية تحتية تولّد مُخرَجات الامتثال كنتيجة طبيعية للعمليات اليومية، تحفظها بصورة لا تقبل التغيير، وتُغذّيها في مستودع جاهز للتدقيق.

مكوّنات هذا الخط تشمل:

  1. مصادر الأحداث — CloudTrail وAWS Config وسجلات تدقيق GCP وسجل تدقيق Kubernetes وسجل نظام Okta وسجل تدقيق GitHub. كل إجراء مميّز ينتج حدثاً قابلاً للقراءة آلياً.
  2. بالوعة السجلات المركزية — S3 + Athena أو GCS + BigQuery أو SIEM. تُكتَب السجلات مع object-lock (WORM — الكتابة مرة واحدة والقراءة متعددة) فلا يمكن تعديلها بأثر رجعي.
  3. استعلامات الأدلة — استعلامات SQL أو Athena مُعدّة مسبقاً تُجيب على أسئلة ضوابط محددة عند الطلب.
  4. وظائف الأدلة المجدوَلة — وظائف cron أو دوال Lambda مشغَّلة بـEventBridge Scheduler تُشغّل الاستعلامات وتكتب الإخراج كمُخرَج مُؤرَّخ في دلو الأدلة.
  5. سجل الضوابط — ملف بيانات وصفية (غالباً ملف YAML في مستودع Git) يُعيّن كل ضابط إلى مُخرَجات الأدلة والمالك وآخر وقت تحقق.
Continuous Evidence Pipeline Event Sources CloudTrail / Audit Logs AWS Config Resource snapshots K8s Audit Log API server events Okta / GitHub Identity & SCM logs WORM Log Sink S3 Object Lock / GCS Retention Policy Query Engine Athena / BigQuery Scheduled SQL jobs Evidence Store Dated artifacts + Git Control Registry YAML manifest / GRC tool Continuous Evidence Pipeline تتدفق السجلات إلى بالوعة غير قابلة للتلاعب؛ تُنتج الاستعلامات المجدوَلة مُخرَجات أدلة مؤرَّخة مُعيَّنة للضوابط.
خط سير الأدلة المستمر: تكتب مصادر الأحداث إلى بالوعة غير قابلة للتلاعب (WORM)، ويُنتج محرك الاستعلامات مُخرَجات أدلة مؤرَّخة بجدول منتظم، ويُعيّن سجل الضوابط كل مُخرَج إلى هدفه.

تطبيق عملي: AWS Config واستعلام Athena للأدلة

يُسجّل AWS Config بصفة مستمرة حالة إعداد كل مورد. مقروناً بـAthena، يمكنك الاستعلام عن هذا التاريخ للإجابة على أسئلة ضوابط محددة. الإعداد التالي يُشحن بأدلة لضابط مثل "لا يحتوي أي دلو S3 على وصول عام" يغطي أي نافذة 90 يوماً — قابلة للاستعلام عند الطلب.

# 1. تفعيل AWS Config مع قناة تسليم S3 aws configservice put-configuration-recorder \ --configuration-recorder name=default,roleARN=arn:aws:iam::123456789012:role/AWSConfigRole \ --recording-group allSupported=true,includeGlobalResources=true aws configservice put-delivery-channel \ --delivery-channel name=default,s3BucketName=my-config-bucket,\ configSnapshotDeliveryProperties={deliveryFrequency=TwentyFour_Hours} aws configservice start-configuration-recorder --configuration-recorder-name default # 2. الاستعلام عن سجل الإعدادات عبر Athena # يجد هذا الاستعلام أي نقطة زمنية كان فيها دلو S3 يحتوي على وصول عام # -- دليل على غياب الدلاء العامة لهدف الضابط SELECT accountId, awsRegion, resourceId AS bucket_name, configuration_item_capture_time, JSON_EXTRACT_SCALAR(configuration, '$.publicAccessBlockConfiguration.blockPublicAcls') AS block_acls, JSON_EXTRACT_SCALAR(configuration, '$.publicAccessBlockConfiguration.blockPublicPolicy') AS block_policy FROM aws_config_configuration_items WHERE resourceType = 'AWS::S3::Bucket' AND configuration_item_capture_time BETWEEN TIMESTAMP '2025-01-01' AND TIMESTAMP '2025-03-31' AND ( JSON_EXTRACT_SCALAR(configuration, '$.publicAccessBlockConfiguration.blockPublicAcls') = 'false' OR JSON_EXTRACT_SCALAR(configuration, '$.publicAccessBlockConfiguration.blockPublicPolicy') = 'false' ) ORDER BY configuration_item_capture_time;

إذا أعاد الاستعلام صفر صفوف، فلديك دليل آلي يُثبت أن أي دلو S3 لم يكن يحتوي على وصول عام خلال ذلك الربع. صدّر النتيجة كملف CSV، واحفظها في s3://evidence-bucket/cc6.1/2025-q1-no-public-s3.csv، وسجّل هذا المسار في سجل الضوابط.

احفظ الأدلة بتسمية موحدة: استخدم مخطط مسار مثل s3://evidence/<framework>/<control-id>/<YYYY-MM>-<description>.<ext>. هذا يُسهّل استرجاع جميع الأدلة لضابط معين عبر جميع الأشهر، ويستطيع المدققون الوصول إليها بأنفسهم دون طلب ملفات من فريقك. اقرن ذلك بملف controls.yaml مُتتبَّع في Git يربط معرّف الضابط بمسارات الأدلة في S3 والمالك وتاريخ آخر مراجعة.

سجل تدقيق Kubernetes كمصدر للأدلة

في بيئة Kubernetes، سجل تدقيق API server يعادل CloudTrail. كل kubectl exec، وكل قراءة سرّ، وكل محاولة تصعيد صلاحيات مُسجَّلة. لضوابط مثل "لا تعمل حاويات مميّزة في الإنتاج" أو "المستخدمون المصرّح لهم فقط يستطيعون exec إلى pods"، سجل التدقيق هو مصدر أدلتك.

# مقتطف سياسة تدقيق — فعّله في إعدادات kube-apiserver: # --audit-policy-file=/etc/kubernetes/audit-policy.yaml # --audit-log-path=/var/log/kubernetes/audit.log # --audit-log-maxage=90 # --audit-log-maxbackup=10 # --audit-log-maxsize=500 # /etc/kubernetes/audit-policy.yaml apiVersion: audit.k8s.io/v1 kind: Policy rules: # سجّل exec وport-forward بمستوى RequestResponse - level: RequestResponse resources: - group: "" resources: ["pods/exec", "pods/portforward"] # سجّل قراءات الأسرار — دليل على "الوصول للأسرار مُدقَّق عليه" - level: Metadata resources: - group: "" resources: ["secrets", "configmaps"] verbs: ["get", "list", "watch"] # سجّل جميع تعديلات الموارد على مستوى الكتلة - level: Request verbs: ["create", "update", "patch", "delete"] resources: - group: "" resources: ["nodes", "namespaces"] - group: "rbac.authorization.k8s.io" resources: ["clusterroles", "clusterrolebindings"] # أسقط الاستدعاءات القراءة كثيرة الضجيج لتقليل الحجم - level: None verbs: ["get", "list", "watch"] resources: - group: "" resources: ["endpoints", "events"]
الاحتفاظ بسجلات التدقيق هو ضابط بحد ذاته: تُلزم معظم الأطر بالاحتفاظ بسجلات التدقيق لفترة دنيا — يستلزم PCI DSS 12 شهراً (3 أشهر متاحة فوراً)، ويريد مدققو SOC 2 عادةً إتاحة كامل نافذة التدقيق. إذا عيّنت --audit-log-maxage=30 أو سمحت لدلو S3 الخاص بـCloudTrail بحذف السجلات بعد 30 يوماً، ستفشل في ضابط الاحتفاظ بالأدلة حتى لو كان كل ضابط آخر مثالياً. عيّن فترة الاحتفاظ لتكون فترة تدقيقك على الأقل مضافاً إليها 30 يوماً كهامش، وأرسل السجلات إلى دلو مقفول بـobject-lock، وأضف قاعدة Config أو دالة Lambda تُنبّهك إذا تغيّرت سياسة دورة حياة الدلو.

بناء سجل الضوابط

سجل الضوابط هو التعيين الموثوق بين متطلبات الامتثال وضوابط الهندسة التي تُلبّيها. على المقياس الكبير، يعيش في مستودع Git جنباً إلى جنب مع بنيتك التحتية كرمز — هذا يجعل تغييرات الضوابط تمر عبر مراجعة طلبات السحب، ويمنحك تاريخاً لمتى تغيّرت الضوابط، ويُتيح لخط CI التحقق من وجود مُخرَجات الأدلة المُشار إليها فعلاً.

إدخال controls.yaml دنيا يبدو هكذا — إدخال واحد لكل هدف ضابط:

# controls.yaml — مُضمَّن في مستودع Git للامتثال controls: - id: CC6.6 framework: SOC2-2022 title: "إزالة الوصول المنطقي خلال 24 ساعة من إنهاء الخدمة" type: detective owner: identity-team implementation: | مزامنة SCIM بين Workday وOkta. يُعطّل Okta الحساب عند webhook إنهاء الخدمة. متحد مع AWS وGCP عبر SAML. evidence: - description: "تصدير سجل نظام Okta — أحداث التعطيل" bucket: s3://evidence/soc2/cc6.6/ schedule: monthly last_generated: "2025-05-01" query_file: queries/cc6_6_okta_deactivations.sql - description: "تقرير المستخدمين غير النشطين الشهري" bucket: s3://evidence/soc2/cc6.6/ schedule: monthly last_generated: "2025-05-01" last_reviewed: "2025-05-15" review_owner: platform-security-eng status: passing - id: CC6.1-S3 framework: SOC2-2022 title: "لا يكشف أي دلو S3 عن كائناته بشكل عام" type: preventive owner: platform-team implementation: | قاعدة AWS Config S3_BUCKET_PUBLIC_ACCESS_PROHIBITED مُطبَّقة. SCPs تحجب s3:PutBucketPublicAccessBlock بقيم false. evidence: - description: "استعلام Athena — لا دلاء عامة في الربع" bucket: s3://evidence/soc2/cc6.1/ schedule: quarterly last_generated: "2025-04-01" query_file: queries/cc6_1_no_public_s3.sql last_reviewed: "2025-04-15" review_owner: platform-security-eng status: passing

هذا السجل، ونصوص توليد الأدلة المؤتمتة في queries/، ووظيفة CI التي تتحقق من أن تواريخ last_generated ضمن النافذة المطلوبة، تُشكّل معاً الأساس التشغيلي لنظام ملتزم بصفة مستمرة. حين يصل المدقق، تُشغّل نصاً برمجياً — لا حالة طوارئ.

أدوات GRC مقابل النهج الأصلي لـGit: منصات GRC المؤسسية مثل Drata وVanta وSecureframe تُؤتمت كثيراً من هذا الجمع للأدلة لتكاملات SaaS الشائعة (AWS وGitHub وOkta وGoogle Workspace). تستحق التقييم للامتثال لـSOC 2. غير أنه بالنسبة لضوابط البنية التحتية المخصصة — خاصةً Kubernetes وTerraform المخصص أو الأدوات غير القياسية — ستحتاج دائماً إلى المهارات التي يعلّمها هذا الدرس: تعريف أهداف الضوابط بدقة، وتحديد مصادر الأدلة، وكتابة استعلامات تُنتج مُخرَجات لا يمكن دحضها. أدوات GRC مكمّلة ولا تحل محل الحكم الهندسي.