ace-compliance 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: ace-compliance
3
+ Version: 0.1.0
4
+ Summary: ACE+RHG CLI — scan infrastructure artifacts for compliance violations before they ship
5
+ Author-email: Omkar <omkar@ace-rhg.dev>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG
8
+ Project-URL: Repository, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG
9
+ Project-URL: Documentation, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG#readme
10
+ Project-URL: Changelog, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG/releases
11
+ Keywords: compliance,security,kubernetes,terraform,devsecops,opa,policy-as-code
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Security
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: click>=8.0
24
+ Requires-Dist: httpx>=0.27
25
+ Requires-Dist: pyyaml>=6.0
26
+
27
+ # ACE+RHG — AI Compliance Engine + Release Hardening Gate
28
+
29
+ Production-grade DevSecOps platform that enforces security compliance automatically inside CI/CD pipelines — before any artifact ever touches production.
30
+
31
+ ## ace-compliance CLI
32
+
33
+ ```bash
34
+ pip install ace-compliance
35
+
36
+ # Scan a file
37
+ ace scan deploy.yaml
38
+
39
+ # Scan a directory, fail pipeline on HIGH+
40
+ ace scan ./k8s/ ./terraform/ --env production --fail-on HIGH
41
+
42
+ # JSON output for CI integration
43
+ ace scan ./artifacts/ --output json
44
+ ```
45
+
46
+ The CLI sends artifacts to the ACE service, evaluates them against CIS/NIST/ISO policy bundles via OPA, and returns structured findings with risk scores.
47
+
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ # Full local stack
52
+ docker compose up -d
53
+ ace scan samples/vulnerable-deploy.yaml --env staging
54
+ ```
55
+
56
+ ## Documentation
57
+
58
+ - `CLAUDE.md` — full system concept, architecture, API contracts
59
+ - `DEVELOPMENT.md` — build guide, phase map, test matrix, Lambda deployment
@@ -0,0 +1,33 @@
1
+ # ACE+RHG — AI Compliance Engine + Release Hardening Gate
2
+
3
+ Production-grade DevSecOps platform that enforces security compliance automatically inside CI/CD pipelines — before any artifact ever touches production.
4
+
5
+ ## ace-compliance CLI
6
+
7
+ ```bash
8
+ pip install ace-compliance
9
+
10
+ # Scan a file
11
+ ace scan deploy.yaml
12
+
13
+ # Scan a directory, fail pipeline on HIGH+
14
+ ace scan ./k8s/ ./terraform/ --env production --fail-on HIGH
15
+
16
+ # JSON output for CI integration
17
+ ace scan ./artifacts/ --output json
18
+ ```
19
+
20
+ The CLI sends artifacts to the ACE service, evaluates them against CIS/NIST/ISO policy bundles via OPA, and returns structured findings with risk scores.
21
+
22
+ ## Quick Start
23
+
24
+ ```bash
25
+ # Full local stack
26
+ docker compose up -d
27
+ ace scan samples/vulnerable-deploy.yaml --env staging
28
+ ```
29
+
30
+ ## Documentation
31
+
32
+ - `CLAUDE.md` — full system concept, architecture, API contracts
33
+ - `DEVELOPMENT.md` — build guide, phase map, test matrix, Lambda deployment
File without changes
@@ -0,0 +1,4 @@
1
+ from ace_compliance.cli import cli
2
+
3
+ if __name__ == "__main__":
4
+ cli()
@@ -0,0 +1,102 @@
1
+ import asyncio
2
+ import base64
3
+ import json
4
+ import os
5
+ from pathlib import Path
6
+
7
+ import click
8
+ import httpx
9
+
10
+ ACE_URL = os.environ.get("ACE_URL", "http://localhost:8000")
11
+ SEVERITY_ORDER = {"CRITICAL": 4, "HIGH": 3, "MEDIUM": 2, "LOW": 1, "INFO": 0}
12
+
13
+
14
+ @click.group()
15
+ def cli():
16
+ """ace-compliance — scan infrastructure before it ships."""
17
+
18
+
19
+ @cli.command()
20
+ @click.argument("paths", nargs=-1, type=click.Path(exists=True))
21
+ @click.option("--env", default="production", help="Target environment")
22
+ @click.option("--output", type=click.Choice(["text", "json"]), default="text")
23
+ @click.option("--fail-on", type=click.Choice(["CRITICAL", "HIGH", "MEDIUM", "LOW"]), default="HIGH")
24
+ @click.option("--ace-url", envvar="ACE_URL", default=ACE_URL, help="ACE service URL")
25
+ def scan(paths, env, output, fail_on, ace_url):
26
+ """Scan one or more artifact files for compliance violations."""
27
+ asyncio.run(_scan(list(paths), env, output, fail_on, ace_url))
28
+
29
+
30
+ async def _scan(paths: list[str], env: str, output: str, fail_on: str, ace_url: str):
31
+ artifacts = []
32
+
33
+ for path_str in paths:
34
+ p = Path(path_str)
35
+ if p.is_dir():
36
+ for f in p.rglob("*.yaml"):
37
+ artifacts.append(_make_artifact(f))
38
+ for f in p.rglob("*.yml"):
39
+ artifacts.append(_make_artifact(f))
40
+ for f in p.rglob("*.tf"):
41
+ artifacts.append(_make_artifact(f))
42
+ else:
43
+ artifacts.append(_make_artifact(p))
44
+
45
+ if not artifacts:
46
+ click.echo("No supported artifacts found.", err=True)
47
+ raise SystemExit(1)
48
+
49
+ async with httpx.AsyncClient() as client:
50
+ resp = await client.post(
51
+ f"{ace_url}/ace/scan",
52
+ json={
53
+ "pipeline_id": "cli-scan",
54
+ "environment": env,
55
+ "artifacts": artifacts,
56
+ },
57
+ timeout=30.0,
58
+ )
59
+ resp.raise_for_status()
60
+ result = resp.json()
61
+
62
+ if output == "json":
63
+ click.echo(json.dumps(result, indent=2))
64
+ else:
65
+ _print_text_report(result)
66
+
67
+ overall = result.get("overall_severity", "INFO")
68
+ if SEVERITY_ORDER.get(overall, 0) >= SEVERITY_ORDER.get(fail_on, 0):
69
+ raise SystemExit(1)
70
+
71
+
72
+ def _make_artifact(path: Path) -> dict:
73
+ ext = path.suffix
74
+ artifact_type = "kubernetes" if ext in (".yaml", ".yml") else "terraform"
75
+ return {
76
+ "type": artifact_type,
77
+ "name": path.name,
78
+ "content": base64.b64encode(path.read_bytes()).decode(),
79
+ }
80
+
81
+
82
+ def _print_text_report(result: dict):
83
+ findings = result.get("findings", [])
84
+ click.echo("")
85
+ click.echo("=" * 60)
86
+ click.echo(f" Risk Score: {result.get('risk_score', '?')}/10")
87
+ click.echo(f" Severity: {result.get('overall_severity', '?')}")
88
+ click.echo(f" Findings: {len(findings)}")
89
+ click.echo("=" * 60)
90
+ for f in findings:
91
+ sev = f.get("severity", "?")
92
+ rule_id = f.get("rule_id", "?")
93
+ msg = f.get("message", "")
94
+ artifact = f.get("artifact", "")
95
+ color = {"CRITICAL": "red", "HIGH": "yellow", "MEDIUM": "blue", "LOW": "white"}.get(sev, "white")
96
+ click.echo(f" [{click.style(sev, fg=color)}] {rule_id} {artifact}")
97
+ click.echo(f" {msg}")
98
+ click.echo("")
99
+
100
+
101
+ if __name__ == "__main__":
102
+ cli()
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: ace-compliance
3
+ Version: 0.1.0
4
+ Summary: ACE+RHG CLI — scan infrastructure artifacts for compliance violations before they ship
5
+ Author-email: Omkar <omkar@ace-rhg.dev>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG
8
+ Project-URL: Repository, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG
9
+ Project-URL: Documentation, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG#readme
10
+ Project-URL: Changelog, https://github.com/omkarP-bit/AI-Compliance-Engine-RHG/releases
11
+ Keywords: compliance,security,kubernetes,terraform,devsecops,opa,policy-as-code
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Security
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Classifier: Topic :: System :: Systems Administration :: Authentication/Directory
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+ Requires-Dist: click>=8.0
24
+ Requires-Dist: httpx>=0.27
25
+ Requires-Dist: pyyaml>=6.0
26
+
27
+ # ACE+RHG — AI Compliance Engine + Release Hardening Gate
28
+
29
+ Production-grade DevSecOps platform that enforces security compliance automatically inside CI/CD pipelines — before any artifact ever touches production.
30
+
31
+ ## ace-compliance CLI
32
+
33
+ ```bash
34
+ pip install ace-compliance
35
+
36
+ # Scan a file
37
+ ace scan deploy.yaml
38
+
39
+ # Scan a directory, fail pipeline on HIGH+
40
+ ace scan ./k8s/ ./terraform/ --env production --fail-on HIGH
41
+
42
+ # JSON output for CI integration
43
+ ace scan ./artifacts/ --output json
44
+ ```
45
+
46
+ The CLI sends artifacts to the ACE service, evaluates them against CIS/NIST/ISO policy bundles via OPA, and returns structured findings with risk scores.
47
+
48
+ ## Quick Start
49
+
50
+ ```bash
51
+ # Full local stack
52
+ docker compose up -d
53
+ ace scan samples/vulnerable-deploy.yaml --env staging
54
+ ```
55
+
56
+ ## Documentation
57
+
58
+ - `CLAUDE.md` — full system concept, architecture, API contracts
59
+ - `DEVELOPMENT.md` — build guide, phase map, test matrix, Lambda deployment
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ ace_compliance/__init__.py
4
+ ace_compliance/__main__.py
5
+ ace_compliance/cli.py
6
+ ace_compliance.egg-info/PKG-INFO
7
+ ace_compliance.egg-info/SOURCES.txt
8
+ ace_compliance.egg-info/dependency_links.txt
9
+ ace_compliance.egg-info/entry_points.txt
10
+ ace_compliance.egg-info/requires.txt
11
+ ace_compliance.egg-info/top_level.txt
12
+ tests/test_cli.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ace = ace_compliance.cli:cli
@@ -0,0 +1,3 @@
1
+ click>=8.0
2
+ httpx>=0.27
3
+ pyyaml>=6.0
@@ -0,0 +1 @@
1
+ ace_compliance
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ace-compliance"
7
+ version = "0.1.0"
8
+ description = "ACE+RHG CLI — scan infrastructure artifacts for compliance violations before they ship"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.12"
12
+ authors = [
13
+ { name = "Omkar", email = "omkar@ace-rhg.dev" },
14
+ ]
15
+ keywords = ["compliance", "security", "kubernetes", "terraform", "devsecops", "opa", "policy-as-code"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Intended Audience :: System Administrators",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Topic :: Security",
24
+ "Topic :: Software Development :: Quality Assurance",
25
+ "Topic :: System :: Systems Administration :: Authentication/Directory",
26
+ ]
27
+ dependencies = [
28
+ "click>=8.0",
29
+ "httpx>=0.27",
30
+ "pyyaml>=6.0",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/omkarP-bit/AI-Compliance-Engine-RHG"
35
+ Repository = "https://github.com/omkarP-bit/AI-Compliance-Engine-RHG"
36
+ Documentation = "https://github.com/omkarP-bit/AI-Compliance-Engine-RHG#readme"
37
+ Changelog = "https://github.com/omkarP-bit/AI-Compliance-Engine-RHG/releases"
38
+
39
+ [project.scripts]
40
+ ace = "ace_compliance.cli:cli"
41
+
42
+ [tool.setuptools.packages.find]
43
+ include = ["ace_compliance*"]
44
+
45
+ [tool.pytest.ini_options]
46
+ asyncio_mode = "auto"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,71 @@
1
+ from unittest.mock import AsyncMock, MagicMock, patch
2
+
3
+ from ace_compliance.cli import cli
4
+ from click.testing import CliRunner
5
+
6
+ MOCK_SCAN_RESPONSE = {
7
+ "scan_id": "abc-123",
8
+ "pipeline_id": "cli-scan",
9
+ "risk_score": 7.5,
10
+ "overall_severity": "HIGH",
11
+ "findings": [
12
+ {"rule_id": "CIS-K8S-5.2.1", "severity": "HIGH",
13
+ "message": "Privileged container", "artifact": "deploy.yaml"}
14
+ ]
15
+ }
16
+
17
+
18
+ class TestCLI:
19
+ def setup_method(self):
20
+ self.runner = CliRunner()
21
+
22
+ def test_scan_exits_nonzero_on_high_findings(self, tmp_path):
23
+ f = tmp_path / "deploy.yaml"
24
+ f.write_text("apiVersion: v1\nkind: Pod")
25
+ with patch("ace_compliance.cli.httpx.AsyncClient") as mock_client:
26
+ mock_client.return_value.__aenter__.return_value.post = AsyncMock(
27
+ return_value=MagicMock(
28
+ status_code=200,
29
+ json=lambda: MOCK_SCAN_RESPONSE,
30
+ raise_for_status=lambda: None,
31
+ )
32
+ )
33
+ result = self.runner.invoke(cli, ["scan", str(f), "--fail-on", "HIGH"])
34
+ assert result.exit_code == 1
35
+
36
+ def test_scan_exits_zero_on_clean_artifact(self, tmp_path):
37
+ f = tmp_path / "deploy.yaml"
38
+ f.write_text("apiVersion: v1\nkind: Pod")
39
+ clean_response = {**MOCK_SCAN_RESPONSE, "overall_severity": "LOW", "findings": []}
40
+ with patch("ace_compliance.cli.httpx.AsyncClient") as mock_client:
41
+ mock_client.return_value.__aenter__.return_value.post = AsyncMock(
42
+ return_value=MagicMock(
43
+ status_code=200,
44
+ json=lambda: clean_response,
45
+ raise_for_status=lambda: None,
46
+ )
47
+ )
48
+ result = self.runner.invoke(cli, ["scan", str(f), "--fail-on", "HIGH"])
49
+ assert result.exit_code == 0
50
+
51
+ def test_json_output_flag(self, tmp_path):
52
+ f = tmp_path / "deploy.yaml"
53
+ f.write_text("apiVersion: v1\nkind: Pod")
54
+ with patch("ace_compliance.cli.httpx.AsyncClient") as mock_client:
55
+ mock_client.return_value.__aenter__.return_value.post = AsyncMock(
56
+ return_value=MagicMock(
57
+ status_code=200,
58
+ json=lambda: MOCK_SCAN_RESPONSE,
59
+ raise_for_status=lambda: None,
60
+ )
61
+ )
62
+ result = self.runner.invoke(cli, ["scan", str(f), "--output", "json"])
63
+ assert result.exit_code == 1
64
+ assert '"scan_id":' in result.output
65
+
66
+ def test_scan_helps_with_no_artifacts(self, tmp_path):
67
+ empty_dir = tmp_path / "empty"
68
+ empty_dir.mkdir()
69
+ result = self.runner.invoke(cli, ["scan", str(empty_dir)])
70
+ assert result.exit_code == 1
71
+ assert "No supported artifacts found" in result.output