Metadata-Version: 2.4
Name: bastion-red
Version: 0.4.14
Summary: Agentic Risk Infrastructure. Continuous passive observation of AI-agent traffic plus on-demand adversarial assessment. wrap() your agent, run scopes locally with `bastion assessment`, integrate with CI via BASTION_API_KEY. Covers OWASP LLM Top 10.
Project-URL: Homepage, https://pistonsolutions.ai/bastion
Project-URL: Documentation, https://demo.pistonsolutions.ai/docs
Project-URL: Repository, https://github.com/pistonsolutions/bastion-red
Project-URL: Issues, https://github.com/pistonsolutions/bastion-red/issues
Author-email: PistonSolutions <info@pistonsolutions.ai>
License: MIT
License-File: LICENSE
Keywords: agentic-risk-infrastructure,ai-agents,ai-observability,bastion,jailbreak,llm,owasp,owasp-llm-top-10,pii-detection,prompt-injection,red-team
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Requires-Dist: click>=8.1
Requires-Dist: httpx>=0.25
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: twine>=4.0; extra == 'dev'
Description-Content-Type: text/markdown

# bastion-red

Adversarial assessment SDK for AI agents. Python equivalent of [`@pistonsolutions/bastion`](https://www.npmjs.com/package/@pistonsolutions/bastion). Same CLI, same `wrap()` programmatic API, same scope authoring, same hosted-runner endpoints.

```bash
pipx install bastion-red          # or: uv tool install bastion-red
bastion login
bastion run --target https://your-agent.example.com/chat --plugin pii-direct
```

The same run appears in your dashboard with the full probe ↔ target transcript.

Full reference: **https://bastion.pistonsolutions.ai/docs**

---

## Quickstart

```bash
pipx install bastion-red
bastion login                 # opens dashboard, hands API key back to terminal
bastion init                  # scaffold .bastion/ in the current repo
bastion run --scope SCOPE.md  # text assessment
# or:
bastion voice --target-ws wss://your-agent.example.com/voice \
              --rule "Do not disclose PII without verification"
```

Requires Python ≥ 3.10.

---

## Architecture

The SDK is a **thin client**. Your machine never runs an LLM, opens a WebSocket to your target, or places a phone call — all of that happens on Bastion infra. The CLI reads your scope, POSTs a job descriptor with your `bk_*` token, polls until the run completes.

What this means: only your target's URL/DID and the scope leave your network. No LLM keys on your end, no telephony provider to integrate, no WebRTC stack to install.

**Failsafe:** if the primary probe engine fails on a given run, Bastion falls back to a curated payload catalog automatically. You get telemetry from every `bastion run`, not an empty report.

---

## Modes

| Mode | Command | When to use |
|------|---------|-------------|
| Text | `bastion run --target <url>` | HTTP chat endpoints, RAG, agent backends |
| Voice WebSocket | `bastion voice --target-ws <wss>` | In-house voice agents you can expose as 8 kHz μ-law WS |
| Telephony | `bastion voice --target-did <e164>` | Agents on a phone number; tests real PSTN conditions |

```bash
bastion run --target https://your-agent.example.com/chat --plugin pii-direct
bastion voice --target-ws wss://your-agent.example.com/voice --rule "..."
bastion voice --target-did +14155551234 --rule "..."
```

**Telephony note:** only test phone numbers you own or have explicit written authorization to test.

---

## Programmatic API: wrap()

```python
from bastion import wrap

def agent(msg: str) -> str:
    return llm.complete(msg)

traced = wrap(agent, mode="observe", on_event=lambda e: print("event", e["session_id"]))
traced("hello")
```

Events flow into the dashboard's Live Activity view. Flagged events auto-promote into scope-seeds so the next assessment can replay them as adversarial probes.

---

## SCOPE.md

YAML frontmatter + markdown body. Frontmatter declares what to test; body describes the agent for grading context.

```markdown
---
target: https://api.example.com/v1/chat/completions
model: gpt-4o-mini

headers:
  Authorization: Bearer ${OPENAI_API_KEY}

categories:
  - system_prompt_extraction
  - pii_leakage
  - jailbreak_resistance
---

# Customer-support agent

The agent answers billing questions for retail customers. Must verify identity
(email + last 4 of card) before discussing any account, must refuse refunds
above $100 without supervisor approval.
```

Env vars in headers interpolate via `${VAR}`. Categories default to `system_prompt_extraction` if omitted.

---

## CLI reference

| Command | What it does |
|---------|--------------|
| `bastion login` | Authenticate; persists `~/.bastion/credentials.json` |
| `bastion whoami` | Print email, org, credential source |
| `bastion init [--ci]` | Scaffold `.bastion/` in the current repo |
| `bastion run` | Text assessment (thin-client by default) |
| `bastion voice --target-ws <url>` | Voice WebSocket probe |
| `bastion voice --target-did <e164>` | Telephony probe |
| `bastion assessment` | Run the configured scope |
| `bastion diff [a] [b]` | Compare two reports |
| `bastion docs` | Open the docs page |

Every command supports `--help`.

---

## Authentication

Two ways to provision a `bk_*` key:

1. **Interactive:** `bastion login` (opens browser, hands key back, persists `~/.bastion/credentials.json` mode 0600)
2. **CI:** `export BASTION_API_KEY=bk_live_...`

Resolution order: env → file. Keys revocable from the dashboard.

---

## CI/CD

```yaml
name: Bastion Assessment
on: { pull_request: {}, push: { branches: [main] } }

jobs:
  bastion:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pipx install bastion-red
      - run: bastion run --scope SCOPE.md --no-tui
        env: { BASTION_API_KEY: ${{ secrets.BASTION_API_KEY }} }
```

---

## Privacy

- Only the scope you write leaves your machine.
- Verbatim target responses are stored as evidence — if your agent returns real PII, that PII is visible in the dashboard transcript.
- API keys never leave the dashboard in plaintext (only a SHA-256 hash).
- Runs are scoped to the org that minted the API key.

---

MIT © Piston Solutions
