Custom Tool Security Considerations
Why Security Matters for Custom Tools
Custom Tools can interact with external services, process sensitive data, and execute code. Without proper security practices, they could:
- Expose sensitive credentials like API keys and passwords
- Leak confidential business data
- Allow unauthorized access to your systems
- Execute malicious code
- Compromise user privacy
Your responsibility:
As a tool creator, you're responsible for ensuring your tools are secure and don't put your organization or users at risk.
Protecting Credentials and Secrets
Never Hardcode Sensitive Information
❌ UNSAFE: Hardcoded API key in API action
URL: https://api.example.com/data
Headers:
Key: Authorization
Value: Bearer sk_live_abc123secretkey456def
If you save this tool or share it, anyone with access can see your API key!
✅ SAFE: Use tool inputs for secrets
Tool Input: apiKey (String)
URL: https://api.example.com/data
Headers:
Key: Authorization
Value: Bearer {{apiKey}}
Now the API key is provided at runtime, not stored in the tool.

What to never hardcode:
- API keys and tokens
- Passwords
- Database connection strings
- OAuth secrets
- Private keys
- Internal URLs and endpoints (if sensitive)
- Personal information
- Credit card numbers or payment tokens
Use environment-based secrets when possible
If your platform supports it, use secure secret storage instead of passing secrets as inputs:
- Use your organization's secrets manager
- Leverage platform-provided secure storage
- Rotate secrets regularly
- Audit who has access to secrets
API Security Best Practices
1. Always Use HTTPS
❌ UNSAFE:
URL: http://api.example.com/data
HTTP sends data in plain text. Anyone monitoring the network can see your data and credentials.
✅ SAFE:
URL: https://api.example.com/data
HTTPS encrypts data in transit, protecting it from eavesdropping.
2. Validate API Responses
Don't trust that APIs always return safe data:
async function main() {
const response = ctx.fetchData.responseBody;
// Validate the structure
if (!response || typeof response !== 'object') {
return { error: "Invalid response format" };
}
// Validate expected fields exist
if (!response.userId || !response.email) {
return { error: "Missing required fields" };
}
// Sanitize string data
const email = String(response.email).trim().toLowerCase();
return { userId: response.userId, email: email };
}
3. Set Appropriate Timeouts
Don't let API calls hang forever:
- Default: 30 seconds (usually sufficient)
- Maximum: 300 seconds (5 minutes)
- Use shorter timeouts for fast APIs
- Use longer timeouts only when necessary
4. Handle Rate Limits
Respect API rate limits to avoid being blocked:
- Use Catch Actions to handle 429 (Too Many Requests) responses
- Implement exponential backoff if retrying
- Don't hammer APIs in tight loops
- Consider caching frequently requested data
5. Limit Data Exposure in URLs
❌ UNSAFE:
URL: https://api.example.com/user?ssn={{socialSecurityNumber}}&password={{password}}
URL Parameters can be logged by proxies, firewalls, and the API itself.
✅ SAFE:
URL: https://api.example.com/user
Method: POST
Body:
{
"ssn": "{{socialSecurityNumber}}",
"password": "{{password}}"
}
Send sensitive data in the request body with HTTPS, not in URL parameters.
JavaScript Code Security
1. Never Use eval() or new Function() with User Input
❌ EXTREMELY UNSAFE:
// NEVER DO THIS
const userCode = ctx.userInput;
eval(userCode); // Allows executing arbitrary code!
This allows execution of any code, including malicious code that could compromise your system.
✅ SAFE:
Use fixed code paths and validate inputs:
const operation = ctx.operation; // User provides: "add", "subtract", etc.
if (operation === "add") {
return ctx.a + ctx.b;
} else if (operation === "subtract") {
return ctx.a - ctx.b;
} else {
return { error: "Invalid operation" };
}
2. Validate and Sanitize All Inputs
Never trust that inputs are what you expect:
async function main() {
// Validate type
if (typeof ctx.age !== 'number' || isNaN(ctx.age)) {
return { error: "Age must be a number" };
}
// Validate range
if (ctx.age < 0 || ctx.age > 150) {
return { error: "Age must be between 0 and 150" };
}
// Sanitize strings (remove dangerous characters)
const name = String(ctx.name)
.trim()
.replace(/[<>\"\']/g, '') // Remove HTML/script characters
.substring(0, 100); // Limit length
if (!name) {
return { error: "Name cannot be empty" };
}
return { age: ctx.age, name: name };
}
3. Don't Log Sensitive Data
❌ UNSAFE:
console.log("Full context:", JSON.stringify(ctx));
// Logs might include: passwords, API keys, SSNs, credit cards, etc.
✅ SAFE:
console.log("Processing user:", ctx.userId);
console.log("Operation:", ctx.operationType);
// Only log non-sensitive identifiers
4. Limit Output to Necessary Data
Don't return more information than needed:
❌ UNSAFE:
async function main() {
const user = ctx.fetchUser.responseBody;
return user; // Might include: password hashes, internal IDs, etc.
}
✅ SAFE:
async function main() {
const user = ctx.fetchUser.responseBody;
// Return only what's needed
return {
userId: user.id,
name: user.name,
email: user.email
// Exclude: passwordHash, apiKey, internalMetadata, etc.
};
}
5. Handle Errors Without Exposing Internals
❌ UNSAFE:
async function main() {
try {
return processData();
} catch (error) {
// Exposes internal paths, function names, database details
return { error: error.stack };
}
}
✅ SAFE:
async function main() {
try {
return processData();
} catch (error) {
console.log("Internal error:", error); // Log for debugging
// Return generic message to users
return {
success: false,
message: "An error occurred while processing your request. Please try again."
};
}
}
Data Privacy and Compliance
1. Minimize Data Collection
Principle: Only collect what you need
❌ Bad:
Tool Inputs:
- firstName
- lastName
- phone
- address
- dateOfBirth
- socialSecurityNumber
// Only using email for the actual operation
✅ Good:
Tool Inputs:
// Only collect what's actually needed
2. Don't Store Sensitive Data Unnecessarily
If data doesn't need to persist, don't save it:
- Process and discard sensitive data immediately
- Don't log sensitive information
- Don't cache sensitive responses
- Don't pass sensitive data to tools that don't need it
3. Respect Data Regulations
Be aware of and comply with:
- GDPR (Europe): User data rights, consent, data minimization
- CCPA (California): Consumer privacy rights
- HIPAA (Healthcare): Protected health information
- PCI DSS (Payment cards): Credit card data security
- Your organization's policies: Internal data handling requirements
4. Sanitize Data Before Logging or Display
Remove sensitive patterns before logging:
function sanitizeForLogging(data) {
const sanitized = { ...data };
// Remove sensitive fields
delete sanitized.password;
delete sanitized.apiKey;
delete sanitized.ssn;
delete sanitized.creditCard;
// Mask email (keep first character and domain)
if (sanitized.email) {
sanitized.email = sanitized.email.replace(/(.{1}).*@/, '$1***@');
}
// Mask phone numbers (keep last 4 digits)
if (sanitized.phone) {
sanitized.phone = '***-***-' + sanitized.phone.slice(-4);
}
return sanitized;
}
async function main() {
console.log("Processing:", sanitizeForLogging(ctx));
// Logs: { email: "j***@example.com", phone: "***-***-5678" }
// But use the real data for processing
return processRealData(ctx);
}
Access Control and Sharing
1. Share Tools Selectively
Before sharing a tool, ask:
- Does this tool access sensitive data or systems?
- Should everyone on my team have access?
- Are there any hardcoded values that shouldn't be shared?
- Does this tool comply with our security policies?
Sharing options:
- Private (default): Only you can use the tool
- Shared with specific users: Selected team members can use it
- Public*: Everyone in your organization can use it
*Only admins can make tools Public

2. Review Shared Tools
Before using a tool someone shared with you:
- Review what data it accesses
- Check what external services it calls
- Understand what it does with your inputs
- Verify it comes from a trusted source
3. Audit Tool Usage
If you're managing tools for a team:
- Regularly review who has access to which tools
- Check for tools that haven't been used in a long time
- Look for duplicate tools that should be consolidated
- Monitor error logs for suspicious activity
- Remove access when team members leave
4. Document Required Permissions
In your tool description, note what access is needed:
Tool Name: Fetch Customer Orders
Description: Retrieves order history for a given customer email.
Required Permissions:
- Read access to Orders API
- Customer email from user input
- Valid API key with 'orders:read' scope
Notes:
- Only returns orders from the last 90 days
- Does not expose payment information
Testing for Security Issues
Security Testing Checklist
Before deploying your tool, test for these security issues:
1. Credential Exposure
- [ ] No hardcoded API keys in tool configuration
- [ ] No hardcoded passwords in tool configuration
- [ ] Secrets are passed via tool inputs or secure storage
- [ ] Test results don't display full credentials
2. Data Validation
- [ ] All inputs are validated for type and format
- [ ] String inputs have length limits
- [ ] Numeric inputs have reasonable ranges
- [ ] Enum inputs only allow specified values
- [ ] Unexpected input types don't cause crashes
3. Error Handling
- [ ] Errors don't expose internal system details
- [ ] Error messages are user-friendly, not technical stack traces
- [ ] Catch Actions handle common failure scenarios
- [ ] Errors are logged securely without sensitive data
4. API Security
- [ ] All API calls use HTTPS
- [ ] Authentication headers use input variables, not hardcoded values
- [ ] Timeouts are set appropriately
- [ ] Rate limiting is handled
- [ ] API responses are validated before use
5. Data Privacy
- [ ] Only necessary data is collected
- [ ] Sensitive data is not logged
- [ ] Output doesn't include unnecessary sensitive fields
- [ ] Personal information is handled per regulations
6. Access Control
- [ ] Tool is shared only with appropriate users
- [ ] Tool description documents security requirements
- [ ] Sensitive tools are not made public
Incident Response
If You Discover a Security Issue
If you find a security vulnerability in a tool:
- Stop using the tool immediately
- Don't run it with real data
- Don't share it with others
- Assess the impact
- Was sensitive data exposed?
- Were credentials compromised?
- Who else has access to the tool?
- Fix the vulnerability
- Update the tool configuration
- Remove hardcoded secrets
- Add proper validation
- Test the fix thoroughly
- Rotate compromised credentials
- Change any exposed API keys
- Reset any exposed passwords
- Revoke and regenerate tokens
- Notify affected parties
- Inform your security team
- Notify users who may have been affected
- Document what happened and how it was fixed
- Review other tools
- Check for similar issues in other tools
- Update your tool creation practices
- Share lessons learned with your team
If Credentials Are Compromised
Immediate actions:
- Revoke the compromised credentials in the external service
- Delete or update the tool to remove the credentials
- Generate new credentials
- Update the tool to use the new credentials securely
- Review logs to see if the credentials were used maliciously
- Notify your security team
Security Resources and Best Practices Summary
Quick Security Checklist
Every time you create a tool, verify:
✅ Credentials
- No hardcoded API keys, passwords, or secrets
- Sensitive values use tool inputs or secure storage
- HTTPS is used for all API calls
✅ Code
- No use of eval() or new Function() with user input
- All inputs are validated and sanitized
- Errors don't expose internal system details
✅ Data
- Only necessary data is collected and processed
- Sensitive data is not logged or displayed unnecessarily
- Output includes only what's needed
✅ Access
- Tool is shared appropriately (not over-shared)
- Tool description documents security requirements
- Regular review of who has access
✅ Testing
- Tool tested with invalid inputs
- Error scenarios tested
- Security checklist completed before deployment
Security Principles
- Least Privilege: Only collect and access what's necessary
- Defense in Depth: Multiple layers of security (validation, error handling, access control)
- Fail Secure: When something goes wrong, fail in a secure way (don't expose data)
- Security by Design: Think about security from the start, not as an afterthought
- Assume Breach: Design tools assuming they might be compromised (limit damage)
When in Doubt
If you're unsure whether something is secure:
- Ask your security team before deploying
- Start with more restrictive settings (you can always loosen later)
- Review similar tools to see how others handle security
- Test thoroughly with security in mind
- Document your security decisions for future reference
Remember: Security is not a one-time checkbox. Regularly review your tools, update practices, and stay informed about security best practices.
Updated on: 03/11/2025
Thank you!