Krate
Try Krate
Security

How Krate keeps an app inside its limits.

For the security team deciding whether Krate may run on your computers. Every line is written from the source code, which is public, so each one can be checked.

Last updated 2026-10-14

What a .krate is

A .krate file is a zip archive. It holds manifest.toml, which names the app and every capability it asks for, and code.wasm, the app itself as a WebAssembly component. It can also carry images and sounds, the source code it was built from, and a signature.

Krate checks the whole archive before it writes anything: a size limit on the archive, on each entry and on the total actually unpacked (counted as it decompresses, not as the archive claims), and a limit on the number of entries. A path that climbs out with .., starts at the root or uses a backslash is refused, and a symbolic link in the archive is unpacked as a plain file. Opening a file grants it nothing.

An app with nothing granted

An app runs inside Wasmtime, a WebAssembly runtime, and Krate gives it no access to the operating system's own calls (no WASI). The only doors out are Krate's interfaces, and each one is checked. A component that imports operating-system calls is refused when it is packed.

Without asking, an app may only: read its own input and arguments, print, read the clock and wait, read the language and number format, open a window, show a message or a yes/no question, draw with the graphics card, and play sound. That is the whole list. Files, the network, the camera, the microphone, location, the clipboard and the rest are not on it.

Everything else is asked for

Every other ability is a named capability that the app's manifest must declare, for example fs.read:notes/**, net.connect:api.example.com:443, camera.capture, audio.capture (the microphone) or location.read. The person sees that list before the app runs and decides. A call to anything the manifest did not declare is refused even if it was granted, and anything declared but not granted is refused.

An answer is remembered only for a signed app, under its publisher's key, and a newer release reuses it only for the same or a narrower list: a wider request is asked again. An unsigned app is asked every time it opens. krate permissions shows what was remembered, and krate permissions --forget <app id> takes it back.

Files and storage

An app names files by paths that Krate resolves inside one folder, chosen when the app opens (the folder it is run from, or a folder of its own for an app installed as a Mac app), and only where an fs.* grant covers them. .. is refused, a symbolic link that leads outside is refused, and a path starting with / stays inside that folder. A manifest cannot use ~ or environment variables. A folder the person picks in a dialog is reached through a token that lasts for that run only.

An app's own data (key-value store, database, secrets) is kept in Krate's folder, never at a path the app chooses. A signed app's data is filed under its publisher's key, so an app from another publisher cannot reach it. Secrets are encrypted with ChaCha20-Poly1305 under a key derived for that app.

Network

An app reaches only the hosts and ports it was granted, as net.connect:<host>:<port> with an exact host or a *.example.com pattern. The check happens before a connection is opened, for web requests, WebSockets and raw sockets alike, and a DNS lookup is allowed only for a host some grant names. HTTPS certificates are always checked. When an app fetches a URL, a redirect is never followed, so a granted host cannot send the request somewhere else.

Apps kept apart

Each app that is opened runs in its own process, with its own WebAssembly instance and memory; one app cannot read another's memory. An app has 256 MiB of memory unless it asks for more with memory.budget and is granted it. krate run --untrusted also puts a limit on how much work an app may do.

By default Krate compiles WebAssembly to machine code as it loads it (Cranelift, through Wasmtime), so it needs to create executable memory. On macOS the signed Krate carries Apple's entitlement for that, under the hardened runtime.

Signed apps

A publisher signs an app with an Ed25519 key. The signature covers a statement that lists every file in the app with its SHA-256, and Krate rebuilds that statement from the file each time, so any change after signing shows. An app changed after it was signed is refused. A root key can be kept offline and authorise release keys for a while, and a release key can be withdrawn; an app signed by a key withdrawn before it signed is refused.

An organisation's private app also carries a mark, covered by the signature, and opens only for that organisation's members (see Organisations). Apps without that mark never check in with Krate's hub when they open. Apps that Krate's hub has removed are refused from a list kept on the computer, offline too (refreshed with krate blocklist --update).

What stays on the computer

Krate keeps what it remembers in ~/.krate in the person's home folder: the permissions they granted, each app's data, and the GitHub sign-in token if they signed in. krate run --log-grants <file> appends the permissions each run was given to a file you choose. Krate itself sends nothing an app reads, writes or shows.

What Krate's hub sees

Usage counts. A random install id, the Krate version, the operating system's name, which of four actions happened (install, make, open, publish), whether an app was made with AI, and for some of them whether it worked and, if not, a reason from a fixed list. Never app names, file paths, prompts or anything about the person. The server limits request rates by the connection's address, and records only whether a count came from a home or a cloud network. Off with krate telemetry off, KRATE_NO_USAGE=1 or DO_NOT_TRACK=1.

Only when someone asks. Publishing uploads the app. Signing in with GitHub asks only to read the person's profile. An organisation's private app checks in with the hub, by the app's fingerprint and the person's sign-in, to confirm the person may still open it; it can then work offline for a time the organisation sets, 30 days at most. Krate sends no crash reports: a support report is uploaded only when the person runs krate support-send.

Reporting a problem

Email yashraj@krate.tech, not a public issue. You will hear back within 72 hours, with a first assessment within 7 days. The full policy is SECURITY.md, and security.txt has the same contact for scanners. Running Krate across an organisation's computers is in Running Krate in an organisation.

← Back to krate.tech