Define and enforce permission boundaries with spending caps, rate limits, allowlists, and custom predicates evaluated locally before any action executes.
The policy engine provides local, in-process enforcement of action constraints. Policies are defined as an array of `PolicyRule` objects passed to `Invariance.init()`. When you call `inv.wrap()`, all configured policies are evaluated before the function executes.
Four rule types are available: `maxAmountUsd` caps the dollar value, `allowlist` restricts a field to specific values, `rateLimit` throttles actions per time window, and `custom` lets you write arbitrary predicates. Rules are matched by action name pattern — use `*` for wildcard or `transfer.*` for prefix matching.
Policies use a deny-first model: if ANY rule denies, the action is blocked with a `POLICY_DENIED` error.
Policy evaluation is purely local (no network calls). Rate limit state is held in memory and resets on process restart.
const inv = Invariance.init({
apiKey: 'dev_...', privateKey: '...',
policies: [
{ action: 'transfer', maxAmountUsd: 10000 },
{ action: 'swap', allowlist: { field: 'to', values: ['ETH', 'USDC', 'WBTC'] } },
{ action: 'swap', rateLimit: { max: 5, windowMs: 60000 } },
{ action: '*', custom: () => {
const hour = new Date().getHours();
return hour >= 9 && hour < 17;
}},
],
});interface PolicyRule {
action: string;
maxAmountUsd?: number;
allowlist?: { field: string; values: string[] };
rateLimit?: { max: number; windowMs: number };
custom?: (action: Action) => boolean;
}interface PolicyCheck {
allowed: boolean;
reason?: string;
}const policies = [
{ action: 'transfer', maxAmountUsd: 10000 },
{ action: 'swap', maxAmountUsd: 50000 },
];policies.push(
{ action: 'swap', allowlist: { field: 'to', values: ['ETH', 'USDC', 'WBTC'] } },
{ action: 'transfer', allowlist: { field: 'chain', values: ['ethereum', 'polygon'] } },
);policies.push(
{ action: 'swap', rateLimit: { max: 10, windowMs: 60000 } }, // 10 swaps/min
{ action: 'transfer', rateLimit: { max: 3, windowMs: 300000 } }, // 3 transfers/5min
);policies.push(
{
action: '*',
custom: () => {
const hour = new Date().getUTCHours();
return hour >= 9 && hour < 17; // business hours only
},
},
);
const inv = Invariance.init({
apiKey: 'dev_...', privateKey: '...', policies,
});import { checkPolicies } from '@invariance/sdk';
const result = checkPolicies(policies, {
action: 'swap',
input: { from: 'ETH', to: 'DOGE', amount: '100' },
});
if (!result.allowed) {
console.log('Blocked:', result.reason);
// "Blocked: Value DOGE not in allowlist for field to"
}