Skip to main content

Webhooks

Rampart supports two types of webhooks:
  1. Action webhooks - Delegate allow/deny decisions to external services
  2. Notification webhooks - Send alerts when policies trigger
This page documents both use cases with examples and validation rules.

Action Webhooks

Action webhooks delegate policy decisions to external HTTP endpoints. Use for LLM-based intent verification, Slack approval bots, or custom authorization logic.

Basic Configuration

policies:
  - name: verify-production
    match:
      tool: ["exec"]
    rules:
      - action: webhook
        when:
          command_matches: ['*production*']
        webhook:
          url: 'http://localhost:8090/verify'
          timeout: 5s
          fail_open: true

Webhook Schema

webhook
object
required
Webhook configuration object. Required when action: webhook.

Request Format

Rampart sends POST requests with this JSON payload:
{
  "tool": "exec",
  "agent": "claude-code",
  "session": "myapp/main",
  "params": {
    "command": "kubectl apply -f deployment.yaml"
  },
  "timestamp": "2026-03-03T14:23:05Z",
  "policy_name": "verify-production",
  "rule_index": 0
}

Request Fields

FieldTypeDescription
toolstringTool type (exec, read, write, fetch, etc.)
agentstringAgent identity (e.g., claude-code, mcp-client)
sessionstringSession identifier (auto-detected as repo/branch from git)
paramsobjectTool-specific parameters (command, path, url, etc.)
timestampstringISO 8601 timestamp of the tool call
policy_namestringName of the policy that triggered this webhook
rule_indexintegerZero-based index of the rule within the policy

Tool-Specific Params

// exec tool
{
  "tool": "exec",
  "params": {
    "command": "rm -rf /tmp/build"
  }
}

// read tool
{
  "tool": "read",
  "params": {
    "path": "/home/user/.env"
  }
}

// write tool
{
  "tool": "write",
  "params": {
    "path": "/etc/hosts",
    "content": "127.0.0.1 localhost"
  }
}

// fetch tool
{
  "tool": "fetch",
  "params": {
    "url": "https://api.github.com/repos/peg/rampart"
  }
}

Response Format

Your webhook endpoint must return JSON with a decision field within the timeout period:
decision
string
required
Allow or deny decision. Must be "allow" or "deny".
{
  "decision": "allow"
}
reason
string
Optional explanation shown to the agent when denying.
{
  "decision": "deny",
  "reason": "Command targets production environment without approval"
}

Response Examples

// Allow the tool call
{
  "decision": "allow"
}

// Deny with reason
{
  "decision": "deny",
  "reason": "LLM verification failed: command intent unclear"
}

// Deny with detailed reason
{
  "decision": "deny",
  "reason": "Blocked by rampart-verify: Command 'rm -rf /var/lib/app' targets sensitive path outside project directory. Confidence: 0.95"
}

Error Handling

ErrorBehavior with fail_open: trueBehavior with fail_open: false
Connection refusedAllowDeny
TimeoutAllowDeny
HTTP 500AllowDeny
Invalid JSONAllowDeny
Missing decisionAllowDeny
Invalid decision valueAllowDeny

Complete Example

policies:
  - name: llm-verify
    match:
      tool: ["exec"]
    rules:
      # Explicit denies (fast pattern matching)
      - action: deny
        when:
          command_matches:
            - "rm -rf /"
            - "mkfs*"
        message: "Destructive command blocked"
      
      # LLM verification for ambiguous commands
      - action: webhook
        when:
          command_matches:
            - "*production*"
            - "*deploy*"
            - "rm -rf *"
        webhook:
          url: "http://localhost:8090/verify"
          timeout: 5s
          fail_open: true
        message: "Command requires intent verification"
      
      # Default allow
      - action: allow
        when:
          default: true

Notification Webhooks

Notification webhooks send alerts to Slack, Discord, Microsoft Teams, or custom endpoints when policies trigger.

Basic Configuration

version: "1"
default_action: allow

notify:
  url: "https://discord.com/api/webhooks/your/webhook"
  on: ["deny"]

policies:
  # ...

Notify Schema

notify
object
Top-level notification configuration. Optional.

Notification Payload

Rampart sends POST requests with this JSON payload:
{
  "timestamp": "2026-03-03T14:23:05Z",
  "decision": "deny",
  "tool": "exec",
  "command": "rm -rf /tmp/*",
  "policy": "block-destructive",
  "message": "Destructive command blocked",
  "agent": "claude-code",
  "session": "myapp/main"
}

Platform-Specific Formatting

Rampart automatically formats payloads for each platform: Slack:
{
  "text": "🔴 Rampart blocked a command",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Decision:* deny\n*Tool:* exec\n*Command:* `rm -rf /tmp/*`\n*Policy:* block-destructive\n*Agent:* claude-code\n*Session:* myapp/main"
      }
    }
  ]
}
Discord:
{
  "embeds": [
    {
      "title": "🔴 Rampart Policy Triggered",
      "color": 15158332,
      "fields": [
        {"name": "Decision", "value": "deny", "inline": true},
        {"name": "Tool", "value": "exec", "inline": true},
        {"name": "Command", "value": "`rm -rf /tmp/*`"},
        {"name": "Policy", "value": "block-destructive"},
        {"name": "Agent", "value": "claude-code", "inline": true},
        {"name": "Session", "value": "myapp/main", "inline": true}
      ],
      "timestamp": "2026-03-03T14:23:05Z"
    }
  ]
}

Platform Setup

  1. In Discord, go to Server Settings → Integrations → Webhooks
  2. Click “New Webhook”
  3. Choose a channel and copy the webhook URL
  4. Add to your policy:
notify:
  url: "https://discord.com/api/webhooks/123/abc"
  on: ["deny"]

Complete Examples

Multi-Event Notifications

version: "1"
default_action: allow

notify:
  url: "https://hooks.slack.com/services/..."
  on: ["deny", "ask", "watch"]

policies:
  - name: security
    match:
      tool: ["exec"]
    rules:
      # Sends notification on deny
      - action: deny
        when:
          command_matches: ["rm -rf /"]
      
      # Sends notification on ask
      - action: ask
        when:
          command_contains: ["sudo"]
      
      # Sends notification on watch
      - action: watch
        when:
          command_matches: ["curl *"]

Deny-Only Notifications

notify:
  url: "https://discord.com/api/webhooks/..."
  on: ["deny"]  # Only notify on blocked commands

policies:
  - name: block-destructive
    match:
      tool: ["exec"]
    rules:
      - action: deny
        when:
          command_matches: ["rm -rf /"]
        message: "Destructive command blocked"

Webhook Security

Action Webhooks

Use HTTPS

Always use HTTPS URLs for production webhooks to prevent interception.

Authenticate Requests

Your webhook endpoint should verify requests come from Rampart. Use a shared secret in a custom header:
# In your webhook handler
if request.headers.get('X-Rampart-Token') != SECRET:
    return {"decision": "deny", "reason": "Unauthorized"}

Rate Limit

Add rate limiting to prevent abuse:
from flask_limiter import Limiter

limiter = Limiter(app, default_limits=["100 per minute"])

@app.route('/verify', methods=['POST'])
@limiter.limit("10 per second")
def verify():
    # ...

Notification Webhooks

Protect Webhook URLs

Webhook URLs act as authentication tokens. Don’t commit them to git. Use environment variables:
notify:
  url: "${RAMPART_NOTIFY_URL}"

Rotate URLs Periodically

Regenerate webhook URLs every 90 days or when team members leave.

Validation Rules

Action Webhooks

  • webhook.url must be a valid HTTP/HTTPS URL
  • webhook.timeout must parse as a valid duration (e.g., 5s, 100ms, 1m)
  • webhook.fail_open must be boolean if present
  • Response must include decision field with value "allow" or "deny"

Notification Webhooks

  • notify.url must be a valid HTTP/HTTPS URL
  • notify.on must be a non-empty array
  • notify.on values must be "deny", "watch", or "ask"
  • notify.platform must be one of: auto, slack, discord, teams, openclaw, webhook

Reference Implementation

See rampart-verify for a complete webhook action implementation:
  • Flask server with /verify endpoint
  • LLM integration (OpenAI, Anthropic, Ollama)
  • Rate limiting and authentication
  • Structured logging
  • Docker deployment

Next Steps

Build docs developers (and LLMs) love