Execution Envelopes
Secure containers that wrap AI agent actions with governance, auditing, and budget controls.
What is an Envelope?
An envelope is the fundamental unit of execution in Fulcrum. Every AI agent action—whether reading a file, calling an API, or generating content—is wrapped in an envelope that provides:
- Policy Enforcement: Rules checked before execution
- Budget Tracking: Cost limits enforced in real-time
- Audit Trail: Complete history of what happened
- State Management: Clear lifecycle from creation to completion
Think of envelopes like a secure transaction wrapper: they ensure every agent action is authorized, budgeted, and recorded.
Why Envelopes Matter
Without governance, AI agents operate as black boxes:
| Problem | Envelope Solution |
|---|---|
| Unauthorized actions | Policy check on every execution |
| Cost overruns | Budget verification before approval |
| No audit trail | Complete event log with timestamps |
| Runaway processes | State machine with terminal states |
| Data breaches | Tenant isolation via RLS |
Envelope Lifecycle
Every envelope follows a defined state machine:
┌─────────────┐
│ PENDING │
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│AUTHORIZED│ │ DENIED │ │CANCELLED │
└────┬─────┘ └──────────┘ └──────────┘
│ (final) (final)
▼
┌──────────┐
│ ACTIVE │
└────┬─────┘
│
┌────┼────┐
▼ ▼
┌──────────┐ ┌──────────┐
│COMPLETED │ │ FAILED │
└──────────┘ └──────────┘
(final) (final)
States Explained
| State | Meaning |
|---|---|
| PENDING | Envelope created, awaiting policy evaluation |
| AUTHORIZED | Policies passed, ready to execute |
| DENIED | Policy violation—action blocked |
| ACTIVE | Currently executing |
| COMPLETED | Finished successfully |
| FAILED | Execution error occurred |
| CANCELLED | Manually stopped or timed out |
How Envelopes Work
1. Creation
When an AI agent wants to perform an action, the SDK creates an envelope:
from fulcrum import FulcrumClient
client = FulcrumClient(host="localhost:50051")
with client.envelope(workflow_id="support-agent") as env:
# Envelope is automatically created and authorized
print(f"Envelope ID: {env.id}")
print(f"Status: {env.status}")
2. Policy Check
Fulcrum evaluates all applicable policies:
- Tool restrictions (e.g., "no bash commands")
- Budget limits (e.g., "max $0.10 per request")
- Rate limits (e.g., "max 60 requests/minute")
- Custom rules (e.g., "require approval for deletions")
3. Execution
If authorized, the envelope moves to ACTIVE:
with client.envelope(workflow_id="support-agent") as env:
if env.guard("send_email", input_text=message):
# Action allowed—proceed
send_email(message)
env.log("email_sent", {"recipient": user.email})
else:
# Action blocked by policy
env.log("action_blocked", {"reason": env.last_denial_reason})
4. Completion
The envelope automatically completes when the context exits:
with client.envelope(workflow_id="support-agent") as env:
# ... do work ...
# Envelope automatically marked COMPLETED
Envelope Data
Each envelope captures rich metadata:
| Field | Description |
|---|---|
envelope_id |
Unique identifier (UUID) |
tenant_id |
Organization that owns this execution |
workflow_id |
Logical grouping (e.g., "support-bot") |
adapter_type |
Integration type (mcp, langchain, sdk) |
budget_id |
Associated budget for cost tracking |
status |
Current state |
metadata |
Custom key-value pairs |
created_at |
When the envelope was created |
updated_at |
Last state transition |
Multi-Tenancy
Envelopes enforce strict tenant isolation using PostgreSQL Row-Level Security:
- Each envelope belongs to exactly one tenant
- Queries automatically filter by tenant
- Cross-tenant access is impossible at the database level
-- RLS policy ensures isolation
CREATE POLICY tenant_isolation ON envelopes
USING (tenant_id = current_setting('fulcrum.current_tenant')::uuid);
Integration Patterns
Python SDK
with client.envelope(workflow_id="my-agent") as env:
# Check before each action
if env.guard("read_file", input_text=filename):
content = read_file(filename)
# Log events for audit
env.log("file_read", {"path": filename})
TypeScript SDK
const envelope = client.envelope({ workflowId: 'my-agent' });
if (await envelope.guard('read_file', filename)) {
const content = await readFile(filename);
}
await envelope.complete();
MCP Integration
When using the Fulcrum MCP server, envelopes are created automatically for each tool call. The MCP server:
- Creates an envelope for the tool invocation
- Evaluates policies for that tool
- Returns ALLOW/DENY to the agent
- Logs the complete execution
Best Practices
- One envelope per logical action - Don't reuse envelopes across unrelated work
- Use workflow IDs - Group related envelopes for easier analysis
- Log meaningful events - Include context that helps with debugging
- Handle denials gracefully - Provide useful feedback when actions are blocked
- Set budget associations - Link envelopes to budgets for cost control
Related Concepts
- Policies - Rules that govern envelope authorization
- Cognitive Layer - AI-powered intent analysis
- Policy Concepts - Policy enforcement and governance
Document Version: 1.0 Last Updated: January 20, 2026