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