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

سجلات التدقيق وإدارة التغيير

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

سجلات التدقيق وإدارة التغيير

كل إطار امتثال — SOC 2 وISO 27001 وPCI DSS وHIPAA — يتقاطع عند السؤال الجوهري ذاته: من الذي غيّر ماذا، ومتى، وهل كان ذلك مصرحاً به؟ سجلات التدقيق تجيب على هذا السؤال للمدققين. أما إدارة التغيير القائمة على طلبات السحب (Pull Requests) فتجيب عنه لفريق الهندسة في الوقت الفعلي. هذان ليسا شأنين منفصلين، بل هما طبقتان لنفس الضابط، وتشغّل المنظمات من الدرجة الأولى كليهما بشكل متناسق.

ما الذي يجعل سجل التدقيق غير قابل للتعديل

لا يُعدّ السجل دليلاً إلا إذا تعذّر العبث به بعد وقوع الحدث. ثلاث خصائص تُعرّف عدم قابلية التعديل في الواقع العملي:

  • التخزين للكتابة مرة واحدة فقط: تُكتب السجلات إلى وجهة لا يستطيع فيها حتى المالك حذف أو تعديل سجلات فردية. تُطبّق كل من AWS CloudTrail مع S3 Object Lock (وضع الامتثال)، وGCS مع Bucket Lock، وAzure Blob مع سياسات عدم القابلية للتعديل هذا المبدأ على مستوى التخزين.
  • التكامل التشفيري: يُحسب لكل دفعة من السجلات تجزئة (hash) تُخزَّن بشكل منفصل أو تُوقَّع. يُسلّم CloudTrail ملف تجزئة (digest file) كل ساعة يحتوي على تجزئات SHA-256 لجميع ملفات السجل في النافذة السابقة. يمكنك التحقق من التكامل دون اتصال بالإنترنت باستخدام: aws cloudtrail validate-logs --trail-arn <arn> --start-time <ISO8601>.
  • التجميع المركزي: تتدفق السجلات من كل خدمة وكل منطقة إلى حساب أمان مخصص أو أرشيف سجلات لا يملك فرق التطبيقات صلاحية الكتابة فيه. في AWS، يكون هذا عادةً حساب Log Archive مخصصاً داخل AWS Organizations، يستقبل السجلات عبر CloudTrail Organization Trail ووجهات CloudWatch Logs المركزية.
عدم قابلية التعديل خاصية تخزينية، لا إجرائية. الوعد بأن لا أحد سيحذف السجلات ليس ضابطاً. أما تهيئة Object Lock بالاحتفاظ لمدة 7 سنوات في وضع الامتثال (Compliance mode) فهو ضابط حقيقي. يمنع وضع الامتثال حتى حساب AWS root من إزالة القفل حتى انتهاء فترة الاحتفاظ — هذا ما يستوفي متطلب PCI DSS رقم 10.5.

ما الذي يجب تسجيله

سجّل كل ما يغيّر الحالة. بالنسبة للبنية التحتية السحابية، يكون الحد الأدنى كالتالي:

  • استدعاءات API لمستوى التحكم (Control Plane): كل CreateInstance وDeleteBucket وAssumeRole وأي تعديل على IAM. يشمل ذلك أحداث إدارة CloudTrail في AWS، وCloud Audit Logs (Admin Activity) في GCP، وAzure Activity Log.
  • قراءات مستوى البيانات على الموارد الحساسة: أحداث بيانات S3 للدلاء التي تحتوي على بيانات شخصية أو بيانات دفع. هذه البيانات ذات حجم كبير وتُكلّف مالاً؛ فعّلها بشكل انتقائي باستخدام S3 event selectors.
  • أحداث المصادقة: تسجيلات الدخول إلى وحدة التحكم (بما فيها حالة MFA)، وإنشاء مفاتيح API، وإخفاقات تدوير بيانات الاعتماد. محاولة MFA فاشلة في 03:00 UTC من عنوان IP غير معتاد هي إشارة تحذيرية — تحتاج إلى القدرة على اكتشافها.
  • تخطيط وتطبيق البنية التحتية كرمز: من الذي نفّذ terraform apply، وما تجزئة الخطة التي جرى اعتمادها، وما الذي تغيّر. يحتفظ Terraform Cloud/Atlantis بهذه البيانات بشكل أصلي؛ أما لخطوط الأنابيب مفتوحة المصدر فيجب عليك التقاط هذه المعلومات في مخزن سجلات CI الخاص بك.
  • سجل تدقيق Kubernetes: كل kubectl exec وحذف pod وتغيير في ربط RBAC والوصول إلى السر (secret) يُسجَّل على مستوى API server. أرسل هذه البيانات إلى SIEM الخاص بك — إنها مكافئ CloudTrail لمستوى التحكم في كتلتك.
# تفعيل مسار CloudTrail للمنظمة مع S3 Object Lock # (يُنفَّذ مرة واحدة من حساب الإدارة) aws cloudtrail create-trail \ --name org-audit-trail \ --s3-bucket-name my-org-audit-logs \ --is-multi-region-trail \ --enable-log-file-validation \ --is-organization-trail aws cloudtrail start-logging --name org-audit-trail # قفل دلو S3 — وضع الامتثال، احتفاظ 7 سنوات aws s3api put-object-lock-configuration \ --bucket my-org-audit-logs \ --object-lock-configuration '{ "ObjectLockEnabled": "Enabled", "Rule": { "DefaultRetention": { "Mode": "COMPLIANCE", "Years": 7 } } }' # التحقق من سلامة سجلات CloudTrail للـ 24 ساعة الماضية aws cloudtrail validate-logs \ --trail-arn arn:aws:cloudtrail:us-east-1:123456789012:trail/org-audit-trail \ --start-time $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \ --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ)

إدارة التغيير القائمة على طلبات السحب باعتبارها قصة التدقيق

لا يُعدّ GitOps مجرد نمط نشر — إنه نظام إدارة التغيير الخاص بك. كل تغيير في البنية التحتية يُدمج عبر طلب سحب يُنتج سجلاً دائماً ومترابطاً: من اقترح التغيير، ومن راجعه، وأي فحوصات آلية اجتازت، ومن وافق عليه، وبالضبط ما هو الفارق الذي طُبِّق. هذا هو الدليل الذي يريده المدقق لـ SOC 2 CC8.1 (إدارة التغيير) وISO 27001 A.12.1.2 (إجراء إدارة التغيير).

يجب أن تكون قصة التدقيق لأي تغيير في الإنتاج قابلة لإعادة البناء من تاريخ Git وحده:

  1. يفتح المهندس طلب سحب (PR) مقابل فرع main في مستودع البنية التحتية.
  2. تُشغّل CI تلقائياً terraform plan وtflint وفحوصات سياسة OPA. تُنشر النتائج كتعليقات على طلب السحب.
  3. يوافق ما لا يقل عن مراجع واحد من الأقران (يُطبَّق بواسطة حماية الفرع: يتطلب N موافقات، يلغي المراجعات القديمة، يتطلب فحوصات الحالة).
  4. عند الدمج، تُشغّل خطة الأنابيب terraform apply باستخدام رمز OIDC محدد المدة — لا بيانات اعتماد طويلة الأمد في CI.
  5. يُرسل تجزئة commit SHA وتجزئة خطة Terraform ومخرجات apply وعنوان URL لطلب السحب إلى مخزن سجل التدقيق المركزي.
PR-based change management audit flow Engineer opens PR GitHub PR Branch Protection Peer Review CI Pipeline tf plan + tflint OPA policy checks Status → PR comment tf apply OIDC token no long-lived creds Audit Log immutable كل خطوة تُنتج سجلاً دائماً ومترابطاً PR URL · commit SHA · plan hash · apply output · CloudTrail event
إدارة التغيير القائمة على PR: كل تغيير في الإنتاج يمر عبر المراجعة وينتج سجل تدقيق غير قابل للتعديل.

حماية الفرع كضابط إلزامي

قواعد حماية الفرع على فرع main أو production ليست اختيارية. بدونها، يستطيع أي شخص لديه صلاحية الكتابة الدفع مباشرة إلى main متجاوزاً عملية المراجعة بأكملها — سجل التدقيق موجود لكن خطوة التفويض مفقودة. الحد الأدنى من الإعدادات المطلوبة لمستودع بنية تحتية متوافق:

# حماية فرع GitHub عبر gh CLI (تُطبَّق على مستودع البنية التحتية) gh api repos/{owner}/{repo}/branches/main/protection \ --method PUT \ --header "Accept: application/vnd.github+json" \ --field required_status_checks='{"strict":true,"contexts":["terraform-plan","opa-policy"]}' \ --field enforce_admins=true \ --field required_pull_request_reviews='{"required_approving_review_count":1,"dismiss_stale_reviews":true,"require_code_owner_reviews":true}' \ --field restrictions=null \ --field allow_force_pushes=false \ --field allow_deletions=false
طبّق الحماية على المدراء أيضاً. enforce_admins: true هو الإعداد الأكثر إغفالاً. بدونه، يستطيع مدراء المستودع الدفع مباشرة إلى main — وفي تدقيق ما بعد الحادث، تُعدّ عبارة "المدير تجاوز العملية" بالضرر نفسه الذي يسببه غياب أي عملية أصلاً. يتحقق مدققو SOC 2 من هذا صراحةً.

ربط دمج طلبات السحب بأحداث النشر في سجل التدقيق

ثغرة تغفلها المنظمات: طلب السحب موجود في GitHub، وحدث النشر موجود في CloudTrail، لكن لا يوجد رابط آلي بينهما. يسأل المدقق: "أرني الموافقة على تغيير مجموعة الأمان المنشور في 14 مارس." بدون ترابط مرجعي، هذا يستلزم تحقيقاً يدوياً عبر نظامين منفصلين.

الحل هو إرسال حدث تدقيق منظّم من خط أنابيب CI/CD الخاص بك وقت التطبيق، يحتوي على عنوان URL لطلب السحب من GitHub وتفاصيل تغيير الموارد السحابية. اكتب هذا إلى وجهة سجلك المركزية (CloudWatch Logs، Datadog، Splunk) بمخطط بيانات (schema) متسق:

# إرسال حدث تدقيق تغيير منظّم من خط أنابيب CI # (مثال على خطوة shell تُنفَّذ بعد terraform apply) COMMIT_SHA=$(git rev-parse HEAD) PR_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" PLAN_HASH=$(sha256sum tfplan.binary | awk '{print $1}') TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) cat <<EOF | aws logs put-log-events \ --log-group-name /audit/infra-changes \ --log-sequence-token $(aws logs describe-log-streams \ --log-group-name /audit/infra-changes \ --query 'logStreams[0].uploadSequenceToken' \ --output text) \ --log-events timestamp=$(date +%s%3N),message="$(cat -)" { "event_type": "infrastructure_change", "timestamp": "${TIMESTAMP}", "actor": "${GITHUB_ACTOR}", "pr_url": "${PR_URL}", "commit_sha": "${COMMIT_SHA}", "plan_hash": "${PLAN_HASH}", "approvers": "${PR_APPROVERS}", "environment": "production", "repository": "${GITHUB_REPOSITORY}" } EOF

أنماط الإخفاق في بيئات الإنتاج

حتى أنظمة التدقيق المصممة بشكل جيد تعاني من أنماط إخفاق متكررة على نطاق واسع:

  • انقطاع وجهة السجل يُضيّع الأحداث بصمت: تستمر تطبيقاتك في العمل لكن أحداث التدقيق تُفقد. استخدم إشعار SNS من CloudTrail عند إخفاق تسليم السجل، أو انشر طابور رسائل ميت (dead-letter queue) لخطوط أنابيب شحن السجلات.
  • انحراف الساعة بين الخدمات: تُظهر السجلات من خدمتين أحداثاً خارج الترتيب السببي، مما يجعل إعادة بناء الحوادث غير موثوقة. طبّق مزامنة NTP على جميع المضيفين واستخدم مُسلسل أحداث رتيب (Kafka offsets، أرقام تسلسل Kinesis) للبثوث عالية الحجم حيث يهم الترتيب دون الثانية.
  • بيانات الاعتماد في سجل التدقيق: ينفّذ مطور aws s3 cp s3://bucket/file . --sse-c AES256 --sse-c-key <base64key> فيظهر المفتاح في CloudTrail. برنامج وسيط لإصفاء السجلات في SIEM يجب أن يحجب أنماط الأسرار المعروفة، لكن الحل الجذري هو منع ظهور الأسرار في وسيطات CLI (استخدم متغيرات البيئة أو مراجع AWS Secrets Manager بدلاً من ذلك).
  • سياسات الاحتفاظ المتقادمة: تحذف قواعد دورة حياة S3 ملفات السجل بعد 90 يوماً، لكن متطلب الامتثال هو 12 شهراً. نفّذ تدقيقاً ربع سنوي: aws s3api get-bucket-lifecycle-configuration --bucket my-org-audit-logs وتحقق من أن الاحتفاظ يطابق سياستك.
لا تخزن سجلات التدقيق أبداً في نفس الحساب الذي يعمل فيه التطبيق. إذا اخترق مهاجم حساب الإنتاج الخاص بك وحصل على بيانات اعتماد root أو admin، فإن أول ما يفعله هو حذف السجلات لإخفاء آثاره. السجلات في حساب Log Archive مخصص ومحمي بدون أذونات حذف متقاطعة بين الحسابات تنجو من اختراق حساب الإنتاج.

الاستعلام عن سجلات التدقيق على نطاق واسع

جمع السجلات مفيد فقط إذا كان بإمكانك الاستعلام عنها بسرعة أثناء حادث أو تدقيق. يتيح لك CloudTrail Lake تشغيل SQL مباشرة على أحداث مسارك دون تصدير إلى Athena أولاً. بالنسبة لمسار على مستوى المنظمة، يبدو استعلام نموذجي يسترجع جميع تغييرات IAM في آخر 30 يوماً كالتالي:

-- CloudTrail Lake: البحث عن جميع طفرات سياسة IAM في آخر 30 يوماً SELECT eventTime, userIdentity.arn AS actor, eventName, requestParameters, sourceIPAddress, userAgent FROM ${event_data_store_id} WHERE eventSource = 'iam.amazonaws.com' AND eventName IN ( 'AttachRolePolicy','DetachRolePolicy', 'PutRolePolicy','DeleteRolePolicy', 'CreatePolicy','DeletePolicy', 'CreateUser','DeleteUser' ) AND eventTime > DATE_ADD('DAY', -30, NOW()) ORDER BY eventTime DESC LIMIT 500

في البيئات متعددة السحابات، وجّه كل شيء عبر SIEM واحد (Splunk أو Elastic أو Datadog) وقيّسه على مخطط موحّد (يكتسب OCSF — إطار مخطط الأمن السيبراني المفتوح — قبولاً واسعاً كمعيار متعدد السحابات). هذا يتيح لاستعلام واحد أن يكشف الأحداث من AWS وGCP وKubernetes في آنٍ واحد خلال الحوادث.