Skip to content

insidia.yaml

insidia init writes insidia.yaml in the current directory. A scan reads that file and nothing else. There is no URL argument on insidia scan.

This is the file it writes:

version: 1
policy: L1
coverage: standard
scope:
- host: localhost
- host: 127.0.0.1
- host: "::1"
targets:
app:
kind: chat
url: http://127.0.0.1:8080/chat
request_template: '{"messages": {{conversation_json}}}'
response_selector: "$.choices[0].message.content"
rate_limit:
rps: 5
concurrency: 1
# A model host must also be listed in scope.
models: {}

Change targets so url is your app before you treat a result as meaningful. Unknown fields are rejected.

FieldWhat to put
version1. Any other number is an error.
policyL1. That is the policy a scan runs. L2 and L3 are names only; a scan does not run them.
coveragestandard or thorough. standard picks one engine per check. thorough runs every installed engine that covers that check.
scopeThe hosts Insidia is allowed to contact. At least one.
targetsThe apps, APIs, or repositories to test. At least one. The key (app above) is the name that shows up in the report.
modelsOptional. attacker and judge are the only keys. {} means no model.

Each entry is one host.

FieldWhat to put
hostHostname only, such as localhost or staging.example.com. No scheme and no path.
authorizedtrue or false. Defaults to false. Anything other than localhost, 127.0.0.1, or ::1 needs true, set by you. A scan of that host also needs insidia scan --yes.
scope:
- host: 127.0.0.1
- host: staging.example.com
authorized: true

A host listed twice is an error. A model endpoint is a host too: if models.attacker.base_url points at another machine, that host has to be in scope. See Scope.

The key under targets is the target name. These are the fields inside it.

FieldRequiredWhat to put
kindyeschat, agent, rag, mcp, web, api, or repo.
urlfor every kind except repoWhere to send the check, such as http://127.0.0.1:8080/chat.
pathfor repoDirectory to scan, such as . or services/api.
commandnoA list of strings accepted by the schema. Local command execution is not available in this release; use a URL target.
methodnoHTTP method. Default POST.
request_templatenoBody template. {{conversation_json}} is replaced with the messages for that check.
response_selectornoJSONPath into the response. The sample uses $.choices[0].message.content.
querynoQuery string as a map of strings.
headersnoExtra request headers as a map of strings.
authnoHow to send a credential. The secret stays in the environment.
rate_limitnorps (default 5) and concurrency (default 1). Both must be positive.
apinoRequest shape. Default http. Also openai, anthropic, graphql, or grpc.
canarynoA string you plant so a leak can be recognized in the reply.

auth looks like this. scheme defaults to Bearer. secret_ref is env: plus the variable name. The value is not written into the file.

targets:
app:
kind: chat
url: http://127.0.0.1:8080/chat
auth:
header: Authorization
secret_ref: env:APP_TOKEN
scheme: Bearer

A repository target has no URL:

targets:
repo:
kind: repo
path: .

Leave this as {} when the checks do not need a model. L1 does not require one.

attacker and judge are the only roles. Each role has:

FieldWhat to put
providerRequired. openai-compatible, anthropic, or gemini. For Ollama or OpenAI, use openai-compatible.
base_urlRequired when configuring a role for a scan. Its host must also be listed in scope.
modelRequired when configuring a role for a scan. The model name served by the endpoint.
secret_refOptional. env:NAME, same rule as target auth.
models:
attacker:
provider: openai-compatible
base_url: http://127.0.0.1:11434/v1
model: llama3.1

This example also needs 127.0.0.1 in scope. The full generated config above already includes it.