mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-11 21:54:56 +03:00
154 lines
5.1 KiB
Python
154 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Pod Security Admission Manager - Audit namespaces for PSA compliance,
|
|
apply labels, and generate migration reports.
|
|
"""
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import argparse
|
|
|
|
|
|
PSA_LABELS = {
|
|
"enforce": "pod-security.kubernetes.io/enforce",
|
|
"enforce-version": "pod-security.kubernetes.io/enforce-version",
|
|
"audit": "pod-security.kubernetes.io/audit",
|
|
"audit-version": "pod-security.kubernetes.io/audit-version",
|
|
"warn": "pod-security.kubernetes.io/warn",
|
|
"warn-version": "pod-security.kubernetes.io/warn-version",
|
|
}
|
|
|
|
SYSTEM_NAMESPACES = {
|
|
"kube-system", "kube-public", "kube-node-lease",
|
|
"calico-system", "tigera-operator", "gatekeeper-system", "falco",
|
|
}
|
|
|
|
|
|
def run_kubectl(args: list) -> str:
|
|
"""Execute kubectl command."""
|
|
cmd = ["kubectl"] + args
|
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
return result.stdout, result.stderr, result.returncode
|
|
|
|
|
|
def get_namespace_psa_labels() -> list:
|
|
"""Get PSA labels for all namespaces."""
|
|
stdout, _, _ = run_kubectl(["get", "namespaces", "-o", "json"])
|
|
data = json.loads(stdout)
|
|
results = []
|
|
for ns in data.get("items", []):
|
|
name = ns["metadata"]["name"]
|
|
labels = ns["metadata"].get("labels", {})
|
|
psa_info = {
|
|
"namespace": name,
|
|
"enforce": labels.get(PSA_LABELS["enforce"], "none"),
|
|
"audit": labels.get(PSA_LABELS["audit"], "none"),
|
|
"warn": labels.get(PSA_LABELS["warn"], "none"),
|
|
"is_system": name in SYSTEM_NAMESPACES,
|
|
}
|
|
results.append(psa_info)
|
|
return results
|
|
|
|
|
|
def dry_run_enforcement(namespace: str, level: str) -> dict:
|
|
"""Test what would happen if PSA enforcement was applied."""
|
|
stdout, stderr, rc = run_kubectl([
|
|
"label", "--dry-run=server", "--overwrite", "namespace", namespace,
|
|
f"pod-security.kubernetes.io/enforce={level}"
|
|
])
|
|
violations = []
|
|
if "Warning" in stderr or "Warning" in stdout:
|
|
for line in (stderr + stdout).split("\n"):
|
|
if "Warning" in line or "violate" in line:
|
|
violations.append(line.strip())
|
|
|
|
return {
|
|
"namespace": namespace,
|
|
"level": level,
|
|
"would_pass": rc == 0 and len(violations) == 0,
|
|
"violations": violations,
|
|
}
|
|
|
|
|
|
def audit_all_namespaces() -> list:
|
|
"""Audit all namespaces for PSA configuration."""
|
|
ns_info = get_namespace_psa_labels()
|
|
|
|
print("\n=== Pod Security Admission Audit ===\n")
|
|
print(f"{'Namespace':<30} {'Enforce':<12} {'Audit':<12} {'Warn':<12} {'System'}")
|
|
print("-" * 85)
|
|
|
|
compliant = 0
|
|
total = 0
|
|
|
|
for ns in ns_info:
|
|
if ns["is_system"]:
|
|
status = "EXEMPT"
|
|
elif ns["enforce"] == "restricted":
|
|
status = "COMPLIANT"
|
|
compliant += 1
|
|
elif ns["enforce"] == "baseline":
|
|
status = "PARTIAL"
|
|
else:
|
|
status = "NON-COMPLIANT"
|
|
|
|
if not ns["is_system"]:
|
|
total += 1
|
|
|
|
system = "Yes" if ns["is_system"] else "No"
|
|
print(f"{ns['namespace']:<30} {ns['enforce']:<12} {ns['audit']:<12} {ns['warn']:<12} {system}")
|
|
|
|
print(f"\n{compliant}/{total} non-system namespaces at restricted level")
|
|
return ns_info
|
|
|
|
|
|
def apply_psa_labels(namespace: str, level: str, version: str = "latest"):
|
|
"""Apply PSA labels to a namespace."""
|
|
labels = [
|
|
f"pod-security.kubernetes.io/enforce={level}",
|
|
f"pod-security.kubernetes.io/enforce-version={version}",
|
|
f"pod-security.kubernetes.io/audit=restricted",
|
|
f"pod-security.kubernetes.io/audit-version={version}",
|
|
f"pod-security.kubernetes.io/warn=restricted",
|
|
f"pod-security.kubernetes.io/warn-version={version}",
|
|
]
|
|
cmd = ["label", "--overwrite", "namespace", namespace] + labels
|
|
stdout, stderr, rc = run_kubectl(cmd)
|
|
if rc == 0:
|
|
print(f"Applied {level} PSA labels to {namespace}")
|
|
else:
|
|
print(f"Failed: {stderr}", file=sys.stderr)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Pod Security Admission Manager")
|
|
subparsers = parser.add_subparsers(dest="command")
|
|
|
|
subparsers.add_parser("audit", help="Audit namespace PSA labels")
|
|
|
|
test_cmd = subparsers.add_parser("test", help="Dry-run PSA enforcement")
|
|
test_cmd.add_argument("--namespace", "-n", required=True)
|
|
test_cmd.add_argument("--level", default="restricted", choices=["baseline", "restricted"])
|
|
|
|
apply_cmd = subparsers.add_parser("apply", help="Apply PSA labels")
|
|
apply_cmd.add_argument("--namespace", "-n", required=True)
|
|
apply_cmd.add_argument("--level", required=True, choices=["privileged", "baseline", "restricted"])
|
|
apply_cmd.add_argument("--version", default="latest")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.command == "audit":
|
|
audit_all_namespaces()
|
|
elif args.command == "test":
|
|
result = dry_run_enforcement(args.namespace, args.level)
|
|
print(json.dumps(result, indent=2))
|
|
elif args.command == "apply":
|
|
apply_psa_labels(args.namespace, args.level, args.version)
|
|
else:
|
|
parser.print_help()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|