---
title: "AI agent security, permissions and audit log - actionlake"
description: "How actionlake governs AI agents: sealed credentials, scoped keys, caps refused before dispatch, a hash-chained audit log, and what is not yet true."
canonical: https://actionlake.com/trust
updated: 2026-10-26
---

# AI agent security and audit Provable, not promised.

actionlake controls what AI agents can do in your systems with mechanisms you can test: credentials encrypted per tenant and never shown to the agent, keys scoped to a system, an action or read-only, spending caps refused before a request is sent, human approval for chosen actions, and a hash-chained audit ledger sealed daily. Where something is not yet true, this page says so. The machine-readable version is [actionlake-trust.json](https://actionlake.com/.well-known/actionlake-trust.json).

[Bring us your security review](https://actionlake.com/contact?plan=security&from=trust) [Trust document (JSON)](https://actionlake.com/.well-known/actionlake-trust.json)

An engineer reads it. Or inspect it yourself first: [start free](https://actionlake.com/console), 100,000 calls, no card.

- AES-256-GCM on every credential under a per-tenant data key, wrapped
- sha256 chains every run to the one before it chain head sealed to storage daily
- 24h to notify a security incident at most; the DPA summary says so
- 0 endpoints that return a credential to an agent, or to any API caller

What the system enforces

## Mechanisms, not adjectives.

Eight controls. Under each one, the field of the trust document that states it, quoted. Click through: the document is the page, in JSON.

### Sealed on arrival. Unwrapped for one call.

A secret is posted once and encrypted before it is stored: AES-256-GCM under a per-tenant data key, wrapped by a master key (envelope encryption). The agent holds an ActionLake API key, never a vendor token.

[credentials.in_use unwrapped in memory for the length of one upstream call; never logged; never returned by any endpoint; never in a prompt or a model's context](https://actionlake.com/.well-known/actionlake-trust.json)

### Never in a prompt.

There is no AI planner inside actionlake. Your agent writes the plan; actionlake runs it. No model is on the data path, and your traffic trains nothing.

[model_on_data_path false · training_on_customer_traffic: false](https://actionlake.com/.well-known/actionlake-trust.json)

### Refused before it leaves.

Every key carries a cap in calls and only the actions it was minted with. At the cap the request is refused before it is sent, so it costs nothing and nothing moved.

code · api/gate/caps.py a cap on every key, in upstream calls; a child's calls count against every parent; the call is refused before dispatch

### The big ones wait for a yes.

A key's confirm policy and its approval rules name who decides. Under human policy the agent key cannot confirm itself. The run pauses; a person decides; it resumes or ends with nothing sent.

code · api/run/approvals.py a run suspends until a named person decides, in the console or from an emailed signed link

### A ledger that shows its own tampering.

Every run is a row. The chain head per tenant is written to object storage once a day. Change a past row and every hash after it stops matching.

[audit_record.mechanism one row per run in `runs`: tenant, key, action, connection, status, cost, cache verdict, timing; each row stores sha256(prev_hash + row)](https://actionlake.com/.well-known/actionlake-trust.json)

### Bodies on a timer.

Every run's vendor request and response: headers and bodies, connection secrets removed, each body cut at 1 MiB, sealed AES-256-GCM under the tenant's data key, readable by the key that made the run, the root key, or a key granted traces:*.

[traces.retention the plan's trace window, fixed when the run is recorded: 24 hours on Free, 72 hours on Starter, 7 days on Pro, 14 days on Team, 30 days on Business and Enterprise; then deleted](https://actionlake.com/.well-known/actionlake-trust.json)

### One door out.

One module makes every outbound request. Private, loopback and metadata addresses are refused; redirects are re-checked on every hop. A connector cannot be pointed at your network.

[egress.allowed_hosts declared per service file; a request to any other host is refused; redirects re-checked against the same allow list on every hop](https://actionlake.com/.well-known/actionlake-trust.json)

### One region you can name.

Hosted in Sydney, Australia (DigitalOcean syd1). There is no US region yet; data is stored in Australia. In transit through Cloudflare's edge, which terminates TLS. A loss of the region is an outage, not a failover.

[residency.note Stored in syd1. In transit via Cloudflare's edge; approval mail via SendGrid (United States). A loss of the region is an outage, not a failover.](https://actionlake.com/.well-known/actionlake-trust.json)

The record

## Everything it did. And why.

1. Intent
   ### It starts with a reason.
   Every run records the caller's one-sentence intent beside the key, the action and the connection. Not what the agent did only: why it said it was doing it.
2. The vault
   ### The credential is unwrapped for one call.
   AES-256-GCM under a per-tenant data key, wrapped by a master key (envelope encryption). Decrypted in memory for the length of one upstream call, never logged, never returned by any endpoint, never in a prompt or a model's context.
3. Dispatch
   ### One door out, and it is guarded.
   The request goes to a host the connector names, over TLS. Private ranges are refused and every redirect is re-checked. The cap was checked before this point; at the cap, nothing leaves.
4. The receipt
   ### The meter is on the response.
   Calls, cost, cache verdict and timing come back on the response itself, and the same numbers are the row in the ledger. A cached answer is a call that never happened, and costs nothing.
5. The seal
   ### Each row hashes the one before it.
   One row per run in `runs`: tenant, key, action, connection, status, cost, cache verdict, timing; each row stores sha256(prev_hash + row). The chain head per tenant is written to object storage once a day. Every run page shows prev_hash, hash and the hashed fields, so any run can be checked against the one before it.
6. 90 days
   ### The record stays. The reason is kept 90 days.
   Hashes, identifiers, cost and outcome are permanent. The agent's stated reason is cleared after 90 days. Request and response bodies live in the trace store for your plan's window, then are deleted.
   Not yet true: an anchor outside our own infrastructure, and an export of the whole chain for recomputing it yourself. The seal proves the history to anyone who holds a copy; the console's CSV export carries the table, not the hashes. Both are in the honest-status list below.

What is kept, and for how long

## Receipts stay. Bodies are on a timer.

### The ledger.

Identifiers, hashes, costs and outcomes. The agent's stated reason is kept for 90 days. The record of the run is permanent.

### Traces.

Each run's request and response, secrets removed, sealed under your tenant's key in Sydney, for your plan's window, then deleted. Readable only by the key that made the run, the root key, or a key granted `traces:*`.

### The cache.

A cacheable read's response, keyed by your tenant and connection, for the action's declared TTL. A write invalidates the reads it affects. A body over 32 KB is sealed in the bucket instead.

Trace window per plan · from the price book

1. Free 24 hours
2. Starter 72 hours
3. Pro 7 days
4. Team 14 days
5. Business 30 days
6. Enterprise 30 days

Isolation and egress

## Structural, not policy.

The tenant id is on every query and the cache key carries the connection id, so a cache hit can never serve another tenant's answer: by construction, not by review.

**Nothing to probe.**

Another tenant's run, key or connection is answered as if it never existed. The error does not confirm existence. Cross-tenant access is tried in the suite on every endpoint and expected to fail; no third-party test yet.

**Your own address.**

With the Dedicated IP add-on, every request to your vendors leaves from one static address of your own, private to your tenant, in Sydney, and is refused rather than sent from any other address when that one is unavailable.

**Never training data.**

Your traffic trains nothing. That is in the terms, not only on this page. No model sits between your agent and your systems.

The Dedicated IP, drawn: one static address, yours, that your vendors allow-list. HTTPS and the three database protocols leave from it; with the address unavailable, the request is refused.

In progress

## Honest status.

SOC 2 Type II, ISO 27001 and a third-party penetration test are in progress. Until each report or certificate is issued, nothing on this page is an attestation. Every open item below is the trust document's own `absences` list, with what closes it.

1. [service_status.status_url](https://actionlake.com/.well-known/actionlake-trust.json)
   No public status page exists yet.
   publish one at status.actionlake.com, with the cache hit rate and latency split by hit and miss
2. [subprocessors](https://actionlake.com/.well-known/actionlake-trust.json)
   Stripe is not listed because no Stripe account is connected: billing.add_card records a token and the plan change, and no card is charged, so no customer data reaches Stripe from ActionLake.
   list Stripe (card tokenisation and invoicing; card details never touch ActionLake), with notice, before the first charge
3. [audit_record.external_witnesses](https://actionlake.com/.well-known/actionlake-trust.json)
   The daily seal proves the history to anyone who holds a copy, but it is not yet anchored outside ActionLake's own infrastructure.
   publish the chain head to an independent, append-only location under a separate credential
4. [credentials.byok](https://actionlake.com/.well-known/actionlake-trust.json)
   Envelope encryption per tenant under one environment master key is what exists. A customer-held key is not offered.
   a KMS-backed master key, when a customer needs it
5. [certifications.held](https://actionlake.com/.well-known/actionlake-trust.json)
   No certification is held yet. SOC 2 Type II, ISO 27001 and a third-party penetration test are in progress.
   complete each one and list the report or certificate under `held`, with its date and scope
6. [dpa.document_url](https://actionlake.com/.well-known/actionlake-trust.json)
   https://actionlake.com/legal/dpa describes what the DPA commits us to; the signable document is not published.
   publish the DPA and its technical measures annex
7. [disclosure.encrypted_channel](https://actionlake.com/.well-known/actionlake-trust.json)
   No OpenPGP key exists for security@actionlake.com. A published fingerprint for a key nobody holds is worse than none.
   generate the key, publish it, add Encryption to security.txt
8. [credentials.per_connection_key](https://actionlake.com/.well-known/actionlake-trust.json)
   Credentials are sealed under the tenant's data key. Deleting a connection deletes its row, but a backup copy of that row stays decryptable until the backup ages out.
   a per-connection data key, wrapped by the tenant's and destroyed with the row
9. [audit_record.verifiable_by_customer](https://actionlake.com/.well-known/actionlake-trust.json)
   A run can be checked against its neighbour on its page; the whole chain cannot yet be recomputed by a customer, because no export or endpoint returns a range of rows with their hashes.
   a chain export: every hashed field and both hashes, for a range
10. [availability.sla_in_force](https://actionlake.com/.well-known/actionlake-trust.json)
    99.9% is a published availability target for team, business, enterprise, not a commitment with credits. Managed MySQL daily backups with 7 days of point-in-time recovery, kept in the region; a restore to a scratch database is exercised monthly and the chain verified from the seal.
    an SLA written into the agreement, with credits
11. [personnel_access.production](https://actionlake.com/.well-known/actionlake-trust.json)
    No product screen shows your content to anyone outside your tenant. Production access is limited to named ActionLake engineers, for operations; the master key is an environment key on the API service, so those engineers could decrypt customer content. That is the position, stated plainly.
    the KMS-backed master key that also closes credentials.byok
12. [isolation.cross_tenant_access_tested](https://actionlake.com/.well-known/actionlake-trust.json)
    Tenant id on every query; cache key carries the connection id; cross-tenant access is tested in the test suite, on the endpoints; no third-party test yet.
    the third-party penetration test above

Security incidents are notified within 24 hours. Role under the DPA: processor. The DPA summary is at [/legal/dpa](https://actionlake.com/legal/dpa); the signed document is part of the enterprise agreement.

Sub-processors

## Who else sees traffic.

Data is stored in Sydney. In transit it passes through Cloudflare's global edge, which terminates TLS for actionlake.com and the api, mcp, connect and auth hosts. Approval mail goes through SendGrid in the United States. Three names; the full list is also in the [privacy policy](https://actionlake.com/legal#subprocessors).

| Sub-processor | Purpose | Region | Country |
| --- | --- | --- | --- |
| DigitalOcean, LLC | compute, managed MySQL, managed Valkey, object storage (traces, seals, spilled cache bodies), the static site | syd1 | Australia |
| Cloudflare, Inc. | DNS, TLS termination, CDN and WAF for actionlake.com and the api, mcp, connect and auth hosts; sees traffic in transit, including API keys, tokens and credentials posted to connections.create | global | United States |
| Twilio Inc. (SendGrid) | approval mail: the approver's address, the request summary, and the action's input with credential-named keys masked | global | United States |

**Pending:** Stripe is not listed because no Stripe account is connected: billing.add_card records a token and the plan change, and no card is charged, so no customer data reaches Stripe from ActionLake.

Machine-readable

## Your agent can read this page.

Every claim here is a field in one public JSON document, absences included, with no placeholders. Point a procurement agent, or a procurement team, at it before anyone signs anything.

- [actionlake-trust.json](https://actionlake.com/.well-known/actionlake-trust.json) version 6 · 2026-10-24
- [security.txt](https://actionlake.com/.well-known/security.txt) RFC 9116 · policy points at the document
- [/legal/dpa](https://actionlake.com/legal/dpa) the DPA summary · role: processor

```
{
  "document": {
    "version": 6,
    "updated": "2026-10-24"
  },
  "credentials": {
    "at_rest": "AES-256-GCM under a per-tenant data key, wrapped by a master key (envelope encryption)",
    "byok": false
  },
  "model_on_data_path": false,
  "certifications": {
    "held": [],
    "soc2": "in progress (Type II)"
  },
  "residency": {
    "regions": [
      "syd1"
    ],
    "single_region": true
  },
  "availability": {
    "published_sla_pct": "99.9",
    "sla_in_force": false
  },
  "incident_notification_hours": 24,
  "absences": "[ 9 items, each with what closes it ]"
}
```

An excerpt. The document holds 22 top-level fields and 9 named absences.

Disclosure

## Security research, welcome.

An engineer reads every report. Write to [security@actionlake.com](mailto:security@actionlake.com). A sandbox tenant for testing is one unauthenticated call away.

"Good-faith research that follows this policy will not be met with legal action from ActionLake, and we will say so in writing to anyone who asks."

**In scope**

the MCP and REST surfaces, the OAuth 2.1 server, tenant-isolation testing across two identities you own, the egress guard, and tamper attempts on the run ledger

**Out of scope**

- Testing against another customer's data or another customer's connected systems. Ask for a sandbox tenant instead - one unauthenticated call creates one.
- Denial of service and volumetric testing.
- Social engineering of ActionLake people or ActionLake's vendors.
- Findings in a third-party product rather than in ActionLake.

**Window**

90 days to coordinated disclosure.

**Encryption**

No OpenPGP key exists yet; a fingerprint for a key nobody holds is worse than none. Send reports in plain text until security.txt says otherwise.

## Bring us your security review.

[Bring us your security review](https://actionlake.com/contact?plan=security&from=trust) [Read the DPA](https://actionlake.com/legal/dpa) [Start free](https://actionlake.com/console?start=sandbox)

An engineer reads it. The DPA summary is published; the signed document is part of the enterprise agreement.

---

Source: https://actionlake.com/trust
More: https://actionlake.com/llms.txt
