# Security

How `TaskCloud` isolates sandboxes, protects access, and handles your data. Report vulnerabilities to `security@task.cloud`.

> We do **not** hold SOC 2 or other certifications today. SOC 2 is planned for year 2. This page describes how the platform is built, not an audited attestation.

## Isolation model

Every sandbox is a separate **Firecracker microVM** with its own Linux kernel. The security boundary is the VM, not a container.

- **Firecracker jailer:** each VMM process runs chrooted, unprivileged, with a seccomp filter.
- **cgroups:** CPU, memory and I/O are limited per VM.
- **Network namespace per VM:** each sandbox has its own tap device and namespace. Sandboxes cannot reach each other, the host, or our internal APIs.
- **Forks** get their own IP, network namespace and copy-on-write disk. A change in a fork never affects the source.
- Inside the sandbox you have root (`user` has passwordless sudo). Treat everything inside one sandbox as one trust domain. **Give each end user their own sandbox.**

## API keys and scopes

Authenticate with `Authorization: Bearer taskcloud_sk_...`. Keys are shown once, stored hashed, expire after 90 days by default (max 365 days or never), and can be rotated with a grace period (`POST /api-keys/{id}/rotate`).

| Scope | Allows |
| --- | --- |
| `sandboxes:read` / `sandboxes:write` | Read / create, update, pause, resume, fork, delete sandboxes; manage ports |
| `exec` | Commands and PTY sessions |
| `files:read` / `files:write` | File access |
| `ssh` | SSH access and account SSH keys |
| `desktop` | Desktop stream URLs, screenshots, input |
| `snapshots:read` / `snapshots:write` | Snapshots |
| `templates:read` / `templates:write` | Templates |
| `webhooks:manage` | Webhook endpoints |
| `usage:read` | Usage and limits |
| `account:read` / `account:manage` | Account and spend limit |
| `api_keys:manage` | Create, rotate, revoke keys |

Presets: `read-only`, `full-sandbox`, `ci`, `admin`. A key can never create a key with more scopes than it has. A missing scope returns `403 insufficient_scope` with `details.required_scopes`.

### Least privilege for platforms

If your product hands sandboxes to end users or to an agent, never ship an `admin` key. Create a key restricted to that user's sandboxes:

```bash
curl -sS -X POST https://api.task.cloud/v1/api-keys \
  -H "Authorization: Bearer $TASKCLOUD_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"user-42","preset":"full-sandbox","restrict":{"labels":{"user":"42"}},"expires_in_days":30}'
```

Sandboxes created with that key automatically get the label `user=42`, and the key cannot see any other sandbox.

## Access to sandbox endpoints

| Surface | Protection |
| --- | --- |
| Domain separation | Sandbox URLs (ports, desktop, SSH) use `taskhost.cloud`, a separate domain from `task.cloud` (website and API), submitted to the Public Suffix List. A sandbox app is never same-site with the API and cannot set cookies for `task.cloud`. |
| Port URLs `https://<short_id>-<port>.taskhost.cloud` | `private` (default): requires an access token (`X-Sandbox-Token` header or `sandbox_token` query) or an API key. `public`: open to anyone with the URL. |
| Desktop stream | Signed URL with TTL (default 10 minutes), optional `read_only` and `single_use`, revocable. The VNC port is never exposed without a token. |
| PTY WebSocket | Signed URL valid 60 s until first connect. |
| Signed file URLs | Single file, 60–3,600 s. |
| SSH | Gateway `ssh.taskhost.cloud`, public-key auth (account keys or per-request keys with TTL) or a one-time password. |

Give browsers short-lived **access tokens** (`POST /sandboxes/{id}/access-tokens`) instead of API keys.

## Network

- **Inbound:** blocked except through our edge (exposed ports, desktop, SSH gateway). All edge traffic uses TLS.
- **Outbound:** open by default. A per-sandbox **egress allowlist** is **Coming soon**.
- Mining, spam, scanning and other abuse are prohibited and detected automatically; offending sandboxes are paused and the account may be suspended.

## Data

- **Location:** EU only. Sandboxes, disks and snapshots run and are stored on dedicated servers in the EU (machines we operate ourselves and machines rented from an EU hosting provider).
- **Encryption:** TLS in transit. Snapshots and disks are stored on our dedicated servers; encryption at rest details will be published before general availability.
- **Snapshots contain memory.** A pause snapshot or named snapshot includes everything in RAM: environment variables, tokens, decrypted secrets. Keep that in mind before turning a snapshot into a template you share or fork for other users.
- `env` and `registry_auth` values are write-only and never returned by the API.
- **Deletion:** `DELETE /sandboxes/{id}` removes the disk and the pause snapshot. Named snapshots and templates are deleted separately. Snapshots kept in object storage are encrypted with a per-organization key; when an organization is deleted, its data is purged after 30 days and that key is destroyed.

## Console accounts

- **Sign-in:** single-use e-mail links (15 minutes) or GitHub. Optional **two-factor authentication** with an authenticator app (TOTP) and single-use recovery codes; organizations can require it for members. See [Teams and roles](teams.md#two-factor-authentication).
- **Sessions:** HttpOnly, Secure, SameSite cookies; every state-changing request needs a CSRF token and the console's origin. Sessions slide for 30 days and end at most 90 days after sign-in.
- **Client IP:** rate limits and the IP addresses in sessions and audit records use the real client address; `X-Forwarded-For` is trusted only from our own proxies.
- **API keys of people** never outlive the person's membership and never exceed their current role.
- **Your data:** export it or delete your account in Settings → Danger zone (details in [Teams and roles](teams.md#your-personal-data-and-deleting-your-account)).
- **E-mails** from us never contain images or remote content and never ask for a code or password.

## Webhooks

Every webhook is signed with HMAC-SHA256 and carries a timestamp. Verify the signature and reject events older than 300 s. See [Webhooks](guides/webhooks.md).

## Agents and computer use

- Content an agent reads (web pages, files, screenshots) can contain prompt injection. Keep credentials the agent does not need out of the sandbox.
- Use `read_only` desktop links for people who only watch.
- Use restricted keys for MCP servers and agent tools (see [MCP](mcp.md)).

## Not available yet

SSO, passkeys, customer-facing audit logs, customer-managed keys, private networking, and self-hosting are on the roadmap.
