Agined security whitepaper
How a catalogued action call is governed and evidenced, where data lives, how receipts are signed and verified offline, and how we run keys, access, incidents and disclosure. Written from Agined's legal documents and runtime, with the source of each statement.
Operated by Avonao, Inc.Legal documents are the binding textNo certification is claimed
Scope and how to read this paper.
Agined is a catalogue of agent actions with policy, human approval, metering and hash-chained evidence that can be verified offline. It also includes Attestor (signed receipts), the Agentic API and ActionFlow.
This paper describes the controls around a call to a catalogued action and the evidence it leaves. It summarises the Data Processing Addendum (Annex 2 is the binding list of technical and organisational measures), the key management policy, the Receipt Practice Statement, the continuity commitment and the sub-processor list, and it reads the gateway's own code for the order in which a call is checked.
Where a control is best-effort rather than a hard gate, the paper says so. Where the documents do not state something, the paper does not either.
Architecture and data flow of a catalogued action call.
A tenant publishes its actions as a catalogue on its own host. Agents call them over REST or over MCP. Both transports go through one gated execution path, so the choice of transport cannot skip a check.
At the platform's gateway, each request first meets a fixed chain of gating steps, stopping at the first refusal: site gate, replay defence, authentication, token binding, workspace context, IP allow-list, idempotency, rate limit, kill switch, permission, mandate, confirmation, intent claim and input validation. The audit write runs on every path, success or refusal, and if the audit write fails the response is a 503 whatever the handler did.
On the tenant's host, the gated path runs these stages in order.
| Stage | What it does | If it cannot decide |
|---|---|---|
| Token scope | A credential whose scope does not cover the action is refused before anything else. | Refuses |
| Idempotency | A repeated call with the same key is answered from the recorded response, not executed twice. | Refuses or replays |
| Kill switch | The tenant can switch off one caller, one action, one domain or its whole surface. The caller's own switch is read first. | Refuses |
| Policy | The tenant's published policy is evaluated for this caller and action. A rule can permit or forbid the call. | A refusal is recorded |
| Mandate | For an action that needs one, a signed mandate is verified (signature, revocation, scope) and its spend ceiling is respected. | Fails closed |
| Access and pricing | Who may call, and what the call costs the caller, including a verified payment where the action is paid. | Fails open on a pricing-table outage, by design; the meter still records the call |
| Human approval | An action set to always ask is refused with an approval handle; it runs only after a person has answered. A live breaker can raise an action to this level, never lower it. | Fails closed |
| Rate, quota, ceilings | Per-minute rate, daily and monthly call caps, the plan's allowance of production actors and the per-actor monetary ceiling are applied before the upstream is touched. A quarantined counterparty is refused. | Counters are a guard rail; they under-count rather than over-charge |
| Execution | The tenant's own backend is called once every gate has passed. | |
| Metering | Every successful execution is metered, not only priced ones, together with a per-call trace and an outcome tally. | Best-effort: a lost meter event never fails the request, and is logged for alerting |
| Evidence | The call, including refusals, is appended as a fact on the tenant's hash chain and the response carries a proof URL only when that fact was written. | The proof URL is withheld rather than promised |
Human approval and policy.
The approval gate decides before an action runs, never after.
- A call to an action that needs a person is refused with an approval handle. Nothing is executed and asked about afterwards. If an approval cannot be created or stored, the call is refused too.
- Approvals are announced in the background. The attempt, accepted or not, is written onto the approval, so an approval that never reached anyone does not look like one somebody ignored.
- A person can answer from the tenant portal without an account. The link is bound to one workspace, one approval, one approver and one deadline, and whether that person may decide is checked at decision time against the stored approver list. Opening the link changes nothing; only the decision does.
- A confirmation token is burned atomically before dispatch, so two requests with the same token cannot both run.
- A policy can read passport conditions only when its compiled rules ask for one, and an absent passport fails every passport floor.
- An autonomous confirmation on an agent's own authority is honoured only under an active autonomy grant whose ceiling covers the action's safety level, and is audited as autonomous. A mandate-policy action can never be confirmed that way.
Tenant isolation and data regions.
The gateway, not the caller, decides the workspace. Separation is logical, by workspace id on every query, with a regional database that only its own region's service reads.
The gateway forwards the workspace to the regional service in headers covered by a signature that only Agined's services can produce, and the service rejects a request without a valid one. A call is never answered from another region. A workspace stays in the region in which it was created.
Agined stores workspace data in one of seven Cloudflare regions, chosen when the workspace is created on paid plans. The Free plan is US West.
| Region | Code | Jurisdiction |
|---|---|---|
| US East | enam | Placed by location hint |
| US West | wnam | Placed by location hint |
| Europe Central | weur-1 | Stored under Cloudflare's EU jurisdiction (enforced) |
| Europe West | weur-2 | Stored under Cloudflare's EU jurisdiction (enforced) |
| Europe North | neur | Stored under Cloudflare's EU jurisdiction (enforced) |
| Asia-Pacific | apac | Placed by location hint |
| Oceania | oc | Placed by location hint |
Where workspace data is stored, by plan.
The Free, Starter, Pro, Pro+ and Team plans keep their data under Cloudflare. In the three European regions it is stored under Cloudflare's EU jurisdiction, so it stays in the EU and Cloudflare chooses the datacenter. In other regions a location hint is a placement request, not a guarantee, and Cloudflare receives each connection at the location nearest the caller.
| Plan | Receipts and workspace data are stored in |
|---|---|
| Free and Starter | The region's shared Cloudflare D1 database, with every query keyed by workspace id. |
| Pro, Pro+ and Team | The workspace's own separate store on Cloudflare, one per workspace, in the workspace's region. |
| Scale, Enterprise and the isolation add-on | The workspace's own Amazon Aurora database on Amazon Web Services, in the AWS region the workspace chose. Existing receipts move there when a workspace moves to one of these plans. |
Evidence: receipt signing, the hash chain and offline verification.
Evidence is built so that it can be checked without Agined, and so that removing a record from the middle of a chain is detectable.
- A receipt is a JSON object signed with pure Ed25519 (RFC 8032) over its RFC 8785 canonical bytes. It names its signing key inside the signed bytes. The service checks the signature against the public key before it returns the receipt.
- Receipts live in a table whose database triggers refuse updates and deletes; deletion passes only through audited routes (the customer's own deletion, a redaction or the retention job).
- Chained records name the previous receipt and the hash of its body. Each audit entry hash is the SHA-256 of the canonical entry core joined with the previous entry's hash, per workspace, starting from a genesis value, with a unique constraint on the sequence number.
- On the Scale and Enterprise plans and with the isolation add-on, the hash of each receipt is filed hourly, in batches of at most 2,000, as a row in the workspace's own Aurora database under a Merkle root signed with the region's receipt key. Database triggers refuse any change to that copy, and refuse deleting it before seven years have passed from the end of the hour it was filed in.
- There is no third-party timestamp authority on receipts. The signed time is the clock of the Cloudflare Worker that signed.
- A dispute packet for a call can be checked on the tenant host's verify page. The page says that a check run on our own server is not independent, shows the key ids in the packet beside the keys the host publishes right now, and gives a command to check the file independently.
How anyone verifies, offline.
Verification needs no account, no API key and no permission.
Ways to run it: the /verify page (the check runs in your browser), the @agined/verify package on npm, your own code in any language with Ed25519 and a JCS library, or the verify.mjs script inside every receipt export, which runs on Node.js 18 or later with no dependencies and no network. Pin the key's kid and x and keep the key set next to the receipt, and the pair verifies years later without us.
A valid signature proves origin, integrity and a signed time. It does not prove that a reported fact is true, who approved the content, or the real time of an event beyond Agined's own clock. The Receipt Practice Statement lists what you still trust Agined for.
Ed25519 is the only signature on receipts today. No receipt carries a post-quantum signature; receipts name their key inside the signed bytes so that a new algorithm can be added under new key ids without breaking old receipts, and the published path to ML-DSA is on the post-quantum page.
| Step | What the verifier does |
|---|---|
| 1. Remove the signature | Drop the receipt's signature member. |
| 2. Canonicalize | Serialize the rest as RFC 8785 canonical JSON: keys sorted, no whitespace, UTF-8. |
| 3. Find the key | Take the published key whose kid equals the receipt's signatureKeyId. |
| 4. Check the signature | Verify the Ed25519 signature, decoded from base64url, over the canonical bytes. |
Key management.
One Ed25519 signing key per data region, seven in all, shared by all workspaces in that region.
| Topic | Position |
|---|---|
| Custody | Encrypted Cloudflare Worker secrets, one per region. Only the receipt service uses them. No API route returns private key material. |
| Fallback | None. If a region's key is not configured, calls fail with 503 signing_unprovisioned; if it cannot be used, with 503 signer_unavailable. No receipt is signed by another region's key or returned unsigned. |
| Key ids | The first 16 bytes of the SHA-256 of the raw public key, base64url, 22 characters, so anyone can recompute it. |
| Publication | A JWK set at api.agined.com, cacheable for one hour and open to any origin, with the region of each key; agined.com/.well-known/tools-keys.json redirects to it. |
| Rotation | A manual key ceremony run by Agined; no automatic rotation and no schedule. No production signing key has been rotated so far. Workspace owners and admins can record a rotation request, which does not rotate anything by itself. |
| Retired keys | Stay in the published set for as long as receipts they signed can be relied on. This is policy; the endpoint does not enforce it, which is why pinning is advised. |
| Compromise | No automated response, no revocation list and no revocation of single receipts. A suspected compromise is handled as a security incident: stop signing, move the region to a new key, publish a notice naming the key id, email the affected workspace owners, and decide whether the key stays published. |
| Custody limit | Encrypted secrets limit who can read a key. They do not stop whoever can deploy the receipt service from causing it to sign, which is why the Receipt Practice Statement keeps observed and reported facts apart. |
Access control and the audit log.
Every request is tied to a workspace before any action code runs.
- API keys, personal access tokens and session tokens are stored only as SHA-256 hashes, and secrets are compared in constant time.
- Keys can be scoped to read, write or manage groups and to specific tools, can expire, be rotated with a grace period, or be revoked with effect on the next request. Tokens can be bound to an IP range.
- The service holds no passwords and no sign-in methods. Sign-up and sign-in happen at Avonao ID, which sends the service OpenID Connect claims.
- Dashboard sessions are HttpOnly, Secure and SameSite=Lax, with a 12-hour absolute lifetime and a 30-minute idle timeout.
- Organisation and workspace roles limit who can manage keys, members, billing and data. Each action declares the permissions it needs, and the gateway checks them before dispatch.
- Access to production systems and secrets is limited to the personnel who deploy and operate the service, who are bound by confidentiality. Support staff cannot open a session as a customer; they see a workspace only through time-limited access the customer grants, and each such session is recorded in the workspace's audit log.
- Security-relevant events (sign-ins, key and role changes, denied access, receipt deletion and redaction, support sessions) go to an append-only audit log with the source IP address and user agent. Workspace admins read their workspace's audit log in the dashboard. The audit log is kept through erasure, with a person's identifier replaced where erasure is required.
- Outbound requests are checked by a filter that refuses non-HTTP schemes, localhost, internal-looking names and private and reserved IP ranges, at submission and again when a scheduled check runs. Relay and webhook tools never follow redirects; capture and watch tools follow a bounded number and check every hop. Agined does not describe the filter as a complete defence.
- Per-IP and per-account rate limits apply at the gateway and on public endpoints. The free test key is restricted, and runtime detection on agent calls raises flags for review by a person.
Encryption and data protection.
- Traffic between you and the service uses TLS.
- Data at rest in Cloudflare D1 is encrypted by Cloudflare with AES-256, as Cloudflare documents.
- Third-party credentials and webhook secrets stored with a tool are additionally sealed with AES-256-GCM, bound to your workspace and the endpoint, and are never returned or written to a receipt.
- Tools that receive content to attest store its hash, not the content. Relayed request and response bodies are not stored in receipts, and not stored at all unless you turn on body retention.
- People in record chains are identified by an HMAC of their identifier keyed with a per-workspace salt; the identifier itself is not stored.
- Receipts are kept for the plan's window (Free 7 days, Starter 30, Pro 90, Pro+ 180, Team 365, Scale 730; Enterprise by contract) and you can shorten it, delete or redact earlier. Deleting an account starts a 30-day grace period with nothing erased, after which workspace data is erased. Exports are available at any time at no charge.
Availability, recovery and continuity.
- The service runs on Cloudflare's distributed platform with a database per data region. Every Cloudflare D1 database can be restored to any minute of the last 30 days with D1 Time Travel; Agined keeps no other backup copy of them.
- Deployments are versioned and can be rolled back without touching data.
- The status page checks each component every minute and keeps the history. Enterprise customers have a 99.9% monthly uptime commitment with service credits; self-serve plans have no uptime commitment.
- Receipts you hold stay verifiable with the published public keys whether or not the service is available.
- If Agined winds the service down, it gives at least 30 days' notice, keeps exports working for the notice period, publishes the final key set in a place that does not depend on its own infrastructure, and stops signing before it stops publishing. There is no third-party escrow of keys or source code today.
Incident and breach notice.
- Personal data breach: the account owner is told by email without undue delay and in any case within 72 hours of Agined becoming aware, with the nature of the breach, the likely consequences, the measures taken and a contact point, in phases if not everything is known at once (DPA section 8).
- Where you are the controller, notices to authorities and data subjects are yours; Agined gives you the information it holds that you reasonably need.
- Pings, port scans, refused sign-in attempts and denial-of-service attempts that expose no data are not personal data breaches under the DPA.
- Incidents are published on the status page while they happen and kept in its history. A suspected signing-key compromise is reported to security@agined.com and handled as described under key management.
Sub-processors.
The sub-processors page is the authoritative list, with each provider's purpose, location, personal data involved and safeguards. It is Annex 3 of the DPA.
- Cloudflare, Inc.: hosting, compute, databases, storage, CDN, DNS, email delivery.
- Amazon Web Services: Amazon Aurora for workspaces on Scale, Enterprise or the isolation add-on, in the region the workspace chose.
- Avonao Billing (operated by Avonao, Inc.) with Stripe as merchant of record: billing and payments. Agined never receives card numbers.
- Anthropic, PBC: the assistant on the website and in the dashboard and the support assistant. The dashboard assistant reads workspace records only for workspaces in the US data regions. OpenAI, Google (Gemini) and Mistral AI are failover models used only when configured.
- Resend (fallback email) and Twilio (text-message approvals, voice calls for severity-1 escalations and phone verification codes).
- Google Analytics and Adobe Fonts load only after you allow them.
- Avonao ID is the sole identity provider and an independent controller for the account data it holds.
- Notice: at least 30 days before a new sub-processor starts, owners of every workspace are emailed and the page is updated. You may object on reasonable data protection grounds, and if the objection cannot be met you may terminate the affected service with a refund of unused prepaid fees. Transfers rely on the Standard Contractual Clauses, the UK Addendum and the Swiss adaptations.
Compliance posture.
Nothing here claims a certification Agined does not hold. This paper does not claim one.
| Item | State | Where |
|---|---|---|
| Data Processing Addendum | In place: part of the Terms, applies on acceptance | /legal/data-processing-addendum |
| Standard Contractual Clauses | In place: covered in the DPA, with the UK Addendum | /legal/data-processing-addendum |
| Company details and EU representative | In place | /legal/imprint |
| Sub-processor list, with notice | In place | /legal/subprocessors |
| Privacy rights and opt-out | In place | /opt-out |
| Security questionnaire and customer audit | On request, on the terms of DPA section 9 | /trust/security-pack/questionnaire |
| EU AI Act, Data Act and Digital Services Act pages | Published | /legal/eu-ai-act /legal/data-act /legal/digital-services-act |
| Bug bounty | Not offered | /legal/responsible-disclosure |
Responsible disclosure.
Report through the form or at security@agined.com. A report can be anonymous.
Research done in good faith under the policy is covered by a safe harbor. We ask for 90 days before public disclosure, by agreement. There is no bug bounty; reporters are credited by name or handle if they wish. These are targets, not guarantees.
Report a vulnerability
The form accepts anonymous reports.
Report →Disclosure policy
Scope, rules for research, safe harbor and what to expect.
Read the policy →| Step | Target |
|---|---|
| Acknowledge your report | Within 3 business days |
| Initial assessment and severity | Within 10 business days |
| Updates while the issue is open | At least every 14 days |
| Fix or mitigation, critical and high severity | We aim for 30 days |
| Fix, lower severity | We aim for 90 days |