Threat model
This model covers the Clank framework, generated authenticated applications, CLI, control plane, deployment artifact path, managed ingress, service drivers, and backup system.
This model covers the Clank framework, generated authenticated applications, CLI, control plane, deployment artifact path, managed ingress, service drivers, and backup system.
Assets
- account credentials, sessions, passkeys, recovery tokens, agent OAuth grants, and CLI tokens;
- organization membership, project permissions, audit history, and deployment authority;
- application source/artifacts, migrations, secrets, databases, files, email, jobs, and webhooks;
- control-plane master keys, encrypted backups, release history, usage history, billing entitlements, and signing/provenance data;
- availability and integrity of active application processes and routes.
Principals
- anonymous browser or agent;
- authenticated application user;
- registered public MCP client acting through a user-approved, scoped OAuth grant;
- organization owner, admin, developer, or viewer;
- allowlisted control-plane platform administrator;
- browser account approving a CLI device;
- account-wide or project-scoped CLI token;
- deployment control-plane process;
- authenticated deployment worker;
- deployed application process/container;
- machine, container, database, DNS, email, object-storage, and TLS operators.
Trust boundaries
- Browser/agent to application HTTP, MCP, OAuth, and live-stream APIs.
- Browser to auth, recovery, MFA, and passkey ceremonies.
- CLI to browser-approved device flow and control-plane bearer API.
- Artifact bytes to extraction, migration, candidate startup, and activation.
- Control plane to application process/container and project filesystem.
- Managed ingress to host routing and application upstream.
- Framework to external email, file, job, webhook, database, billing, and provisioning providers.
- Live database to encrypted backup repository and restore target.
- Git source to CI, attestation, GitHub release, and npm publication.
- Trusted application source through the TSX compiler to generated executable modules.
- Web mutation to durable queue and leased worker/scheduler to external side effects.
Primary abuse cases
| Threat | Representative attack | Principal controls | Residual responsibility |
|---|---|---|---|
| Account takeover | Credential stuffing, reset replay, stolen session, cloned authenticator | Scrypt, generic login errors, shared HMAC-keyed control-plane rate limits, single-use recovery, MFA, WebAuthn verification/counters, revocation | Upstream abuse controls, bot defense, email security, user/device risk policy |
| Cross-site action | CSRF, forged Origin, cross-site device approval | Strict cookies, CSRF token, Fetch Metadata/origin checks | Correct proxy scheme/host configuration and CSP |
| Agent credential abuse | Malicious dynamic client, authorization-code interception, refresh replay, token confused with another API or tenant | Exact HTTPS/loopback redirects, PKCE S256, explicit consent, resource indicators and audience checks, short access lifetime, hashed tokens, refresh rotation, bounded encrypted single-successor adaptive handoff chain, strict-mode family revocation, read/write scopes, MCP-only bearer resolution, per-user grant inbox with monotonic scope reduction and immediate revocation | Adaptive recovery cannot distinguish a legitimate lagging client replica from a thief holding the same predecessor bearer token; its authority converges on the unspent successor's existing scope, resource, client, family, and expiry through at most 64 links. Choose strict mode for replay-driven family revocation. Client identity remains self-asserted, so users must review names/scopes; endpoint TLS, agent-host security, and edge registration limits remain operational responsibilities |
| Agent action abuse | Prompt injection or compromised client invokes hidden/destructive tools, guesses a write tool with a read token, or submits adversarial arguments | Authenticated tool discovery, mutation scope enforcement before dispatch, agent: false, destructive annotations, shared runtime schemas/authorization/ownership/transactions, bounded messages, generic failures | Domain authorization and confirmation inside handlers; annotations guide clients but are not security controls |
| Tenant escape | Guess project/user IDs, reuse scoped token, stale membership | Owned SQL, membership/role checks, project/scope checks on every request, revocation | Domain-specific row/resource authorization |
| Privilege escalation | Admin grants excess scopes, removes last owner, uses viewer token to deploy | Role matrix, scope intersection, last-owner protection, audit | Periodic access review and separation of duties |
| Platform-admin abuse | Workspace admin assumes global authority, stolen CLI token lists tenants, stale allowlist retains access | Separate operator role, exact startup reconciliation, browser-only global APIs, same-origin sessions, bounded redacted directory | Protect operator email accounts, require strong authenticators, review the allowlist and global audit trail |
| Impersonation abuse | Operator silently edits tenant data, targets another operator, replays a support token, or denies accessing an account | Recent-auth and CSRF gate, exact target confirmation, required reason, admin/self/disabled-target denial, hashed 15-minute session-bound capability, safe-method-only effective identity, visible banner, real-actor start/stop audit | Limit the operator allowlist, alert on support sessions, require ticket-linked reasons and customer approval where policy or law requires it |
| Invitation replay or disclosure | Reuse a superseded token, create an uninvited account while signup is closed, scrape pending addresses or audit metadata, flood active invitations, leak links through request logs, or duplicate a retry | Hashed email-bound single-use account-creation capability, pre-hash origin check, transactional consume/membership, failed-account cleanup, atomic replacement/revocation, administrator-only pending metadata, developer audit redaction, 100-active cap, fragment links, encrypted transactional outbox, cross-instance leases, idempotency, ciphertext erasure, audit | Protect invited mailboxes and mail-provider credentials; provider-accepted messages cannot be recalled |
| Artifact compromise | Traversal, symlink, decompression bomb, digest swap, malicious install hook | Bounded deterministic bundle, path/type/mode validation, SHA-256 verification, no remote install/build hooks | Review trusted source and isolate runtime execution |
| Migration/data loss | Edited history, unsafe SQL, failed migration, destructive rollback | Immutable ledger, restricted SQL, quiesced backup, transactional apply, safety restore, confirmation | Schema review, off-host backups, restore drills |
| Preview data leak or quota bypass | Branch deploy copies raw production data/secrets, weakens sanitization in pull-request code, nests children, or creates unbounded temporary runtimes | Empty default; active-production-bound table/row/transform policy; unconditional credential/job purge; per-preview HMAC; integrity, vacuum, staging overwrite, migration, and health gates; separate IDs/hostnames; nested-preview denial; ordinary quotas and bounded TTL cleanup | Review every explicit keep, prefer synthetic fixtures, remove previews when CI closes, and monitor project capacity |
| Historical value disclosure or destructive rewind | A deleted/changed secret survives in document history, another owner enumerates revisions, or restore overwrites a newer edit and erases evidence | Same owner scope as current reads; bounded snapshot/page retention; schema revalidation; exact revision cursor; expected current version/deletion state; append-only compensating restore; unconditional history purge in sanitized previews | Choose retention for data sensitivity, keep app SQLite/backups private, expose history actions only to intended roles, and redact secrets before writing them as ordinary document fields |
| Pull-request deployment identity abuse | Commit a broad token, replay a workflow JWT, rename/recycle a repository, substitute a workflow or target branch, target production or another pull request, or run untrusted code in the control plane | GitHub Actions OIDC with fixed issuer/JWKS and RS256, exact HTTPS audience, immutable repository ID plus name, workflow path/SHA, trusted cleanup ref, event/ref/time checks, hashed one-time JWT ID, 15-minute pull-N token, production/sibling denial, cleanup revocation, isolated-runtime gate, pinned actions, secretless workflows | Protect GitHub administrators and trusted-base workflow review, keep pull-request runtimes isolated, monitor exchange audit, and accept that fork policy may withhold OIDC |
| Traffic quota bypass or privacy leak | Race monthly admission, route around ingress, stream undeclared bytes, or turn usage dimensions into request/user tracking | Immediate SQLite admission transaction, fixed workspace/project/month rows, metadata-minimal policy input, fail-closed decisions, bounded retention, explicit known-transfer semantics | Keep app ports private; enforce edge connection/body/response/DDoS limits; do not treat known transfer as total egress or a monetary record |
| Billing entitlement forgery or replay | Forge checkout, substitute an account/plan/Price, replay or reorder a webhook, future-date state, use a project token to inspect billing, or turn cancellation into destructive deletion | Browser-only CSRF checkout/portal, durable attempt and session binding, exact provider/customer/subscription/plan identity, fixed-origin bounded Stripe adapter, raw-body HMAC and delivery-time validation, live/test separation, event digest replay/conflict ledger, monotonic subscription state, account-token scope checks, fail-closed snapshots, non-destructive admission | Protect provider keys/dashboard/webhook configuration, test tax/refund/dispute flows, monitor delivery failures, review operator grants, and meet business/legal billing obligations |
| Queue inspection | Job payloads, results, exception text, owner/group identity, worker or lease credentials copied into the control plane | Allowlisted metadata-only reads, bounded responses, presence-only error flags, conditional RBAC mutations, payload-free audit/events | Keep detailed diagnostics in private app telemetry; review operator access |
| Secret disclosure | API response/log leak, filesystem exposure, package publication | AES-GCM, no secret reads, recursive log redaction, private umask, npm package audit | KMS, rotation, OS/operator access, provider logging |
| SSRF/proxy confusion | Attacker-chosen upstream, scheme-relative path, duplicate host, hop-header smuggling | Loopback/allowlist upstreams, target origin assigned before path, exact unique hosts, Connection-nominated header stripping, manual redirects | Network egress policy and trusted DNS/TLS edge |
| Domain/certificate takeover | Reassign pending hostname, spoof TXT, route elsewhere, trigger certificates for arbitrary SNI | Exact random TXT proof, immutable cross-project assignment, separate routing state, reserved namespaces, indexed TLS allow check restricted to deployed sites | Private edge link, CAA/ACME policy, certificate storage and CA monitoring |
| Worker split brain | Expired worker completes after reassignment | Authenticated leases, monotonic fences, idempotent durable operations | Highly available backing store and supervisor integration |
| Runner enrollment theft or replay | Reuse a provisioning link, enroll the wrong region, race a legitimate node, or use a CLI token as operator authority | Browser-only recent-auth administrator creation, CSRF, exact node/region binding, high-entropy digest-only token, expiry, transactional reservation, single-use commit, active-token cap, credential rotation, secret-free audit | Deliver the one-time token through a trusted channel, remove it after enrollment, edge-rate-limit the coordinator, and protect runner hosts |
| Provider bridge takeover | Steal a provider token, replay a reconcile, downgrade a generation, smuggle a release/runtime, or leak a provider error | Separate high-entropy bearer, HTTPS/private-network guidance, fixed protocols, strict headers, bounded binary body, fresh artifact/capsule validation and desired-state binding, no coordinator credentials, durable operation/generation/fence state, generic errors | Rotate/scoped provider tokens, network admission, provider audit and isolation |
| Docker client environment injection | Name an application secret DOCKER_HOST, LD_PRELOAD, or another process/transport control so the host-side launch client executes or connects under application influence | Docker CLI inherits one inert encoded runtime envelope rather than application-named variables; the in-container Node bootstrap decodes and deletes it before application import; executable/PATH/HOME remain operator-controlled; values stay out of arguments | Protect the Docker socket and runner host, restrict who can change runner configuration, and treat privileged host/container administrators as trusted |
| Provider container escape or secret persistence | Escape a shared container boundary, inspect another tenant, leave an old process reachable after provider restart, or persist a capsule secret in Docker configuration | Immutable image digest by default, read-only exact release/root, project-only writable data, non-root uid/gid, dropped capabilities, no-new-privileges, CPU/memory/PID/tmpfs/log limits, loopback-only web publish, stdin-only post-loader environment delivery, exact owner labels, verified orphan removal, no process adoption, close-race fencing | Docker daemon/kernel/provider host remain trusted; protect the socket, enforce egress/tenant network and disk policy, use rootless/user namespaces and LSM/seccomp, patch promptly, and move hostile tiers to dedicated VMs or microVMs |
| Remote ingress confusion | Send public traffic to an old generation, spoof provider binding headers, escape a provider route with a scheme-relative/encoded traversal path, race activation/authentication or a late response, or expose its route token | Exact desired/observed release-generation-node activation, allowlisted HTTPS edge origin/path, overwritten binding headers, provider-side exact project/protocol/generation/token-digest validation, loopback-only target, pre-auth request lease, overlapping generations, revoke-before-drain, generation-scoped/race-fenced circuits, reserved header stripping, generic failures | Keep the provider hop private and application ports unreachable; drill node outage and route revocation, and do not bypass managed ingress |
| Runtime placement disclosure | Cache or log a capsule, expose secret values in headers/errors, substitute another project's data, or place data on a compromised host | Exact current node/operation lease, canonical operation selection, post-load lease recheck, whole/section SHA-256, strict project/release/generation binding, no-store binary bodies, secrets only in the body, generic failures | Provider hosts are trusted application compute; require private TLS transport, host isolation, provider log suppression, backup/restore drills, and secret rotation after compromise |
| Provider diagnostics disclosure or confusion | Read another generation's output, return forged resource totals, expose Docker/container/environment identity, infer cross-project activity from shared capacity, or grow diagnostics memory/body without bound | Separate generation-derived control token, exact running state, private allowlisted origin, no redirects/encoding, strict response identity/schema/aggregate checks, post-transfer placement recheck, 128 KiB/1,000-entry memory tail, 512 KiB body cap, no container IDs/paths/environment, configured-secret redaction, exact shared filesystem capacity restricted to platform-administrator browser sessions | Applications must not log unregistered secrets or personal data; protect the provider TLS hop and Docker logs; use infrastructure telemetry for historical data |
| Provider job disclosure or stale mutation | Read payloads/errors from another tenant or generation, operate a replaced database, smuggle fields through a provider response, or race a worker transition | Generation-derived control token, private allowlisted origin, lifecycle serialization, project-root path confinement, read-only inspection, strict length/media/identity/schema checks, post-transfer placement recheck, conditional SQLite writes, payload-free responses/events/audit | Protect provider TLS and node access; use application-authorized logs for error detail; retry only the fixed current-generation failure |
| Runner overcommit or unsafe data failover | Concurrent placement exceeds a node, a heartbeat lowers capacity below assigned work, a network partition leaves the old SQLite writer alive, or node-local data is silently activated elsewhere | Transactional process-slot reservation, durable per-placement demand, required capability/region checks, capacity-shrink rejection, portable-only automatic reassignment, stateful pinning, browser-admin/recent-auth recovery, exact revoked source and backup confirmation, two risk acknowledgements, verified encrypted recovery point, old-ingress removal, higher-generation target observation, audit | Physically or network-fence the source before affirming recovery; revocation only fences Clank credentials. Size slots for real CPU/memory limits, keep recovery objects in a separate failure domain, and drill stateful node recovery |
| Provider lifecycle reordering or stale replay | Start background effects before data commit, restore SQLite beneath a live candidate, publish before complete health, replay an old fence, or substitute an operation/capsule at one generation | Capsule rehash/decode before durable intent, exact operation/generation/fence state, drain-before-stop, candidate cleanup before rollback, journal retention when cleanup is uncertain, deferred workers/scheduler, ingress-last activation, exact idempotent retry | One writer per provider root, stateful node pinning, encrypted independent backups, restore/deletion drills, and application-level idempotency for unavoidable startup/external effects |
| Provider data corruption | Crash between database/metadata writes, change a stored path, replace another project, follow a storage link, or lose rollback bytes during cleanup | Independent capsule/desired binding, per-project state, exact scoped metadata, owner-only real paths, SQLite integrity checks, apply/rollback journals, atomic state commit, one referenced safety snapshot, explicit confirmations | Durable disks, filesystem/operator security, encrypted independent backups, and restore drills |
| Application job duplication | Worker performs a remote effect, then times out or crashes before recording success | Transactional enqueue, renewable random-token leases, stale-settlement fencing, bounded retry/dead letter, deterministic cron keys, rollout quiescing | Idempotent handlers/provider keys, cooperative aborts, shared durable volume, queue monitoring |
| Durable-object retry or storage abuse | Reuse an expired key, replay a prior incarnation's result, force cleanup across another namespace, hide a committed result behind maintenance failure, or create unbounded attacker-selected IDs and retry records | Exact retention lookup, lifecycle-cleared ledgers, namespace-scoped best-effort cleanup, atomic state/result commit, tombstone-accounted namespace ceilings, per-object retry ceilings, UTF-8-bounded diagnostics, renewable leases, and revision fencing | Authorize exact object IDs, rate-limit public creation, use provider idempotency for external effects, monitor capacity, and keep state on one durable SQLite placement |
| Workflow graph drift or confused dependency | A new release reinterprets an active graph, a step reads an undeclared result, duplicate reconcilers enqueue twice, or failed siblings continue | Revision-bound graph/schema/mapper contract; explicit acyclic edges; transactionally idempotent step enqueue; owner-scoped start keys; fail-closed propagation and child cancellation; bounded durable run/step/event state | Keep step side effects idempotent, expose starts through authorized mutations, review graph changes like migrations, and monitor failed retained runs |
| Browser journey credential or navigation abuse | An agent embeds a password, escapes the application origin, attaches to a remote debugging endpoint, records private field values, or supplies executable test data | Environment-only secret references; literal password denial in the Chrome driver; same-origin navigation; loopback-only CDP; isolated sandboxed browser profiles; bounded steps, files, waits, reports, DOM inspection, and exception text; value/query redaction; owner-only atomic artifacts | Use synthetic least-privilege test accounts, protect CI environment variables and artifacts, review trusted JavaScript journey modules, and keep Chrome patched |
| Blueprint registry substitution or rollback | Replace a reusable app plan, publish under another owner, serve an older catalog, redirect installation, escape the registry path, smuggle executable configuration, or leak a signing key | Separate Ed25519 publisher/registry roles; exact namespace/origin scopes; normalized data-only blueprint; canonical signed metadata and SHA-256 digests; exact SemVer without tags; explicit revocations and minimum sequences; same-origin traversal-safe paths; bounded no-redirect JSON; full re-verification before ordinary generation | Bootstrap trust out of band, protect offline private keys, persist highest accepted sequence, update revocations, secure registry TLS/DNS/availability, and still review generated product behavior |
| Collaboration room escape or presence abuse | A signed-in user joins another document, reuses another participant's connection ID, sends cross-site updates, floods cursors, or places private data in presence | Exact-room authorization on every request; private principal binding; random connection IDs that are not authorization; existing CSRF verification; same-origin and Fetch Metadata checks; bounded rooms/connections/data/depth/rate/idle leases; no-store transport; aggregate-only diagnostics | Keep authorization object-specific, never place secrets or hidden records in peer-visible presence, use sticky routing or a reviewed shared adapter for multi-process presence, and persist important state through backend mutations |
| Product analytics identity or inference leak | Record personal content as event properties, bypass consent, recover a raw subject, isolate one person's behavior in a time bucket, retain data forever, or exhaust app storage | Aggregate-safe finite schemas; explicit consent and DNT; domain-separated HMAC pseudonyms; no raw-event read API; unique-subject cohort suppression; bounded range/buckets/funnel scans/retention/capacity; subject erasure; memory-only browser queue | Store consent authoritatively, rate-limit same-origin ingestion, protect and retain the analytics HMAC secret, include backups in erasure policy, and expose only role-appropriate aggregate queries |
| Backup tampering or omission | Ciphertext/catalog/manifest alteration, incomplete object promotion, duplicate schedulers, missed recovery point, restore wrong copy | AES-GCM envelope, catalog and manifest HMAC, bounded chunk SHA-256, durable leased scheduling, local fallback, repository binding, bounded retention, explicit confirmation | Monitoring, separate key custody, independent object repository, restore drills |
| Object-storage compromise | Redirect credentials, alter stored bytes/metadata, return an oversized body, reinterpret an old release through a new bucket, reuse broad bucket authority, or delete another environment's objects | HTTPS origin validation, SigV4 signed payload/headers, redirect refusal, strict content-addressed keys, persisted repository identity, independent bounds and SHA-256, generic errors, optional namespace prefix | Bucket-scoped credentials/policy, environment separation, provider audit/retention, client-side encryption, growth/integrity alerts, retry monitoring across the external/local cleanup boundary |
| Managed-bucket escape or upload abuse | Choose another owner, forge/replay an upload URL, race quota, spoof an image type, replace a current object with a partial generation, enumerate private storage keys, or retain abandoned uploads | Auth/OAuth-derived owner only; CSRF/origin-gated management; operation/resource/owner/expiry-bound HMAC capabilities; transactional active-plus-reserved project/bucket/owner quotas; offset-locked resumable staging; signature/dimension/type/length/SHA checks; immutable generation swap; opaque public IDs; startup/pre-reservation expiry sweep | Keep signing and S3 credentials private, use private visibility for controlled content, add edge request/rate limits, configure a reviewed image transformer, back up catalog and bytes together, and monitor storage growth/orphans |
| Destructive project action | Stolen scoped token, developer error, path substitution, partial site deletion | Owner/admin account principal, scoped-token denial, CSRF, exact slug confirmation, separate data-loss acknowledgement, durable lock, derived symlink-safe paths, token revocation, retained audit event | Account-token protection, off-platform copy deletion, legal retention policy, deletion drills |
| Audit repudiation or tenant disclosure | Hide a destructive event, read another workspace, reuse stale elevated scope | Non-cascading organization attribution, current membership/role joins, project-token intersection, bounded cursor pagination, no audit mutation API, deleted-target retention | Trusted SQLite admins can alter local rows; replicate or sign events independently when operator tampering is in scope |
| Supply-chain compromise | Mutable CI action, leaked npm token, package includes local state | Commit-pinned actions, least privilege, OIDC trusted publishing, attestation, package allowlist, zero dependencies | GitHub/npm account security and protected release environment |
| Compiler boundary confusion | Treat attacker-controlled data as TSX source or assume generated code is sandboxed | Compiler accepts project source only, performs no build-time evaluation, and emits reviewable modules | Never compile request/database values; isolate mutually untrusted app execution |
| Denial of service | Chunked oversized request, CBOR/artifact bomb, repeated retained releases, scrypt/device-code exhaustion, high-cardinality limiter keys, failing upstream, unbounded metric labels, site/domain exhaustion | Streaming byte/count/time bounds, CBOR depth/collection limits, per-project artifact count/byte ceilings, password queue, bounded durable auth and traffic rate-limit state, circuits, transactional monthly quotas, fixed-cardinality metrics, leases/retries | Edge rate limits, whole-volume monitoring, compute quotas, autoscaling, capacity planning |
Explicit assumptions
- The operating-system administrator and master-key holder are trusted.
- The process runner executes trusted applications. Use Docker or stronger isolation for mutually untrusted deployers.
- TypeScript and TSX files are trusted executable application source. The compiler is not a sanitizer for attacker-controlled data.
- OAuth authenticates the approving user and client grant; it does not make model-generated tool arguments trustworthy.
- TLS termination, certificate/key custody, ACME issuer policy, DDoS protection, WAF rules, and public network policy are external to the core package. Clank only decides hostname eligibility.
- An application process can read its own decrypted environment and database.
- SQLite is a strong single-node transactional default, not a globally replicated database.
- External drivers are trusted only to the authority represented by their narrowly scoped token and endpoint.
Review triggers
Repeat this threat review when adding a credential type, raw HTML path, file parser, public protocol, proxy rule, external provider, database engine, runner, multi-node coordinator, privileged role, destructive action, or release channel.