# 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](https://github.com/openbasil/basil) as a library: broker core, backend adapters, gRPC services, transport, and the
offline operator command implementations. The [`basil-bin`](../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
| `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.
| `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`](../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`](../basil-bin) binary and
talk to it with the [`basil`](../basil-client) 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.