Files
mukul975 c21af3347e Complete folder anatomy for all 649 cybersecurity skills + update LICENSE to Mahipal
- Add scripts/agent.py and references/api-reference.md to all remaining skills
- Update all 648 LICENSE files: copyright now reads 'Mahipal'
- Add implementing-security-monitoring-with-datadog (new skill with full anatomy)
- All 649 skills now have: SKILL.md, LICENSE, scripts/agent.py, references/api-reference.md
2026-03-11 00:22:12 +01:00

192 lines
7.7 KiB
Python

#!/usr/bin/env python3
"""Agent for auditing and managing GCP Organization Policy constraints."""
import json
import argparse
import subprocess
from datetime import datetime
BASELINE_BOOLEAN_CONSTRAINTS = {
"constraints/compute.vmExternalIpAccess": {"type": "list", "expected": "DENY_ALL"},
"constraints/compute.requireOsLogin": {"type": "boolean", "expected": True},
"constraints/compute.disableSerialPortAccess": {"type": "boolean", "expected": True},
"constraints/compute.disableNestedVirtualization": {"type": "boolean", "expected": True},
"constraints/storage.uniformBucketLevelAccess": {"type": "boolean", "expected": True},
"constraints/sql.restrictPublicIp": {"type": "boolean", "expected": True},
"constraints/iam.disableServiceAccountKeyCreation": {"type": "boolean", "expected": True},
"constraints/iam.automaticIamGrantsForDefaultServiceAccounts": {"type": "boolean", "expected": True},
}
def run_gcloud(args_list):
"""Run a gcloud command and return parsed JSON."""
cmd = ["gcloud"] + args_list + ["--format=json"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
if result.returncode != 0:
return {"error": result.stderr.strip()}
try:
return json.loads(result.stdout) if result.stdout.strip() else {}
except json.JSONDecodeError:
return {"raw": result.stdout.strip()}
def list_org_policies(org_id):
"""List all active organization policies."""
return run_gcloud(["org-policies", "list", f"--organization={org_id}"])
def describe_policy(org_id, constraint):
"""Get details of a specific org policy constraint."""
return run_gcloud(["org-policies", "describe", constraint,
f"--organization={org_id}"])
def audit_baseline_compliance(org_id):
"""Audit organization against security baseline constraints."""
findings = []
for constraint, expected in BASELINE_BOOLEAN_CONSTRAINTS.items():
policy = describe_policy(org_id, constraint)
if isinstance(policy, dict) and "error" in policy:
findings.append({
"constraint": constraint,
"status": "NOT_SET",
"severity": "HIGH",
"recommendation": f"Enable {constraint}",
})
continue
if expected["type"] == "boolean":
enforced = False
if isinstance(policy, dict):
bp = policy.get("booleanPolicy", {})
enforced = bp.get("enforced", False)
findings.append({
"constraint": constraint,
"status": "COMPLIANT" if enforced else "NON_COMPLIANT",
"severity": "INFO" if enforced else "HIGH",
"current": enforced,
"expected": expected["expected"],
})
elif expected["type"] == "list":
lp = policy.get("listPolicy", {}) if isinstance(policy, dict) else {}
all_denied = lp.get("allValues") == "DENY" or lp.get("deniedValues") == ["*"]
findings.append({
"constraint": constraint,
"status": "COMPLIANT" if all_denied else "NON_COMPLIANT",
"severity": "INFO" if all_denied else "HIGH",
})
return findings
def audit_project_policies(project_id):
"""Audit organization policies effective on a specific project."""
policies = run_gcloud(["org-policies", "list", f"--project={project_id}"])
if isinstance(policies, dict) and "error" in policies:
return [{"error": policies["error"]}]
return policies if isinstance(policies, list) else []
def check_resource_location_constraint(org_id):
"""Check if resource location constraint is configured."""
policy = describe_policy(org_id, "constraints/gcp.resourceLocations")
if isinstance(policy, dict) and "error" not in policy:
lp = policy.get("listPolicy", {})
allowed = lp.get("allowedValues", [])
if allowed:
return {"status": "CONFIGURED", "allowed_locations": allowed}
return {"status": "NOT_CONFIGURED", "severity": "MEDIUM",
"recommendation": "Restrict resource locations to approved regions"}
def generate_terraform_policies(org_id, constraints=None):
"""Generate Terraform HCL for baseline org policies."""
constraints = constraints or list(BASELINE_BOOLEAN_CONSTRAINTS.keys())
tf_blocks = []
for c in constraints:
info = BASELINE_BOOLEAN_CONSTRAINTS.get(c, {"type": "boolean", "expected": True})
resource_name = c.split("/")[1].replace(".", "_")
if info["type"] == "boolean":
tf_blocks.append(f'''resource "google_organization_policy" "{resource_name}" {{
org_id = "{org_id}"
constraint = "{c}"
boolean_policy {{
enforced = true
}}
}}''')
elif info["type"] == "list":
tf_blocks.append(f'''resource "google_organization_policy" "{resource_name}" {{
org_id = "{org_id}"
constraint = "{c}"
list_policy {{
deny {{
all = true
}}
}}
}}''')
return "\n\n".join(tf_blocks)
def generate_compliance_report(findings):
"""Generate a compliance summary from audit findings."""
total = len(findings)
compliant = sum(1 for f in findings if f.get("status") == "COMPLIANT")
non_compliant = sum(1 for f in findings if f.get("status") == "NON_COMPLIANT")
not_set = sum(1 for f in findings if f.get("status") == "NOT_SET")
return {
"total_constraints": total,
"compliant": compliant,
"non_compliant": non_compliant,
"not_set": not_set,
"compliance_percentage": round(compliant / total * 100, 1) if total else 0,
"high_severity_gaps": [f for f in findings if f.get("severity") == "HIGH"],
}
def main():
parser = argparse.ArgumentParser(description="GCP Organization Policy Agent")
parser.add_argument("--org-id", help="GCP organization ID")
parser.add_argument("--project", help="GCP project ID for project-level audit")
parser.add_argument("--action", choices=["audit", "list", "terraform", "locations"],
default="audit")
parser.add_argument("--output", default="gcp_orgpolicy_report.json")
args = parser.parse_args()
report = {"generated_at": datetime.utcnow().isoformat(), "results": {}}
if args.action == "audit" and args.org_id:
findings = audit_baseline_compliance(args.org_id)
summary = generate_compliance_report(findings)
report["results"]["findings"] = findings
report["results"]["summary"] = summary
print(f"[+] Compliance: {summary['compliance_percentage']}%"
f" ({summary['compliant']}/{summary['total_constraints']})")
elif args.action == "list" and args.org_id:
policies = list_org_policies(args.org_id)
report["results"]["policies"] = policies
count = len(policies) if isinstance(policies, list) else 0
print(f"[+] Active policies: {count}")
elif args.action == "terraform" and args.org_id:
tf = generate_terraform_policies(args.org_id)
report["results"]["terraform"] = tf
print("[+] Terraform configuration generated")
elif args.action == "locations" and args.org_id:
result = check_resource_location_constraint(args.org_id)
report["results"]["location_constraint"] = result
print(f"[+] Location constraint: {result['status']}")
if args.project:
project_policies = audit_project_policies(args.project)
report["results"]["project_policies"] = project_policies
print(f"[+] Project {args.project}: {len(project_policies)} policies")
with open(args.output, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"[+] Report saved to {args.output}")
if __name__ == "__main__":
main()