Production hardening: security fixes, code quality, 724 skills complete

- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
This commit is contained in:
mukul975
2026-03-19 13:26:49 +01:00
parent 63b442d347
commit c47eed6a64
900 changed files with 23085 additions and 2720 deletions
@@ -1,27 +1,183 @@
# API Reference: OPA policy-as-code implementation audit
# API Reference: Open Policy Agent (OPA) Policy-as-Code
## API Endpoints
OPA: POST /v1/data/{package}, PUT /v1/policies/{id}, GET /v1/data, Rego policy language
## Libraries Used
| Library | Purpose |
|---------|---------|
| `requests` | HTTP client for OPA REST API |
| `json` | Parse OPA decision responses |
| `subprocess` | Run `opa eval` and `opa test` CLI commands |
| `yaml` | Parse Kubernetes admission review objects |
## Installation
```bash
pip install requests
# OPA binary
curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64_static
chmod 755 opa && sudo mv opa /usr/local/bin/
# Python dependencies
pip install requests pyyaml
```
## Libraries
## OPA REST API Endpoints
| Library | Use |
|---------|-----|
| `requests` | requests SDK/client |
| Method | Endpoint | Description |
|--------|----------|-------------|
| PUT | `/v1/policies/{id}` | Create or update a policy module |
| GET | `/v1/policies/{id}` | Retrieve a policy module |
| DELETE | `/v1/policies/{id}` | Delete a policy module |
| GET | `/v1/policies` | List all policy modules |
| PUT | `/v1/data/{path}` | Create or overwrite a document |
| GET | `/v1/data/{path}` | Evaluate a rule or retrieve data |
| POST | `/v1/data/{path}` | Evaluate a rule with input |
| PATCH | `/v1/data/{path}` | Patch a data document |
| POST | `/v1/query` | Execute ad-hoc Rego query |
| POST | `/v1/compile` | Partially evaluate a query |
| GET | `/health` | Health check (liveness) |
| GET | `/health?bundles` | Health check including bundle status |
## Authentication
## Core Operations
| Method | Header |
|--------|--------|
| Bearer Token | `Authorization: Bearer <token>` |
| API Key | `X-API-Key: <key>` |
### Upload a Rego Policy
```python
import requests
import os
OPA_URL = os.environ.get("OPA_URL", "http://localhost:8181")
policy_rego = """
package authz
default allow := false
allow if {
input.user.role == "admin"
}
allow if {
input.user.role == "editor"
input.action == "read"
}
"""
resp = requests.put(
f"{OPA_URL}/v1/policies/authz",
data=policy_rego,
headers={"Content-Type": "text/plain"},
timeout=10,
)
resp.raise_for_status()
```
### Evaluate a Policy Decision
```python
decision_input = {
"input": {
"user": {"role": "editor", "name": "alice"},
"action": "read",
"resource": "/api/reports",
}
}
resp = requests.post(
f"{OPA_URL}/v1/data/authz/allow",
json=decision_input,
timeout=10,
)
result = resp.json()
allowed = result.get("result", False) # True
```
### Upload Data Documents
```python
role_permissions = {
"admin": ["read", "write", "delete", "admin"],
"editor": ["read", "write"],
"viewer": ["read"],
}
resp = requests.put(
f"{OPA_URL}/v1/data/roles",
json=role_permissions,
timeout=10,
)
```
### List All Policies
```python
resp = requests.get(f"{OPA_URL}/v1/policies", timeout=10)
policies = resp.json().get("result", [])
for p in policies:
print(f" {p['id']}{len(p.get('raw', ''))} bytes")
```
## OPA CLI Reference
```bash
# Evaluate a policy locally
opa eval -i input.json -d policy.rego "data.authz.allow"
# Run Rego unit tests
opa test ./policies/ -v
# Check policy syntax
opa check policy.rego
# Format Rego files
opa fmt -w policy.rego
# Start OPA as a server
opa run --server --addr :8181 ./policies/ ./data/
# Build an OPA bundle
opa build -b ./policies/ -o bundle.tar.gz
```
## Kubernetes Gatekeeper Integration
```yaml
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {l | input.review.object.metadata.labels[l]}
required := {l | l := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
```
## Output Format
```json
{"timestamp": "ISO-8601", "findings": [], "risk_level": "HIGH"}
{
"decision_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"result": true,
"policy": "data.authz.allow",
"input": {
"user": {"role": "admin"},
"action": "delete",
"resource": "/api/users/42"
}
}
```
@@ -1,61 +1,273 @@
#!/usr/bin/env python3
"""OPA policy-as-code implementation audit."""
import argparse, json, sys
"""Open Policy Agent (OPA) policy-as-code agent.
Evaluates security policies against infrastructure configurations using
the OPA REST API or CLI. Supports evaluating Rego policies for Kubernetes
admission control, Terraform plans, IAM policies, and custom security rules.
"""
import argparse
import json
import os
import subprocess
import sys
from datetime import datetime, timezone
try:
import requests
except ImportError:
requests = None
def audit_config(target, token):
findings = []
if not requests: return [{"error": "requests required"}]
headers = {"Authorization": f"Bearer {token}"}
try:
resp = requests.get(f"{target}/api/v1/status", headers=headers, timeout=10)
if resp.status_code == 200:
data = resp.json()
if not data.get("enabled", True):
findings.append({"check": "Service Status", "status": "DISABLED", "severity": "CRITICAL"})
elif resp.status_code == 401:
findings.append({"check": "Authentication", "status": "UNAUTHORIZED", "severity": "HIGH"})
except requests.RequestException as e:
findings.append({"error": str(e)})
return findings
def check_compliance(target, token):
findings = []
if not requests: return []
headers = {"Authorization": f"Bearer {token}"}
def find_opa_binary():
"""Locate the OPA binary on the system."""
custom_path = os.environ.get("OPA_PATH")
if custom_path and os.path.isfile(custom_path):
return custom_path
for name in ["opa", "opa.exe"]:
for directory in os.environ.get("PATH", "").split(os.pathsep):
full_path = os.path.join(directory, name)
if os.path.isfile(full_path):
return full_path
return None
def eval_policy_cli(opa_bin, policy_path, input_path, data_path=None, query="data"):
"""Evaluate a Rego policy using OPA CLI."""
cmd = [opa_bin, "eval", "--format", "json"]
cmd.extend(["--bundle", policy_path])
if input_path:
cmd.extend(["--input", input_path])
if data_path:
cmd.extend(["--data", data_path])
cmd.append(query)
print(f"[*] Running: {' '.join(cmd)}")
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=120,
)
if result.returncode != 0:
print(f"[!] OPA error: {result.stderr}", file=sys.stderr)
return None
try:
resp = requests.get(f"{target}/api/v1/compliance", headers=headers, timeout=10)
if resp.status_code == 200:
for item in resp.json().get("checks", []):
if item.get("status") != "PASS":
findings.append({"check": item.get("name"), "status": item.get("status"),
"severity": item.get("severity", "MEDIUM")})
except requests.RequestException:
pass
return findings
return json.loads(result.stdout)
except json.JSONDecodeError:
print(f"[!] Failed to parse OPA output", file=sys.stderr)
return None
def eval_policy_api(opa_url, policy_path, input_data):
"""Evaluate a policy via OPA REST API."""
if not requests:
print("[!] 'requests' library required for API mode", file=sys.stderr)
sys.exit(1)
url = f"{opa_url}/v1/data/{policy_path.replace('.', '/')}"
print(f"[*] Querying OPA API: {url}")
resp = requests.post(
url,
json={"input": input_data},
timeout=30,
)
resp.raise_for_status()
return resp.json()
def test_policies(opa_bin, policy_dir):
"""Run OPA test suite against policy directory."""
cmd = [opa_bin, "test", "--format", "json", policy_dir, "-v"]
print(f"[*] Running policy tests: {' '.join(cmd)}")
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=120,
)
try:
test_results = json.loads(result.stdout)
except json.JSONDecodeError:
test_results = []
return test_results, result.returncode
def check_policy_syntax(opa_bin, policy_path):
"""Check Rego policy syntax."""
cmd = [opa_bin, "check", "--format", "json", policy_path]
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=30,
)
if result.returncode == 0:
print(f"[+] Policy syntax valid: {policy_path}")
return True, []
try:
errors = json.loads(result.stdout)
except json.JSONDecodeError:
errors = [{"message": result.stderr}]
print(f"[!] Syntax errors in {policy_path}")
return False, errors
def extract_violations(eval_result, violation_key="violations"):
"""Extract policy violations from OPA evaluation result."""
violations = []
if not eval_result:
return violations
results = eval_result.get("result", [])
if isinstance(results, list):
for entry in results:
bindings = entry.get("bindings", {})
expressions = entry.get("expressions", [])
for expr in expressions:
value = expr.get("value", {})
if isinstance(value, dict):
for key, val in value.items():
if key == violation_key and isinstance(val, list):
violations.extend(val)
elif isinstance(val, dict):
nested_violations = val.get(violation_key, [])
if isinstance(nested_violations, list):
violations.extend(nested_violations)
elif isinstance(results, dict):
violations = results.get(violation_key, [])
return violations
def format_summary(violations, test_results, policy_path, input_path):
"""Print evaluation summary."""
print(f"\n{'='*60}")
print(f" OPA Policy Evaluation Report")
print(f"{'='*60}")
print(f" Policy : {policy_path}")
print(f" Input : {input_path or 'N/A'}")
print(f" Violations: {len(violations)}")
if test_results:
passed = sum(1 for t in test_results if t.get("pass", t.get("result") == "pass"))
failed = len(test_results) - passed
print(f" Tests : {passed} passed, {failed} failed")
if violations:
severity_counts = {}
for v in violations:
sev = "HIGH"
if isinstance(v, dict):
sev = v.get("severity", v.get("level", "HIGH"))
severity_counts[sev] = severity_counts.get(sev, 0) + 1
print(f"\n Violations by Severity:")
for sev, count in sorted(severity_counts.items()):
print(f" {sev:10s}: {count}")
print(f"\n Violation Details:")
for v in violations[:20]:
if isinstance(v, dict):
msg = v.get("msg", v.get("message", str(v)))
resource = v.get("resource", v.get("name", ""))
sev = v.get("severity", "HIGH")
print(f" [{sev:6s}] {resource:30s} | {msg[:60]}")
else:
print(f" {str(v)[:80]}")
return len(violations)
def main():
p = argparse.ArgumentParser(description="OPA policy-as-code implementation audit")
p.add_argument("--target", required=True, help="Target URL")
p.add_argument("--token", required=True, help="API token")
p.add_argument("--output", "-o", help="Output JSON report")
p.add_argument("--verbose", "-v", action="store_true")
a = p.parse_args()
print("[*] OPA policy-as-code implementation audit")
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "findings": []}
report["findings"].extend(audit_config(a.target, a.token))
report["findings"].extend(check_compliance(a.target, a.token))
high = sum(1 for f in report["findings"] if f.get("severity") in ("HIGH", "CRITICAL"))
report["risk_level"] = "HIGH" if high else "MEDIUM" if report["findings"] else "LOW"
print(f"[*] {len(report['findings'])} findings, risk: {report['risk_level']}")
if a.output:
with open(a.output, "w") as f: json.dump(report, f, indent=2)
else:
parser = argparse.ArgumentParser(
description="Open Policy Agent policy-as-code evaluation agent"
)
sub = parser.add_subparsers(dest="command", help="Action")
p_eval = sub.add_parser("eval", help="Evaluate policy against input")
p_eval.add_argument("--policy", required=True, help="Path to Rego policy or bundle dir")
p_eval.add_argument("--input", dest="input_file", help="Path to input JSON")
p_eval.add_argument("--data", help="Path to external data JSON")
p_eval.add_argument("--query", default="data", help="OPA query (default: data)")
p_eval.add_argument("--violation-key", default="violations",
help="Key in result containing violations")
p_api = sub.add_parser("api", help="Evaluate via OPA REST API")
p_api.add_argument("--url", default="http://localhost:8181", help="OPA server URL")
p_api.add_argument("--policy-path", required=True, help="OPA document path (e.g., authz.allow)")
p_api.add_argument("--input", dest="input_file", required=True, help="Input JSON file")
p_test = sub.add_parser("test", help="Run OPA test suite")
p_test.add_argument("--policy-dir", required=True, help="Directory containing policies and tests")
p_check = sub.add_parser("check", help="Check Rego syntax")
p_check.add_argument("--policy", required=True, help="Policy file or directory")
parser.add_argument("--output", "-o", help="Output JSON report path")
parser.add_argument("--verbose", "-v", action="store_true")
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(1)
opa_bin = find_opa_binary()
violations = []
test_results = []
if args.command == "eval":
if not opa_bin:
print("[!] OPA binary not found", file=sys.stderr)
sys.exit(1)
eval_result = eval_policy_cli(
opa_bin, args.policy, args.input_file, args.data, args.query
)
violations = extract_violations(eval_result, args.violation_key)
format_summary(violations, [], args.policy, args.input_file)
elif args.command == "api":
with open(args.input_file, "r") as f:
input_data = json.load(f)
eval_result = eval_policy_api(args.url, args.policy_path, input_data)
violations = extract_violations(eval_result)
format_summary(violations, [], args.policy_path, args.input_file)
elif args.command == "test":
if not opa_bin:
print("[!] OPA binary not found", file=sys.stderr)
sys.exit(1)
test_results, returncode = test_policies(opa_bin, args.policy_dir)
format_summary([], test_results, args.policy_dir, None)
elif args.command == "check":
if not opa_bin:
print("[!] OPA binary not found", file=sys.stderr)
sys.exit(1)
valid, errors = check_policy_syntax(opa_bin, args.policy)
if not valid:
for e in errors:
print(f" Error: {e}")
report = {
"timestamp": datetime.now(timezone.utc).isoformat(),
"tool": "Open Policy Agent",
"command": args.command,
"violations_count": len(violations),
"violations": violations,
"test_results": test_results,
"risk_level": (
"CRITICAL" if len(violations) > 10
else "HIGH" if len(violations) > 0
else "LOW"
),
}
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
print(f"\n[+] Report saved to {args.output}")
elif args.verbose:
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()