basil-core
Basil is a host-local secrets broker: your app never touches the key. The kernel attests who's calling, a default-deny policy decides, the key is used where it lives (OpenBao/Vault, KMS, or a sealed local store), and every operation is audited.
The Basil daemon as a library: broker core, backend adapters, gRPC services, transport, and the
offline operator command implementations. The basil-bin binary is a thin
cli wrapper over this crate; embedders and the integration tests link it directly.
Basil's job is to let workloads use keys and secrets without holding them. basil-core is where
that promise is enforced: every request is attributed to a kernel-attested peer, evaluated against
a default-deny policy, executed against a backend where the key material stays put, and written to
a structured audit record.
Layout
| Module | Owns |
|---|---|
core::catalog |
The key inventory and authorization policy loaded at startup: what exists, who may do what to it. |
core::state |
The loaded policy + backend manager bundle shared across services; reload swaps it atomically (core::reload). |
core::backend |
Backend adapters (table below). |
core::audit, core::decision |
Decision records: subject, action, target, outcome, policy generation. |
core::seal, x25519_seal, ed25519_sign, ml_dsa_sign, ml_kem_envelope |
Local crypto used for sealed invocations and materialize-to-use operations. |
core::minter, core::revocation |
JWT/SVID minting and revocation state. |
service |
tonic service adapters: broker, signing, aead, secret, minting, invocation, admin, jwks, spiffe, sds. |
transport |
tonic wiring over the Unix socket, SO_PEERCRED peer extraction, and authorization helpers. |
init, bundle_cli, agent_cli, doctor, unlock |
Offline operator commands: scaffolding, sealed credential bundles, run/explain/doctor, and the fail-closed startup unlock path. |
Backends
The backend decides where keys live; policy decides who may use them. In-place backends never release private key material; the keystore backends materialize a key locally for exactly one operation and zeroize it.
| Backend | Kind |
|---|---|
vault |
OpenBao / HashiCorp Vault, used in place. Composes the transit client (signing, AEAD, BYOK import, kv2 secret access) and the pki client (X.509 issuance). |
spiffe / svid |
SPIFFE Workload API surface and SVID issuance over the Vault backend. |
aws_kms, gcp_kms (features) |
Cloud KMS, used in place. |
keystore (feature) |
Materialize-to-use stores from basil-keystore-backend: the built-in encrypted db-keystore and 1Password. |
Feature flags
http (JWKS/OIDC surface, default) and http-tls; keystore-backend with db-keystore and
onepassword; aws-kms and gcp-kms (large SDKs); unlock methods unlock-age-yubikey
(default, experimental), unlock-bip39 (default), unlock-tpm and tpm2 (experimental);
otlp telemetry export; live-e2e is test-only and boots live OpenBao/Vault dev servers.
Using it
Most consumers should not depend on this crate. Run the basil-bin binary and
talk to it with the basil client crate. Use basil-core if you are
embedding the broker in another process, building an alternative binary, or writing integration
tests that need the daemon in-process.