Updated 5 hours ago
Updated 5 hours ago
5 hours ago
0ec7301a5ef7 · 4.7GB ·
Generate OPA/Rego policies + unit tests from compliance rules, designed to evaluate Terraform plan JSON across AWS / GCP / Azure.
This repo includes:
- A ready-to-push Ollama Modelfile for a policy generator model
- A minimal Node.js API (POST /generate) that calls the local Ollama model and validates the output
- A starter multi-cloud policy pack (4 rules) + OPA unit tests + fixtures
- Exception support (time-bound allowlists) via exceptions/exceptions.yaml
You give the assistant a rule like: - “No public object storage” - “Encryption keys must rotate” - “No wildcard permissions in prod” - “Centralized audit logging must be enabled”
…and it generates a policy bundle that includes:
- Rego policy (policy/rules/<rule_id>.rego) enforcing the rule
- OPA unit tests (policy/tests/<rule_id>_test.rego) proving the policy behavior
- Exceptions template (exceptions/exceptions.yaml) for controlled, time‑bound exceptions
- Rationale + notes explaining what the policy checks and why
The output is JSON only so it can be validated and integrated into automation safely.
This assistant is multi-cloud because it targets Terraform plan JSON as the universal input.
Terraform plan JSON typically contains input.resource_changes[], where each entry includes:
- resource type (e.g., aws_*, google_*, azurerm_*)
- resource address
- the planned configuration in change.after
The generated policies read resource_changes[] and apply provider‑specific checks within the same rule, so you can run one policy pack across AWS/GCP/Azure.
The Node API is a “guardrail” around the generator model:
1. Calls your local Ollama model (cloud-pac-assistant)
2. Extracts the JSON response
3. Validates it in two layers:
- JSON Schema validation: required fields/types exist (src/schema.js)
- Rule-based validation: required files exist + rule defines deny[...]
If validation fails, the server rejects the output so you don’t ship broken policy bundles.
This repo includes 4 starter policies (each has unit tests):
no_public_object_storageallUsers/allAuthenticatedUsersallow_blob_public_access = falsekey_rotation_requiredno_wildcard_identity_prodenv=prod|production)Action="*" or Resource="*"roles/owner, roles/editor)Owner, Contributor)centralized_audit_loggingReal orgs need exceptions (migrations, temporary access, legacy systems).
Exceptions are loaded via data.exceptions and can match by:
- rule_id
- provider (aws|gcp|azure|any)
- resource_type (or any)
- exact address or address_prefix
This lets you allow a specific resource temporarily while still enforcing guardrails everywhere else.
deny[...] is non-emptyRule text (plain English)
|
v
Node API POST /generate
|
v
Ollama model (cloud-pac-assistant) -> JSON bundle
|
v
Server validation (schema + rule-based)
|
v
Rego policies + tests + exceptions template
|
v
Run in CI via opa test / conftest test (Terraform plan JSON)
policy/
lib/
terraform.rego # tfplan helpers (resource_changes, after(), prod detection)
exceptions.rego # exception matching (data.exceptions)
rules/
no_public_object_storage.rego
key_rotation_required.rego
no_wildcard_identity_prod.rego
centralized_audit_logging.rego
tests/
*_test.rego
exceptions/
exceptions.yaml # example exceptions (top-level list)
fixtures/
tfplan_*.json # minimal demo inputs
server.js # /generate API that calls Ollama
Modelfile # build the Ollama generator model
Pull a base model (you can swap this later):
ollama pull qwen2.5-coder:7b
Create the model:
ollama create cloud-pac-assistant -f ./Modelfile
npm install
cp .env.example .env
npm start
Health check:
curl -s http://localhost:8088/health | jq .
curl -s http://localhost:8088/generate -H "Content-Type: application/json" -d '{
"profile": "generic",
"rule_id_hint": "no_public_object_storage",
"rule_text": "No public object storage across AWS S3, GCP GCS, and Azure Blob. Disallow public principals/members and require provider-native public access prevention settings."
}' | jq .
The API returns JSON only. It includes rule metadata plus file contents for the policy, tests, and exceptions template.
{
"result": {
"rule_id": "no_public_object_storage",
"title": "No Public Object Storage",
"description": "Blocks public access patterns for object storage across AWS/GCP/Azure using Terraform plan JSON.",
"providers_supported": ["aws", "gcp", "azure"],
"target_inputs": ["terraform_plan_json"],
"rego_files": [
{
"path": "policy/rules/no_public_object_storage.rego",
"content": "package rules.no_public_object_storage\n\nimport data.lib.terraform as tf\nimport data.lib.exceptions as ex\n...\n\ndeny[msg] { ... }\n"
},
{
"path": "policy/tests/no_public_object_storage_test.rego",
"content": "package rules.no_public_object_storage_test\n\nimport data.rules.no_public_object_storage as r\n...\n"
}
],
"exceptions_template": {
"path": "exceptions/exceptions.yaml",
"content": "- rule_id: no_public_object_storage\n provider: aws\n resource_type: aws_s3_bucket_public_access_block\n address: module.logs.aws_s3_bucket_public_access_block.log_archive\n reason: \"Temporary exception\"\n expires_on: \"2026-02-01\"\n"
},
"rationale": "Public access to object storage is a common source of data exposure. This policy blocks AWS/GCP/Azure public access patterns and requires provider-native safety settings.",
"notes": [
"Terraform provider schemas can vary; tune attribute names if your provider version differs.",
"Use exceptions only for temporary, approved cases."
]
}
}
Policies return actionable deny messages: - AWS: “Enable S3 Public Access Block (all four flags true).” - GCP: “GCS bucket IAM must not grant access to allUsers/allAuthenticatedUsers (public).” - Azure: “Set allow_blob_public_access=false for Azure Storage.”
opa)npm run opa:test
conftest)conftest test fixtures/tfplan_aws_public_s3.json --policy policy --data exceptions/exceptions.yaml
conftest test fixtures/tfplan_gcp_public_gcs.json --policy policy --data exceptions/exceptions.yaml
conftest test fixtures/tfplan_azure_public_blob.json --policy policy --data exceptions/exceptions.yaml
Add an entry to exceptions/exceptions.yaml:
- rule_id: no_public_object_storage
provider: aws
resource_type: aws_s3_bucket_public_access_block
address: module.logs.aws_s3_bucket_public_access_block.log_archive
reason: "Migration window; compensating controls in place."
expires_on: "2026-02-01"
You can also use address_prefix to scope the exception to a module prefix.
After local validation:
ollama signin
ollama cp cloud-pac-assistant bharathreddyjanumpally/cloud-policy-as-code-assistant
ollama push bharathreddyjanumpally/cloud-policy-as-code-assistant
centralized_audit_logging is a presence check (by design). If you want stronger guarantees, tailor it to your org’s chosen architecture (e.g., specific sinks/buckets/workspaces).This project provides general engineering guidance and guardrails. It is not legal advice.