What we protect, and what we don't.
An honest accounting of Veto's security posture. We list what's strong, what's still maturing, and how to report a bug.
The on-chain enforcement contract VetoGuardedAccount on Base is currently unaudited. We're scoping an external audit before mainnet. Until then, the CLI gates Mainnet-Beta deploys behind a typed-phrase acknowledgment ("i understand unaudited"). Don't put more on the contract than you can afford to lose.
What's strong today
- Engine isolation. Eight risk stages — precheck, policy, prompt-injection, merchant fraud (typosquat), crypto safety (OFAC live feed, drainer index, address poisoning), intent verification (LLM-as-judge), anomaly, behavioral baseline, aggregate verdict. A bug in one stage doesn't bypass the others.
- Receipts are signed and verifiable offline. Every decision (allow / deny / escalate) is signed Ed25519. The public key is at
/.well-known/jwks.json. Anyone can verify a Veto decision happened — Veto doesn't need to be online. - Mandate domain separation. The on-chain mandate is bound to
(chain, contract, jti, exp, recipient, amount, token)via EIP-712 on EVM andkeccak("VetoMandate:v1" || vault || …)on Solana. A mandate signed for one vault cannot be replayed against another. - Single-use mandates. Each mandate has a unique
jti; the contract creates a per-jti PDA on EVM (and equivalent on Solana). A second use of the same jti revertsMandateAlreadySpent(). - Open-source primitives. The CLI, SDK, contracts, verifier, MCP server, and our own policy file are MIT-licensed on veto-protocol. Anyone can read the threat model.
What's still maturing
- Anomaly + behavioral baselines. Statistical detectors that depend on traffic volume. They're live but quiet — they need real spend data to be useful. Today they catch obvious outliers; the long tail comes online as we have more agents in flight.
- External audit of the smart contract. Pending. v2 ships post-audit.
- SOC 2. We've not yet undergone third-party audit. We'll publish the report when we do.
- Token-2022 extensions on Solana. Current scope is classic SPL. Transfer hooks and fee config aren't covered yet.
- Multi-key Veto signer. Today the Veto signer is a single Ed25519 key (with rotation). v2 ships multisig.
Threat model snapshot
Covered
Replay across vaults · replay of the same mandate · mutated mandate fields · spend over the cap · spend after expiry · wrong recipient · wrong token mint · OFAC-sanctioned addresses · canonical merchant typosquats
Not covered (yet)
External audit · SPL token-2022 extensions · multi-key Veto signer · MEV/leader-schedule front-running on Solana (partial: jti single-use + exp window) · novel attack patterns we haven't seen yet
Operational security
- TLS everywhere in transit (Let's Encrypt). HTTP→HTTPS redirect at the edge.
- Encryption at rest for the database and signing-key material.
- Least privilege for internal access; production access is keypair-based, no shared passwords.
- API keys are hashed at rest. Lost-key rotation is one CLI command away.
- Secrets are not committed to git, anywhere. We use a managed env-var path on the application server.
Responsible disclosure
If you think you've found a security issue:
- Email tomer@veto-ai.com with the subject
SECURITY:and a clear write-up. - We respond within one business day.
- Please don't disclose publicly until we've had a chance to fix and ship.
- If you'd like to be credited in the disclosure, say so. We'll publish your name (or handle) when we patch.
- A formal bug bounty program is on the roadmap; until then we offer thanks, credit, and (for high-severity findings) a manual reward.
Where to look
- veto-protocol/contracts — Solidity source + threat model
- veto-protocol/solana-program — Rust/Anchor source + sysvar verification
- veto-protocol/mandate-verifier — pure-TS receipt verifier
- veto-protocol/veto-policies — our own policy file, in the open
- /.well-known/jwks.json — public Ed25519 verification key