Security
How TroveFiles isolates tenants, what the exec sandbox blocks, and how we handle keys and audit. Last updated May 2026.
The short version
- Each customer is a workspace, sliced into namespaces (typically one per end-user). Files, snapshots, and exec are scoped to a namespace; no shared paths between them.
- /exec has no outbound network. Agents run shell commands inside their namespace but cannot reach the internet, your VPC, or AWS metadata.
- Keys are SHA-256 hashed at rest. Plaintext is shown once at mint time. Webhooks are HMAC-SHA256 signed.
- Every state-changing API call is in the audit log with the API key that produced it.
- Found a vulnerability? Email support@trovefiles.dev.
Tenant isolation
The unit of isolation is the namespace. Get this right and the rest follows.
A workspace is your account; inside it you create namespaces. The recommended pattern is one namespace per end-user — your customer's data lives behind their own boundary.
- Filesystem. Each namespace is its own subtree. Path traversal is rejected at the API layer and at the kernel layer (Linux Landlock).
- Exec. Each
/execcall runs as an ephemeral process scoped to the calling namespace, with a separate UID from the API and kernel-enforced filesystem and network confinement (Landlock + seccomp). - Activity log. Reads are filtered server-side based on the API key's scope — see below.
API key scopes
Three flavors. Pick the smallest one that does the job.
- ✓Mint and revoke keys
- ✓Manage webhooks
- ✓Read events across every namespace
- ✗Read or write file contents (no /exec, no /files)
- ✓Read and write files in any namespace via X-Namespace
- ✓Run /exec in any namespace
- ✓Read events for one explicitly chosen namespace
- ✗Mint or revoke keys
- ✗Enumerate namespaces (events require ?namespace)
- ✓Read and write files in its locked namespace
- ✓Run /exec in its locked namespace
- ✓Read events for its locked namespace only
- ✗Pass X-Namespace pointing anywhere else (403)
- ✗See any other namespace exists
The /exec sandbox
What an agent can and cannot do once it's inside the box.
/exec drops the agent into an ephemeral, kernel-confined process with the namespace mounted at workspace/. Standard Debian base, language runtimes, common CLI tools. What it doesn't have:
| Surface | Status | How |
|---|---|---|
| Outbound network | Blocked | socket() returns EACCES. No DNS, no HTTP, no TCP — not the public internet, not internal infrastructure. |
| Filesystem outside the namespace | Blocked | Linux Landlock confines the shell to the namespace mount. Symlinks pointing out are rejected by the file APIs. |
| Other tenants' files | Isolated | Each namespace is its own subtree on object storage. No shared filesystem path exists between tenants. |
| Other tenants' processes | Isolated | Each /exec invocation runs as a separate process with kernel-enforced filesystem and network confinement (Linux Landlock + seccomp) and a separate UID from the API. Other tenants' files and outbound network are unreachable. |
| Path traversal via API | Blocked | "..", absolute paths, encoded variants, and out-pointing symlinks are rejected identically across cat, get, write, ls, and delete. |
| Shell exec inside the namespace | Allowed | This is the product. 30-second wall-clock cap per call. |
Keys, crypto, storage
Where each piece of sensitive material lives, and what protects it.
| What | How it's protected |
|---|---|
| API keys at rest | Stored as SHA-256 hashes only. Plaintext is shown to you once at mint and discarded — we cannot recover it. |
| API keys in transit | TLS 1.2+ enforced. HTTP is redirected; non-TLS clients are refused. |
| Webhook payloads | Every delivery signed with HMAC-SHA256 over the raw body. Verify with the SDK helper before trusting. |
| Webhook destinations | URLs are validated against private and link-local ranges (loopback, RFC 1918, CGNAT, AWS metadata, IPv4-mapped IPv6) at both registration and delivery. Webhooks pointing at internal infrastructure are refused — you cannot use a webhook to probe our network. |
| Files at rest | Object storage with AES-256 server-side encryption. Snapshots stored in the same bucket with the same encryption. |
| Inter-service traffic | API, runtime, and event store communicate over an isolated private network with TLS — never the public internet. |
Audit log
What's recorded, who can read it, and how to keep it longer.
Every state-changing call writes an event tagged with the namespace and theactor_key_id that produced it. Reads are scoped:
- Namespace-locked keys see only their own namespace's events.
- Unlocked workspace keys must specify a namespace — they can't enumerate the workspace.
- Admin keys can list across namespaces. Use them only from your control plane.
Events are kept 7 days. For longer audit, subscribe a webhook to your own logging system — every payload is HMAC-SHA256 signed.
Where it runs
High-level infrastructure posture.
- Region. United States. Other regions available on request.
- API. Served behind a load balancer with TLS termination. HTTP is refused.
- Exec containers. Isolated per-tenant. Outbound traffic is blocked at multiple enforcement layers — network policy and seccomp.
- Storage. Files and snapshots in encrypted object storage; metadata (keys, events, webhooks) in a separate encrypted database.
- Secrets. Service credentials are managed by a dedicated secrets system, loaded at process start — not in environment variables or config files.
Reporting a vulnerability
Email support@trovefiles.dev with reproduction steps and the workspace ID + key prefix you used. We'll acknowledge within one business day, ship a fix as fast as severity warrants, and credit you when it's out.