Adding Templates & Rules¶
This guide covers adding new vulnerability templates and discovery rules, both as embedded assets and as operator-supplied files.
Adding Embedded Templates¶
Embedded templates are compiled into the binary and available without --templates-dir.
1. Create the Template File¶
Add a YAML file under pkg/vulncheck/templates/<category>/:
pkg/vulncheck/templates/
├── a2a/
├── bentoml/
├── campaign/
├── gradio/
├── huggingface/
├── jupyter/
├── kubeflow/
├── langchain/
├── litellm/
├── mcp/
├── mlflow/
├── ollama/
├── openai/
├── ray/
├── tfserving/
├── torchserve/
├── triton/
├── vectordb/
├── vllm/
└── myservice/ # new category
└── myservice-auth-001-unauthenticated-api.yaml
2. Write the Template¶
Follow the Template Format specification:
id: myservice-auth-001-unauthenticated-api
transport: http # default; use "mcp" for MCP stateful checks (see below)
info:
name: "MyService - Unauthenticated API Access"
type: detection # or "exploit" for active payloads
severity: high
author: aipostex
description: |
MyService is accessible without authentication.
reference:
- https://example.com/advisory
tags: [myservice, auth, misconfiguration]
detect:
- method: GET
path: /api/status
matchers:
- type: body_contains
value: "myservice"
checks:
- name: "Data enumeration without auth"
method: GET
path: /api/data
matchers:
- type: status
value: "200"
severity: high
finding:
title: "MyService Unauthenticated Data Access"
description: "Data endpoint is accessible without authentication."
remediation: "Enable authentication."
3. Verify Embedding¶
The embed.FS directive in pkg/vulncheck/templates_embed.go automatically includes all files under templates/:
New subdirectories and files are included automatically -- no code changes needed.
The detect: phase and transport:
The optional detect: block runs before checks: as a service gate — if no detect step
matches, the template short-circuits and produces no findings, which is what keeps a template
from firing against the wrong service. Set transport: mcp (instead of the default http) for
templates that must drive a stateful Model Context Protocol handshake rather than raw HTTP; MCP
checks dispatch on the JSON-RPC method in the check body (tools/list for detection,
tools/call for the exploit path). See Template Execution Model
for exactly how detect gating, matcher AND-logic, and transport dispatch work at runtime.
4. Test¶
# Verify the template loads
go run ./cmd/aipostex templates list | grep myservice
# View details
go run ./cmd/aipostex templates info myservice-auth-001-unauthenticated-api
# Run against a target
go run ./cmd/aipostex scan targets --target http://127.0.0.1:9000
5. Count Templates¶
Adding Embedded Discovery Rules¶
Embedded rules are compiled into the binary and available without --rules-dir.
1. Create or Edit a Rule File¶
Add rules to an existing file or create a new YAML file under pkg/discover/rules/:
pkg/discover/rules/
├── api_keys.yaml
├── mcp_configs.yaml
├── local_llm.yaml
├── vectordb_rag.yaml
├── core_assessment.yaml
└── myservice.yaml # new rule pack
2. Write Rules¶
Follow the Rule Format specification:
rules:
- name: "MyService Configuration"
category: "myservice-config"
severity: "high"
description: "MyService configuration with credentials."
file_patterns:
- "myservice.yaml"
- "myservice.json"
content_patterns:
- 'MYSERVICE_API_KEY\s*[=:]\s*\S+'
3. Verify Embedding¶
The embed.FS directive in pkg/discover/rules_embed.go automatically includes all files under rules/:
4. Test¶
# Create a test file
echo 'MYSERVICE_API_KEY=test123' > /tmp/test-myservice.yaml
# Run discovery
go run ./cmd/aipostex discover files --path /tmp --verbose
Operator-Supplied Templates & Rules¶
Operators can supply additional templates and rules at runtime without rebuilding:
Custom Templates¶
# Create a directory with custom templates
mkdir -p my-templates/custom/
cp my-template.yaml my-templates/custom/
# Run with custom templates
./aipostex scan targets --target http://target:9000 --templates-dir ./my-templates
./aipostex templates list --templates-dir ./my-templates
Custom templates load after embedded ones. If a custom template has the same ID as a built-in, the custom version takes precedence.
Custom Rules¶
# Create a directory with custom rules
mkdir -p my-rules/
cp my-rules.yaml my-rules/
# Run with custom rules
./aipostex discover files --path /home/user --rules-dir ./my-rules
Custom rules load after embedded ones and are applied alongside them.
Template ID Conventions¶
| Pattern | Example | Usage |
|---|---|---|
<service>-auth-NNN-<slug> |
ollama-auth-001-unauthenticated-api |
Authentication issues |
<service>-enum-NNN-<slug> |
mlflow-enum-002-artifact-surface |
Information exposure |
cve-YYYY-NNNNN-<slug> |
cve-2025-65513-fetch-mcp-ssrf |
CVE-specific checks |
<campaign>-NNN-<slug> |
bizarre-bazaar-001-llmjacking-validation |
Campaign emulation |
Testing Checklist¶
- Template loads without errors (
templates listcommand) - Template details display correctly (
templates info <id>) -
typefield is set correctly (detectionfor passive,exploitfor active payloads) - Detect phase correctly gates execution
- Matchers produce findings on vulnerable targets
- Extractors populate variables correctly
- Finding text renders with interpolated values
- Tags enable correct filtering
- No false positives on unrelated services
- Exploit templates are skipped in
--mode detect(default)