Documentation Index Fetch the complete documentation index at: https://mintlify.com/plawio/veto/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Communication pack provides guardrails for AI agents that send emails, messages, or notifications. It prevents mass messaging, blocks messages containing credentials, and automatically redacts PII from message outputs.
Use this pack for:
Email automation agents
Customer support chatbots
Marketing automation tools
Notification systems
Messaging integrations (Slack, Teams, SMS)
Complete Policy
version : "1.0"
name : communication-pack
description : Guardrails for email and messaging tools.
rules :
- id : comm-block-mass-recipients
name : Block mass email sends
description : Require approval when sending to more than 5 recipients.
enabled : true
severity : high
action : require_approval
tools :
- send_email
- send_message
- notify
- send_notification
conditions :
- field : arguments.to
operator : length_greater_than
value : 5
- id : comm-block-sensitive-content
name : Block emails containing credentials
description : Block messages that contain password-like or key-like strings.
enabled : true
severity : critical
action : block
tools :
- send_email
- send_message
condition_groups :
- - field : arguments.body
operator : matches
value : '(?:[Pp]assword|[Ss]ecret|[Aa][Pp][Ii][_-]?[Kk]ey|[Tt]oken)\s*[:=]\s*\S+'
- - field : arguments.subject
operator : matches
value : "(?:[Pp]assword|[Cc]redentials|[Ss]ecret)"
output_rules :
- id : comm-redact-pii-in-output
name : Redact PII from messaging outputs
description : Redact phone numbers and emails from messaging tool outputs.
enabled : true
severity : medium
action : redact
tools :
- send_email
- read_email
- get_messages
output_conditions :
- field : output
operator : matches
value : '\\b\\d{3}[-.]?\\d{3}[-.]?\\d{4}\\b'
redact_with : "[REDACTED_PHONE]"
Rules Explained
1. Block Mass Email Sends
Rule ID: comm-block-mass-recipients
What it does: Requires human approval when sending emails/messages to more than 5 recipients.
Why it’s important:
Spam prevention - Stops AI agents from unintentionally spamming users
Reputation protection - Mass emails can get your domain blacklisted
GDPR compliance - Mass communications require consent and privacy notices
Cost control - Prevents expensive bulk sends (especially SMS)
Example:
// This requires approval:
await sendEmail ({
to: [ 'user1@example.com' , 'user2@example.com' , 'user3@example.com' ,
'user4@example.com' , 'user5@example.com' , 'user6@example.com' ],
subject: 'Update' ,
body: 'Important message'
});
// User sees:
// "Approve sending email to 6 recipients?"
// Recipients: user1@..., user2@..., [+4 more]
// Subject: Update
// [Approve] [Reject]
// Meanwhile, individual messages are allowed:
await sendEmail ({
to: [ 'user1@example.com' ],
subject: 'Personal message' ,
body: 'Hello!'
});
// ✓ Executes immediately (1 recipient)
Customizing the threshold:
rules :
- id : comm-block-mass-recipients
conditions :
- field : arguments.to
operator : length_greater_than
value : 100 # Allow up to 100 recipients before requiring approval
2. Block Sensitive Content
Rule ID: comm-block-sensitive-content
What it does: Blocks emails/messages that contain credentials, API keys, passwords, or secrets.
Detection patterns:
In message body:
password: <value>
Password = <value>
secret: <value>
API_KEY: <value>
api-key: <value>
token: <value>
In subject line:
Contains password
Contains credentials
Contains secret
Why it’s important:
Security risk - Credentials should never be sent via email (unencrypted)
Compliance - Violates PCI DSS, SOC 2, HIPAA
Data breach - Email can be intercepted, forwarded, or hacked
Social engineering - AI could be tricked into leaking credentials
Example blocked calls:
// BLOCKED: Password in body
await sendEmail ({
to: 'user@example.com' ,
subject: 'Account Setup' ,
body: 'Your password: abc123xyz'
});
// Error: Message contains credentials
// BLOCKED: API key in body
await sendMessage ({
to: '+1234567890' ,
body: 'API_KEY: sk_live_123abc456def'
});
// Error: Message contains credentials
// BLOCKED: Password in subject
await sendEmail ({
to: 'user@example.com' ,
subject: 'Password Reset' ,
body: 'Click here to reset'
});
// Error: Subject contains sensitive keyword
Safe alternatives:
// ✓ Send a password reset link instead
await sendEmail ({
to: 'user@example.com' ,
subject: 'Reset Your Account' ,
body: 'Click here: https://app.example.com/reset?token=...'
});
// ✓ Use a secure credential sharing tool
await sendEmail ({
to: 'user@example.com' ,
subject: 'Account Access' ,
body: 'Your credentials are available at: https://vault.example.com/share/xyz'
});
Output Redaction Rules
3. Redact PII from Messaging Outputs
Rule ID: comm-redact-pii-in-output
What it does: Automatically redacts phone numbers from tool outputs (sent messages, read emails, fetched messages).
Pattern matched: \b\d{3}[-.]?\d{3}[-.]?\d{4}\b
Matches:
123-456-7890
123.456.7890
1234567890
Why it’s important:
Prevents AI from seeing/storing customer phone numbers
Reduces PII exposure in logs
Helps with GDPR/CCPA compliance
Example:
// Tool returns message content with phone number
const result = await readEmail ({ messageId: '12345' });
// Original: { from: 'user@example.com', body: 'Call me at 555-123-4567' }
// After redaction (what the AI sees):
// { from: 'user@example.com', body: 'Call me at [REDACTED_PHONE]' }
Adding email redaction:
output_rules :
- id : custom-redact-email-in-messages
name : Redact email addresses from message outputs
action : redact
severity : medium
tools :
- read_email
- get_messages
output_conditions :
- field : output
operator : matches
value : '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}'
redact_with : "[REDACTED_EMAIL]"
Usage Example
Basic Setup
version : "1.0"
extends : "@veto/communication"
mode : "strict"
# Configure approval workflow for mass sends
approval :
callbackUrl : "https://your-approval-service.com/approve"
timeout : 60000 # 60 seconds
timeoutBehavior : "block"
With TypeScript SDK
import { Veto } from 'veto-sdk' ;
import nodemailer from 'nodemailer' ;
const veto = await Veto . init ();
const emailTools = [
{
name: 'send_email' ,
description: 'Send an email to one or more recipients' ,
handler : async ({ to , subject , body } : {
to : string [];
subject : string ;
body : string ;
}) => {
const transporter = nodemailer . createTransport ({
host: 'smtp.example.com' ,
port: 587 ,
auth: {
user: process . env . SMTP_USER ,
pass: process . env . SMTP_PASSWORD ,
},
});
const info = await transporter . sendMail ({
from: 'agent@example.com' ,
to: to . join ( ',' ),
subject ,
text: body ,
});
return { messageId: info . messageId , sent: true };
},
},
{
name: 'send_message' ,
description: 'Send an SMS message' ,
handler : async ({ to , body } : { to : string ; body : string }) => {
// Call your SMS API (Twilio, AWS SNS, etc.)
const result = await smsAPI . send ({ to , message: body });
return { messageId: result . id };
},
},
];
const wrappedTools = veto . wrap ( emailTools );
// Use with your AI agent
// Mass sends require approval
// Credentials in messages are blocked
With Slack Integration
import { WebClient } from '@slack/web-api' ;
import { Veto } from 'veto-sdk' ;
const veto = await Veto . init ();
const slack = new WebClient ( process . env . SLACK_BOT_TOKEN );
const slackTools = [
{
name: 'send_message' ,
handler : async ({ to , body } : { to : string []; body : string }) => {
// 'to' is an array of channel IDs or user IDs
const results = await Promise . all (
to . map ( channel =>
slack . chat . postMessage ({ channel , text: body })
)
);
return { sent: results . length , channels: to };
},
},
];
const wrappedTools = veto . wrap ( slackTools );
// Sending to >5 channels requires approval
Customization
Different Limits by Message Type
Allow more recipients for notifications vs. emails:
rules :
- id : comm-block-mass-recipients
# Override for send_email only
tools :
- send_email
conditions :
- field : arguments.to
operator : length_greater_than
value : 5
- id : custom-allow-more-notifications
name : Allow up to 50 notification recipients
action : require_approval
tools :
- notify
- send_notification
conditions :
- field : arguments.to
operator : length_greater_than
value : 50
Block Specific Domains
Prevent sending to competitor domains:
rules :
- id : custom-block-competitor-domains
name : Block emails to competitor domains
action : block
severity : high
tools :
- send_email
conditions :
- field : arguments.to
operator : matches
value : '@(competitor1\\.com|competitor2\\.com)$'
Require Approval for External Emails
Only allow internal emails automatically:
rules :
- id : custom-approve-external-emails
name : Require approval for external emails
action : require_approval
severity : high
tools :
- send_email
conditions :
- field : arguments.to
operator : not_matches
value : '@yourcompany\\.com$'
Add Attachment Protection
Block potentially dangerous attachments:
rules :
- id : custom-block-executable-attachments
name : Block executable attachments
action : block
severity : critical
tools :
- send_email
condition_groups :
- - field : arguments.attachments
operator : contains
value : ".exe"
- - field : arguments.attachments
operator : contains
value : ".bat"
- - field : arguments.attachments
operator : contains
value : ".sh"
Add Unsubscribe Link Requirement
Ensure marketing emails include unsubscribe links:
rules :
- id : custom-require-unsubscribe-link
name : Block marketing emails without unsubscribe link
action : block
severity : high
tools :
- send_email
conditions :
- field : arguments.category
operator : equals
value : marketing
- field : arguments.body
operator : not_contains
value : unsubscribe
Real-World Scenarios
Customer Support Agent
const supportTools = [
{
name: 'send_email' ,
handler : async ({ to , subject , body , ticketId }) => {
// Always single recipient for support
await emailClient . send ({
to: [ to ],
subject: `[Ticket # ${ ticketId } ] ${ subject } ` ,
body ,
replyTo: 'support@example.com' ,
});
return { sent: true };
},
},
{
name: 'read_email' ,
handler : async ({ ticketId }) => {
const messages = await emailClient . getThread ( ticketId );
return { messages };
},
},
];
const wrappedTools = veto . wrap ( supportTools );
// Phone numbers in customer emails are auto-redacted
// Credentials in responses are blocked
Marketing Automation
marketing-automation.yaml
version : "1.0"
extends : "@veto/communication"
rules :
# Require approval for sends over 1000 recipients
- id : comm-block-mass-recipients
conditions :
- field : arguments.to
operator : length_greater_than
value : 1000
# Require unsubscribe link
- id : custom-require-unsubscribe-link
name : Require unsubscribe link in marketing emails
action : block
severity : high
tools :
- send_email
conditions :
- field : arguments.body
operator : not_contains
value : "{{unsubscribe_url}}"
Internal Notification System
internal-notifications.yaml
version : "1.0"
extends : "@veto/communication"
rules :
# Allow more recipients for internal notifications
- id : comm-block-mass-recipients
conditions :
- field : arguments.to
operator : length_greater_than
value : 50 # Up to 50 employees
# Disable credential blocking for internal system messages
- id : comm-block-sensitive-content
enabled : false
Testing
# Test mass recipient block
npx veto-cli guard check \
--tool send_email \
--args '{"to": ["user1@example.com", "user2@example.com", "user3@example.com", "user4@example.com", "user5@example.com", "user6@example.com"], "subject": "Update", "body": "Message"}' \
--json
# Output:
# {
# "action": "require_approval",
# "rule": "comm-block-mass-recipients"
# }
# Test credential blocking
npx veto-cli guard check \
--tool send_email \
--args '{"to": ["user@example.com"], "subject": "Account", "body": "Your password: abc123"}' \
--json
# Output:
# {
# "action": "deny",
# "rule": "comm-block-sensitive-content"
# }
# Test valid single email (should allow)
npx veto-cli guard check \
--tool send_email \
--args '{"to": ["user@example.com"], "subject": "Hello", "body": "How are you?"}' \
--json
# Output:
# {
# "action": "allow"
# }
Email Security Best Practices
Configure email authentication to prevent spoofing: ; SPF record
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
; DMARC record
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"
Rate limit sends per agent session
Implement additional rate limiting beyond recipient count: const veto = await Veto . init ({
budgets: [{
tool: 'send_email' ,
limit: 100 ,
window: 3600 , // 100 emails per hour
}],
});
Log all sent messages for auditing
Keep records for compliance and debugging: const handler = async ({ to , subject , body }) => {
await auditLog . write ({
action: 'email_sent' ,
recipients: to ,
subject ,
timestamp: new Date (),
});
return await emailClient . send ({ to , subject , body });
};
Use templates for consistent formatting
Policy Pack Overview Learn about all available policy packs
Data Access Pack Additional PII redaction for customer data
Output Patterns Reference Built-in regex patterns for PII detection
Human-in-the-Loop Guide Set up approval workflows for mass sends