Policy as Code
1) What counts as "politics"
A policy is a deterministic rule that answers the question "can/cannot" (or "how exactly can") given the context:- Access/authorization: RBAC/ABAC, ReBAC, data export, step-up (MFA).
- Infrastructure security: admission control Kubernetes, image/secret policy, network rules.
- Compliance and privacy: consent management, PII tagging, local reporting days, geo-restrictions.
- Configurations and quality: "deny: latest," resource limits, mandatory resource tags (Cloud).
- Data and ML: prohibition of training on sets without consent, k-anonymity, DP-budgets, Data Lineage-invariants.
2) PaC Architectural Model
PAP (Policy Administration Point): repository and management processes (MR/PR, review, version).
PDP (Policy Decision Point): engine that calculates the policy decision (OPA, Cedar-engine, native interpreter).
PEP (Policy Enforcement Point): application point (API gateway, webhook administration in K8s, ETL transformer, SDK).
PIP (Policy Information Point): sources of attributes/facts: IdP, resource directories, data warehouse, risk rate.
Decision Log/Audit: unchangeable solution logs (for incident analysis and compliance).
Stream: request → PEP forms context → PDP loads facts (PIP) → calculates solution → PEP applies (allow/deny/edit) → log/metrics.
3) Tools and domains
OPA/Rego is a universal engine and language for declarative policies (webhook administration in K8s: Gatekeeper, in CI - Conftest, in API - sidecar/service).
Kyverno - declarative policies for Kubernetes in YAML, patch/validation/generation.
Cedar (AWS/portable) is a policy language with a focus on who-over-what authorization.
Cloud IAM (AWS/GCP/Azure) - cloud resource policies (preferably check PaC static and in IaC plans).
Custom - DSL/rules over JSON/SQL for specifics (for example, ML compliance).
4) Policy lifecycle
1. Definition of the target and domain: "Prohibition on loading containers with High/CRITICAL vulnerabilities."
2. Formalization in code: Rego/Cedar/YAML.
3. Tests: truth tables, negative cases, property-based.
4. CI checks: linter, unit, integration on fictitious manifests/requests.
5. Release and distribution: publication in bundle, signature, delivery to PDP/edge.
6. Monitoring: hit-rate, latency p95/p99, deny share, drift dashboards.
7. Exceptions/waivers: time/volume limited, audited and owned.
8. Refactoring and archive: versions, compatibility, migrations.
5) Storage and distribution
Repo-layout: `policies/<domain>/<policy>.rego|cedar|yaml`, `tests/`, `bundles/`, `schemas/`.
Versioning: semver and 'policy _ version' in PDP responses.
Bundles - compressed policy packages + schemas + configs, signed (supply chain security).
Distribution: pull (PDP pulls from registry/S3) or push (controller sends).
Partial evaluation: Anticipates policies for rapid execution at the perimeter.
6) Data model and schemas
Single context contract: 'subject', 'resource', 'action', 'env', 'legal'.
JSON-Schema/Protobuf: validate actual models; schema mismatch - cause for "indeterminate → deny."
Attribute normalization: unified names (for example, 'tenant _ id', 'risk _ level', 'pii _ tags', 'image. vulns`).
7) Performance and reliability
Solution cache: key '(subject_hash, resource_key, action, policy_version)'; short TTL, disability by event (role/tag change).
Local Facts: Don't pull heavy PIPs on the hot track - sync snapshots.
Fail-open vs fail-closed: critical domain security - fail-closed; for UX-critical - degradation (edition instead of deny).
Latency budget: target '<3-10 ms' per solution in PDP memory, '<30-50 ms' with PIP.
8) Exception management (waivers)
Limited time (e.g. 7 days), with mandatory owner and reason.
Coupled: by resource/project/namespace; banning global "forever."
Audit and reminders: reports on expiring waivers, auto-close/escalation.
9) Metrics and observability
Policy Coverage: proportion of paths/endpoints protected by PaC.
Decision Latency / QPS / Error rate.
Deny Rate and False Positive/Negative (via dry-run/shadow mode).
Drift: discrepancy between plan (IaC) and fact (live), between SDK and server solutions.
Аудит: `decision_id, policy_ids, version, attributes_digest, effect, reason`.
10) Anti-patterns
Policies "hardwired" into code without versions and tests.
Lack of schematics/context validation → unpredictable decisions.
One monolithic file "mega. rego».
There is no exception process → manual rounds and chaos.
Only runtime application without shift-left in CI (late failures).
Hidden side effects in policy (policy should be a pure function).
11) Examples
11. 1 Rego (OPA) - deny vulnerable images in K8s
rego package k8s. admission. vulns
deny[msg] {
input. kind. kind == "Pod"
some c img:= input. request. object. spec. containers[c].image vulns:= data. registry. scan [img] # actual-snapshot from PIP count ({v v:= vulns[_]; v.severity == "CRITICAL"}) > 0 msg:= sprintf("image %s has CRITICAL vulns", [img])
}
11. 2 Rego: export data from MFA and white IP only
rego package api. export
default allow = false
allow {
input. action == "export"
input. subject. mfa_verified == true net. cidr_contains("203. 0. 113. 0/24", input. env. ip)
}
11. 3 Cedar: Only read to owner or team members
cedar permit(
principal in Group::"team_members",
action in [Action::"read"],
resource in Photo::"")
when { resource. owner == principal resource. team_id in principal. team_ids };
11. 4 Kyverno (YAML): Prohibition ': latest' and obligatory. resources
yaml apiVersion: kyverno. io/v1 kind: ClusterPolicy metadata:
name: disallow-latest-and-require-limits spec:
validationFailureAction: Enforce rules:
- name: disallow-latest match: { resources: { kinds: ["Pod"] } }
validate:
message: "Image tag 'latest' is not allowed."
pattern:
spec:
containers:
- name: ""
image: "!:latest"
- name: require-limits match: { resources: { kinds: ["Pod"] } }
validate:
message: "resources. limits.{cpu,memory} required."
pattern:
spec:
containers:
- resources:
limits:
cpu: "?"
memory: "?"
11. 5 Conftest in CI for Terraform Plan
bash terraform plan -out tf. plan terraform show -json tf. plan > tf. json conftest test tf. json --policy policies/terraform
12) Embedding in existing abilities
RBAC/ABAC: PaC - declaration layer; PDP/PEP from the role engine article are reused.
Consent management: "ads/personalization" policy as data/endpoint access conditions.
Anonymization/PII: Policies prohibit training/export without anonymization and DP budget profiles.
Geo-routing: policy for routing traffic/data by storage region.
13) Processes and people
Policy domain owners: security, platform, data, product/marketing.
Reviewers: security + domain owners.
Policy catalog: target description, risk, SLO, contact, examples, incident links.
Training: guides and snippets for developers (how to write tests, how to debug Rego).
14) Architect checklist
1. Minimum set of domains and owners defined?
2. Policy repository with tests, linter and CI?
3. Are PDPs/PEPs placed on the perimeter, in the API, in the K8s, and in the data pipelines?
4. Are there context diagrams and validation?
5. Signature and delivery bundles, cache and disability strategy?
6. Metrics (latency, deny, drift), decision-log and audit?
7. Exception process with TTL and reporting?
8. Dry-run/shadow-mode before Enforce?
9. Partial evaluation/precompilation for hot spots?
10. Runbook for degradation (fail-closed/allow-with-redaction)?
Conclusion
Policy as Code makes rules reproducible, verifiable, and managed on the same principles as the application: review code, tests, CI/CD, metrics, and rollbacks. By connecting PaC with authorization (RBAC/ABAC), compliance and platform security, you get a single, predictable and scalable control loop for system behavior - from admission control to data exports and ML pipelines.