Your first boundary.
Run Pyro on your own infrastructure, choose a policy, and get an explicit decision from your terminal or application before untrusted input reaches your AI.
1. Choose how to start
Install the CLI
With Node.js 22.13 or newer, install the published @delvisor/pyro package with pnpm:
pnpm add --global @delvisor/pyro
pyro --helpThe CLI connects to a running Pyro instance. Continue below to sign in, or choose Docker to start your own instance first.
2. Connect and sign in
Set the gateway and control-plane URLs for your running Pyro instance. These addresses match the Docker setup; replace them with your own server addresses if you host Pyro elsewhere.
pyro config set gateway-url http://localhost:8080
pyro config set control-url http://localhost:8081
pyro auth loginEnter your instance's administrator password at the hidden prompt. For Docker, use ADMIN_PASSWORD from .env. The CLI and dashboard share the same profiles, applications, webhooks, and activity.
Dashboard commands use your saved administrator session. Gateway commands such as classify, jobs, and events use an application API key. To try a request with your dashboard session right away, run pyro playground 'Summarize this document.'.
3. Make the policy yours
Choose a curated starting point in Protection Profiles or from the CLI. Review its questions, thresholds, failure behavior, and local rules before importing. Download the Balanced assistant profile and run these commands from the folder where you saved it:
pyro profiles presets
pyro profiles preview --file ./balanced-assistant.yaml
pyro profiles import --file ./balanced-assistant.yaml
pyro apps create --name "Support" --default-profile-id balanced-assistantSave the application ID returned by the last command for the next step. Import preserves a profile's ID and rejects duplicates; skip the import if you already have that profile. You can also download and edit any of these starting points:
- Balanced assistant — general prompt-injection and exfiltration checks.
- Strict tool agent — lower thresholds and checks for destructive commands.
- Support assistant — prompt injection, disclosure, and account access bypass.
- Local secret guard — common credential patterns without a model call.
Profiles use versioned YAML. Import or export them from the dashboard or CLI. Application and profile rules both apply; a block outranks a review, followed by the highest risk. Regex uses RE2 syntax, without lookaround or backreferences.
pyro profiles list
pyro profiles export balanced-assistant --output my-profile.yaml
# Create your own profile from a full JSON configuration:
pyro profiles create --data @profile.json
# Replace an existing profile with a full JSON configuration:
pyro profiles update PROFILE_ID --data @updated-profile.jsonThe JSON files above are your own profile configurations, including detectors and localRules. Use pyro profiles create --help for the available fields. Updates replace the full profile; imports never overwrite it.
These are starting configurations, not guarantees. Test against representative traffic and compare changes with a shadow policy. Exports leave out environment-specific shadow references.
4. Get your first decision
Create a key for the application you just added. Replace APP_ID with its returned ID, then set PYRO_API_KEY to the one-time key shown in the response.
pyro keys create --name "Support backend" --app-id APP_ID
export PYRO_API_KEY="paste-your-application-key-here"
pyro classify "Summarize this document." --profile balanced-assistantYou receive JSON with an allow, review, or block action, a risk score, a reason, and trace identifiers. Your application must enforce the action. A successful CLI request exits 0 even when the action is review or block.
printf '%s' 'A message to inspect' | pyro classify --profile balanced-assistant
pyro classify --file prompt.txt --labels '{"tenant":"acme"}'
pyro classify --input '{"messages":[{"role":"user","content":"Hello"}]}'
pyro classify --data @envelope.jsonUse your own prompt.txt or envelope.json for file input. --file reads text, --input accepts structured JSON, and --data sends an exact API request body. Omit --profile to use the effective default for your key and application.
5. Use the same policy in your code
Use the same application key and profile ID in your code. The CLI and HTTP API are ready to use. The optional SDKs are separate from the published CLI package and are available from source.
Build the optional SDKs from source
# TypeScript — run from the Pyro repository
pnpm install --frozen-lockfile
pnpm run build:packages
pnpm --filter @pyro/contracts pack
pnpm --filter @pyro/sdk pack
# Install both generated .tgz files in your application.
# Python — run from the Pyro repository
pip install -e ./sdks/python
# Rust — add to your application's Cargo.toml
[dependencies]
pyro-client = { path = "../Pyro/sdks/rust" }The CLI, TypeScript, Python, and cURL examples use the Balanced assistant profile after import. The Rust example uses your application’s default profile.
pnpm add --global @delvisor/pyro# Use your application's PYRO_API_KEY.pyro classify "Summarize this document." \ --profile balanced-assistant \ --labels '{"environment":"production"}'# Evaluate a request in the background.pyro jobs create "Summarize this document." \ --profile balanced-assistant# Stream decisions for your application.pyro events --count 10A decision contains an action, risk, detector results, reason, and trace identifiers. The TypeScript and Rust clients support background jobs, bounded polling, labels, request IDs, and webhook signature verification. Keep gateway keys on the server.
The CLI also manages profiles, applications, keys, and provider settings. The SDKs focus on evaluating inputs; use the CLI or the control-plane REST API for administration.
6. Follow decisions from the terminal
Inspect the same activity as the dashboard, filter by application or label, and export matching records. These commands use your saved dashboard session:
pyro overview
pyro usage --range 7d
pyro activity list --action block --limit 20
pyro activity list --label-key tenant --label-value acme
pyro activity list --format csv --output events.csv
pyro activity watchFor a live stream scoped to your application API key, run pyro events. Stop either stream with Ctrl-C. Add --json for compact JSON responses in scripts; live streams already emit one JSON event per line. Export files are created with owner-only permissions and never overwritten.
Use pyro COMMAND --help for flags and the underlying API operation, or pyro spec control and pyro spec gateway to inspect the bundled OpenAPI contracts.
7. Connect your webhooks
Add your HTTPS receiver from Webhooks or the CLI. Filter by application, profile, action, and minimum risk. Send a test and inspect delivery history.
# Replace the URL with your own receiver.
pyro webhooks create --name "Decision alerts" \
--url https://your-receiver.example/events \
--actions '["review","block"]' --minimum-risk 0.7
# Use the webhook ID returned above.
pyro webhooks test WEBHOOK_ID
pyro webhooks deliveries --integration-id WEBHOOK_ID
pyro webhooks retry DELIVERY_IDTo restrict delivery, pass --app-ids or --profile-ids as JSON arrays of existing IDs. Empty arrays mean all applications or profiles. All filters must match.
Webhook signatures use HMAC-SHA256 over the timestamp, a period, and the exact raw request body. Save the signing secret shown when creating a destination. Verify the signature and timestamp, then deduplicate by the delivery ID.
Deliveries are queued in PostgreSQL with up to five attempts. HTTP 429 and server failures retry; most other client errors need attention. Notifications leave out prompts, previews, labels, and metadata.
The webhook guide includes a sample receiver and local checks for signatures, retries, and delivery of a local-rule decision.
Keep the boundary honest.
Pyro screens input; your application must enforce its decision. It complements authorization, tool permissions, sandboxing, and output validation. Semantic detectors send input to the configured model provider. Raw input previews remain off unless explicitly enabled.
Explore Pyro on GitHub ↗