Security Middleware for AI Agents - Zero Trust Architecture with JIT Token Vending
Open Claw Guard is a TypeScript library that acts as a security layer between AI agents and their tools. It implements a Zero Trust architecture where the agent never directly holds sensitive credentials - instead, it requests permission and receives ephemeral tokens just-in-time.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ │ │ │ │ │
│ AI Agent │─────▶│ Open Claw Guard │─────▶│ External APIs │
│ (OpenClaw) │ │ (Interceptor) │ │ (Stripe, AWS) │
│ │◀─────│ │◀─────│ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
│
▼
┌───────────────────────┐
│ │
│ Guard Server │
│ (The Brain) │
│ │
│ • Policy Engine │
│ • Content Moderation │
│ • Token Vending │
│ • Audit Logging │
│ │
└───────────────────────┘
- 🛡️ Zero Trust Architecture: Agents never hold master secrets
- ⏱️ JIT Token Vending: Ephemeral credentials that expire in minutes
- 📝 Content Moderation: PII detection, sentiment analysis, offensive content filtering
- 💰 Budget Controls: Daily, hourly, and per-request spending limits
- 🔐 Role-Based Access: Fine-grained authorization for different operations
- 📊 Audit Logging: Complete trail of all decisions and token issuances
- 🔌 One-Line Integration: Wrap your tools with a single command
npm install Open Claw-guardimport { guard } from 'Open Claw-guard';
// 1. Initialize the guard
await guard.init();
// 2. Protect your tools
const protectedTools = guard.protectAll(myToolsList);
// 3. Use them normally - they're secured!
await protectedTools.stripe.charge({ amount: 1000 });Every tool call is converted into a GuardRequest:
interface GuardRequest {
intent: string; // Human-readable intent
toolName: string; // Name of the tool being called
parameters: object; // Arguments to the tool
metadata: {
userId: string;
budgetUsed: number;
userRole?: UserRole;
cost?: number;
};
}The Guard Server responds with a decision:
interface GuardResponse {
decision: 'ALLOW' | 'DENY' | 'FLAG';
jitToken?: JitToken; // Ephemeral credential if allowed
moderationNotes: string; // Explanation of the decision
decisionId: string; // For audit trail
}Just-In-Time tokens are ephemeral credentials:
interface JitToken {
token: string;
type: 'AWS' | 'STRIPE' | 'Open ClawBOOK';
expiresAt: number;
scopes?: string[];
// AWS-specific fields
accessKeyId?: string;
secretAccessKey?: string;
sessionToken?: string;
}import { guard } from 'Open Claw-guard';
await guard.init();
const stripeApi = {
charge: async (params) => { /* ... */ },
refund: async (params) => { /* ... */ },
};
// Wrap with security
const securedStripe = guard.protect(stripeApi, 'financial_policy');
// Set user context
guard.setContext({
userId: 'user_123',
userRole: UserRole.ADMIN,
});
// Use normally - Guard intercepts and validates
await securedStripe.charge({ amount: 1000 });import { Protected } from 'Open Claw-guard';
class PaymentService {
@Protected('financial_policy')
async processPayment(amount: number): Promise<void> {
// Implementation
}
}await guard.init({
policy: {
strictMode: true,
budget: {
dailyLimit: 500,
perRequestLimit: 50,
},
moderation: {
detectPii: true,
analyzeSentiment: true,
minSentimentScore: 0, // Only positive content
},
},
});const awsToken = await guard.vendToken(ServiceType.AWS, {
userId: 'user_123',
toolName: 'deploy_lambda',
intent: 'Deploy new function',
});
// Use the temporary credentials
const s3Client = new S3Client({
credentials: {
accessKeyId: awsToken.accessKeyId!,
secretAccessKey: awsToken.secretAccessKey!,
sessionToken: awsToken.sessionToken!,
},
});- Agent calls
stripe.charge() - SDK Proxy intercepts the call - "Hold on, I need to check this."
- SDK sends payload to Guard Server
- Guard checks:
- Budget? ✓ OK
- Intent? ✓ "Charge User" → Allowed
- Auth? ✓ User is Admin → Allowed
- Guard calls Token Vendor - "Give me a Stripe key."
- Guard replies to SDK - "ALLOW. Here is the key."
- SDK injects key into
stripe.charge()arguments and executes - Agent gets the result, unaware it was moderated
Policies are defined in JSON:
{
"version": "1.0.0",
"strictMode": false,
"budget": {
"dailyLimit": 1000,
"perRequestLimit": 100
},
"moderation": {
"detectPii": true,
"detectOffensive": true,
"analyzeSentiment": true
},
"rules": [
{
"id": "rule-001",
"name": "Block negative posts",
"targetTools": ["post_to_Open Clawbook"],
"conditions": [],
"action": {
"decision": "ALLOW",
"requireModeration": true
}
}
],
"allowlistedTools": ["read_file", "search_web"],
"denylistedTools": ["delete_all", "format_disk"]
}# Guard configuration
Open Claw_GUARD_JWT_SECRET=your-secure-secret
Open Claw_GUARD_API_KEY=your-api-key
# AWS (for JIT token vending)
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
Open Claw_GUARD_AWS_ROLE_ARN=arn:aws:iam::123456789012:role/AgentRole
# Stripe
STRIPE_SECRET_KEY=sk_live_...
# Open Clawbook
Open ClawBOOK_API_KEY=...
Open ClawBOOK_APP_ID=...Initialize the Open Claw Guard system.
Wrap a single tool with security checks.
Wrap multiple tools at once.
Set the current user/session context.
Directly evaluate a GuardRequest.
Vend a JIT token for a service.
Dynamically update the policy.
MIT