-
Notifications
You must be signed in to change notification settings - Fork 2
Configuration
This guide covers all configuration options that apply across REST, GraphQL, and gRPC testing modes.
- Generating Configuration with Claude Code
- Authentication (auth.yaml)
- Roles and Permissions (roles.yaml)
- Custom Headers
- Rate Limiting
- Proxy Support
- LLM Triage
- Output Formats
- Production Safety
- Environment Variables
Instead of writing auth.yaml and roles.yaml by hand, use the included Claude Code skill to generate them from your API spec:
claude --plugin-dir /path/to/hadrian
# "Generate Hadrian auth.yaml and roles.yaml from openapi.yaml"Supports OpenAPI/Swagger, GraphQL SDL, and gRPC proto files.
Configure how to authenticate as each role. The same format works across all test modes.
method: bearer
roles:
admin:
token: "eyJhbGciOiJIUzI1NiIs..."
user:
token: "eyJhbGciOiJIUzI1NiIs..."
guest:
token: ""method: basic
roles:
admin:
username: "${ADMIN_USER}"
password: "${ADMIN_PASS}"
readonly:
username: "reader"
password: ""method: api_key
location: header # or "query"
key_name: X-API-Key
roles:
admin:
api_key: "${ADMIN_API_KEY}"
service:
api_key: "service-key-123"method: cookie
cookie_name: JSESSIONID
roles:
administrator:
cookie: "6916A1CBD61194CA9A2C64B6ECAB729C"
anonymous:
cookie: ""| Method | Config Fields | Example Header |
|---|---|---|
bearer |
token |
Authorization: Bearer <token> |
basic |
username, password
|
Authorization: Basic <base64> |
api_key |
api_key, location, key_name
|
X-API-Key: <key> |
cookie |
cookie, cookie_name
|
Cookie: session=<value> |
Use no_auth: true to send requests without any auth header:
method: bearer
roles:
admin:
token: "${ADMIN_TOKEN}"
anonymous:
no_auth: trueRoles with empty credentials still send auth headers with empty values. This tests how APIs handle malformed auth:
| Method | Config | Header Sent |
|---|---|---|
| any | no_auth: true |
(no header) |
bearer |
token: "" |
Authorization: Bearer |
basic |
username: "", password: ""
|
Authorization: Basic Og== |
api_key |
api_key: "" |
X-API-Key: |
cookie |
cookie: "" |
Cookie: session= |
Tokens can reference environment variables to avoid hardcoding credentials:
roles:
admin:
token: "${ADMIN_TOKEN}"Security: Hadrian warns if auth.yaml has world-readable permissions. Run chmod 0600 auth.yaml.
Define your application's roles, privilege levels, and permissions:
objects:
- users
- posts
- admin
roles:
- name: admin
level: 100
permissions:
- "read:users:all"
- "write:users:all"
- "delete:users:all"
- "execute:admin:all"
- name: user
level: 10
permissions:
- "read:users:own"
- "read:posts:all"
- "write:posts:own"
- name: guest
level: 0
permissions: []
endpoints:
- path: "/api/users/{id}"
object: users
owner_field: idPermissions follow <action>:<object>:<scope>:
| Component | Values | Description |
|---|---|---|
| Action |
read, write, delete, execute, *
|
What the role can do |
| Object | Any value from the objects list |
What resource it applies to |
| Scope |
public, own, org, all, *
|
How broadly it applies |
The level field defines explicit privilege ordering:
- Higher values = more privileged (e.g., admin: 100, user: 10, guest: 0)
- Used by
role_selectorto determine "lower" vs "higher" permission levels - Prevents misclassification when admins have fewer but more powerful permissions
Add custom HTTP headers to every request:
hadrian test rest --api api.yaml --roles roles.yaml \
-H "X-Custom-Tenant: acme" \
-H "X-Request-Source: hadrian"Limits outgoing requests to a configured rate (default: 5 req/s):
hadrian test rest --api api.yaml --roles roles.yaml --rate-limit 10.0Automatically retries on rate limit responses (429/503):
hadrian test rest --api api.yaml --roles roles.yaml \
--rate-limit-backoff fixed \
--rate-limit-max-retries 10 \
--rate-limit-max-wait 120s| Strategy | Behavior | Use Case |
|---|---|---|
| exponential (default) | Wait doubles: 1s, 2s, 4s, 8s... | Most APIs |
| fixed | Constant wait between retries | APIs with fixed rate windows |
| Flag | Default | Description |
|---|---|---|
--rate-limit |
5.0 | Requests per second |
--rate-limit-backoff |
exponential | Strategy: exponential or fixed
|
--rate-limit-max-retries |
5 | Maximum retry attempts |
--rate-limit-max-wait |
60s | Maximum backoff wait |
--rate-limit-status-codes |
429,503 | Status codes triggering backoff |
Route traffic through Burp Suite or other intercepting proxies:
# HTTP proxy
hadrian test rest --api api.yaml --roles roles.yaml --proxy http://localhost:8080
# HTTPS proxy with custom CA
hadrian test rest --api api.yaml --roles roles.yaml \
--proxy https://localhost:8080 --ca-cert burp-ca.crt
# Skip TLS verification (development only)
hadrian test rest --api api.yaml --roles roles.yaml \
--proxy https://localhost:8080 --insecureOptional AI-powered finding analysis using Ollama to reduce false positives:
hadrian test rest --api api.yaml --roles roles.yaml \
--llm-host http://localhost:11434 \
--llm-model llama3.2:latest \
--llm-context "This API handles financial data with PCI DSS requirements"| Flag | Default | Description |
|---|---|---|
--llm-host |
— | LLM host URL (e.g., http://localhost:11434) |
--llm-model |
— | Model name (e.g., llama3.2:latest) |
--llm-timeout |
180 | Request timeout in seconds |
--llm-context |
— | Additional context for analysis |
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llama3.2:latest
# Runs at http://localhost:11434 by defaultData safety: Hadrian redacts sensitive data (tokens, credentials) before sending findings to the LLM.
[FINDING] API1:2023 - BOLA - Cross-User Resource Access
Severity: HIGH
Endpoint: GET /api/users/{id}
Attacker: user -> Victim: admin
Evidence: Status 200, body contains user data
Summary: 2 findings (1 CRITICAL, 1 HIGH)
hadrian test rest --api api.yaml --roles roles.yaml --output json --output-file report.jsonhadrian test rest --api api.yaml --roles roles.yaml --output markdown --output-file report.md| Flag | Default | Description |
|---|---|---|
--output |
terminal | Format: terminal, json, markdown
|
--output-file |
— | Write to file (stdout if omitted) |
--request-ids |
1 | Request IDs per finding (0 = all) |
| Safeguard | Default | Override |
|---|---|---|
| YAML bomb protection | 1MB size, 20-depth | Not configurable |
| TLS 1.3 enforcement | Enabled | Not configurable |
| Credential validation | Warns on insecure config | Not configurable |
| Audit logging | .hadrian/audit.log |
--audit-log <file> |
| Variable | Description | Default |
|---|---|---|
HADRIAN_TEMPLATES |
Custom templates directory | ./templates/rest |
OLLAMA_HOST |
Ollama host for LLM triage | http://localhost:11434 |