How it works
Kratex runs inside your Node process. When your code or one of its dependencies does something sensitive (reads a file, opens a network connection, spawns a process), Kratex checks it against your policy at that moment and decides whether it proceeds.
net.connect("203.0.113.9:443")net, so the call is intercepted before it openskratex.policy.jsonIn-process guards
When you run kratex run node app.js, the CLI spawns Node with a preload attached via --import (Node 20.6+) or --require (older). The preload patches Node’s core APIs (fs, net, http, child_process, module, process.env) so any call into them passes through Kratex first.
Kratex enforces in-process, from JavaScript, because kernel-level mechanisms (eBPF, seccomp) lose the JavaScript call stack: the information Kratex needs to know which package made each call.
Caller-chain attribution
Kratex walks the call stack and tags each frame with the package that owns it. The owner nearest the call is the primary caller, and that is what a rule’s subject matches.
So you can allow a network call from your own code but block the identical call from a dependency. See Policy authoring → Subject for how to target specific packages or source classes.
How rules become decisions
For every intercepted operation, the runtime evaluates all matching rules and keeps the single best match. More specific rules beat less specific ones; user rules beat built-ins at equal specificity. If nothing matches, the default is allow. Policy reference has the full ordering.
The matched rule’s effect.action is one of allow, audit, or block. What happens next depends on the policy’s mode:
enforcemode:blockthrowsKratexPolicyViolation(error codeERR_KRATEX_POLICY) in the child, so the guarded operation never completes.auditmode:blockis demoted towould-block: the operation proceeds, an event records the violation. A small set of structural built-in rules (wallet reads, install-time network, self-propagation) fire hard even in audit mode. Demoting them would let the irreversible operation complete: the wallet is read, the credential leaves the machine.
A concrete flow
A third-party package tries to read ~/.aws/credentials:
- The patched
fs.readFileSyncintercepts the call. - The caller chain identifies the third-party package as the primary owner.
- The built-in
kratex.builtin.third-party-credential-readrule matches. - Under enforce mode, the read throws
KratexPolicyViolationand never returns the file contents.
The read also stamps the caller with a credentials exposure label: if that same package later makes a network call, the built-in kratex.builtin.third-party-exposed-outflow-network rule blocks it. Static scanners see code at rest; this chain (read, exposure, blocked outflow) happens at run time.