Security
Security
Unaudited beta. No third party has audited this code. Probarion runs on NEAR testnet today, with test tokens, and one small mainnet vault holds a little real USDC.
How to report a vulnerability
Send a direct message to @probarionhq on X that says you have a security report, with no details. We answer with a private channel for them.
You can also report it privately on GitHub: open the repository's Security tab and choose Report a vulnerability. Only you and the maintainers see that advisory.
We aim to acknowledge a report within 72 hours. There is no bug bounty. Test only against vaults you deployed yourself, on testnet or in the sandbox, or against the Canary under its rules.
What the contract enforces
- The payee comes from the mandate the owner signed:
spendtakes no address. - Every spend stays inside its mandate's per-payment limit, total, uses and expiry, and the vault's daily backstop.
- A spend above
approval_abovepays only after an approver approves it. - Every owner and approver method except
freezeneeds an attached deposit (exactly 1 yoctoNEAR, or the storage cost forcreate_mandate), so a dapp login key cannot call them. - Any owner key can freeze the vault, with no deposit, and stop every spend at once.
If Probarion itself is breached
An attacker with full control of Probarion's servers can do what the left column says, and still cannot do what the right column says.
| The attacker can | but cannot |
|---|---|
Call spend with stolen agent keys | Pay anyone not named in a mandate |
| Submit fake invoice hashes against open mandates, or skip the owner's Confirm on a waiting invoice | Exceed a mandate's per-payment cap, total cap, uses or expiry, or the vault's daily backstop; a spend above approval_above still waits for an approver |
| Rewrite off-chain history | Hide a rewrite of a range already anchored: the anchored roots and verify expose the first altered entry |
| Stop the service | Lock the owner out of their funds: the owner can freeze, withdraw and revoke keys with their own keys, for example near-cli-rs, without Probarion |
| Use a hijacked owner or approver session, or a function-call key on their account, such as a dapp login key | Approve, withdraw, rotate keys, revoke mandates or unfreeze: each needs exactly 1 yoctoNEAR, which only a full-access key can attach, through a wallet prompt |
What a proof cannot show
- That the TEE hardware is honest.
- That the POA bridge operator releases funds on Base.
- How the Intents Verifier DAO uses its roles.
SECURITY.md lists everything that is not proven yet. (opens in a new tab)
What we rely on
- The NEAR protocol: a function-call key cannot attach a deposit, and a contract controls its own keys.
- NEAR AI Cloud's TEE for the privacy of invoice text. The model only proposes, so it cannot move money.
- NEAR Intents and the POA bridge for payouts to Base, on mainnet.
- Vercel and Supabase for the console being up and for the privacy of off-chain records, not for your funds.
- Your wallet, which shows what it signs, and your care of your full-access keys.
Check a vault yourself
These commands run the probarion package from npm with npx, which asks once before it downloads it. Needs Node 24 or later.
For a vault hosted on Probarion, first download its signed ledger from /proof/<vault>/ledger.jsonl, on the address of its network: a member of the vault can, and anyone can when its proof page is public. Then run this in the folder that holds it, with --network mainnet for a mainnet vault:
npx probarion verify --network testnet --vault <vault> --ledger probarion-<vault>-ledger.jsonlWithout --ledger, the command checks the chain against an empty ledger, and a vault with an anchor fails. The vault's proof page at /proof/<vault> shows the same command for that vault.