
Building wallets for production applications means going beyond key management. Every wallet-powered application eventually runs into the same question: how do you control what transactions are allowed, and under what conditions?
Usually the answer is "write some middleware." A few if-statements in the API layer, a database lookup, maybe a webhook. It works — until it doesn't. The logic is brittle, scattered across services, and invisible to anyone trying to audit what a wallet can actually do.
Today we're shipping programmable wallet controls for Openfort's backend wallets: a structured policy engine that governs every transaction before it's signed and submitted. Think of it as a configurable middleware layer that sits between your application and the signing infrastructure — evaluating every operation against rules you define, at the project or account level.
It turns out this is the piece most wallet infrastructure skips. And it's the piece that matters most once you're in production.
Two layers, one security model

Most wallet providers force a choice. Either your controls live offchain — fast and flexible, but opaque to the blockchain — or they live onchain in a smart contract, where they're verifiable but harder to update. Openfort gives you both, working in parallel.
1. Offchain policies are the new capability. They're evaluated before a transaction ever reaches the signing layer. If a transaction violates a policy — exceeds a spending limit, targets a non-allowlisted contract, attempts a restricted operation — it's rejected before key shares are even assembled. No signature is produced. No gas is spent. The transaction simply doesn't happen.
2. Onchain permissions are the existing capability, enforced by the ERC-4337 smart account itself. Session keys, contract-level restrictions, spending caps enforced by the blockchain, time-locked operations. These are verifiable by anyone, composable across protocols, and upgradeable without key rotation.
The practical difference: offchain policies give you speed and flexibility — you can update rules instantly, apply them across all wallets in a project, and enforce logic that doesn't need to be visible onchain. Onchain permissions give you verifiability and composability — third parties can independently confirm that controls are active and correctly configured.
Together, they create defense in depth. An attacker would need to bypass both layers — the offchain policy engine and the onchain smart contract — to execute an unauthorized transaction.
How offchain policies work
A policy is a set of rules that define what operations a backend wallet is allowed to perform. Each rule specifies an action (accept or reject), an operation type, and the criteria that trigger it.
Policies operate at two scopes:
- Project-level policies apply to every backend wallet in your project. They're your baseline — the default guardrails that every wallet inherits. A project-level policy is evaluated first, before any account-specific rules.
- Account-level policies target individual wallets. They let you override or extend the project defaults for specific use cases — a higher spending limit for a treasury wallet, tighter restrictions for a consumer-facing account, custom allowlists for an AI agent.
The evaluation flow is straightforward: project policy first, then account policy. If a transaction is rejected at either layer, it doesn't proceed.
What you can control
- Spending limits. Set per-transaction value caps, denominated in native tokens or USD. Essential for bounding financial exposure on agent wallets, consumer accounts, or any wallet that shouldn't be able to drain itself in a single call.
- Address allowlists and blocklists. Restrict which destination addresses a wallet can interact with. An allowlist ensures that even if credentials are compromised, the wallet can only send to pre-approved addresses. Blocklists prevent interaction with known malicious or sanctioned addresses.
- Operation restrictions. Control which operations a wallet can perform — signing transactions, sending transactions, signing messages, signing typed data, preparing or sending user operations. You can, for example, allow a wallet to sign messages but prevent it from submitting transactions directly.
- Combined criteria. Rules can combine multiple conditions. A single rule might say: accept transactions with a value under 1 ETH, but only to addresses on this allowlist, and only for the sendTransaction operation. This gives you precise, composable control without sprawling application logic.
Configuring policies
Policies are defined as JSON and can be managed through the Openfort dashboard or the API. A typical policy looks like this:
_33{_33 "scope": "project",_33 "description": "Default spending controls",_33 "rules": [_33 {_33 "action": "accept",_33 "operation": "sendTransaction",_33 "criteria": [_33 {_33 "type": "value",_33 "value": "1000000000000000000",_33 "operator": "<="_33 }_33 ]_33 },_33 {_33 "action": "accept",_33 "operation": "sendTransaction",_33 "criteria": [_33 {_33 "type": "value",_33 "value": "5000000000000000000",_33 "operator": "<="_33 },_33 {_33 "type": "address",_33 "addresses": ["0xTreasuryAddress"],_33 "operator": "in"_33 }_33 ]_33 }_33 ]_33}
This policy accepts any transaction under 1 ETH, and transactions up to 5 ETH if the destination is the treasury address. Everything else is rejected.
What onchain permissions add
Offchain policies handle the fast, flexible layer. But some controls need to be verifiable by the blockchain itself — and by any third party interacting with your wallets.
This is where Openfort's smart account permissions come in. Every backend wallet created through Openfort can be paired with a smart account, and these onchain controls have been available since day one:
- Session keys. Temporary, scoped access tokens that grant limited permissions for a defined period. A game session that can mint items but not transfer tokens. An AI agent that can execute trades within a budget but not withdraw funds. Session keys can be registered via the wallet_grantPermissions method or through the REST API.
- Contract-level restrictions. Restrict which smart contracts and functions a wallet can interact with, enforced by the smart account itself.
- Time-locked operations. Mandatory delays on high-risk operations, giving operators a window to review and cancel before finalization.
- Multi-party approvals. Require multiple parties to authorize sensitive transactions — for example, 2-of-3 approval for withdrawals above a threshold.
- Gas policies. Control when and how you sponsor transaction fees through Openfort's policy engine, with rate limiting and fraud checks.
The key distinction: onchain permissions are transparent and composable. They work across any protocol or dApp that interacts with the smart account, not just transactions routed through Openfort's API. Third parties can verify they're active without trusting anyone's backend.
Built for AI agents
The rise of autonomous AI agents operating onchain creates the sharpest need for layered wallet controls. An AI agent with unrestricted wallet access is a liability. An AI agent with well-defined guardrails is a product.
This is where the two-layer model pays off. For AI agents, you want both:
Offchain policies act as the first line of defense. Before the agent's transaction is even signed, the policy engine checks: is this within the spending limit? Is the destination allowlisted? Is this an operation the agent is permitted to perform? If not, it's rejected instantly — no signature, no gas, no onchain footprint.
Onchain permissions act as the verifiable safety net. Even if an offchain policy is misconfigured or bypassed, the smart account enforces its own rules. Session keys expire. Contract restrictions hold. Spending caps are enforced by the blockchain itself. And crucially, counterparties can verify these constraints independently — which matters when your agent is interacting with third-party protocols in regulated environments.
Openfort provides non-custodial wallets specifically designed for AI agents with programmable guardrails at both layers, verifiable credentials (W3C standard) for KYC compliance and scoped authorization, full audit trails with context on every transaction, and emergency kill switches for high-risk scenarios.
The security model
Programmable controls are only as strong as the infrastructure enforcing them. Openfort's security architecture is designed so that compromising any single layer is insufficient to bypass controls.
Defense in depth across two boundaries. Every transaction passes through two independent enforcement boundaries. The offchain policy engine rejects unauthorized transactions before key shares are assembled. The onchain smart account enforces its own constraints even if a transaction somehow reaches the chain. An attacker would need to compromise both layers simultaneously.
Key sharding. Private keys are split using Shamir Secret Sharing. No single party — including Openfort — holds the complete key. Keys are reconstructed only momentarily within isolated execution environments (TEEs for backend wallets, browser-isolated iframes for embedded wallets) and wiped immediately after signing. Critically, offchain policies are evaluated before key reconstruction begins.
Transaction lifecycle. Every transaction follows a five-stage lifecycle:
- Authentication — Establish the session; step-up auth available for sensitive flows
- Policy evaluation — Evaluate the request against offchain policies (project, then account)
- Key orchestration — Assemble required key shares only after policy approval
- Signing and onchain enforcement — Execute within the security boundary; smart account permissions enforced onchain
- Audit — Log the event with full context for forensics and compliance
A note on open source. Openfort's key management module, OpenSigner, is fully open-source and auditable — four independent security audits by Certik, Omniscia, Cure 53, and Quantstamp cover smart contracts, key management, and account delegation. The offchain policy engine and backend wallet infrastructure are proprietary, operated by Openfort as a managed service. This is a deliberate design choice: the signing and key management layer is open for verification, while the policy enforcement layer is managed to ensure consistent evaluation, rapid updates, and SLA-backed reliability.
How it compares
| Capability | Openfort (offchain + onchain) | Offchain-only enforcement | Application-layer logic |
|---|---|---|---|
| Pre-signing rejection | Yes (offchain policies) | Yes | Custom build |
| Onchain verifiability | Yes (smart account) | No | No |
| Composability | Cross-protocol (onchain) + API-scoped (offchain) | API-specific | App-specific |
| Upgradeability | Instant (offchain) + without key rotation (onchain) | Instant | Code changes |
| Project-wide defaults | Yes | Varies | Custom build |
| AI agent support | Native (both layers) | Limited | Custom build |
Getting started
Programmable wallet controls are available today for all Openfort backend wallets. Onchain permissions remain available across all wallet types — embedded wallets, backend wallets, and global wallets.
The fastest path to production:
- Create a backend wallet with Openfort's API or SDK
- Set a project-level policy — define your baseline spending limits, allowlists, and operation restrictions through the dashboard or API
- Add account-level policies for wallets that need custom rules
- Configure onchain permissions — set session keys, contract restrictions, and approval requirements on the smart account
- Register and monitor — configure alerts and review audit logs
Whether you're powering AI agents, building consumer fintech, or managing treasury operations, the combination of offchain policies and onchain permissions gives you the governance layer your application needs — without compromising on flexibility or verifiability.
