# clavis-cli Pure C CLI for credential access by AI agents. Talks to a Clavitor vault over HTTPS, decrypts L2 fields locally. ## Build ``` make # build for host make strip # strip binary make clean # remove artifacts ``` Target: `clavitor-cli` binary, <1MB stripped. Requires: C11 compiler, POSIX (Linux/macOS/FreeBSD/Windows). ## Architecture - **src/main.c** — CLI entry point, argument parsing, commands (get, list, totp, test-crypto, test-roundtrip, eval, test-totp) - **src/http.c** — HTTPS client using BearSSL. Loads system CA certs for TLS validation. Supports plain HTTP fallback. - **src/keystore.c** — Config storage at `~/.config/clavitor/config`. AES-128-GCM encrypted + HMAC-SHA256 signed. Inconvenience barrier only — real security is vault-side. - **src/jsbridge.c** — QuickJS bridge exposing BearSSL crypto primitives to JS. Loads `crypto/crypto.js` and `crypto/totp.js` from `../clavis-crypto/`. - **src/util.c** — Base64 (standard + url-safe), URL encoding. ## Vendored dependencies All in `vendor/`, no system package dependencies: - **BearSSL** — TLS, AES-GCM, HKDF, HMAC, PRNG - **QuickJS** — JS runtime for shared crypto logic - **cJSON** — JSON parsing ## Crypto design Three-tier encryption model: - **L1** — first 8 bytes of L2 key, used as Bearer auth token - **L2** — 16-byte AES-128-GCM key, client-side field encryption/decryption - **L3** — requires hardware key (not handled by CLI) JS crypto in `../clavis-crypto/` is the single source of truth for encrypt/decrypt logic. The C code bridges BearSSL primitives into QuickJS so the same JS runs in CLI and browser. ## Token format `--token` value is a base64url-encoded, AES-GCM encrypted blob containing: `vault_host \0 agent_name \0 l2_key_16_bytes`. Decrypted using HKDF-derived key from seed `clavitor-l2-`. ## Vault communication All API calls go to `https://` (port 443 by default, override with `--port`) with `Authorization: Bearer ` and `X-Agent: ` headers. Endpoints used: `/api/entries`, `/api/search?q=`, `/api/entries/`, `/api/ext/totp/`. ## ⚒️ Foundation First — No Mediocrity. Ever. The rule is simple: do it right, or say something. Johan is an architect. Architects do not patch cracks in a bad foundation — they rebuild. Every agent on this team operates the same way. ### What this means in practice If you need three fixes for one problem, stop. Something fundamental is wrong. Name it, surface it — we fix that, not the symptom. If the code is spaghetti, say so. Do not add another workaround. The workaround is the problem now. Quick fixes are not fixes. A "temporary" hack that ships is permanent. If it is not the right solution, it is the wrong solution. Foundation > speed. A solid base makes everything downstream easy. A shaky base makes everything downstream a nightmare. We build bases. ### The restart rule When the foundation is wrong: start over. Not "refactor slightly." Not "add an abstraction layer on top." Start over. This applies to code, infrastructure, design, encryption schemes, and written work alike. ### Q&D is research, not output Exploratory/throwaway work has its place — but it stays in research. Nothing Q&D ships. Nothing Q&D becomes the production path. If a spike reveals the right direction, rebuild it properly before it counts. ### When you hit a bad foundation Call it out. Do not work around it. Bad foundations are not your fault — but silently building on them is. Surface the problem, we work on it together. The bar is high. The support is real. ## Testing ``` ./clavitor-cli test-crypto # BearSSL + JS crypto self-tests ./clavitor-cli test-totp # TOTP generation from base32 seed ./clavitor-cli test-roundtrip # runs crypto/test_crypto.js ```