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

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.3
File Size Uploaded Provenance
bastion_red-0.5.3.tar.gz 43.7 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 93.5 kB

Release files / bastion_red-0.5.3.tar.gz

Download URL bastion_red-0.5.3.tar.gz
Size 43.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a64fb343133ea118b779b5a1482f856ffa5f1895f46ce5b6600367f076f1749b
BLAKE2b-256 checksum
How to use checksums
0034298819936d80d4d86144e2d481b10508669a96dcba7fc0364d8bd63e86c5
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.3-py3-none-any.whl

Download URL bastion_red-0.5.3-py3-none-any.whl
Size 49.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e41daba233851854a726ce8e71ff62d3b2ed53b30eacb89fa9e296465ccc0e8
BLAKE2b-256 checksum
How to use checksums
6ca38cb31c0cfb8fca93fbb069d438e526748c67564411b167db540fdc73bac7
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.3

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