| name | policy-validation |
| description | Understand Matimo's security policy engine. Learn which tool types are allowed, what domains are safe, how SSRF is prevented, and how the policy validator (matimo_doctor) enforces rules. |
| metadata | {"category":"Security & Policy","difficulty":"intermediate","apply-to":"matimo_doctor matimo_validate_tool"} |
Policy Validation: Security Rules and Enforcement
This skill teaches you Matimo's security policy engineโa developer-controlled, object-frozen, non-bypassable system that blocks dangerous tool patterns before they execute.
Core Principle: Policy is Immutable
Once the developer initializes Matimo with a policy configuration, that policy is frozen and cannot be changed by agents. This ensures:
- โ
Agents cannot weaken security rules
- โ
Agents cannot bypass domain restrictions
- โ
Agents cannot create shell commands if blocked
- โ
Policy is transparent and auditable
const policyConfig: PolicyConfig = {
allowedDomains: ['api.github.com', 'api.weatherapi.com'],
allowedHttpMethods: ['GET', 'POST'],
allowCommandTools: false,
allowFunctionTools: false,
protectedNamespaces: ['matimo_'],
allowedCredentials: ['GITHUB_TOKEN', 'WEATHER_API_KEY']
};
Object.freeze(policyConfig);
The matimo_doctor Meta-Tool
matimo_doctor is the policy validator. It checks tool definitions against:
- Schema validation โ YAML structure is correct
- Policy validation โ Tool complies with security rules
Input: YAML tool definition (string)
Output: { valid: true, ... } โ
Safe to use
OR: { valid: false, schemaErrors: [...], policyErrors: [...] } โ Blocked
Example: Valid Tool โ Passes Both Checks
name: github_user_lookup
version: "1.0.0"
description: Look up a GitHub user
parameters:
username:
type: string
required: true
execution:
type: http
method: GET
url: "https://api.github.com/users/{username}"
matimo_doctor result:
{
"valid": true,
"schemaErrors": [],
"policyErrors": []
}
Example: Invalid YAML โ Schema Error
name: my_tool
matimo_doctor result:
{
"valid": false,
"schemaErrors": [
{"field": "version", "message": "Invalid input: expected string, received undefined"},
{"field": "execution", "message": "Invalid input: expected object, received undefined"}
],
"policyErrors": []
}
Example: Policy Violation โ Policy Error
name: shell_exec
version: "1.0.0"
execution:
type: command
command: bash
args: ["-c", "rm -rf /"]
matimo_doctor result:
{
"valid": false,
"schemaErrors": [],
"policyErrors": [
{"rule": "allowCommandTools", "severity": "critical", "message": "Command tools are blocked by policy"}
]
}
Policy Rules Reference
1. Allowed Domains (HTTP Tools Only)
What it does: Restricts HTTP tools to specific domains to prevent abuse.
Config:
allowedDomains: ['api.github.com', 'api.weatherapi.com', 'jsonplaceholder.typicode.com']
Example: Allowed
execution:
type: http
url: "https://api.github.com/users/octocat" โ
In allowedDomains
Example: Blocked
execution:
type: http
url: "https://backdoor.attacker.com/hack" โ Not in allowedDomains
matimo_doctor: "Domain blocked: backdoor.attacker.com not in allowed list"
2. Allowed HTTP Methods
What it does: Restricts HTTP verbs to prevent unintended data modification.
Config:
allowedHttpMethods: ['GET', 'POST']
Example: Allowed
execution:
type: http
method: GET โ
In allowedHttpMethods
Example: Blocked
execution:
type: http
method: DELETE โ Not in allowedHttpMethods
matimo_doctor: "HTTP method DELETE not allowed; must use GET or POST"
3. Allow/Disallow Command Tools
What it does: Command tools execute shell commandsโinherently risky.
Config:
allowCommandTools: false
Example: Blocked
execution:
type: command
command: "cat /etc/passwd" โ Commands blocked
matimo_doctor: "Command tools are blocked by policy"
4. Allow/Disallow Function Tools
What it does: Function tools execute arbitrary JavaScript code.
Config:
allowFunctionTools: false
Example: Blocked
execution:
type: function
code: |
return require('fs').readFileSync('/etc/passwd'); โ Blocked
matimo_doctor: "Function tools are blocked by policy"
5. Protected Namespaces
What it does: Prevents agents from hijacking reserved tool names (matimo_* for built-ins).
Config:
protectedNamespaces: ['matimo_']
Example: Allowed
name: github_webhook โ
Doesn't start with matimo_
Example: Blocked
name: matimo_backdoor โ Tries to hijack reserved namespace
matimo_doctor: "Reserved namespace violation: matimo_* is protected for built-in tools"
6. Allowed Credentials
What it does: Whitelists which environment variables can be used for auth.
Config:
allowedCredentials: ['GITHUB_TOKEN', 'WEATHER_API_KEY']
Example: Allowed
authentication:
type: api_key
location: header
name: Authorization
Example: Blocked
authentication:
type: api_key
location: header
name: X-Custom-Secret
matimo_doctor: "Credential X_CUSTOM_SECRET not in allowed list"
Security Patterns Blocked by Policy
Pattern 1: SSRF (Server-Side Request Forgery)
Attack: Probe internal IPs to discover service topology or exploit internal endpoints.
Blocked ranges:
169.254.169.254/32 โ AWS EC2 metadata service
127.0.0.1/8, localhost โ Local machine
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 โ Private networks
::1, fe80::/10 โ IPv6 loopback/link-local
Example: Attempted Attack
name: metadata_probe
execution:
type: http
method: GET
url: "http://169.254.169.254/latest/meta-data/" โ SSRF!
matimo_doctor: "SSRF detected: forbidden IP range 169.254.* is not allowed"
Pattern 2: Shell Command Execution
Attack: Execute arbitrary commands on the host system.
Example: Attempted Attack
name: shell_exec
execution:
type: command
command: bash
args: ["-c", "{user_command}"] โ Dangerous!
matimo_doctor: "Command tools are blocked by policy"
Pattern 3: Arbitrary Code Execution
Attack: Run untrusted JavaScript code with full system access.
Example: Attempted Attack
name: code_executor
execution:
type: function
code: |
const fs = require('fs');
return fs.readFileSync('/etc/passwd', 'utf8'); โ Dangerous!
matimo_doctor: "Function tools are blocked by policy"
Pattern 4: Namespace Hijacking
Attack: Create a tool named matimo_* to impersonate a built-in tool.
Example: Attempted Attack
name: matimo_create_tool_backdoor โ Looks like built-in!
matimo_doctor: "Reserved namespace violation: matimo_* is protected"
Using matimo_doctor in Agent Workflows
Step 1: Validate YAML Before Creating
Agent: "I'll validate this tool first"
Agent: matimo_doctor(yaml_content="...")
Result: { valid: true } โ
or { valid: false, errors: [...] } โ
Step 2: Understand Errors
If matimo_doctor returns { valid: false, errors: [...] }:
For schema errors:
- Read field name and message
- Fix YAML syntax or missing fields
- Re-validate
For policy errors:
- Understand which rule was violated
- Redesign tool to comply
- Use allowed domains, methods, execution types
- Re-validate
Step 3: Only Create Valid Tools
Once matimo_doctor returns { valid: true }:
Agent: matimo_create_tool(name, yaml_content, target_dir)
Result: Tool created on disk, marked as draft
Examples: Learning from Blocked Patterns
Example 1: Redesign for Policy
Agent's first attempt (blocked):
name: file_system
execution:
type: command
command: cat
args: ["{path}"]
Agent learns: "I can't use commands; let me use HTTP instead"
Agent's redesign (approved):
name: file_server_lookup
execution:
type: http
method: GET
url: "https://api.example.com/files/{file_id}"
Example 2: Respect Domain Restrictions
Agent's first attempt (blocked):
name: internal_service_caller
execution:
type: http
method: POST
url: "http://10.0.0.5:8080/admin"
Agent learns: "I can't probe internal networks; only public APIs"
Agent's redesign (approved):
name: public_api_caller
execution:
type: http
method: POST
url: "https://api.public-service.com/endpoint"
Example 3: Avoid Namespace Conflicts
Agent's first attempt (blocked):
name: matimo_my_tool
Agent learns: "Built-in tools use matimo_*; I need a different name"
Agent's redesign (approved):
name: my_custom_tool
Policy in Action: Complete Flow
Developer deploys Matimo:
policyConfig = {
allowedDomains: ['api.github.com'],
allowCommandTools: false
}
Object.freeze(policyConfig)
Agent receives goal: "I need a tool to run bash commands"
Agent designs:
execution: { type: command, command: bash }
Agent validates:
matimo_doctor(yaml) โ { valid: false, error: "Command tools blocked" }
Agent learns:
"Commands are not allowed; policy is immutable; I must redesign"
Agent redesigns:
execution: { type: http, method: GET, url: "https://api.github.com/..." }
Agent validates:
matimo_doctor(yaml) โ { valid: true }
Agent creates:
matimo_create_tool(...) โ Success โ
Developer Perspective: Setting Policy
const policyConfig: PolicyConfig = {
allowedDomains: [
'api.github.com',
'api.slack.com',
'jsonplaceholder.typicode.com'
],
allowedHttpMethods: ['GET', 'POST'],
allowCommandTools: false,
allowFunctionTools: false,
protectedNamespaces: ['matimo_'],
allowedCredentials: ['GITHUB_TOKEN', 'SLACK_BOT_TOKEN']
};
Object.freeze(policyConfig);
const matimo = await MatimoInstance.init({
policyConfig,
});
Key Takeaways
- โ
Policy is immutable โ Agents cannot bypass or weaken security rules
- โ
matimo_doctor enforces policy โ Use it to validate YAML before creating
- โ
Domains are restricted โ Only allowed APIs can be called
- โ
Commands and functions are optional โ Developers can block them entirely
- โ
SSRF is prevented โ Internal IP ranges are blocked by default
- โ
Namespaces are protected โ
matimo_* is reserved for built-ins
- โ
Credentials are whitelisted โ Only approved env vars can be used
References
- Tool lifecycle: See
meta-tools-lifecycle skill
- Complete tool creation: See
tool-creation skill
- Tool discovery: See
tool-discovery skill
Last Updated: March 2026
Status: Complete
Level: Intermediate