# API Authentication (/docs/api-auth) API Keys [#api-keys] Create keys at [platform.tachyonic.co/settings](https://platform.tachyonic.co/settings). ```bash curl -H "x-api-key: tach_live_..." https://api.tachyonic.sh/api/v1/scans ``` Keys are scoped to a workspace. Available scopes: | Scope | Description | | --------------- | ------------------------------ | | `scan:read` | List and view scans | | `scan:write` | Submit and cancel scans | | `target:read` | List and view targets | | `target:write` | Create targets | | `target:manage` | Update, delete, verify targets | | `finding:read` | List and view findings | Device Flow (CLI) [#device-flow-cli] The CLI uses OAuth device flow for interactive login: ```bash tachyonic login ``` 1. CLI requests a device code from the platform 2. User opens a browser URL and approves 3. CLI polls until approved, receives a JWT 4. JWT is stored locally and refreshed automatically Headless / CI [#headless--ci] For non-interactive environments, use an API key: ```bash tachyonic login --platform-api-key tach_live_... ``` Session Auth (Dashboard) [#session-auth-dashboard] The dashboard uses browser session authentication. No manual setup required — sign in at [platform.tachyonic.co](https://platform.tachyonic.co). Token Refresh [#token-refresh] Device flow JWTs are automatically refreshed before expiry. If a token expires, run `tachyonic login` again. # API Reference (/docs/api) Base URL: `https://api.tachyonic.sh/api/v1` Authentication [#authentication] All API requests require authentication via one of: | Method | Header | Use Case | | ------------ | ----------------------------- | --------------------------- | | API Key | `x-api-key: tach_live_...` | CLI, CI/CD, scripts | | Device Token | `Authorization: Bearer ` | CLI after `tachyonic login` | | Session | Browser session | Dashboard | Create API keys at [platform.tachyonic.co/settings](https://platform.tachyonic.co/settings). Targets [#targets] Create Target [#create-target] ``` POST /targets ``` ```json { "name": "Production API", "endpoint": "https://api.example.com/v1/chat/completions", "provider": "anthropic" } ``` Response `201`: ```json { "id": "f1df1a66-bf05-40f2-8b75-7aaf438815ae", "name": "Production API", "endpoint": "https://api.example.com/v1/chat/completions", "provider": "anthropic", "verified_at": null, "workspace_id": "..." } ``` List Targets [#list-targets] ``` GET /targets ``` Verify Domain [#verify-domain] Before scanning external targets from the dashboard, verify ownership: ``` POST /targets/{id}/verify ``` Returns DNS TXT and HTTP verification instructions: ```json { "token": "tachyonic-verify-abc123...", "methods": { "dns": { "type": "TXT", "host": "_tachyonic-verify.api.example.com", "value": "tachyonic-verify-abc123..." }, "http": { "url": "https://api.example.com/.well-known/tachyonic-verify.json", "body": { "token": "tachyonic-verify-abc123..." } } } } ``` Check verification status: ``` GET /targets/{id}/verify ``` Scans [#scans] Submit Scan [#submit-scan] ``` POST /scans ``` ```json { "target_id": "f1df1a66-...", "config": { "categories": ["prompt-injection", "tool-abuse"], "max_attacks": 48, "provider": "anthropic" } } ``` Response `201`: ```json { "id": "3297a21f-...", "status": "queued", "config": { ... }, "kueue_job_name": "scan-3297a21f", "started_at": "2026-04-05T12:57:24Z" } ``` List Scans [#list-scans] ``` GET /scans ``` Get Scan [#get-scan] ``` GET /scans/{id} ``` Cancel Scan [#cancel-scan] ``` DELETE /scans/{id} ``` Returns `204 No Content`. Terminates the running job. Stream Events (SSE) [#stream-events-sse] ``` GET /scans/{id}/events ``` Returns Server-Sent Events. Initial event contains current status. Terminal events (`completed`, `failed`, `cancelled`) close the stream. ``` data: {"type":"status","data":{"status":"queued"}} data: {"type":"status","data":{"status":"completed","summary":{"attack_count":88,"finding_count":2,"score":97}}} ``` Findings [#findings] List Findings [#list-findings] ``` GET /findings ``` Query parameters: `severity`, `verdict`, `target_id` Response: ```json { "findings": [ { "id": "...", "attack_id": "filesystem_sandbox_escape", "category": "tool_abuse", "severity": "critical", "verdict": "confirmed", "confidence": 1.0, "raw_data": { "payload": "...", "response": "...", "triage": { ... } } } ], "total": 2 } ``` Rate Limits [#rate-limits] | Plan | Requests/min | | ---------- | ------------ | | Free | 10 | | Pro | 60 | | Team | 120 | | Enterprise | 300 | Rate limit headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `Retry-After`. Errors [#errors] ```json { "error": "Target domain not verified" } ``` | Status | Meaning | | ------ | ---------------------------------------------- | | 400 | Bad request / validation error | | 401 | Authentication required | | 403 | Forbidden (domain not verified, scope missing) | | 404 | Resource not found | | 429 | Rate limit exceeded | | 502 | Job submission failed | # Attack Catalog (/docs/attacks) Tachyonic ships 210 attack patterns across 16 categories — 168 from the open attack taxonomy plus 42 built-in offensive modules. Each attack is mapped to the [OWASP LLM Top 10 2025](https://owasp.org/www-project-top-10-for-large-language-model-applications/) and [MITRE ATLAS](https://atlas.mitre.org/). Categories [#categories] Prompt Injection (LLM01) [#prompt-injection-llm01] Direct prompt injection attacks that attempt to override system instructions, extract hidden context, or alter model behavior through crafted user input. * 20 attack definitions (PI-001 to PI-020) * Tests: instruction override, role hijacking, delimiter attacks, encoding bypass System Prompt Extraction (LLM01) [#system-prompt-extraction-llm01] Attempts to leak the system prompt or hidden instructions configured by the developer. * 12 attack definitions (SPL-001 to SPL-012) * Tests: direct extraction, indirect leakage, format manipulation Jailbreak (LLM01) [#jailbreak-llm01] Guardrail bypass techniques that attempt to make the model ignore safety constraints. * 22 attack definitions (JB-001 to JB-022) * Tests: DAN prompts, character roleplay, encoding tricks, multi-language bypass, hypothetical framing Indirect Injection (LLM01) [#indirect-injection-llm01] Attacks that inject malicious instructions through external data sources (RAG documents, tool responses, web content) rather than direct user input. * Requires RAG-enabled targets Tool Abuse (LLM06) [#tool-abuse-llm06] Manipulation of tool/function calling to achieve unintended actions. * 12 attack definitions (EA-001 to EA-012) * Tests: parameter manipulation, tool chaining, path traversal via tools, SQL injection via tools, SSRF via API tools Multi-Turn Manipulation (LLM01) [#multi-turn-manipulation-llm01] Attacks that build context across multiple conversation turns to gradually shift model behavior. * 8 attack definitions (MT-001 to MT-008) * Tests: context poisoning, incremental jailbreak, trust building Vision Injection (LLM01) [#vision-injection-llm01] Attacks targeting vision-enabled models through crafted images. * 12 attack definitions (VI-001 to VI-012) * Tests: text-in-image injection, steganographic payloads, adversarial patches * Requires vision-capable target Sensitive Disclosure (LLM02) [#sensitive-disclosure-llm02] Attempts to extract sensitive information, PII, credentials, or internal data from model responses. * 10 attack definitions (SID-001 to SID-010) * Tests: social engineering, data exfiltration, credential harvesting Supply Chain (LLM05) [#supply-chain-llm05] Attacks targeting the model's dependency chain, including tool schemas, plugins, and external integrations. * 8 attack definitions (SC-001 to SC-008) * Tests: tool schema poisoning, dependency confusion, plugin backdoor Improper Output (LLM09) [#improper-output-llm09] Testing for unsafe output that could be used for downstream attacks (XSS, code injection, etc.). * 8 attack definitions (IOH-001 to IOH-008) * Tests: code generation safety, HTML/JS injection, command injection in generated code Unbounded Consumption (LLM10) [#unbounded-consumption-llm10] Resource exhaustion attacks that attempt to consume excessive compute, tokens, or time. * 2 attack definitions (UC-001 to UC-002) * Tests: recursive expansion, infinite loop prompts Permission Escalation (LLM06) [#permission-escalation-llm06] Attacks that attempt to escalate privileges within agent systems, bypassing authorization controls. * Tests: admin impersonation, token privilege escalation, cross-tenant data access, role confusion Multi-Agent Injection (LLM06) [#multi-agent-injection-llm06] Attacks targeting multi-agent architectures where multiple AI agents collaborate. * Tests: orchestrator override, agent impersonation, inter-agent prompt injection Misinformation (LLM09) [#misinformation-llm09] Attempts to generate convincing false information or manipulate factual outputs. Vector Embedding (LLM08) [#vector-embedding-llm08] Manipulation of vector embeddings and semantic search systems. * 8 attack definitions (VE-001 to VE-008) Video Injection (LLM01) [#video-injection-llm01] Attacks targeting video-processing models. Severity Levels [#severity-levels] | Level | Weight | Description | | -------- | ------ | ----------------------------------------------------------------- | | Critical | 5.0 | Remote code execution, credential leakage, full system compromise | | High | 3.0 | Data exfiltration, privilege escalation, safety bypass | | Medium | 2.0 | Information disclosure, partial guardrail bypass | | Low | 1.0 | Minor information leakage, low-impact behavior change | | Info | 0.5 | Informational findings, no direct security impact | Resistance Score [#resistance-score] After a scan, Tachyonic calculates a resistance score from 0-100: | Score | Rating | | ------ | --------- | | 90-100 | Excellent | | 75-89 | Good | | 50-74 | Fair | | 25-49 | Poor | | 0-24 | Critical | The score is severity-weighted — a single critical finding has more impact than multiple low findings. Custom Heuristics [#custom-heuristics] Attack definitions are YAML files. Set `HEURISTICS_PATH` to load a custom attack library: ```bash export HEURISTICS_PATH=/path/to/your/attacks tachyonic scan --target ... --include-builtin ``` See the [attack schema](https://github.com/tachyonic-sh/taxonomy) for the YAML format. # CI/CD Integration (/docs/ci-cd) Overview [#overview] Tachyonic integrates with CI/CD pipelines via SARIF output. Run scans on every PR or deployment and surface findings directly in your code review workflow. GitHub Actions [#github-actions] Basic Scan [#basic-scan] ```yaml name: AI Security Scan on: pull_request: push: branches: [main] jobs: security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Tachyonic run: curl -fsSL https://tachyonic.sh/install | bash - name: Run security scan env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | tachyonic scan \ --target ${{ vars.TARGET_URL }} \ --provider anthropic \ --categories prompt-injection,system-prompt-extraction,tool-abuse \ --max-attacks 20 \ --format sarif \ --output results.sarif \ --no-progress - name: Upload SARIF to GitHub if: always() uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif ``` Findings appear in the **Security** tab under **Code scanning alerts**. Cloud Scan (Platform) [#cloud-scan-platform] Submit to the Tachyonic platform for team visibility: ```yaml - name: Run cloud scan env: TACHYONIC_PLATFORM_API_KEY: ${{ secrets.TACHYONIC_API_KEY }} run: | tachyonic login --platform-api-key "$TACHYONIC_PLATFORM_API_KEY" tachyonic scan \ --target ${{ vars.TARGET_URL }} \ --provider anthropic \ --cloud ``` Fail on Findings [#fail-on-findings] Block the pipeline if vulnerabilities are found: ```yaml - name: Run scan id: scan env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | tachyonic scan \ --target ${{ vars.TARGET_URL }} \ --provider anthropic \ --format json \ --output results.json \ --no-progress FINDINGS=$(python3 -c "import json; r=json.load(open('results.json')); print(r['scan']['vulnerabilities_found'])") echo "findings=$FINDINGS" >> "$GITHUB_OUTPUT" - name: Check findings if: steps.scan.outputs.findings != '0' run: | echo "Security scan found ${{ steps.scan.outputs.findings }} vulnerabilities" exit 1 ``` GitLab CI [#gitlab-ci] ```yaml ai-security-scan: stage: test image: ubuntu:latest before_script: - curl -fsSL https://tachyonic.sh/install | bash script: - | tachyonic scan \ --target "$TARGET_URL" \ --provider anthropic \ --categories prompt-injection,tool-abuse \ --max-attacks 20 \ --format sarif \ --output gl-sast-report.sarif \ --no-progress artifacts: reports: sast: gl-sast-report.sarif variables: ANTHROPIC_API_KEY: "$ANTHROPIC_API_KEY" ``` Generic Pipeline [#generic-pipeline] Any CI system that can run shell commands: ```bash # Install curl -fsSL https://tachyonic.sh/install | bash # Scan tachyonic scan \ --target "$TARGET_URL" \ --provider anthropic \ --format json \ --output results.json \ --no-progress # Check results SCORE=$(python3 -c "import json; print(json.load(open('results.json'))['score']['total'])") echo "Resistance score: $SCORE" if [ "$SCORE" -lt 80 ]; then echo "FAIL: Score below threshold" exit 1 fi ``` Environment Variables [#environment-variables] Set these as CI secrets: | Variable | Required | Description | | ---------------------------- | ------------------------ | ------------------- | | `ANTHROPIC_API_KEY` | Yes (if using Anthropic) | Provider API key | | `OPENAI_API_KEY` | Yes (if using OpenAI) | Provider API key | | `TARGET_URL` | Yes | Endpoint to scan | | `TACHYONIC_PLATFORM_API_KEY` | Optional | For `--cloud` scans | Cost Control [#cost-control] Limit scan cost in CI to avoid surprise bills: ```bash tachyonic scan \ --target "$TARGET_URL" \ --provider anthropic \ --max-attacks 20 \ --max-cost 5.00 \ --no-progress ``` # Agent Testing (/docs/cli-agents) Overview [#overview] Tachyonic can test AI agents that run as CLI programs — not just HTTP APIs. This covers agents like Codex, Claude Code, custom chatbots, and any agent accessible via a command-line interface. Local CLI Agent [#local-cli-agent] Test an agent that runs as a local command: ```bash tachyonic scan \ --cli-command "my-agent" \ --categories prompt-injection,tool-abuse \ --max-attacks 10 ``` Tachyonic sends payloads to the agent's stdin and reads responses from stdout. With Agent Name [#with-agent-name] Some CLI tools (like Clawdbot) require an `--agent` flag: ```bash tachyonic scan \ --cli-command "clawdbot" \ --cli-agent "my-assistant" \ --categories prompt-injection ``` Declare Capabilities [#declare-capabilities] Tell Tachyonic what the agent supports so it selects the right attacks: ```bash tachyonic scan \ --cli-command "my-agent" \ --cli-supports-tools true \ --cli-supports-rag true \ --cli-supports-multi-turn true ``` | Flag | Default | Effect | | --------------------------- | ------- | --------------------------------------- | | `--cli-supports-tools` | false | Include tool-abuse attacks | | `--cli-supports-rag` | false | Include indirect-injection attacks | | `--cli-supports-multi-turn` | false | Include multi-turn manipulation attacks | Remote Agent via SSH [#remote-agent-via-ssh] Test an agent running on a remote machine: ```bash tachyonic scan \ --cli-command "my-agent" \ --ssh-host "user@staging-server.com" \ --categories prompt-injection,system-prompt-extraction ``` Tachyonic SSH-es into the host, runs the command, and sends payloads over the SSH session. SSH Requirements [#ssh-requirements] * SSH key-based authentication (no password prompts) * Agent command must be in the remote PATH * Remote host must have the agent installed and configured Examples [#examples] Test a Customer Support Bot [#test-a-customer-support-bot] ```bash tachyonic scan \ --cli-command "./support-bot" \ --categories prompt-injection,sensitive-disclosure \ --max-attacks 20 \ --format html \ --output support-bot-report.html ``` Test a Code Generation Agent [#test-a-code-generation-agent] ```bash tachyonic scan \ --cli-command "code-agent --no-interactive" \ --cli-supports-tools true \ --categories tool-abuse,permission-escalation,jailbreak \ --format json \ --output code-agent-results.json ``` Test a Remote Staging Agent [#test-a-remote-staging-agent] ```bash tachyonic scan \ --cli-command "production-agent" \ --ssh-host "admin@staging.example.com" \ --categories prompt-injection,system-prompt-extraction \ --max-attacks 10 ``` # Listing Attacks (/docs/cli-attacks) List All Attacks [#list-all-attacks] ```bash tachyonic attacks ``` Shows all attacks available from your heuristics library. Filter by Category [#filter-by-category] ```bash tachyonic attacks --category tool-abuse ``` Detailed View [#detailed-view] ```bash tachyonic attacks --detailed ``` Shows full attack metadata: ID, name, category, severity, modality, payloads count, and OWASP mapping. Include Built-in Attacks [#include-built-in-attacks] By default, only the external heuristics library is loaded. Add built-in attacks: ```bash tachyonic attacks --include-builtin ``` Example Output [#example-output] ``` prompt-injection PI-001 Direct Instruction Override critical text 4 payloads PI-002 System Prompt Extraction high text 3 payloads PI-003 Role Hijacking high text 3 payloads ... tool-abuse EA-001 Tool Parameter Manipulation high text 4 payloads EA-002 Tool Chaining Attack critical text 3 payloads ... ``` Categories [#categories] | Category | Count | Description | | -------------------------- | ----- | -------------------------- | | `prompt-injection` | 20 | Direct prompt injection | | `system-prompt-extraction` | 12 | System prompt leakage | | `jailbreak` | 22 | Guardrail bypass | | `tool-abuse` | 12 | Tool/function manipulation | | `multi-turn-manipulation` | 8 | Multi-turn attacks | | `vision-injection` | 12 | Image-based attacks | | `sensitive-disclosure` | 10 | Data exfiltration | | `supply-chain` | 8 | Dependency attacks | | `permission-escalation` | — | Privilege escalation | | `multi-agent-injection` | — | Multi-agent attacks | | `improper-output` | 8 | Output handling | | `unbounded-consumption` | 2 | Resource exhaustion | | `misinformation` | — | False information | | `vector-embedding` | 8 | Embedding manipulation | | `video-injection` | — | Video-based attacks | | `indirect-injection` | — | Context injection (RAG) | # Cloud Scans (/docs/cli-cloud) Overview [#overview] Cloud scans run on Tachyonic's infrastructure and store results on the platform. Your team can view findings, track trends, and export reports from the dashboard. Login [#login] ```bash tachyonic login ``` Opens a browser for device authorization. Once approved, credentials are stored locally. Check Status [#check-status] ```bash tachyonic login --status ``` Shows platform authentication status and provider credentials. API Key Login [#api-key-login] For CI/CD or headless environments: ```bash tachyonic login --platform-api-key tach_live_... ``` Submit a Cloud Scan [#submit-a-cloud-scan] ```bash tachyonic scan \ --target https://your-api.com/v1/chat/completions \ --provider anthropic \ --cloud ``` The scan runs on Tachyonic's infrastructure. Results stream to the dashboard in real-time via SSE. With Options [#with-options] ```bash tachyonic scan \ --target https://your-api.com/v1/chat/completions \ --provider anthropic \ --categories tool-abuse,permission-escalation \ --max-attacks 48 \ --cloud ``` Upload Local Results [#upload-local-results] Already ran a scan locally? Upload the results: ```bash tachyonic upload --file scan-results.json ``` View Results [#view-results] Open [platform.tachyonic.co](https://platform.tachyonic.co) to view: * Scan history with status and scores * Individual findings with severity, evidence, and reproduction steps * Resistance score trends per target Logout [#logout] ```bash tachyonic logout --platform ``` # MCP Scanning (/docs/cli-mcp) Overview [#overview] Tachyonic can directly test MCP (Model Context Protocol) servers by calling their tools with adversarial inputs. This tests the tool layer without going through an LLM. Stdio Transport [#stdio-transport] For MCP servers that run as local processes: ```bash tachyonic scan \ --mcp-transport stdio \ --mcp-command npx \ --mcp-args "-y @modelcontextprotocol/server-filesystem /tmp/sandbox" \ --categories tool-abuse \ --provider anthropic ``` Tachyonic starts the MCP server process, performs the protocol handshake, discovers available tools, and sends adversarial tool calls. HTTP Transport [#http-transport] For MCP servers exposed over HTTP: ```bash tachyonic scan \ --mcp-transport http \ --mcp-url https://your-mcp-server.com/mcp \ --categories tool-abuse,permission-escalation \ --provider anthropic ``` What Gets Tested [#what-gets-tested] When scanning MCP servers, Tachyonic: 1. Connects and performs the MCP handshake (`initialize`) 2. Discovers available tools via `tools/list` 3. Analyzes tool schemas for poisoning patterns (malicious instructions in descriptions) 4. Sends adversarial `tools/call` requests testing: * Path traversal via file operation tools * SQL injection via database tools * Command injection via shell/exec tools * SSRF via HTTP/API tools * Parameter manipulation across all tool types Tool Schema Poisoning Detection [#tool-schema-poisoning-detection] Tachyonic passively analyzes MCP tool schemas for embedded prompt injection: ```bash tachyonic scan \ --mcp-transport stdio \ --mcp-command npx \ --mcp-args "-y your-mcp-server" \ --provider anthropic ``` Detects patterns like: * Override instructions in tool descriptions * Hidden commands in parameter documentation * Conflicting tool names that shadow legitimate tools Disable with `--disable-tool-schema-poisoning`. Expected Server Identity [#expected-server-identity] Verify the MCP server identity during handshake: ```bash tachyonic scan \ --mcp-transport stdio \ --mcp-command npx \ --mcp-args "-y @modelcontextprotocol/server-filesystem /tmp" \ --mcp-expected-server-name "filesystem" ``` Allowed Tools [#allowed-tools] Restrict which tools the scanner interacts with: ```bash tachyonic scan \ --mcp-transport http \ --mcp-url https://your-server.com/mcp \ --allowed-tool read_file,write_file,list_directory ``` # Reports (/docs/cli-reports) Generate During Scan [#generate-during-scan] ```bash # HTML report tachyonic scan --target ... --provider anthropic --format html --output report.html # SARIF for CI/CD tachyonic scan --target ... --provider anthropic --format sarif --output results.sarif # JSON (default) tachyonic scan --target ... --provider anthropic --output results.json ``` Generate After Scan [#generate-after-scan] Already have a JSON scan result? Convert it to another format: ```bash # JSON → HTML tachyonic report --input results.json --format html --output report.html # JSON → SARIF tachyonic report --input results.json --format sarif --output results.sarif ``` HTML Report [#html-report] Self-contained single-file HTML with: * Executive summary with resistance score * Severity breakdown (critical, high, medium, low, info) * Individual findings with payload, response, and evidence * Remediation guidance per OWASP category * Cost summary (tokens, estimated spend) Open directly in a browser — no server needed. SARIF Report [#sarif-report] [Static Analysis Results Interchange Format](https://sarifweb.azurewebsites.net/). Compatible with: * GitHub Code Scanning (upload via `github/codeql-action/upload-sarif`) * GitLab SAST * Azure DevOps * VS Code SARIF Viewer extension GitHub Code Scanning Example [#github-code-scanning-example] ```yaml - name: Run Tachyonic scan run: | tachyonic scan \ --target ${{ secrets.TARGET_URL }} \ --provider anthropic \ --format sarif \ --output results.sarif - name: Upload SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif ``` JSON Report Structure [#json-report-structure] ```json { "scan": { "id": "uuid", "target": "https://...", "started_at": "ISO8601", "completed_at": "ISO8601", "duration_ms": 16817, "attacks_executed": 88, "vulnerabilities_found": 2, "results": [ { "attack_name": "Tool Parameter Manipulation", "category": "tool_abuse", "severity": "high", "success": true, "confidence": 1.0, "evidence": "...", "payload": "...", "response": "...", "triage": { "verdict": "confirmed", "matched_heuristics": ["TP-INFO-LEAK"] } } ] }, "score": { "total": 97, "rating": "excellent", "category_scores": { ... } }, "remediations": [ ... ] } ``` # CLI Reference (/docs/cli) Commands [#commands] | Command | Description | | ------------------- | ----------------------------------------- | | `tachyonic scan` | Run a security scan against a target | | `tachyonic attacks` | List available attacks | | `tachyonic report` | Generate a report from scan results | | `tachyonic login` | Authenticate with the Tachyonic platform | | `tachyonic logout` | Remove stored credentials | | `tachyonic upload` | Upload local scan results to the platform | scan [#scan] Run a security scan against an LLM endpoint, AI agent, or MCP server. ```bash tachyonic scan [OPTIONS] ``` Target Options [#target-options] | Flag | Description | | -------------------- | ---------------------------------------------------------------------------------------------------------- | | `--target ` | Target URL or endpoint | | `--provider ` | Provider preset: `anthropic`, `open-ai`, `gemini`, `mistral`, `deep-seek`, `ollama`, `groq`, `together-ai` | | `--model ` | Model to use | | `--api-key ` | API key (prefer env vars for security) | | `--auth-mode ` | Credential mode: `api-key` (default), `session`, `auto` | Scan Options [#scan-options] | Flag | Description | | ---------------------- | ----------------------------------------------------- | | `--categories ` | Comma-separated attack categories to run | | `--max-attacks ` | Maximum number of attacks | | `--parallel` | Enable parallel execution | | `--max-concurrent ` | Max concurrent requests (default: 5) | | `--min-delay ` | Min delay between requests in ms (default: 100) | | `--no-triage` | Disable triage engine, emit raw findings | | `--include-builtin` | Include built-in attacks alongside heuristics library | | `--max-cost ` | Stop scan when estimated cost exceeds threshold | Output Options [#output-options] | Flag | Description | | ----------------- | ------------------------------------------------ | | `--format ` | Output format: `json` (default), `html`, `sarif` | | `--output ` | Output file (default: stdout) | | `--no-progress` | Hide progress bar | | `--include-raw` | Include raw responses in output | | `--verbose` | Enable verbose logging | MCP Options [#mcp-options] | Flag | Description | | ------------------------ | ------------------------------------ | | `--mcp-transport ` | Transport: `stdio` (default), `http` | | `--mcp-command ` | MCP server command (stdio) | | `--mcp-args ` | MCP server arguments (stdio) | | `--mcp-url ` | MCP server URL (HTTP) | Verification Options [#verification-options] | Flag | Description | | -------------------------- | ------------------------------------------------------ | | `--verify-llm` | Enable LLM-based verification of borderline detections | | `--verify-provider ` | Verification provider | | `--verify-model ` | Verification model | | `--verify-consensus` | Enable multi-judge consensus verification | Cloud Options [#cloud-options] | Flag | Description | | --------- | --------------------------------- | | `--cloud` | Submit scan to Tachyonic platform | CLI Agent Options [#cli-agent-options] | Flag | Description | | --------------------- | --------------------------------- | | `--cli-command ` | CLI command for agent testing | | `--cli-agent ` | CLI agent name | | `--ssh-host ` | SSH host for remote CLI execution | Environment Variables [#environment-variables] | Variable | Description | | ------------------- | ------------------------------------------------ | | `ANTHROPIC_API_KEY` | Anthropic API key | | `OPENAI_API_KEY` | OpenAI API key | | `GOOGLE_API_KEY` | Google AI API key | | `MISTRAL_API_KEY` | Mistral API key | | `DEEPSEEK_API_KEY` | DeepSeek API key | | `GROQ_API_KEY` | Groq API key | | `TOGETHER_API_KEY` | Together AI API key | | `TACHYONIC_API_KEY` | Fallback API key for any provider | | `HEURISTICS_PATH` | Path to attack library (default: `~/.tachyonic`) | | `RUST_LOG` | Log level: `info`, `debug`, `tachyonic=debug` | Attack Categories [#attack-categories] ```bash tachyonic scan --categories prompt-injection,jailbreak,tool-abuse ``` | Category | OWASP | Description | | -------------------------- | ----- | ---------------------------------------- | | `prompt-injection` | LLM01 | Direct prompt injection attacks | | `system-prompt-extraction` | LLM01 | System prompt leakage | | `jailbreak` | LLM01 | Jailbreak and guardrail bypass | | `indirect-injection` | LLM01 | Indirect prompt injection via context | | `tool-abuse` | LLM06 | Tool parameter manipulation and chaining | | `multi-turn-manipulation` | LLM01 | Multi-turn conversation attacks | | `vision-injection` | LLM01 | Vision model attacks via images | | `sensitive-disclosure` | LLM02 | Sensitive information disclosure | | `supply-chain` | LLM05 | Supply chain and dependency attacks | | `improper-output` | LLM09 | Output handling vulnerabilities | | `unbounded-consumption` | LLM10 | Resource exhaustion attacks | | `permission-escalation` | LLM06 | Privilege escalation via agents | | `multi-agent-injection` | LLM06 | Multi-agent system attacks | | `misinformation` | LLM09 | Misinformation generation | | `vector-embedding` | LLM08 | Vector/embedding manipulation | | `video-injection` | LLM01 | Video-based attacks | # Configuration (/docs/configuration) Heuristics Library [#heuristics-library] Tachyonic loads attack definitions from a YAML library. By default, it checks `~/.tachyonic/attacks/`. ```bash # Use a custom path export HEURISTICS_PATH=/opt/tachyonic # Include built-in attacks alongside the library tachyonic scan --target ... --include-builtin ``` The public attack taxonomy is at [github.com/tachyonic-sh/taxonomy](https://github.com/tachyonic-sh/taxonomy). Output Formats [#output-formats] JSON (default) [#json-default] ```bash tachyonic scan --target ... --format json --output results.json ``` Contains full scan metadata, all results with payloads/responses, score, and remediations. HTML [#html] ```bash tachyonic scan --target ... --format html --output report.html ``` Self-contained HTML report with severity breakdown, findings detail, and remediation guidance. SARIF [#sarif] ```bash tachyonic scan --target ... --format sarif --output results.sarif ``` Static Analysis Results Interchange Format. Compatible with GitHub Code Scanning and other SARIF viewers. Parallel Execution [#parallel-execution] ```bash tachyonic scan \ --target ... \ --parallel \ --max-concurrent 4 \ --min-delay 150 ``` * `--parallel` enables concurrent attack execution * `--max-concurrent` controls parallelism (default: 5) * `--min-delay` sets minimum ms between requests (default: 100) Cost Control [#cost-control] ```bash tachyonic scan --target ... --max-cost 5.00 ``` Stops the scan when estimated cost exceeds the threshold. Cost is estimated from token usage per provider pricing. Baseline Comparison [#baseline-comparison] Compare against a previous scan to see what changed: ```bash # Save a baseline tachyonic scan --target ... --save-baseline baseline.json # Compare against it tachyonic scan --target ... --baseline baseline.json ``` Request Customization [#request-customization] Custom Headers [#custom-headers] For targets behind authentication or custom routing: ```bash tachyonic scan \ --target https://your-api.com/chat \ --request-overrides '{"headers":{"X-Custom-Auth":"token123"}}' ``` Tool Definitions [#tool-definitions] Include tool/function definitions in scan requests: ```bash tachyonic scan \ --target ... \ --tools-file tools.json \ --tool-choice auto ``` Request Overrides [#request-overrides] Merge additional fields into every request: ```bash tachyonic scan \ --target ... \ --request-overrides '{"temperature":0,"max_tokens":1024}' ``` Or from a file: ```bash tachyonic scan \ --target ... \ --request-overrides-file overrides.json ``` # Detection and Triage (/docs/detection) Detection Pipeline [#detection-pipeline] Each attack payload goes through a multi-stage detection pipeline: ``` Payload → Target → Response → Pattern Matching → Triage Engine → [LLM Verification] → Finding ``` Pattern Matching [#pattern-matching] The first stage checks the model response against detection conditions defined in each attack: | Condition | Description | Confidence | | ---------------------- | -------------------------------------- | ---------- | | `Pattern` | Case-insensitive substring match | 0.95 | | `Regex` | Regex with optional capture extraction | 0.85 | | `ToolInvocation` | Tool call name matching | 0.60 | | `ToolArgumentPattern` | Nested JSON argument matching | 0.84-0.92 | | `ContainsSystemPrompt` | System prompt leak detection | 0.75 | | `NotContains` | Absence of expected refusal | 0.70 | | `ContentLength` | Response length anomaly | 0.60 | Default confidence threshold: 0.7. Tool-only conditions use 0.5. Triage Engine [#triage-engine] Raw detections pass through the triage engine which filters false positives using heuristic rules: * **FP-LOW-CONF-REFUSAL**: Suppress low-confidence matches where the model clearly refused * **FP-ATTACK-IDENTIFIED**: Suppress when the model identified and described the attack * **FP-PAGE-CONTENT-ECHO**: Suppress when response echoes page/document content * **TP-INFO-LEAK**: Confirm when response contains internal information not in the input * **TP-VIOLATION-MARKER**: Confirm when lab markers indicate a true violation * **TP-ATTACKER-ARGS**: Confirm path traversal via regex pattern matching Disable triage with `--no-triage` to see raw scanner output. LLM Verification (Optional) [#llm-verification-optional] For borderline detections, enable LLM-based verification: ```bash tachyonic scan \ --target ... \ --verify-llm \ --verify-provider anthropic \ --verify-model claude-haiku-4-5-20251001 ``` A separate LLM judges whether the detection is a true positive. This adds cost but improves precision. Consensus Verification (Optional) [#consensus-verification-optional] Use multiple LLM judges for high-confidence results: ```bash tachyonic scan \ --target ... \ --verify-consensus \ --verify-judges "openai:gpt-4o,anthropic:claude-sonnet-4-20250514" \ --verify-consensus-strategy majority ``` Strategies: `majority`, `unanimous`, `weighted`. Verdicts [#verdicts] | Verdict | Meaning | | ------------ | --------------------------------------------------- | | `confirmed` | Triage engine or LLM verifier confirmed the finding | | `probable` | High confidence match, not independently verified | | `suspicious` | Low confidence, warrants manual review | | `dismissed` | Triage engine determined false positive | # Tachyonic Documentation (/docs) Security testing for AI systems. Tachyonic tests LLM endpoints, AI agents, and MCP servers against [OWASP LLM Top 10](https://owasp.org/www-project-top-10-for-large-language-model-applications/) and [MITRE ATLAS](https://atlas.mitre.org/). Install [#install] ```bash curl -fsSL https://tachyonic.sh/install | bash ``` First Scan [#first-scan] ```bash # Set your provider API key export ANTHROPIC_API_KEY=sk-ant-... # Scan an endpoint tachyonic scan --target https://your-api.com/v1/chat/completions --provider anthropic ``` What's Next [#whats-next] # Platform Guide (/docs/platform) Overview [#overview] The Tachyonic platform at [platform.tachyonic.co](https://platform.tachyonic.co) provides a dashboard for managing security scans, starting runtimes, reviewing findings, and tracking your AI systems' security posture over time. Sign Up [#sign-up] Create an account at [platform.tachyonic.co/sign-up](https://platform.tachyonic.co/sign-up). Sign up with email/password or Google/GitHub OAuth. An organization and default workspace are created automatically. Targets [#targets] Targets represent the AI endpoints you want to scan. Create a target with: * **Name**: descriptive label. * **Endpoint**: the URL of the LLM API, for example `https://api.openai.com/v1/chat/completions`. * **Provider**: the LLM provider, which determines request and response format. Domain Verification [#domain-verification] For dashboard-initiated scans, external targets must be verified. After creating a target: 1. Go to target settings and click **Verify** 2. Choose DNS or HTTP verification: * **DNS**: Add a TXT record at `_tachyonic-verify.yourdomain.com` * **HTTP**: Serve a JSON file at `https://yourdomain.com/.well-known/tachyonic-verify.json` 3. Click **Check** to confirm Known providers (Anthropic, OpenAI, Google, etc.) are auto-verified. CLI and API key scans bypass domain verification. Scans [#scans] Submit a Scan [#submit-a-scan] From the dashboard: 1. Select a target 2. Choose attack categories 3. Set max attacks (optional) 4. Click **Start Scan** Scans run on Tachyonic's infrastructure. Progress updates stream in real-time. Scan Status [#scan-status] | Status | Description | | --------- | --------------------------- | | Queued | Waiting for runner capacity | | Running | Attacks in progress | | Completed | Finished with results | | Failed | Runner error (check logs) | | Cancelled | Stopped by user | Cancel a Scan [#cancel-a-scan] Click **Cancel** on a running scan to terminate it immediately. Findings [#findings] Each finding includes: * **Attack name**: which attack triggered the finding. * **Category**: OWASP LLM Top 10 mapping. * **Severity**: critical, high, medium, low, info. * **Verdict**: confirmed, probable, suspicious, dismissed. * **Confidence**: 0.0 to 1.0. * **Evidence**: what the model response contained. * **Payload**: the adversarial input sent. * **Response**: the model's actual response. * **Reproduction steps**: how to reproduce. Runtimes [#runtimes] For scans that need a bounded runtime, budget caps, approval gates, or egress allowlists, start a **runtime** instead of a plain scan. This is the path for MCP servers, agent stacks, and production endpoints with sensitive data. * **Runtime pool**: Free uses the default pool. Paid plans can select `aws-us-east-1` or `aws-eu-west-1`. * **Budget envelope**: wall-clock minutes, model tokens, and spend caps. * **Approval gates**: tools matching `policy.approvals.require_before` pause and create a pending approval. * **Egress allowlist**: the runtime allows only platform endpoints, the target host, and hosts listed in policy. Starting a runtime [#starting-a-runtime] From the dashboard: 1. Go to **Runtimes > New Runtime**. 2. Choose the target endpoint, region, model, and budget. 3. Click **Start Runtime** to start a live runtime or **Create Plan** for a dry run that validates the runtime bundle without spending budget. The runtime appears on `/runtimes` with live status streamed via SSE. Click through for the runtime detail page: state-transition timeline, events, artifacts, findings, and the approval inbox. The same surface is available from the CLI under `tachyonic runtime ...`. See [Runtimes](/docs/runtime) for the full command reference and the manifest schema. API Keys [#api-keys] Create API keys at **Settings > API Keys** for CLI and CI/CD integration. Each key is scoped to your workspace with configurable permissions. Billing [#billing] Scan limits [#scan-limits] | Plan | Scans/month | Rate limit | | ---------- | ----------: | ---------: | | Free | 5 | 10/min | | Pro | 50 | 60/min | | Team | Unlimited | 120/min | | Enterprise | Unlimited | 300/min | Runtime limits [#runtime-limits] | Plan | Runtime starts | Runtime pool | Minutes | Spend | Evidence retention | | ---------- | -------------: | --------------- | ------: | ----: | -----------------: | | Free | 3/month | Default | 15 | $1 | 72 hours | | Pro | 50/month | Default, US, EU | 60 | $10 | 30 days | | Team | Unlimited | Default, US, EU | 120 | $50 | 90 days | | Enterprise | Unlimited | Default, US, EU | 240 | $250 | 365 days | Upgrade at **Settings > Billing**. Signed runtime evidence is downloadable and shareable only during the plan retention window. Artifact downloads and reviewer links return HTTP 410 after that window closes. # Provider Setup (/docs/providers) Supported Providers [#supported-providers] | Provider | Flag | Env Variable | Default Endpoint | | ----------- | ------------------------ | ------------------- | ----------------------------------------- | | Anthropic | `--provider anthropic` | `ANTHROPIC_API_KEY` | `api.anthropic.com/v1/messages` | | OpenAI | `--provider open-ai` | `OPENAI_API_KEY` | `api.openai.com/v1/chat/completions` | | Google AI | `--provider gemini` | `GOOGLE_API_KEY` | Gemini API (URL key) | | Mistral | `--provider mistral` | `MISTRAL_API_KEY` | `api.mistral.ai/v1/chat/completions` | | DeepSeek | `--provider deep-seek` | `DEEPSEEK_API_KEY` | `api.deepseek.com/chat/completions` | | Groq | `--provider groq` | `GROQ_API_KEY` | `api.groq.com/openai/v1/chat/completions` | | Together AI | `--provider together-ai` | `TOGETHER_API_KEY` | `api.together.xyz/v1/chat/completions` | | Ollama | `--provider ollama` | — | `localhost:11434` | Anthropic [#anthropic] ```bash export ANTHROPIC_API_KEY=sk-ant-api03-... tachyonic scan --provider anthropic --model claude-haiku-4-5-20251001 ``` No `--target` needed — uses the default Anthropic endpoint. Session Auth (OAuth) [#session-auth-oauth] For Anthropic OAuth tokens (e.g., from Claude Code): ```bash tachyonic login --provider anthropic # Follow prompts to paste OAuth token tachyonic scan --provider anthropic --auth-mode session ``` OpenAI [#openai] ```bash export OPENAI_API_KEY=sk-... tachyonic scan --provider open-ai --model gpt-4o ``` Session Auth (Codex) [#session-auth-codex] Tachyonic can reuse credentials from [Codex CLI](https://github.com/openai/codex). If you have Codex installed and logged in: ```bash tachyonic login --provider open-ai # Reuses existing Codex credentials from ~/.codex/auth.json tachyonic scan --provider open-ai --auth-mode session ``` If Codex isn't installed, use `--device-auth` for device flow guidance: ```bash tachyonic login --provider open-ai --device-auth ``` Google AI (Gemini) [#google-ai-gemini] ```bash export GOOGLE_API_KEY=AI... tachyonic scan --provider gemini --model gemini-2.5-flash ``` Ollama (Local) [#ollama-local] Run models locally with no API key: ```bash # Start Ollama ollama serve # Pull a model ollama pull llama3.1 # Scan tachyonic scan --provider ollama --model llama3.1 ``` Ollama uses the OpenAI-compatible API at `localhost:11434`. Groq [#groq] ```bash export GROQ_API_KEY=gsk_... tachyonic scan --provider groq --model llama-3.1-70b-versatile ``` Together AI [#together-ai] ```bash export TOGETHER_API_KEY=... tachyonic scan --provider together-ai --model meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo ``` DeepSeek [#deepseek] ```bash export DEEPSEEK_API_KEY=... tachyonic scan --provider deep-seek --model deepseek-chat ``` Mistral [#mistral] ```bash export MISTRAL_API_KEY=... tachyonic scan --provider mistral --model mistral-large-latest ``` Custom Endpoints [#custom-endpoints] For OpenAI-compatible APIs not listed above: ```bash tachyonic scan \ --target https://your-api.com/v1/chat/completions \ --api-key your-key-here \ --model your-model-name ``` Tachyonic auto-detects OpenAI-compatible request/response format when no `--provider` is set. # Quickstart (/docs/quickstart) This path starts a bounded runtime, waits for signed evidence, downloads the bundle, and verifies it locally. Install [#install] ```bash curl -fsSL https://tachyonic.sh/install | bash ``` Supports macOS (arm64, amd64) and Linux (arm64, amd64). The installer verifies the SHA-256 checksum. Create an account [#create-an-account] 1. Sign up at [platform.tachyonic.co/sign-up](https://platform.tachyonic.co/sign-up). 2. Open **Settings > API Keys**. 3. Create an API key with `scan:read` and `scan:write`. 4. Save it in your shell: ```bash export TACHYONIC_PLATFORM_KEY=tach_live_... tachyonic login --platform-api-key "$TACHYONIC_PLATFORM_KEY" ``` You can also run `tachyonic login` for browser device authorization. Check your free limits [#check-your-free-limits] ```bash curl -sS \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ https://api.tachyonic.sh/api/v1/entitlements | jq . ``` Free workspaces can start 3 runtimes per month in the default runtime pool. The free runtime cap is 15 minutes, $1, and 50,000 model tokens. Approval gates are required. Evidence is retained for 72 hours and reviewer links can last up to 72 hours. Start a runtime [#start-a-runtime] Use a target you own or are authorized to test. Do not pass `--region` on Free. The platform selects the default signed runtime pool. ```bash tachyonic runtime start --target https://your-api.example.com | tee runtime.out RID=$(awk '/^Runtime:/ { print $2; exit }' runtime.out) ``` Follow it to a terminal state: ```bash tachyonic runtime watch "$RID" ``` Download signed evidence [#download-signed-evidence] The runtime artifacts API returns presigned URLs. This shell snippet downloads the result bundle and manifest into a local directory. It uses `jq`. ```bash mkdir -p "tachyonic-evidence/$RID" curl -sS \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ "https://api.tachyonic.sh/api/v1/runtimes/$RID/artifacts?limit=100" \ | jq -r '.data[] | select(.type == "finding_bundle_v1" or .type == "evidence_manifest_v1") | [.filename, .url] | @tsv' \ | while IFS="$(printf '\t')" read -r name url; do curl -fsSL "$url" -o "tachyonic-evidence/$RID/$name" done ``` Verify the bundle: ```bash tachyonic verify "tachyonic-evidence/$RID" ``` A passing verification prints `OK`, the artifact path, the SHA-256 digest, and the signing key ID. Share with a reviewer [#share-with-a-reviewer] Create a read-only evidence link after the runtime completes: ```bash curl -sS -X POST \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ -H "content-type: application/json" \ -d '{"expires_in_hours":72}' \ "https://api.tachyonic.sh/api/v1/runtimes/$RID/share" | jq . ``` The response contains a `url` under `https://platform.tachyonic.co/share/evidence/...`. Send that link to the reviewer. See [Share Evidence](/docs/share-evidence) for the response shape and limits. Local scans [#local-scans] For local-only testing, set the provider API key and run `tachyonic scan`: ```bash export ANTHROPIC_API_KEY=sk-ant-... tachyonic scan \ --target https://your-api.example.com/v1/chat/completions \ --provider anthropic \ --model claude-haiku-4-5-20251001 ``` Local scans write results to stdout by default. Use `--format json --output scan-results.json` or `--format html --output report.html` to save a report. Next steps [#next-steps] * [Runtimes](/docs/runtime): lifecycle, limits, regions, budgets, approvals, and CLI commands. * [Share Evidence](/docs/share-evidence): reviewer links and expiry limits. * [Verifying Evidence](/docs/verify-evidence): local signature verification. * [CLI Reference](/docs/cli): all commands and flags. * [Attack Catalog](/docs/attacks): what Tachyonic tests for. # Runtimes (/docs/runtime) Overview [#overview] A **runtime** is a single isolated execution of the Tachyonic scanner against your target. It carries an explicit target, policy, budget envelope, evidence capture, and audit trail. You can operate runtimes from the dashboard at [platform.tachyonic.co/runtimes](https://platform.tachyonic.co/runtimes) or from the CLI under `tachyonic runtime ...`. Both surfaces drive the same platform API. Plans and limits [#plans-and-limits] Runtime limits are enforced before infrastructure is created. If a request exceeds the plan, the API returns HTTP 402 with `upgrade_required: true`. Signed evidence downloads and reviewer links remain available only inside the plan's evidence retention window. After that window closes, artifact and share-link endpoints return HTTP 410. | Plan | Runtime starts | Regions | Minutes | Spend | Model tokens | Evidence retention | Reviewer link max | | ---------- | -------------: | ----------------------------------------- | ------: | ----: | -----------: | -----------------: | ----------------: | | Free | 3/month | Default pool only | 15 | $1 | 50,000 | 72 hours | 72 hours | | Pro | 50/month | Default, `aws-us-east-1`, `aws-eu-west-1` | 60 | $10 | 300,000 | 30 days | 14 days | | Team | Unlimited | Default, `aws-us-east-1`, `aws-eu-west-1` | 120 | $50 | 1,000,000 | 90 days | 30 days | | Enterprise | Unlimited | Default, `aws-us-east-1`, `aws-eu-west-1` | 240 | $250 | 5,000,000 | 365 days | 30 days | Check the limits for your workspace: ```bash curl -sS \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ https://api.tachyonic.sh/api/v1/entitlements | jq . ``` Free users should omit `--region`; the platform selects the default signed runtime pool. Paid regional runtimes are available through the API and dashboard. Verify each evidence bundle with `tachyonic verify` before relying on it in a review package. Regions [#regions] Every runtime is pinned to one runtime pool at start. * Free: default runtime pool only. * Paid: default runtime pool plus `aws-us-east-1` and `aws-eu-west-1`. When you need a paid region from the CLI, pass `--region`: ```bash tachyonic runtime start --target https://api.example.com --region aws-us-east-1 ``` Budgets [#budgets] Each runtime carries a budget that caps spend before it runs. | Field | What it limits | | --------------------- | -------------------------------------------------------------- | | `max_runtime_minutes` | Wall-clock runtime duration. | | `max_model_tokens` | Inference tokens routed through the platform metered endpoint. | | `max_spend_usd` | Runtime spend cap. | The platform applies the lower of your requested value and your plan limit. The runtime stops issuing inference requests when a hard cap is reached. Approvals [#approvals] Free and Pro plans require approval gates for: * `destructive_action` * `credentialed_action` * `exploit_attempt` * `out_of_scope_access` Tools matching the runtime policy pause execution and create a pending approval. Approve or deny from the dashboard or with `tachyonic runtime approve`. Team and Enterprise can run without required approval gates, but explicit policy gates still apply when present. Egress controls [#egress-controls] Every runtime pod runs alongside an egress-gateway sidecar that proxies outbound HTTP/HTTPS. A deny-default allowlist permits: 1. The platform callback endpoint. 2. The platform metered inference endpoint. 3. Hosts listed in `policy.network.allowlist`. 4. The host of your scan target. Direct outbound is dropped at the cluster layer. Lifecycle [#lifecycle] | Status | Description | | ------------------------- | ----------------------------------------------------- | | `planned` | Bundle rendered; no infrastructure yet. | | `queued` | Admitted to the runner pool and awaiting scheduling. | | `running` | The scanner is executing attacks against your target. | | `waiting_approval` | Paused on a gated action. | | `completed` | Terminal; artifacts and findings ingested. | | `failed_budget_exhausted` | Hit a runtime, token, or spend cap. | | `failed` | Runner error or operator denial. | | `cancelled` | Stopped by operator. | Manifest [#manifest] Reproducible runs use a runtime manifest: ```yaml objective: Pentest the MCP server for tool poisoning target: https://mcp.example.com region: aws-us-east-1 model: policy: passive-only budget: max_runtime_minutes: 30 max_spend_usd: 5 ``` Unknown keys are rejected. `objective` is the only required field. Free users should omit `region` unless the value is supplied by the entitlement API. From the dashboard [#from-the-dashboard] 1. Sign in at [platform.tachyonic.co](https://platform.tachyonic.co). 2. Go to **Runtimes > New Runtime**. 3. Choose the target endpoint, runtime pool, model, and budget. 4. Click **Start Runtime** for a live runtime or **Create Plan** for a dry run. The runtime detail page shows state transitions, events, artifacts, findings, and the approval inbox. From the CLI [#from-the-cli] Authenticate the same way as cloud scans: ```bash tachyonic login ``` For CI or a headless shell: ```bash tachyonic login --platform-api-key "$TACHYONIC_PLATFORM_KEY" ``` All commands accept `--api-url` or `TACHYONIC_API_URL` for non-default platforms. Plan [#plan] Validate the manifest and render the runtime bundle without spending budget. ```bash tachyonic runtime plan runtime.yml ``` Returns the runtime ID and `status: planned`. Start [#start] Two forms are supported. Manifest: ```bash tachyonic runtime start runtime.yml ``` Shorthand: ```bash tachyonic runtime start --target https://api.example.com ``` Returns the runtime ID and `status: queued`. Status [#status] ```bash tachyonic runtime status ``` Watch [#watch] Follow a runtime until it reaches a terminal state. Exits 0 on `completed`; exits non-zero on failure or cancellation. ```bash tachyonic runtime watch tachyonic runtime watch --timeout 1800 --interval 5 ``` Events [#events] ```bash tachyonic runtime events tachyonic runtime events --follow tachyonic runtime events --limit 200 ``` Logs [#logs] ```bash tachyonic runtime logs tachyonic runtime logs --follow ``` Artifacts [#artifacts] List result artifacts with presigned URLs: ```bash tachyonic runtime artifacts ``` Output is a table of `type`, `filename`, `bytes`, and `url`. Fetch any URL directly with `curl`. Signed evidence usually includes: * `finding_bundle_v1`: the runtime result bundle. * `evidence_manifest_v1`: the Ed25519 evidence manifest. Download both and run: ```bash tachyonic verify ./tachyonic-evidence/ ``` See [Verifying Evidence](/docs/verify-evidence). Approve [#approve] Approve or deny a gated action surfaced by `runtime status` or `runtime events`. ```bash tachyonic runtime approve tachyonic runtime approve --deny tachyonic runtime approve --deny --note "out of agreed scope" ``` Cancel [#cancel] ```bash tachyonic runtime cancel ``` Cancel is idempotent. Share evidence [#share-evidence] Create a reviewer link after a completed runtime: ```bash curl -sS -X POST \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ -H "content-type: application/json" \ -d '{"expires_in_hours":72}' \ "https://api.tachyonic.sh/api/v1/runtimes//share" | jq . ``` See [Share Evidence](/docs/share-evidence). When things go wrong [#when-things-go-wrong] | Symptom | Likely cause | What to do | | ---------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------- | | HTTP 402 on start | Region, duration, spend, or monthly start count exceeds your plan | Run `GET /api/v1/entitlements` or upgrade at **Settings > Billing**. | | Runtime stuck in `queued` | Runtime pool capacity is starting or exhausted | Wait and check `runtime events`. | | Runtime completed with no findings | Detection thresholds are too strict for your target response shape | See [Detection tuning](/docs/detection). | | `failed_budget_exhausted` | Runtime hit a hard cap | Raise the cap within your plan limit or narrow attack scope. | | Approval repeatedly denied | Policy is too strict | Review `policy.approvals` in your manifest. | | `egress_blocked` in findings | Allowlist missing a required host | Add it to `policy.network.allowlist`. | Next steps [#next-steps] * [Quickstart](/docs/quickstart): first runtime and evidence verification. * [Share Evidence](/docs/share-evidence): reviewer links. * [Platform Guide](/docs/platform): dashboard workflows. * [API Reference](/docs/api): call the same surface from your own tooling. * [Configuration](/docs/configuration): manifest fields in depth. # Share Evidence (/docs/share-evidence) Evidence share links give reviewers a read-only view of a completed runtime's signed evidence. The page shows runtime metadata, signature status, SHA-256 values, and artifact entries. Reviewers do not need a Tachyonic account. Use share links only for evidence you are allowed to disclose. The default production runtime path has been live-proven with signed evidence and public reviewer rendering. Paid regional evidence should still be verified with `tachyonic verify` before you rely on it in a review package. Requirements [#requirements] * A completed runtime. * An API key or CLI token with `scan:write`. * Signed artifacts available for the runtime. Expiry limits [#expiry-limits] Reviewer links are capped by the lower of the plan's reviewer-link limit and the remaining evidence retention window. | Plan | Evidence retention | Maximum reviewer link expiry | | ---------- | -----------------: | ---------------------------: | | Free | 72 hours | 72 hours | | Pro | 30 days | 14 days | | Team | 90 days | 30 days | | Enterprise | 365 days | 30 days | The API returns HTTP 402 with `upgrade_required: true` when `expires_in_hours` exceeds your plan. The API returns HTTP 410 when the signed evidence has passed the plan retention window or is too close to expiry to create a one-hour reviewer link. Existing reviewer links stop loading after the evidence retention window even if the token itself has not expired. Create a link [#create-a-link] ```bash export RID= curl -sS -X POST \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ -H "content-type: application/json" \ -d '{"expires_in_hours":72}' \ "https://api.tachyonic.sh/api/v1/runtimes/$RID/share" | jq . ``` Response: ```json { "id": "c526c5dd-643a-4a2b-b0f8-887104395615", "runtime_id": "tachyonic-rt-b885be17bce342a39a598a29f2cb981d", "url": "https://platform.tachyonic.co/share/evidence/", "expires_at": "2026-06-09T12:00:00.000Z", "max_expires_in_hours": 72, "evidence_retention": { "retained": true, "retention_hours": 72, "anchor_at": "2026-06-06T12:00:00.000Z", "expires_at": "2026-06-09T12:00:00.000Z", "remaining_hours": 71, "source": "artifact.collection_updated_at" } } ``` Send the `url` to your reviewer. What the reviewer sees [#what-the-reviewer-sees] The public page renders: * verification status * signing key ID * runtime ID * SHA-256 digest * artifact list * link expiry time Opening the page records an `evidence_verified` event for the Program 1 funnel when signed evidence is present. Retain a local copy [#retain-a-local-copy] A share link is not a substitute for retaining the evidence bundle. Download the bundle and manifest before the retention window closes: ```bash mkdir -p "tachyonic-evidence/$RID" curl -sS \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ "https://api.tachyonic.sh/api/v1/runtimes/$RID/artifacts?limit=100" \ | jq -r '.data[] | select(.type == "finding_bundle_v1" or .type == "evidence_manifest_v1") | [.filename, .url] | @tsv' \ | while IFS="$(printf '\t')" read -r name url; do curl -fsSL "$url" -o "tachyonic-evidence/$RID/$name" done tachyonic verify "tachyonic-evidence/$RID" ``` Current boundaries [#current-boundaries] Share links are for signed evidence review. They are not supply-chain provenance, hosted signing identity, structured runtime attestation, or a legal conclusion. Structured runtime attestation is planned for Phase B. # Verifying evidence bundles (/docs/verify-evidence) Overview [#overview] Signed runtime evidence consists of a result bundle and an adjacent evidence manifest. The manifest carries: * The SHA-256 of the artifact bytes. * The Ed25519 signature over that hash. * The signing key identifier. * An optional [Rekor](https://docs.sigstore.dev/logging/overview/) transparency-log entry. The default production runtime path emits signed evidence. Paid regional paths are being validated separately; always run `tachyonic verify` on the exact bundle you plan to retain or share. The CLI ships a `tachyonic verify` command that validates the manifest end to end. Once you have the published public key, your scan data stays local during verification. Quick start [#quick-start] ```bash tachyonic verify ./tachyonic-scan.manifest.json ``` You can pass any of: * a manifest file (`*.manifest.json`) * the artifact file itself, when the adjacent manifest is present * a directory containing both A passing verification prints: ```text OK artifact: ./tachyonic-scan.json manifest: ./tachyonic-scan.manifest.json sha256: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad key_id: tachyonic-signing-2026-05 signed_at: 2026-05-29T10:00:00+00:00 rekor: 4f2c...b7e1 (logIndex 8123410) rekor URL: https://rekor.sigstore.dev/api/v1/log/entries/4f2c...b7e1 ``` Any of these fail verification: * the artifact bytes do not match the recorded SHA-256 * the signature does not validate against the published public key * the manifest's `key_id` is not in the published key bundle Download from a runtime [#download-from-a-runtime] Use the artifacts API after `tachyonic runtime watch ` reaches `completed`: ```bash mkdir -p "tachyonic-evidence/$RID" curl -sS \ -H "x-api-key: $TACHYONIC_PLATFORM_KEY" \ "https://api.tachyonic.sh/api/v1/runtimes/$RID/artifacts?limit=100" \ | jq -r '.data[] | select(.type == "finding_bundle_v1" or .type == "evidence_manifest_v1") | [.filename, .url] | @tsv' \ | while IFS="$(printf '\t')" read -r name url; do curl -fsSL "$url" -o "tachyonic-evidence/$RID/$name" done tachyonic verify "tachyonic-evidence/$RID" ``` Fetching artifacts records evidence retention for product telemetry when signed evidence is present. The published public key [#the-published-public-key] The active signing public key lives at: ```text https://tachyonic.sh/.well-known/signing-pubkey.json ``` Shape: ```json { "keys": [ { "key_id": "tachyonic-signing-2026-05", "algorithm": "ed25519", "pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n", "active_from": "2026-05-29" } ] } ``` The bundle returns keys used to sign artifacts. Retired keys carry a `retired_at` date. Historical artifacts can continue to verify after ordinary key rotation. Offline verification [#offline-verification] If you cannot reach `tachyonic.sh`, save the public key locally and pass it explicitly: ```bash curl -s https://tachyonic.sh/.well-known/signing-pubkey.json \ | jq -r '.keys[0].pem' > ~/.tachyonic/signing-pubkey.pem tachyonic verify ./tachyonic-scan.manifest.json \ --pubkey ~/.tachyonic/signing-pubkey.pem ``` You can also point at a private mirror with `--pubkey-url`. Rekor transparency log [#rekor-transparency-log] When the runtime can reach `https://rekor.sigstore.dev`, it publishes a `hashedrekord` entry recording the artifact hash, signature, and public key. The entry is public and append-only. If Rekor is unreachable, the manifest is emitted without the entry and local verification still succeeds. In that case the output shows `rekor: none`. To disable Rekor in an air-gapped runner, set `TACHYONIC_REKOR_DISABLED=1`. Current boundaries [#current-boundaries] Verification proves that the artifact bytes are exactly what Tachyonic signed, and that the signer held the private key matching the published public key. Verification does not yet prove a specific runtime region, runtime policy, supply-chain provenance, hosted signing identity, or framework conformance. Structured runtime attestation is planned for Phase B. It will be documented separately when it ships.