Skip to content

Building and local setup

The full engine is a Rust application. Install Rust/Cargo, a C++ compiler, CMake, libclang, protoc, Python 3.11 or newer, and Soufflé with its development headers and mcpp. Local TLS setup also uses OpenSSL. The Python SDK uses uv; JavaScript SDK builds use Node/npm, and guard builds also use Bun. Consult your platform’s packages for these dependencies.

From the source repository:

Terminal window
make build-rust # Development engine: sasy-services/target/debug/sasy
make build-rust-release # Optimized engine: sasy-services/target/full-release/release/sasy

Both targets use the committed Cargo lockfile. The optimized full-engine target uses a separate output directory so that a restricted guard build cannot replace its binary. Override SASY_RELEASE_TARGET_DIR to choose another build directory.

The full engine embeds its policy compiler source assets, but still invokes Soufflé, mcpp, and a C++ compiler when compiling new policies. Those tools and headers must be available on the machine running the engine. Match the Soufflé runtime and headers, including their RamDomain word size. Copying the executable alone does not install this toolchain.

make build-rust-restricted instead packages the shipped guard policies into a restricted engine. It is not the custom-policy development engine. For a complete guard wheel, including its daemon and native hook, follow building sasy-guard locally.

flake.nix and flake.lock pin the Rust, native, Python and JavaScript development tools. Install Nix separately, then enter the shell from the assembled public repository:

Terminal window
scripts/nix-dev.sh
python3 scripts/nix-smoke.py

The smoke check compiles and runs Rust, loads libclang, processes a protobuf definition, and compares interpreted and compiled SASY policy decisions. It uses temporary files and does not start an engine.

On Linux, build the full engine and its runtime policy toolchain with:

Terminal window
nix/build.sh
./result/bin/sasy --help

This package includes the full engine’s default features, Soufflé and matching headers, the C++ compiler, Python, and the interpreted backend’s native assets. Use the installed bin/sasy launcher: it selects the packaged tools and assets, so policy compilation does not depend on the current source checkout. Build outputs and their dependencies remain in the Nix store. These are Nix packages, not portable standalone binaries or release wheels. The existing native release targets remain available.

The Linux launcher also selects a packaging-generated runtime manifest. This lists the Nix dependency paths that the policy sandbox may mount read-only and the tools it may execute. The engine validates the manifest and uses a controlled search path inside the sandbox. The interpreted evaluator receives the explicit directory of the selected policy’s functor library, preventing an unrelated installed library from taking precedence. Invalid configuration must fail rather than fall back to unsandboxed execution. The manifest is operator configuration; policy authors cannot supply extra filesystem paths through a policy upload. The manifest and selected store items must be root-owned and read-only. User-owned single-user Nix stores are not supported by this runtime integration.

The host must permit Bubblewrap’s namespaces and mounts. Container hosts can restrict those operations independently of SASY. Keep the engine’s sandbox enabled when qualifying a deployment; a successful toolchain smoke outside the sandbox does not establish that a deployment can compile and evaluate policies safely.

Use the launchers when working from a private checkout. scripts/nix-dev.sh stages the flake definitions needed for the development shell. nix/build.sh stages only the explicitly listed build inputs in nix/source-files.json and the packaging definitions. Local credentials and installed dependencies are excluded. Directly evaluating the entire checkout as a flake does not provide this source filtering.

The development shell has Linux and macOS outputs for ARM64 and x86-64. Full-engine package outputs currently target Linux. Declaring a platform does not qualify its build or runtime behavior; see the recorded validation for the revision being distributed.

Terminal window
make init-config
make certs

init-config creates ignored local files from the examples and preserves existing files. Edit config/auth/apikey.json: replace demo-key and admin-test-key with different, independently generated secrets, keeping their client and admin entity mappings. Generate each key separately, for example with:

Terminal window
python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
chmod 600 config/auth/apikey.json
unset SASY_API_KEY_SUFFIX

Keep the complete client key for your SDK’s SASY_API_KEY; keep the admin key separate. Do not put either in source control. The role mappings in config/auth_config.yaml give the client reference-monitor and observability access. See authentication for the provider schema, OIDC, and the legacy demo suffix behavior.

Start the optimized engine:

Terminal window
make serve SASY_BIN=sasy-services/target/full-release/release/sasy

The public Makefile binds 127.0.0.1:50051, uses the generated TLS certificate, and stores graph and credential data under data/. A new store starts with a deny-all policy. An existing store can retain earlier policy bindings. The example certificate is for local development; remote clients need operator-managed certificates and a separately distributed trust root. See configuration before changing addresses, credentials, or storage paths.

In the assembled public repository, use Node.js 24 or newer:

Terminal window
cd docs-site
npm ci
npm run dev

Open the local URL printed by Astro. For the production output, run npm run build and then npx astro preview. The public entry points include /quickstart/, /policy-language/, /configuration/, and /claude-code-sasy-guard/management/.

For maintainers working in the private source repository, release/public-core/overrides/docs-site is only a partial overlay. It must be combined with the selected shared pages by the exporter before previewing; running Astro in that overlay alone leaves sidebar entries missing. Follow release/public-core/README.md to export a committed revision to a fresh directory, then run these commands in that export’s docs-site.

A successful optimized build is a host-platform artifact, not evidence for every supported platform. Before distributing it, test TLS/authentication, policy compilation, and allowed/denied actions against that exact binary. Record the source revision, lockfiles, Rust and native-tool versions, target platform, build features, and artifact checksum. The guard release workflow builds its own restricted artifacts; it does not currently publish a standalone full-engine release archive.