Repository navigation
claustrum v0.2.0
This release follows v0.1.3. Its main reason: programs the subc supervisor did not start,
such as editor plugins, can now enroll with the vault and receive their own identity. A v0.1.3 vault answers unknown_method to
auth.enroll_propose, so the CortexKit auth plugins cannot connect to it. Upgrading fixes
that. The upgrade migrates the store forward, and v0.1.3 cannot open the result, so read
Upgrading from v0.1.3 before you start.
What's new
Consumer enrollment and scoped grants
- A program the supervisor did not start enrolls over the same connection consumers use to
read credentials. It proposes a name
(auth.enroll_propose), an operator admits the name withck auth enroll approve, and the
consumer collects its own token by polling (auth.enroll_poll). Approval mints nothing,
so only the process holding the request secret can collect the token.auth.enroll_rotate
rotates a token. Operators manage enrollments withck auth enroll list | approve | deny | revoke | reissue, and grant toenrolled:<name>like any other principal. - Grants name a principal, a selector and one operation. An
exactselector matches one
credential id byte for byte. Acategoryselector matches every credential carrying that
category and follows category assignments. Operations are separate and none implies another:
read,sign,open(KEM keys),seal(exact selectors only),list(the account roster
without tokens),deposit(browser cookies) andaccount_token(with theaudience
selector kind). credential.list_scopedserves enrolled callers as well as supervised modules, and returns
account identity only to callers holdinglistorread.auth.watch_scopedsends the
current scoped view and then its changes, coalesced over 250 ms.ck auth categorieslists every category, how many credentials carry it, and which
principals hold grants naming it.credential.deposit_cookielets a granted module
deposit a browser session cookie.credential.account_tokenmints short-lived account
worker tokens for granted principals.
Provider catalog
- API-key providers:
abliteration,aiand,anthropic,baseten,charm-hyper,
cline-pass,commandcode,deepinfra,firepass,gmi-cloud,meta,minimax-code,
minimax-code-cn,nanogpt,novita,ollama-cloud,opencode-go,opencode-zen,
qianfan,qwen-portal,sakana,siliconflow,siliconflow-cn,singularityapi-dev,
singularityapi-tech,stepfun,synthetic,typesafe,umans,venice,
vercel-ai-gateway,wafer-serverless,xiaomi-token-plan-ams,xiaomi-token-plan-cn,
xiaomi-token-plan-sgp,yolo-auto,zenmuxandzhipu-coding-plan, each stored as
apikey:<name>. - Web search providers, classified
web-search:apikey:tavily,apikey:kagi,
apikey:exa,apikey:parallel,apikey:brave,apikey:firecrawl,apikey:jinaand
apikey:tinyfish. apikey:inception(Mercury),apikey:cloudflare-workers-ai, andapikey:kiro, whose login
checks the key against the provider's model list.- Meta: a device login,
oauth:meta, alongside theapikey:metakey. - Gmail:
oauth:gmail, an operator-owned OAuth login for sending mail.
Plan tiers and provider ids
ck auth set-providersattaches provider ids to a credential (up to 32), so a consumer can
tell which providers one credential serves. They are operator metadata; the vault never
derives them.ck auth set-planrecords a subscription tier. Login and refresh detect the tier for
ChatGPT (plus,prolite,pro) and for recognised Claude profiles, and leave it unset
rather than guess. An operator-set tier takes precedence over a detected one. Both appear in
the scoped listing.
KEM keys: credential.open and credential.seal
ck auth mint-kem-keycreates a vault-held X25519 key. Its public key is readable; its
private key never leaves the vault.credential.opendecrypts an HPKE message addressed to that key for a principal holding
open.credential.sealencrypts with the vault key as an authenticated sender for a
principal holdingsealon that exact key, and returns only the encapsulation and
ciphertext.
Per-signature audit
- A signing key minted with
--audit-each-signaturegets one entry in the HMAC-chained audit
log for every signature, written before the signature is returned. If the entry cannot be
written, no signature is returned. The flag is off by default. ck auth signsigns exact payload bytes with a signing key minted with--operator-sign.
That flag also turns on per-signature audit for the key.
Linux and Windows
- Native master-key storage: Windows Credential Manager (per-user, DPAPI-protected) and the
Linux Secret Service (GNOME Keyring or KWallet, already unlocked, over the session bus). A
new vault uses its platform's store by default. A key file (--key-pathor
CK_MASTER_KEY_PATH) remains an explicit choice, for example on headless Linux, and is
never a silent fallback when the native store is missing or locked. - The vault records its key choice in
<data_dir>/key-source, so later runs of the daemon
andck authneed no override. An override that disagrees with the record is refused. - Owner-only files: the key file is checked on every load (on Unix a regular file owned by
the current user with no group or other bits; on Windows the handle's owner and DACL), and
on Windows the data directory and the vault's own files get owner-only DACLs. - Process hardening: on Linux both programs make themselves non-dumpable at startup; on
Windows they restrict the process DACL. ck auth loginon Linux with no display goes straight to the paste flow.
Refresh cooldown
- A consumer's stale report no longer triggers an immediate refresh if the credential was
written less than 60 seconds ago. The current token is served, the stale mark is kept, and
the first read after the window refreshes. A token that is expiring, empty, or shorter than
the caller'smin_ttl_msstill refreshes at once. This protects providers that revoke the
whole token family when a refresh token is reused.
Upgrading from v0.1.3
v0.1.3 stores are at schema 9. v0.2.0 applies migrations 10 through 18 the first time either
binary opens the store. Migrations run forward only. Once migrated, v0.1.3 refuses the store
("store schema 18 is newer than this binary's 9"), so rolling back means restoring a copy
taken before the upgrade.
- Upgrade the supervisor first. subc-core 0.20.83 (
ck0.20.83) is the oldest
supervisor this release is supported and tested on. If your subc is older, upgrade it
before you install v0.2.0 rather than after. - Check your grants while still on v0.1.3: run
ck auth grants. Migration 10 converts
each prefix grant to anexactgrant on the one credential it covers today. A prefix grant
that covers no credential, or more than one, makes the migration refuse
(migration 10 refused prefix row ...), and the store is left at schema 9. Revoke such
grants with v0.1.3'sck auth revoke-grantbefore upgrading, and re-create them afterwards
asexactorcategorygrants. Category grants carry over unchanged in reach. - Stop the vault module in your supervisor.
- Copy the whole data directory (by default
~/.local/share/cortexkit/claustrum) to a
place outside~/.local/share/cortexkit, as described in
Reading the store directly.
Copy the directory, notstore.dbalone. The copy does not contain the master key; keep
the key where it is (Backups and restore). - Replace both binaries together,
ck-claustrumandck-auth. Whichever runs first
migrates the store. - If you used a key file on v0.1.3 (the only option there on Linux and Windows), keep
CK_MASTER_KEY_PATH(or--key-path) set for the first start. The first successful key
load records that file inkey-source, and the vault keeps using it. - Start the module and verify:
ck-auth --versionreports 0.2.0, then
ck auth verify-audit,ck auth statusandck auth grants.
To go back, restore the copied directory together with the v0.1.3 binaries; see
Roll back.
Behaviour changes you may notice
ck auth grant --prefixis gone. It is refused with guidance.--selector-kindis now
required (exact,categoryoraudience); there is no default.- Selectors match differently.
exactcompares the credential id byte for byte, where
v0.1.3 matched a prefix. Acategoryselector is the bare category name (--selector <category>), notcategory:<name>. Existing grants are converted by migration 10 without
changing what they reach (see step 2 above). - Key-source record.
--key-pathandCK_MASTER_KEY_PATHstill work, but must agree
with the vault's recordedkey-source. A different file, or a file for a native-store
vault, is refused with both choices named. - Stale reports wait out the 60-second refresh cooldown described above.
- Devin: a token the provider will not renew now needs a fresh login; the vault no longer
extends it locally. - GitHub App: an App installed on more than one account is refused at refresh instead of
silently using the first installation, and installations are re-discovered on every
refresh. - Scoped replies carry more.
credential.get_scopedandcredential.list_scopedaccept
an enrollment token, and list rows include provider ids, plan tier and authentication
method. See the wire contract.
No existing ck auth verb or wire method was removed or renamed.
Windows: update ck first
subc-core 0.20.121 fixes two Windows setup bugs: ck setup claustrum failing on a clean
machine, and ck upgrade being unable to replace a running daemon. If your ck is older,
update it before anything else:
- Rerun the installer in PowerShell:
irm https://cortexkit.io/install/win | iex. This
replacesck.exewith 0.20.121 or newer. - Run
ck upgrade.
Running ck upgrade straight from an older ck can still hit the running-daemon bug once.
Requirements
- subc-core 0.20.83 (
ck0.20.83) or newer. - Platforms: macOS arm64, Linux x64, Windows x64. Each asset is built on its own platform.
- A native key store (macOS Keychain, Windows Credential Manager, an unlocked Linux Secret
Service) or an operator key file outside the data directory.
Assets are built on the platform they run on. Each zip has a SHA-256
sidecar holding the digest of the zip bytes.
The macOS binaries are ad-hoc signed, not notarized: a browser-downloaded
zip carries a quarantine attribute and Gatekeeper will refuse it.
Installing via curl does not apply that attribute.
claustrum does not self-initialize. Run ck auth bootstrap before enabling
the module, or the daemon will exit with 'no master key has been provisioned'.
A new vault keeps its master key in the OS key store: the Keychain on
macOS, Credential Manager on Windows, and the Secret Service (GNOME Keyring
or KWallet, already unlocked) on Linux. Where no unlocked Secret Service is
reachable, as on a headless Linux server, bootstrap with --key-path <file>
or CK_MASTER_KEY_PATH= instead: a file outside the data directory,
owned by the vault user, with owner-only permissions. A missing or locked
OS store is refused; there is no automatic fallback to a file. Bootstrap
records the choice in the vault's key-source file, so later runs of the
daemon and ck auth need no key-path override.
REQUIRES subc-core 0.20.83 OR NEWER (ck 0.20.83). Upgrade the supervisor
before installing this release.