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.
- ace_compliance-0.1.0/PKG-INFO +59 -0
- ace_compliance-0.1.0/README.md +33 -0
- ace_compliance-0.1.0/ace_compliance/__init__.py +0 -0
- ace_compliance-0.1.0/ace_compliance/__main__.py +4 -0
- ace_compliance-0.1.0/ace_compliance/cli.py +102 -0
- ace_compliance-0.1.0/ace_compliance.egg-info/PKG-INFO +59 -0
- ace_compliance-0.1.0/ace_compliance.egg-info/SOURCES.txt +12 -0
- ace_compliance-0.1.0/ace_compliance.egg-info/dependency_links.txt +1 -0
- ace_compliance-0.1.0/ace_compliance.egg-info/entry_points.txt +2 -0
- ace_compliance-0.1.0/ace_compliance.egg-info/requires.txt +3 -0
- ace_compliance-0.1.0/ace_compliance.egg-info/top_level.txt +1 -0
- ace_compliance-0.1.0/pyproject.toml +46 -0
- ace_compliance-0.1.0/setup.cfg +4 -0
- ace_compliance-0.1.0/tests/test_cli.py +71 -0
|
@@ -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,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 @@
|
|
|
1
|
+
|
|
@@ -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,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
|