github-guardian 1.0.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,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: github-guardian
3
+ Version: 1.0.0
4
+ Summary: Deep Forensic Security Audit Engine & Pre-Commit Shield
5
+ Author: GitHub Guardian Team
6
+ Requires-Dist: typer>=0.9.0
7
+ Requires-Dist: rich>=13.7.0
8
+ Requires-Dist: httpx>=0.27.0
9
+ Dynamic: author
10
+ Dynamic: requires-dist
11
+ Dynamic: summary
@@ -0,0 +1 @@
1
+ # Marks the core directory as a Python package
@@ -0,0 +1,49 @@
1
+ import os
2
+ import stat
3
+ import platform
4
+
5
+ HOOK_SCRIPT = """#!/usr/bin/env bash
6
+ # GitHub Guardian Pre-Commit Shield
7
+
8
+ echo "🛡️ GitHub Guardian: Running Pre-Commit Shield Audit..."
9
+
10
+ # We use the isolated virtual environment from the CLI directory
11
+ CLI_DIR="$(git rev-parse --show-toplevel)/github-guardian-cli"
12
+ $CLI_DIR/venv/bin/python $CLI_DIR/guardian.py scan-local . --hook
13
+
14
+ if [ $? -ne 0 ]; then
15
+ echo "❌ COMMIT BLOCKED! Secrets or semantic vulnerabilities were detected in your staging area."
16
+ echo "Please fix the issues. To bypass the shield (NOT RECOMMENDED), use 'git commit --no-verify'."
17
+ exit 1
18
+ fi
19
+
20
+ echo "✅ Code looks clean. Proceeding with commit."
21
+ exit 0
22
+ """
23
+
24
+ import subprocess
25
+
26
+ def install_pre_commit_hook(console):
27
+ try:
28
+ git_root_proc = subprocess.run(["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True, check=True)
29
+ git_root = git_root_proc.stdout.strip()
30
+ except Exception:
31
+ console.print("[bold red]Error:[/bold red] Not inside a git repository. Cannot install hook.")
32
+ return
33
+
34
+ git_dir = os.path.join(git_root, ".git")
35
+ hook_path = os.path.join(git_dir, "hooks", "pre-commit")
36
+
37
+ try:
38
+ with open(hook_path, "w") as f:
39
+ f.write(HOOK_SCRIPT)
40
+
41
+ # Make the bash script executable (Unix/macOS only)
42
+ if platform.system() != 'Windows':
43
+ st = os.stat(hook_path)
44
+ os.chmod(hook_path, st.st_mode | stat.S_IEXEC)
45
+
46
+ console.print(f"[bold green]✅ Success![/bold green] Pre-commit shield installed at: {hook_path}")
47
+ console.print("[italic]Your commits will now be securely blocked if secrets or SAST vulnerabilities are staged.[/italic]")
48
+ except Exception as e:
49
+ console.print(f"[bold red]Failed to install hook:[/bold red] {str(e)}")
@@ -0,0 +1,76 @@
1
+ import httpx
2
+ import time
3
+ from rich.progress import Progress, SpinnerColumn, TextColumn
4
+ from rich.table import Table
5
+
6
+ BACKEND_URL = "http://localhost:8000/api/v1"
7
+
8
+ def run_remote_scan(owner: str, repo: str, console):
9
+ try:
10
+ # 1. Trigger the asynchronous scan task on FastAPI
11
+ with console.status("[bold cyan]Triggering remote forensic scan on Guardian Core...[/bold cyan]") as status:
12
+ res = httpx.post(f"{BACKEND_URL}/scan", json={"owner": owner, "repo_name": repo}, timeout=10.0)
13
+ if res.status_code != 200:
14
+ console.print(f"[bold red]Failed to trigger scan. Status Code: {res.status_code}[/bold red]")
15
+ console.print(res.text)
16
+ return
17
+
18
+ task_id = res.json().get("task_id")
19
+ console.print(f"[green]Scan initiated successfully. Task ID:[/green] {task_id}\n")
20
+
21
+ # 2. Poll the FastAPI backend for status updates
22
+ with Progress(
23
+ SpinnerColumn(),
24
+ TextColumn("[progress.description]{task.description}"),
25
+ transient=True,
26
+ ) as progress:
27
+ task = progress.add_task(description="Initializing scanners...", total=None)
28
+
29
+ while True:
30
+ status_res = httpx.get(f"{BACKEND_URL}/scan/status/{task_id}", timeout=10.0)
31
+ if status_res.status_code != 200:
32
+ time.sleep(2)
33
+ continue
34
+
35
+ data = status_res.json()
36
+
37
+ if data.get("status") == "completed":
38
+ progress.update(task, description="[bold green]Scan Completed! Processing AI Report...[/bold green]")
39
+ break
40
+ elif data.get("status") == "failed":
41
+ progress.update(task, description=f"[bold red]Scan Failed: {data.get('error')}[/bold red]")
42
+ return
43
+ else:
44
+ msg = data.get("message", "Processing pipelines...")
45
+ progress.update(task, description=f"[cyan]Engine Status:[/cyan] {msg}")
46
+
47
+ time.sleep(2)
48
+
49
+ # 3. Download and Render the final AI enriched report
50
+ res_data = httpx.get(f"{BACKEND_URL}/scan/status/{task_id}").json()
51
+ report = res_data.get("report", {})
52
+
53
+ score = report.get("score", 0.0)
54
+ verdict = report.get("verdict", "Unknown")
55
+
56
+ console.print("\n[bold underline]🛡️ GitHub Guardian Audit Report[/bold underline]")
57
+ console.print(f"\nFinal AI Dampened Score: [bold {'red' if score > 5 else 'green'}]{score} / 10.0[/bold]")
58
+ console.print(f"Verdict: [italic]{verdict}[/italic]\n")
59
+
60
+ # Table of Actionable Findings
61
+ if report.get("negatives"):
62
+ vuln_table = Table(title="Actionable Architectural Threats", show_header=True, header_style="bold red")
63
+ vuln_table.add_column("Issue Detected", style="white")
64
+
65
+ for neg in report.get("negatives"):
66
+ vuln_table.add_row(neg)
67
+
68
+ console.print(vuln_table)
69
+
70
+ if report.get("positives"):
71
+ console.print("\n[bold green]Security Positives:[/bold green]")
72
+ for pos in report.get("positives"):
73
+ console.print(f" [green]✔[/green] {pos}")
74
+
75
+ except Exception as e:
76
+ console.print(f"[bold red]Critical Error during remote scan orchestration:[/bold red] {str(e)}")
@@ -0,0 +1,97 @@
1
+ import os
2
+ import re
3
+ from rich.table import Table
4
+
5
+ # Re-using the professional-grade patterns from the backend
6
+ SECRET_PATTERNS = {
7
+ "AWS Access Key": r'AKIA[0-9A-Z]{16}',
8
+ "GitHub Token": r'ghp_[0-9a-zA-Z]{36}',
9
+ "Slack Webhook": r'https://hooks\.slack\.com/services/T[0-9A-Z]{8}/B[0-9A-Z]{8}/[0-9a-zA-Z]{24}',
10
+ "Stripe API Key": r'sk_live_[0-9a-zA-Z]{24}',
11
+ "Private Key": r'-----BEGIN (?:RSA|OPENSSH) PRIVATE KEY-----',
12
+ "Google API Key": r'AIza[0-9A-Za-z\-_]{35}'
13
+ }
14
+
15
+ SAST_PATTERNS = {
16
+ "SQL Injection (Raw Query)": r"\.execute\(\".*%\s*\"",
17
+ "Insecure Rendering (XSS)": r"dangerouslySetInnerHTML",
18
+ "Hardcoded Auth/Secret": r"password\s*=\s*['\"][^'\"]+['\"]"
19
+ }
20
+
21
+ def ask_gitignore(files):
22
+ import sys
23
+ try:
24
+ with open("/dev/tty", "w") as tty_out, open("/dev/tty", "r") as tty_in:
25
+ tty_out.write("\n⚠️ Would you like to automatically add these vulnerable files to .gitignore? (y/N): ")
26
+ tty_out.flush()
27
+ ans = tty_in.readline().strip().lower()
28
+ return ans in ['y', 'yes']
29
+ except Exception:
30
+ ans = input("\n⚠️ Would you like to automatically add these vulnerable files to .gitignore? (y/N): ")
31
+ return ans.lower() in ['y', 'yes']
32
+
33
+ def run_local_scan(path: str, console, hook_mode: bool = False) -> bool:
34
+ console.print(f"[*] Scanning local directory: [yellow]{os.path.abspath(path)}[/yellow]...\n")
35
+ findings = []
36
+
37
+ for root, _, files in os.walk(path):
38
+ # Ignore common build/dependency directories
39
+ if any(x in root for x in [".git", "node_modules", "venv", "__pycache__"]):
40
+ continue
41
+ for file in files:
42
+ ext = os.path.splitext(file)[1]
43
+ if ext in [".png", ".jpg", ".pdf", ".zip", ".pyc"]:
44
+ continue
45
+
46
+ # Skip the scanner scripts themselves to prevent false positives!
47
+ if file in ["scanner.py", "leak_forensics.py", "sast_analyzer.py"]:
48
+ continue
49
+
50
+ filepath = os.path.join(root, file)
51
+ try:
52
+ with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
53
+ lines = f.readlines()
54
+
55
+ for line_idx, line in enumerate(lines, 1):
56
+ # Check for Secrets
57
+ for name, pat in SECRET_PATTERNS.items():
58
+ if re.search(pat, line):
59
+ findings.append((filepath, line_idx, "SECRET LEAK", name))
60
+
61
+ # Check for Semantic vulnerabilities
62
+ for name, pat in SAST_PATTERNS.items():
63
+ if re.search(pat, line):
64
+ findings.append((filepath, line_idx, "SAST VULN", name))
65
+ except Exception:
66
+ pass
67
+
68
+ if not findings:
69
+ console.print("[bold green]✅ No local leaks or vulnerabilities detected. Ready to push![/bold green]")
70
+ return True
71
+
72
+ table = Table(title="Guardian Local Shield Findings")
73
+ table.add_column("File Path", style="cyan")
74
+ table.add_column("Line", justify="right", style="magenta")
75
+ table.add_column("Threat Class", style="yellow")
76
+ table.add_column("Pattern Matched", style="red")
77
+
78
+ for f in findings:
79
+ table.add_row(os.path.relpath(f[0], path), str(f[1]), f[2], f[3])
80
+
81
+ console.print(table)
82
+
83
+ if hook_mode:
84
+ vulnerable_files = list(set([os.path.relpath(f[0], path) for f in findings]))
85
+ if ask_gitignore(vulnerable_files):
86
+ gitignore_path = os.path.join(path, ".gitignore")
87
+ with open(gitignore_path, "a") as gf:
88
+ gf.write("\n# GitHub Guardian: Auto-ignored vulnerable files\n")
89
+ for vf in vulnerable_files:
90
+ gf.write(f"{vf}\n")
91
+ console.print("\n[bold green]✅ Vulnerable files appended to .gitignore![/bold green]")
92
+ console.print("[yellow]Note: If the files were already tracked by git, you must also run 'git rm --cached <file>'.[/yellow]")
93
+ console.print("[yellow]Please review your changes and try committing again.[/yellow]")
94
+ return False
95
+
96
+ console.print("\n[bold red]❌ SCAN FAILED! Active vulnerabilities were detected locally.[/bold red]")
97
+ return False
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: github-guardian
3
+ Version: 1.0.0
4
+ Summary: Deep Forensic Security Audit Engine & Pre-Commit Shield
5
+ Author: GitHub Guardian Team
6
+ Requires-Dist: typer>=0.9.0
7
+ Requires-Dist: rich>=13.7.0
8
+ Requires-Dist: httpx>=0.27.0
9
+ Dynamic: author
10
+ Dynamic: requires-dist
11
+ Dynamic: summary
@@ -0,0 +1,12 @@
1
+ guardian.py
2
+ setup.py
3
+ core/__init__.py
4
+ core/hook.py
5
+ core/remote.py
6
+ core/scanner.py
7
+ github_guardian.egg-info/PKG-INFO
8
+ github_guardian.egg-info/SOURCES.txt
9
+ github_guardian.egg-info/dependency_links.txt
10
+ github_guardian.egg-info/entry_points.txt
11
+ github_guardian.egg-info/requires.txt
12
+ github_guardian.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ guardian = guardian:app
@@ -0,0 +1,3 @@
1
+ typer>=0.9.0
2
+ rich>=13.7.0
3
+ httpx>=0.27.0
@@ -0,0 +1,2 @@
1
+ core
2
+ guardian
@@ -0,0 +1,34 @@
1
+ import typer
2
+ from rich.console import Console
3
+ from rich.panel import Panel
4
+ from core.scanner import run_local_scan
5
+ from core.remote import run_remote_scan
6
+ from core.hook import install_pre_commit_hook
7
+
8
+ app = typer.Typer(help="GitHub Guardian - Forensic Security Audit CLI")
9
+ console = Console()
10
+
11
+ @app.command()
12
+ def scan_local(
13
+ path: str = typer.Argument(".", help="Path to scan locally"),
14
+ hook_mode: bool = typer.Option(False, "--hook", help="Run in git hook mode (prompts to gitignore)")
15
+ ):
16
+ """Scan local directory for exposed secrets and vulnerabilities before committing."""
17
+ console.print(Panel.fit("[bold cyan]GitHub Guardian[/bold cyan] - Local Shield", border_style="cyan"))
18
+ run_local_scan(path, console, hook_mode)
19
+
20
+ @app.command()
21
+ def scan_remote(owner: str = typer.Argument(..., help="GitHub Repository Owner"),
22
+ repo: str = typer.Argument(..., help="GitHub Repository Name")):
23
+ """Trigger an AI-driven forensic scan on the Guardian backend."""
24
+ console.print(Panel.fit(f"[bold magenta]GitHub Guardian[/bold magenta] - Remote Scan: {owner}/{repo}", border_style="magenta"))
25
+ run_remote_scan(owner, repo, console)
26
+
27
+ @app.command()
28
+ def hook_install():
29
+ """Install the Pre-Commit Shield to block insecure commits."""
30
+ console.print(Panel.fit("[bold green]GitHub Guardian[/bold green] - Pre-Commit Hook", border_style="green"))
31
+ install_pre_commit_hook(console)
32
+
33
+ if __name__ == "__main__":
34
+ app()
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,20 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="github-guardian",
5
+ version="1.0.0",
6
+ description="Deep Forensic Security Audit Engine & Pre-Commit Shield",
7
+ author="GitHub Guardian Team",
8
+ packages=find_packages(),
9
+ py_modules=["guardian"],
10
+ install_requires=[
11
+ "typer>=0.9.0",
12
+ "rich>=13.7.0",
13
+ "httpx>=0.27.0"
14
+ ],
15
+ entry_points={
16
+ "console_scripts": [
17
+ "guardian=guardian:app",
18
+ ],
19
+ },
20
+ )