Skip to main content

bastion-red

Adversarial assessment SDK for AI agents. Python equivalent of @pistonsolutions/bastion. Same CLI, same wrap() programmatic API, same scope authoring, same hosted-runner endpoints.

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

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
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()

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.

---
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

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

Metadata

Release files for bastion-red 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bastion-red 0.5.0
File Size Uploaded Provenance
bastion_red-0.5.0.tar.gz 42.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bastion-red 0.5.0
File Interpreter ABI Platform
bastion_red-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 91.0 kB

Release files / bastion_red-0.5.0.tar.gz

Download URL bastion_red-0.5.0.tar.gz
Size 42.5 kB
Tags Source
SHA-256 checksum
How to use checksums
6dfd9f1d696e3ea4ca1f0adfb791c9efa9c11fc852a8e637e3f4c74fd1843fb2
BLAKE2b-256 checksum
How to use checksums
fbd3dd547c7c99181b8e049a3d3398465ef7f580825b3c0d2c7e89bb7eeed960
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / bastion_red-0.5.0-py3-none-any.whl

Download URL bastion_red-0.5.0-py3-none-any.whl
Size 48.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ee56d903e88b7e39024951abf92141577b7c288344e3499e1e0f870dcdb2c78
BLAKE2b-256 checksum
How to use checksums
89100a6b11ee891e497d213e18f51b28e1cf229f28053e05f95d85475add33bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for bastion-red 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page