Time-Based Policies
Restrict agent transactions to specific hours, days, and timezones. Control when your AI agent can spend money.
Overview
Time-based policies let you control when an AI agent can spend money. Combined with amount limits and merchant restrictions, time windows provide an additional layer of safety by ensuring transactions only occur during supervised periods.
Default: If no time policy is set, transactions are allowed 24/7 UTC. All time comparisons use UTC internally. Timezone offsets are applied before evaluation.
Timezone Handling
All policy times are stored and evaluated in UTC. When you specify a timezone (e.g., America/New_York), Sardis converts the current time to your timezone before checking the policy window.
# IANA timezone names (recommended)
timezone: "America/New_York" # EST/EDT auto-handled
timezone: "Europe/London" # GMT/BST auto-handled
timezone: "Asia/Tokyo" # JST (no DST)
# UTC offset (fixed, no DST adjustment)
timezone: "UTC"
timezone: "UTC-5"
timezone: "UTC+9"DST Handling: When using IANA timezone names (e.g.,
America/New_York), Sardis automatically adjusts for Daylight Saving Time.
Configuration Examples
1. Business Hours Only (Weekdays 9 AM - 5 PM EST)
policy = await client.policies.create(
wallet_id="wallet_abc",
rules={
"time_policy": {
"timezone": "America/New_York",
"allowed_hours": {"start": 9, "end": 17},
"allowed_days": ["mon", "tue", "wed", "thu", "fri"],
},
"max_per_transaction": 100_000_000, # $100
},
)2. Block Weekends
policy = await client.policies.create(
wallet_id="wallet_abc",
rules={
"time_policy": {
"timezone": "UTC",
"allowed_days": ["mon", "tue", "wed", "thu", "fri"],
},
},
)3. Combined: Time + Amount Limits
Different spending limits for business hours vs. after hours:
policy = await client.policies.create(
wallet_id="wallet_abc",
rules={
"time_policy": {
"timezone": "America/New_York",
"schedules": [
{
"days": ["mon", "tue", "wed", "thu", "fri"],
"hours": {"start": 9, "end": 17},
"max_daily": 1000_000_000, # $1,000/day during biz hours
"max_per_transaction": 200_000_000, # $200/tx
},
{
"label": "after_hours",
"hours": {"start": 17, "end": 9},
"max_daily": 100_000_000, # $100/day after hours
"max_per_transaction": 50_000_000, # $50/tx
},
],
},
},
)Natural Language Examples
| Natural Language Input | Parsed Policy |
|---|---|
| "Only allow spending during business hours EST" | {timezone: "America/New_York", hours: {start:9, end:17}, days: ["mon"-"fri"]} |
| "Block all weekend transactions" | {blocked_days: ["sat", "sun"]} |
| "Allow between 6 AM and 10 PM UTC" | {timezone: "UTC", hours: {start:6, end:22}} |
| "$50 limit after hours, $200 during work" | {schedules: [{hours:9-17, max_per_tx:200}, {hours:17-9, max_per_tx:50}]} |
| "Only 9 to 5 Tokyo time on weekdays" | {timezone: "Asia/Tokyo", hours: {start:9, end:17}, days: ["mon"-"fri"]} |
Edge Cases
- Midnight Boundaries -- If
start > end(e.g.,{start: 22, end: 6}), Sardis treats this as an overnight window spanning midnight. - DST Transitions -- During spring-forward, the "lost" hour is treated as outside the window. During fall-back, the repeated hour is evaluated once. Always use IANA names for correct DST handling.
- Multiple Schedules -- When using the
schedulesarray, overlapping windows are evaluated in order. The first matching schedule applies. - No Time Policy Set -- If
time_policyis omitted entirely, transactions are allowed at all times.
Best Practices
- Use IANA timezone names instead of UTC offsets to get automatic DST handling
- Start with business hours until you understand your agent's spending patterns
- Combine with amount limits for defense-in-depth (lower limits outside business hours)
- Monitor blocked transactions to fine-tune your time windows over time
- Consider global teams -- use the timezone of the person responsible for oversight