feat(docs): Enhance README with headless mode and CI/CD integration examples
This commit is contained in:
34
README.md
34
README.md
@@ -111,6 +111,40 @@ strix --target api.your-app.com --instruction "Prioritize authentication and aut
|
|||||||
strix --target https://your-app.com --instruction "Test with credentials: testuser/testpass. Focus on privilege escalation and access control bypasses."
|
strix --target https://your-app.com --instruction "Test with credentials: testuser/testpass. Focus on privilege escalation and access control bypasses."
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 🤖 Headless Mode
|
||||||
|
|
||||||
|
Run Strix programmatically without interactive UI using the `-n/--non-interactive` flag—perfect for servers and automated jobs. The CLI prints real-time vulnerability findings, and the final penetration test report before exiting. Exits with non-zero code when vulnerabilities are found.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
strix --target https://your-app.com -n --instruction "Focus on authentication bypass and session management"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔄 CI/CD (GitHub Actions)
|
||||||
|
|
||||||
|
Strix can be added to your pipeline to run a security test on pull requests with a lightweight GitHub Actions workflow:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: strix-penetration-test
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
security-scan:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Strix
|
||||||
|
run: pipx install strix-agent
|
||||||
|
|
||||||
|
- name: Run Strix
|
||||||
|
env:
|
||||||
|
STRIX_LLM: ${{ secrets.STRIX_LLM }}
|
||||||
|
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
||||||
|
run: strix -n --target ./
|
||||||
|
```
|
||||||
|
|
||||||
### ⚙️ Configuration
|
### ⚙️ Configuration
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915
|
|||||||
instructions_text.append("📋 Instructions: ", style="bold cyan")
|
instructions_text.append("📋 Instructions: ", style="bold cyan")
|
||||||
instructions_text.append(args.instruction, style="white")
|
instructions_text.append(args.instruction, style="white")
|
||||||
|
|
||||||
|
results_text = Text()
|
||||||
|
results_text.append("📊 Results will be saved to: ", style="bold cyan")
|
||||||
|
results_text.append(f"agent_runs/{args.run_name}", style="bold white")
|
||||||
|
|
||||||
|
note_text = Text()
|
||||||
|
note_text.append("\n\n", style="dim")
|
||||||
|
note_text.append("⏱️ ", style="dim")
|
||||||
|
note_text.append("This may take a while depending on target complexity. ", style="dim")
|
||||||
|
note_text.append("Vulnerabilities will be displayed in real-time.", style="dim")
|
||||||
|
|
||||||
startup_panel = Panel(
|
startup_panel = Panel(
|
||||||
Text.assemble(
|
Text.assemble(
|
||||||
start_text,
|
start_text,
|
||||||
@@ -36,6 +46,9 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915
|
|||||||
target_text,
|
target_text,
|
||||||
"\n" if args.instruction else "",
|
"\n" if args.instruction else "",
|
||||||
instructions_text if args.instruction else "",
|
instructions_text if args.instruction else "",
|
||||||
|
"\n",
|
||||||
|
results_text,
|
||||||
|
note_text,
|
||||||
),
|
),
|
||||||
title="[bold green]🛡️ STRIX PENETRATION TEST INITIATED",
|
title="[bold green]🛡️ STRIX PENETRATION TEST INITIATED",
|
||||||
title_align="center",
|
title_align="center",
|
||||||
@@ -113,9 +126,8 @@ async def run_cli(args: Any) -> None: # noqa: PLR0915
|
|||||||
tracer.cleanup()
|
tracer.cleanup()
|
||||||
|
|
||||||
def signal_handler(_signum: int, _frame: Any) -> None:
|
def signal_handler(_signum: int, _frame: Any) -> None:
|
||||||
console.print("\n[bold yellow]Interrupted! Saving reports...[/bold yellow]")
|
|
||||||
tracer.cleanup()
|
tracer.cleanup()
|
||||||
sys.exit(0)
|
sys.exit(1)
|
||||||
|
|
||||||
atexit.register(cleanup_on_exit)
|
atexit.register(cleanup_on_exit)
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|||||||
@@ -752,6 +752,11 @@ def main() -> None:
|
|||||||
results_path = Path("agent_runs") / args.run_name
|
results_path = Path("agent_runs") / args.run_name
|
||||||
display_completion_message(args, results_path)
|
display_completion_message(args, results_path)
|
||||||
|
|
||||||
|
if args.non_interactive:
|
||||||
|
tracer = get_global_tracer()
|
||||||
|
if tracer and tracer.vulnerability_reports:
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user