الامتثال والحوكمة ونضج DevSecOps

السياسة كرمز مع OPA و Rego

4 دقيقة للقراءة

السياسة كرمز (PaC) تتعامل مع سياسات الأمان والامتثال كرمز يخضع للتحكم بالإصدارات. Open Policy Agent (OPA) ولغته Rego أصبحا المعيار لتعريف وإنفاذ السياسات عبر دورة حياة تطوير البرمجيات.

لماذا السياسة كرمز؟

النهج التقليدي السياسة كرمز
مراجعات السياسات اليدوية إنفاذ آلي
قائم على التوثيق سياسات قابلة للتنفيذ
تطبيق غير متسق متسق عبر البيئات
دورات موافقة بطيئة تحقق في الوقت الفعلي
صعب التدقيق يخضع للتحكم بالإصدارات، قابل للتدقيق

نظرة عامة على Open Policy Agent (OPA)

┌─────────────────────────────────────────────────────────┐
│                   إنفاذ السياسات                         │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────────┐    ┌──────────────┐                  │
│  │ بيانات الإدخال│───▶│     OPA      │                  │
│  │ (JSON)       │    │              │                  │
│  └──────────────┘    │  ┌────────┐  │                  │
│                      │  │ سياسة  │  │───▶ القرار       │
│  ┌──────────────┐    │  │ Rego   │  │     (سماح/رفض)  │
│  │   الاستعلام  │───▶│  └────────┘  │                  │
│  └──────────────┘    └──────────────┘                  │
│                                                          │
└─────────────────────────────────────────────────────────┘

البدء مع OPA

التثبيت

# macOS
brew install opa

# Linux
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64_static
chmod +x opa
sudo mv opa /usr/local/bin/

# التحقق من التثبيت
opa version

سياسة Rego أساسية

# policy.rego
package authz

# الرفض الافتراضي
default allow := false

# السماح إذا كان المستخدم مسؤولاً
allow if {
    input.user.role == "admin"
}

# السماح إذا كان المستخدم يملك المورد
allow if {
    input.user.id == input.resource.owner_id
}

اختبار السياسة

# بيانات الإدخال (input.json)
{
  "user": {
    "id": "user123",
    "role": "developer"
  },
  "resource": {
    "owner_id": "user123",
    "type": "document"
  }
}

# تقييم السياسة
opa eval -i input.json -d policy.rego "data.authz.allow"
# النتيجة: true (المستخدم يملك المورد)

التحكم في قبول Kubernetes مع OPA

Gatekeeper: OPA لـ Kubernetes

# تثبيت Gatekeeper
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml

قالب القيد

# template.yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        violation[{"msg": msg}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("Missing required labels: %v", [missing])
        }

القيد

# constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: pods-must-have-owner
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
  parameters:
    labels: ["app", "owner", "environment"]

إنفاذ السياسات في CI/CD

مثال سياسة Terraform

# terraform_policy.rego
package terraform

# رفض S3 buckets العامة
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_s3_bucket"
    resource.change.after.acl == "public-read"
    msg := sprintf("S3 bucket '%s' لا يمكن أن يكون عاماً", [resource.name])
}

# طلب التشفير على RDS
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_db_instance"
    not resource.change.after.storage_encrypted
    msg := sprintf("مثيل RDS '%s' يجب أن يكون مشفراً", [resource.name])
}

# فرض الحد الأدنى لحجم المثيل
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_instance"
    not valid_instance_type(resource.change.after.instance_type)
    msg := sprintf("المثيل '%s' يستخدم نوعاً غير مسموح '%s'", [resource.name, resource.change.after.instance_type])
}

valid_instance_type(type) {
    allowed := {"t3.micro", "t3.small", "t3.medium", "m5.large"}
    allowed[type]
}

تكامل GitHub Actions

# .github/workflows/policy-check.yml
name: Policy Check

on:
  pull_request:
    paths:
      - '**/*.tf'

jobs:
  opa-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3

      - name: Terraform Plan
        run: |
          terraform init
          terraform plan -out=tfplan
          terraform show -json tfplan > tfplan.json

      - name: Setup OPA
        uses: open-policy-agent/setup-opa@v2

      - name: Run OPA Policy Check
        run: |
          opa eval -i tfplan.json \
            -d policies/ \
            --format pretty \
            "data.terraform.deny"

أنماط السياسات الشائعة

وسم الموارد

package tags

required_tags := {"environment", "owner", "cost-center"}

deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_instance"
    tags := object.get(resource.change.after, "tags", {})
    missing := required_tags - {tag | tags[tag]}
    count(missing) > 0
    msg := sprintf("المورد '%s' ينقصه الوسوم: %v", [resource.name, missing])
}

أمان الشبكة

package network

# رفض مجموعات الأمان المتساهلة جداً
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_security_group_rule"
    resource.change.after.type == "ingress"
    resource.change.after.cidr_blocks[_] == "0.0.0.0/0"
    resource.change.after.from_port == 0
    resource.change.after.to_port == 65535
    msg := "مجموعة الأمان تسمح بكل الحركة من الإنترنت"
}

اختبار سياسات Rego

# policy_test.rego
package terraform

test_deny_public_s3 {
    deny["S3 bucket 'test' cannot be public"] with input as {
        "resource_changes": [{
            "type": "aws_s3_bucket",
            "name": "test",
            "change": {"after": {"acl": "public-read"}}
        }]
    }
}

test_allow_private_s3 {
    count(deny) == 0 with input as {
        "resource_changes": [{
            "type": "aws_s3_bucket",
            "name": "test",
            "change": {"after": {"acl": "private"}}
        }]
    }
}
# تشغيل الاختبارات
opa test policies/ -v

بعد ذلك، سنستكشف أتمتة الامتثال لـ SOC2 و HIPAA و PCI-DSS. :::

اختبار

الوحدة 6: الامتثال والحوكمة ونضج DevSecOps

خذ الاختبار