Security
Security model
FYAT is designed so that a compromised agent, a forged request or a replayed signature cannot move more than the mandate allows.
What we defend against
The main risk is an agent that has been tricked, for example by a prompt injection. Because the agent only holds a temporary session key limited by a mandate, the worst it can do is stay inside that mandate until it expires or is revoked.
- The owner's private key is never given to the agent or to the FYAT server.
- Funds sit in a vault address with no private key.
- Cap, budget, target and expiry are set by the owner, not by the agent.
Signed requests
Every request that changes something must be signed by the owner wallet. The signature covers the domain, the wallet, the HTTP method, the path, a hash of the body, a nonce and the time. The server rebuilds this message itself and verifies the signature, so a signature for one request cannot be reused for another.
Requests are read, then authenticated, and only then validated. A caller without a valid signature never reaches validation.
FYAT Agent: authorize this request
Domain: <app host>
Wallet: <owner address>
Request: POST /api/mandates
Body SHA-256: <hash of the body>
Nonce: <32 hex characters>
Issued At: <ISO-8601 UTC time>
Sign only if you started this action on the site above.Replay protection
A signature is accepted only for 5 minutes, with up to 1 minute of tolerance for a client clock that runs ahead. Each nonce can be used once, and the check is a single atomic database insert, so two requests with the same nonce cannot both succeed.
A nonce is stored only after its signature is valid, which stops someone without a key from filling the nonce table.
Server-side rules
The server does not trust the browser for anything that matters.
- The vault is derived from the signing wallet, not taken from the request.
- Expiry is calculated with the server clock.
- Ownership checks for revoking run inside the SQL query.
- Request bodies must match their schema exactly; unknown fields are rejected.
- Unexpected errors return a generic 500 and never expose internals.
Rate limits
Each limit applies per client address and per minute.
- Vault registration: 10 requests.
- Mandate creation: 20 requests.
- Mandate revocation: 30 requests.
- Receipts feed: 60 requests.
Known limits
FYAT Agent is a Devnet prototype and has not been audited. The mandate rules are checked by the Builder and the server today. Enforcement inside the onchain program is the design target and has not shipped, so do not treat the current checks as a substitute for it.
Do not use real funds or a key you care about while the program is not live.
