Skarbiec:面向 AI Agent 时代的密钥与认证管理工具
wisent-ai/skarbiec
Wisent 推出 Skarbiec,一个面向 AI Agent 时代的本地密钥与认证管理器,将 SSH 密钥、2FA、API key 等集中存放,并以签名一次性凭证替代长期可读 token,支持字段级授权、轮换、恢复与防篡改审计。当前为 0.2.x 早期公开版本,本地 broker 无需 Wisent 账号、无条目上限与付费席位,托管同步与治理等属后续规划服务。
Skarbiec: Secrets and Authentication Management for the AI Agent Era
Credential and Authentication Management for the AI Era.
Your devices hold your SSH keys, 2FA, API keys and card details. You don’t want your AI to send them to an external provider, right? Skarbiec holds your information in one accessible place — and makes sure only authorised AI have access to it.
Since it is in one place, it also becomes easy to go full yolo — and give your agent access to every secret you have so that it has nothing stopping it. But this is not all! With embedded browser use integration through Weles, every secret can be rotated and, if you are missing something, the agent can get a secret independently and save it for future use. Think of this as 1Password and Bitwarden reimagined for the AI Agent Era.
All Your Auth Needs Sorted with One Install of Skarbiec.
Install · Quick start · CLI · Examples · Security · Contributing
Skarbiec is an early public 0.2.x product, not a hosted secret manager or a
claim that local brokering makes a compromised host safe. The complete local
broker works without a Wisent account, network licence check, item limit, or
paid seat. Operated fleet synchronization, retained organization audit,
governance, and custodied recovery are separate planned services.
flowchart LR
W[Workload identity] -->|signed, nonced request| B[Local Skarbiec broker]
B -->|policy + exact field check| C[One-use capability]
C -->|one field, once| W
B --> A[Tamper-evident audit]
Loading
Problem and intended users
Long-lived environment variables and copied credential files give every process that can read them the whole secret for an indefinite period. AI workloads make that boundary harder to review: operators need to know which identity requested which field, reject replay, revoke access, rotate recipients, and recover the vault without putting plaintext into prompts or audit logs.
Skarbiec serves:
- individual operators storing and using credentials on machines they control;
- agent and service owners replacing standing read tokens with signed, one-use acquisition;
- security and platform teams defining exact consumer, item, and field grants and reviewing a hash-chained local journal;
- recovery custodians proving that an isolated recovery key can open a deterministic canary before an incident;
- self-hosting teams synchronizing ciphertext while retaining their own host, keyring, network, backup, and upgrade responsibilities.
Product boundaries
Skarbiec stores API keys, logins, sessions, tokens, and typed fields as per-recipient ciphertext. It supports scoped grants, finite capabilities, field-bound acquisition, injection, sharing, TOTP, rotation, recovery, emergency access, breach checks, audit verification, a loopback API, CLI, MCP server, managed browser boundary, and self-hosted ciphertext sync.
It does not protect secrets from a host already compromised while the matching owner key is usable; encrypt item names and other vault metadata; replace OS permissions, GPG key custody, TLS, firewalling, backups, monitoring, or recovery drills; or provide automatic plaintext cloud fallback. The optional Weles path is a separate reviewed browser workflow—not blanket authority to navigate providers, accept terms, or create credentials.
Every accepted credential action records non-sensitive identifiers. Secret values, one-use tokens, signatures, and public keys are excluded from the audit journal.
Core use cases
| Goal | Observable outcome | Start here |
|---|---|---|
| Let a new workload borrow one field | The workload has no standing read bearer; the first matching read succeeds and replay fails | Executable acquisition proof |
| Issue a finite capability against a routed credential | Issuance refuses before handing one out, naming the coordinate and the reason, unless the credential the route names can actually serve | Capability issuance example |
| Store and inspect a credential without printing it | The write returns the item id; list returns metadata only |
Add a credential |
| Share an item, then withdraw access | The recipient can decrypt only the shared item; revocation re-encrypts it to the remaining recipients | Sharing example |
| Replace a lost or departing owner | Every current and historical ciphertext is rewrapped and recovery remains present | Owner rotation |
| Prove recovery before an incident | An isolated custodian keyring opens and discards a deterministic canary and records pass/fail | Recovery commands |
| Move ciphertext between hosts | A replica receives encrypted vault state; local-only data is protected from accidental overwrite | Sync examples |
Real product journeys
These GIFs are regenerated by sh scripts/generate-readme-gifs.sh. The command
builds the current source, executes each journey against a disposable vault and
isolated GPG keyring, checks its decisive outcome, and renders the resulting
terminal transcript. They are not mocked UI recordings.
One field, one use, replay rejected
Recoverable deletion and restore
Encrypted vault lifecycle and operator status
Transcripts and SHA-256 provenance are retained beside the GIFs. The journeys use only explicit demonstration values and remove their temporary vaults and keyrings after capture.
How it works
- Store. The owner writes a typed item. Each value is encrypted to the item's recipient set; the vault file never contains plaintext values.
- Register. For a new consumer, the operator registers one exact
acquire:item#fieldcapability and an Ed25519 workload public key. Wildcards and direct capabilities cannot be mixed into that identity. A workload that should not know which item holds its secret registersacquire:role:<role>#fieldinstead: it asks forrole:<role>, and redemption reads the one live item taggedstado:role:<role>. A scoped consumer that reads directly (POST /v1/items/read) is grantedread:role:<role>#fieldthe same way and asks forid: "role:<role>"; the answer carries the requested coordinate asidand the item that played the role asitem, and no holder, or two, is404with the role named. A credential operation may name a role too:skarbiec credential acquire role:<role> …(andadopt,rotate,reset,verify) acts on the one live item taggedstado:role:<role>; an acquisition nobody holds yet runs under a fresh random id, a repeated one resumes that id, and the item the Weles write creates is tagged with the role. The Weles writer is grantedstage:role:<role>#fieldand writesid: "role:<role>"; Skarbiec checks the grant against that coordinate and writes the item it resolves to. A role that resolves to no item is409naming what it needs. The items list shows a role-granted consumer the item that plays its role. Every single-field read answers the version of what it read beside the value:item_uid(kept by a rename, new after a purge and recreate) andrevision(raised by every new value, unchanged by tags, recipients and renames).POST /v1/items/revision, under the samereadgrant, answers that version without the value, decrypting nothing, so a consumer holding a value reads it again only when the version moved;skarbiec get <id> --revisionis the owner's form of the same answer. - Prove. The workload signs the consumer, item, field, workload id, timestamp, and nonce. Skarbiec rejects a proof signed after now, one older than the newest proof that workload already spent, capability mismatches, and replayed proof hashes; a nonce is remembered until the grant ends.
- Borrow once. Skarbiec issues an opaque bearer that lives until it is spent or until the acquire grant that lent it ends: it cannot outlive its authority, and no shorter lifetime is configured. The first successful matching read deletes its stored hash before returning the field.
- Record. Issuance and consumption append non-sensitive identifiers to a hash-chained local journal. Values, signatures, and public keys are excluded.
At the failure boundary, authorization failures remain authorization failures.
An item that exists but cannot be decrypted returns infra_down rather than
masquerading as missing or dropping the connection. key-doctor reads the
vault and keyring directly, so diagnosis does not depend on a healthy broker.
The error_code in those replies is not skarbiec's own word. The vocabulary,
and what each code means -- its severity, whether it is retryable, whether it
names an outage -- come from
wisent-errors, pinned by commit
in Cargo.toml. A caller deciding whether to retry a refused read is reading
the fleet's definition, not this repository's.
Install
Use an exact, checksum-verified tagged archive for deployment. The complete release and update procedure is in Install and updates.
Contributors can build and atomically install from source:
git clone https://github.com/wisent-ai/skarbiec
cd skarbiec
sh scripts/install.shSKARBIEC_INSTALL_DIR overrides the default $HOME/.stado/bin.
Quick start
Start with the credentials you already have. Select an existing vault with
SKARBIEC_VAULT_FILE, or create one with skarbiec init <owner-uid>, then import
your password-manager or browser export:
skarbiec import "$HOME/Downloads/1PasswordExport.1pux" --format 1password # Alternatively, import during setup: skarbiec onboarding --import "$HOME/Downloads/bitwarden.json" --format bitwarden
The importer accepts 1Password 1PUX v3/JSON/CSV, unencrypted Bitwarden JSON/CSV,
browser CSV, and canonical Skarbiec JSON rows. The default --conflict keep
preserves existing values; replace is explicit and error refuses a changed
existing record before any write. A repeated source identity reuses the saved
item even after a local rename. The complete accepted batch is encrypted before
one generation-checked vault save; the source export is never changed.
Desktop offers the same operation in first use and Items → Import existing
items, including vault selection or creation, counts, warnings, and access to
the actual saved records and attachments. On the CLI the entry points are
skarbiec import and skarbiec onboarding --import above; the first-use
walkthrough names them and asks nothing that could be mistaken for a file
name. See formats, retained fields, limits and refusals
for the complete 0.3.0 source contract.
Optional acquisition walkthrough
The acquisition walkthrough is executable rather than a transcript that can drift.
From a source checkout with skarbiec installed, it creates a disposable vault,
an isolated GPG keyring, and an Ed25519 workload identity. It stores only the
literal non-secret value not-a-secret.
SKARBIEC_EXAMPLE_DIR="${TMPDIR:-/tmp}/skarbiec-acquisition-quickstart" \
sh docs/examples/acquire-one-field.shThe script performs the product's defining path:
- create a vault and item;
- register
demo-workloadfor exactlydemo-note#value, with no standing bearer; - sign a timestamped, nonced acquisition request with the workload key;
- consume the issued capability once;
- retry the same capability and receive
unauthorized; - print the matching audit records.
Setup commands also print JSON. The decisive first read and replay have these output shapes:
{
"consumer": "demo-workload",
"field": "value",
"item": "demo-note",
"ok": true,
"value": "not-a-secret"
}
{
"error": "unauthorized",
"ok": false
}The registration output has workload_bound: true, token: null, and one exact
acquire capability. The final audit query contains acquisition-issued and
acquisition-consumed; it never contains the field value, signature, public
key, or one-use token.
POST /v1/acquisitions returns 400 when a required request member is
missing, the id or field is empty, or the timestamp is not an unsigned integer.
Supplied item, field, or workload values that fail exact-name or workload-proof
validation return 401 with {"error":"unauthorized"}, as do an absent
consumer, a missing or ended acquisition grant, a timestamp after now or older
than the workload's newest spent proof, or a replay.
After the workload has proved its identity, a field that the item does not
carry returns 404 with {"error":"acquisition field does not exist on item"}.
Other issuance failures return 503 with {"error":"infra_down"}. The
missing-field distinction is therefore
available to an authorized workload without exposing field existence to an
unproved caller.
The script refuses to overwrite an existing demo directory. Remove the isolated state when finished:
rm -rf "${TMPDIR:-/tmp}/skarbiec-acquisition-quickstart"For a real vault, first follow
the recovery boundary, move the
recovery private material to its custodian, and verify it with
recovery drill. Store real values through stdin, as shown in
the executable examples, and register new
workloads through acquisition rather than a legacy direct bearer.
Primary interfaces
| Interface | Canonical purpose | Stability | Documentation and example |
|---|---|---|---|
skarbiec CLI |
Owner administration, diagnostics, and supervised automation | Public 0.2.x; tracked by the versioned command surface |
CLI reference · Examples |
| Loopback HTTP broker | Service acquisition, compatibility item access, health, and ciphertext sync | Public /v1; acquisition is the default, direct scopes are compatibility-only |
Acquisition contract · Examples |
| MCP server | Agent-safe metadata and audit, plus explicitly configured declared route resolution | Public restricted surface; raw reads and administrative mutation are intentionally absent | MCP boundary · Server commands |
| Chrome native host | Origin-checked fill through the managed extension | Public managed integration; the extension never receives a vault bearer or private key | Browser boundary · Managed installation |
| Stado adapter | Preserve exact deployed Wisent consumer/item contracts over the broker | Compatibility interface outside the core binary | Examples |
The MCP surface deliberately excludes raw item reads, minting, rotation, and
export. Its skarbiec_route_resolve tool writes a mode-0600 env file and returns
only the path and exported variable names. That path is not the acquisition
model and should not be used for new machine integrations.
Documentation
- Choose and install a release: Install and updates
- Use a command or integration surface: CLI reference
- Run an end-to-end task: Executable examples
- Review trust and failure boundaries: Security model
- Understand storage and network design: Architecture
- Understand current priorities and planned work: Product contract
- Trace the public code lineage: Lineage
- Prepare a change: Contributing guide
- Run and configure a host: Operating Skarbiec
- Read the release's boundaries and support contract: Project status and support
来源:GitHub · github.com



