Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
116 lines (88 loc) · 4.36 KB
/
Copy pathmain.py
File metadata and controls
116 lines (88 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
GitOps Infrastructure-as-Code (IaC) Automated Security Auditor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A DevOps automation daemon that monitors a repository directory for Kubernetes manifests,
Terraform files, or Dockerfiles, passes changes to LibreChat for AI-assisted security
and compliance auditing, and generates markdown audit reports.
"""
import os
import sys
import time
import logging
from pathlib import Path
from dotenv import load_dotenv
# Ensure parent directory is in python path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
from librechat_client import LibreChatClient
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] (GitOps-Auditor) %(message)s"
)
logger = logging.getLogger("GitOpsAuditor")
DEFAULT_IAC_EXTENSIONS = {".yaml", ".yml", ".tf", ".dockerfile", "dockerfile"}
GITOPS_SECURITY_PROMPT = """
You are an expert DevOps & DevSecOps engineer performing an automated security code review.
Analyze the following Infrastructure-as-Code (IaC) configuration for security risks, compliance violations, and best practices.
Focus on:
1. Least Privilege & Access Control (e.g., non-root containers, open security groups 0.0.0.0/0).
2. Resource Management (missing CPU/memory limits, quotas).
3. Secret Exposure (hardcoded credentials, API keys, unencrypted storage).
4. Container Security (floating image tags, privilege escalation).
Return your findings formatted as a clear Markdown report with risk ratings (HIGH, MEDIUM, LOW) and actionable fix recommendations.
File Content:
```
{content}
```
"""
def run_iac_auditor():
load_dotenv()
watch_dir = Path(os.getenv("IAC_WATCH_DIR", "./iac_repository")).resolve()
reports_dir = Path(os.getenv("REPORTS_DIR", "./reports")).resolve()
watch_dir.mkdir(parents=True, exist_ok=True)
reports_dir.mkdir(parents=True, exist_ok=True)
base_url = os.getenv("LIBRECHAT_BASE_URL", "https://chat.example.com")
refresh_token = os.getenv("LIBRECHAT_REFRESH_TOKEN")
connect_sid = os.getenv("LIBRECHAT_CONNECT_SID")
if not refresh_token or refresh_token == "YOUR_REFRESH_TOKEN_HERE":
logger.error("LIBRECHAT_REFRESH_TOKEN is not configured in .env!")
return
client = LibreChatClient(
base_url=base_url,
refresh_token=refresh_token,
connect_sid=connect_sid
)
logger.info(f"GitOps Security Auditor running. Monitoring IaC folder: {watch_dir}")
processed_files = set()
while True:
for file_path in watch_dir.rglob("*"):
if not file_path.is_file() or file_path.name.startswith("."):
continue
is_iac_file = file_path.suffix.lower() in DEFAULT_IAC_EXTENSIONS or "dockerfile" in file_path.name.lower()
if not is_iac_file:
continue
file_key = f"{file_path.resolve()}:{file_path.stat().st_mtime}"
if file_key in processed_files:
continue
logger.info(f"--> Auditing IaC configuration file: {file_path.name}")
try:
content = file_path.read_text(encoding="utf-8")
prompt = GITOPS_SECURITY_PROMPT.format(content=content)
logger.info(f"Submitting '{file_path.name}' to LibreChat LLM endpoint...")
result = client.send_agent_message(prompt=prompt)
report_text = result.get("text") if isinstance(result, dict) else str(result)
report_path = reports_dir / f"audit_{file_path.stem}_{int(time.time())}.md"
report_content = (
f"# GitOps Security Audit Report\n"
f"- **Target File**: `{file_path.name}`\n"
f"- **Audited At**: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n"
f"--- \n\n"
f"{report_text}\n"
)
report_path.write_text(report_content, encoding="utf-8")
logger.info(f"[✓] Audit Report generated: {report_path}")
processed_files.add(file_key)
except Exception as err:
logger.error(f"[x] Failed to audit file '{file_path.name}': {err}")
time.sleep(15)
if __name__ == "__main__":
run_iac_auditor()