The Polyglot Rust Security NIF
How the Rust NIF at the heart of KRAIT's security performs AST analysis across 6 languages, integrates with the BEAM, and enforces the seven rules.
Why Rust
KRAIT's security analyzer must be fast, memory-safe, and impossible for the host runtime to corrupt. Rust satisfies all three requirements. There are no garbage collection pauses during analysis, no null pointer exceptions, and no buffer overflows. The type system guarantees at compile time that the NIF will not crash the BEAM with a segfault.
Performance matters because every piece of generated code must be analyzed before execution. In a self-evolving agent that may produce dozens of candidate modules per evolution cycle, the analyzer is on the critical path. The NIF typically completes a full seven-rule analysis pass in under 2 milliseconds for a standard module — across all 6 supported languages.
How the NIF Integrates with the BEAM
Narsil is compiled as a Rust NIF (Native Implemented Function) using the rustler crate. It exposes a small API surface to the Elixir side: Narsil.validate/1 takes a binary containing Elixir source code and returns either {:ok, :safe} or {:error, violations} where violations is a list of rule IDs and descriptions.
The NIF is loaded once at application startup and runs on the BEAM's dirty CPU scheduler to avoid blocking normal Erlang process scheduling. Long-running analyses are automatically yielded to prevent scheduler starvation. From the Elixir side, calling Narsil feels like calling any other function — the Rust boundary is invisible.
Polyglot Analysis
The NIF includes dedicated tree-sitter parsers for 6 languages:
- Elixir — Full AST analysis with 5-tier module allowlist, evasion detection (10+ bypass patterns), and all 7 KRAIT rules
- Python — Import-based allowlist,
eval()/exec()/subprocessdetection, credential path checks - JavaScript/TypeScript — Require/import-based allowlist,
eval()/new Function()detection,child_process/fsblocking (TypeScript uses a separate grammar for correct query dispatch) - Go — Import-based analysis,
reflect/os/exec/net/http/unsafedetection - Rust — Use-based analysis,
std::process::Command/std::net/std::fsdetection
Each language implements the LanguageRules trait with a check_all method that runs all applicable KRAIT rules. Shared constants (credential paths, immutable segments, KRAIT internal prefixes) are defined once and reused across all language modules.
What It Validates
The NIF performs a multi-stage analysis pipeline. First, it parses the input using the language-appropriate tree-sitter grammar. Then it runs each KRAIT rule as an independent check. For Elixir, this includes the full allowlist gate plus 10+ evasion detection patterns. For other languages, each rule is adapted to the language's specific dangerous patterns.
If any rule produces a violation, the entire module is rejected. There is no partial approval. The NIF returns all violations found so that the evolution system can learn from the rejection and produce a compliant candidate on the next iteration.
Immutability of the NIF
The NIF is compiled ahead of time and shipped as a shared library. It is not interpreted, not JIT-compiled, and not modifiable at runtime. KRAIT-006 explicitly protects the path where the NIF binary resides. The agent cannot rewrite the analyzer any more than it can rewrite the CPU. NIF binary integrity is verified at boot via SHA-256 checksum.