# Policy as Code Reference

## Overview

Policy as Code (PaC) translates compliance requirements into machine-executable policies that can be tested, versioned, and enforced automatically in CI/CD pipelines and runtime environments.

---

## Tool Landscape

| Tool | Language | Use Case | Integration |
|------|----------|----------|-------------|
| **OPA (Open Policy Agent)** | Rego | General-purpose policy engine | Kubernetes, Terraform, CI/CD, API gateways |
| **Conftest** | Rego (via OPA) | Configuration file testing | Terraform, Kubernetes YAML, Dockerfile |
| **Checkov** | Python/YAML | IaC security scanning | Terraform, CloudFormation, Kubernetes, ARM |
| **Sentinel** (HashiCorp) | Sentinel | Terraform policy enforcement | Terraform Cloud/Enterprise |
| **Kyverno** | YAML | Kubernetes-native policies | Kubernetes admission controller |
| **AWS Config Rules** | Python/JSON | AWS resource compliance | AWS native |
| **Azure Policy** | JSON | Azure resource compliance | Azure native |
| **GCP Organization Policy** | YAML | GCP resource constraints | GCP native |

---

## OPA/Rego Patterns for Compliance

### Access Control Policy (SOC2 CC6.1, PCI-DSS Req 7)

```rego
package compliance.access_control

# Deny if user lacks required role for resource
deny[msg] {
    input.action == "access"
    not has_required_role(input.user, input.resource)
    msg := sprintf("User %s lacks required role for %s", [input.user.id, input.resource.type])
}

has_required_role(user, resource) {
    required := role_requirements[resource.type]
    user.roles[_] == required[_]
}

role_requirements := {
    "cardholder_data": ["pci_admin", "payment_processor"],
    "ephi": ["hipaa_authorized", "healthcare_admin"],
    "audit_logs": ["security_admin"],
}
```

### Encryption Enforcement (PCI-DSS Req 3.4, HIPAA §164.312)

```rego
package compliance.encryption

# Terraform: Deny unencrypted storage
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_s3_bucket"
    not has_encryption(resource)
    msg := sprintf("S3 bucket %s must have encryption enabled (PCI-DSS Req 3.4)", [resource.name])
}

deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_rds_instance"
    not resource.change.after.storage_encrypted
    msg := sprintf("RDS instance %s must have storage encryption (HIPAA §164.312(a)(2)(iv))", [resource.name])
}

has_encryption(resource) {
    resource.change.after.server_side_encryption_configuration[_].rule[_].apply_server_side_encryption_by_default[_].sse_algorithm
}
```

### Logging Requirements (PCI-DSS Req 10, SOC2 CC7.2)

```rego
package compliance.logging

# Ensure CloudTrail is enabled and configured
deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_cloudtrail"
    not resource.change.after.enable_logging
    msg := "CloudTrail logging must be enabled (PCI-DSS Req 10)"
}

deny[msg] {
    resource := input.resource_changes[_]
    resource.type == "aws_cloudtrail"
    not resource.change.after.is_multi_region_trail
    msg := "CloudTrail must be multi-region (SOC2 CC7.2)"
}
```

---

## CI/CD Integration

### Pipeline Architecture

```
Code Commit
    |
    v
[Static Analysis] -> Sentinel/Conftest (IaC policies)
    |
    v
[Build]
    |
    v
[Test] -> OPA unit tests for policies
    |
    v
[Compliance Gate] -> OPA/Conftest evaluation against compliance policies
    |                 PASS -> continue
    |                 FAIL -> block + notify
    v
[Deploy] -> Kubernetes admission (OPA Gatekeeper / Kyverno)
    |
    v
[Runtime] -> Continuous compliance monitoring
```

### Conftest in CI Example

```yaml
# .github/workflows/compliance.yml
compliance-check:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - name: Install conftest
      run: |
        wget -qO- https://github.com/open-policy-agent/conftest/releases/download/v0.50.0/conftest_0.50.0_Linux_x86_64.tar.gz | tar xz
        sudo mv conftest /usr/local/bin/
    - name: Run compliance policies
      run: |
        conftest test terraform/ --policy policy/compliance/ --output json
        conftest test kubernetes/ --policy policy/compliance/ --output json
```

---

## Policy Testing

```rego
# policy/compliance/access_control_test.rego
package compliance.access_control

test_deny_unauthorized_access {
    deny["User user123 lacks required role for cardholder_data"] with input as {
        "action": "access",
        "user": {"id": "user123", "roles": ["viewer"]},
        "resource": {"type": "cardholder_data"}
    }
}

test_allow_authorized_access {
    count(deny) == 0 with input as {
        "action": "access",
        "user": {"id": "admin1", "roles": ["pci_admin"]},
        "resource": {"type": "cardholder_data"}
    }
}
```

---

## Continuous Compliance Monitoring

| Component | Purpose | Tools |
|-----------|---------|-------|
| Drift detection | Detect configuration changes that break compliance | AWS Config, OPA + periodic scan |
| Evidence collection | Automated compliance evidence gathering | Custom scripts, cloud-native tools |
| Dashboard | Real-time compliance posture visualization | Grafana, cloud-native dashboards |
| Alerting | Notify on compliance violations | PagerDuty, Slack, OpsGenie |
| Reporting | Scheduled compliance status reports | Custom reporting + Scribe agent |

---

## Anti-Patterns

| Anti-Pattern | Problem | Fix |
|-------------|---------|-----|
| Policies only in CI, not runtime | Drift goes undetected | Add runtime enforcement (OPA Gatekeeper, cloud-native policies) |
| Policies without tests | False positives/negatives go unnoticed | Test every policy with positive and negative cases |
| Manual exception process | Exceptions are undocumented | Codify exceptions as policy rules with expiry dates |
| Overly broad policies | Too many false positives, developers ignore | Scope policies to specific resource types and environments |
| No policy versioning | Can't track policy changes over time | Store policies in git with conventional commits |
