Policy Templates
Ready-to-use policy templates for common security scenarios.
Starter Template
A minimal policy that denies all actions by default:
Go
package firewall
# Deny by default
default decision = {"result": "deny", "reason": "No matching policy"}
# Add your allow rules below
decision = {"result": "allow"} {
# Example: Allow all GET requests
input.action.operation == "GET"
}Domain Allowlist
Only allow requests to approved domains:
Go
package firewall
default decision = {"result": "deny", "reason": "Domain not in allowlist"}
allowed_domains := [
"api.company.com",
"api.stripe.com",
"api.github.com"
]
decision = {"result": "allow"} {
input.action.tool == "http_proxy"
url := input.action.params.url
domain_allowed(url)
}
domain_allowed(url) {
some domain in allowed_domains
regex.match(sprintf("https?://%s", [domain]), url)
}Read-Only Mode
Allow only read operations, require approval for writes:
Go
package firewall
default decision = {"result": "deny", "reason": "Operation not permitted"}
# Allow all read operations
decision = {"result": "allow"} {
input.action.operation in ["GET", "HEAD", "OPTIONS"]
}
# Require approval for write operations
decision = {"result": "require_approval", "reason": "Write operations need approval"} {
input.action.operation in ["POST", "PUT", "PATCH", "DELETE"]
}Business Hours Only
Restrict actions outside business hours:
Go
package firewall
default decision = {"result": "require_approval", "reason": "Outside business hours"}
decision = {"result": "allow"} {
business_hours
}
business_hours {
hour := time.hour(time.now_ns())
weekday := time.weekday(time.now_ns())
# Monday-Friday, 9 AM - 5 PM
weekday >= 1
weekday <= 5
hour >= 9
hour < 17
}PII Protection
Block actions that may expose personally identifiable information:
Go
package firewall
default decision = {"result": "allow"}
pii_patterns := [
"ssn",
"social_security",
"credit_card",
"password",
"secret"
]
decision = {"result": "deny", "reason": "Potential PII exposure detected"} {
input.action.tool == "http_proxy"
body := json.marshal(input.action.params.body)
lower_body := lower(body)
some pattern in pii_patterns
contains(lower_body, pattern)
}Rate Limiting
Require approval when rate limits are exceeded:
Go
package firewall
default decision = {"result": "allow"}
# Require approval if too many requests in the last hour
decision = {"result": "require_approval", "reason": reason} {
input.context.request_count_1h > 100
reason := sprintf("Rate limit exceeded: %d requests in last hour", [input.context.request_count_1h])
}
# Hard deny if way over limit
decision = {"result": "deny", "reason": "Rate limit critically exceeded"} {
input.context.request_count_1h > 500
}Environment-Based
Different rules for production vs. development:
Go
package firewall
default decision = {"result": "deny", "reason": "Environment not configured"}
# Development: allow most actions
decision = {"result": "allow"} {
input.context.environment == "development"
input.action.operation in ["GET", "POST", "PUT", "DELETE"]
}
# Staging: require approval for writes
decision = {"result": "allow"} {
input.context.environment == "staging"
input.action.operation in ["GET", "HEAD"]
}
decision = {"result": "require_approval", "reason": "Staging write requires approval"} {
input.context.environment == "staging"
input.action.operation in ["POST", "PUT", "DELETE"]
}
# Production: strict controls
decision = {"result": "require_approval", "reason": "Production action requires approval"} {
input.context.environment == "production"
}Combined Template
A comprehensive policy combining multiple patterns:
Go
package firewall
default decision = {"result": "deny", "reason": "No matching policy"}
# 1. Block dangerous patterns first
decision = {"result": "deny", "reason": "Blocked domain"} {
blocked_domain(input.action.params.url)
}
# 2. Allow safe read operations
decision = {"result": "allow"} {
input.action.operation in ["GET", "HEAD"]
safe_domain(input.action.params.url)
}
# 3. Require approval for writes
decision = {"result": "require_approval", "reason": "Write operation"} {
input.action.operation in ["POST", "PUT", "PATCH", "DELETE"]
safe_domain(input.action.params.url)
}
# Helper functions
blocked_domains := ["malicious.com", "untrusted.io"]
blocked_domain(url) {
some domain in blocked_domains
contains(url, domain)
}
safe_domains := ["api.company.com", "internal.company.com"]
safe_domain(url) {
some domain in safe_domains
contains(url, domain)
}