已发布版本仅 v0.3.0 CLI/MCP,桌面应用和分享链接等功能仍在源码中、无公开版本;v0.2.0 及更早版本存在会覆盖他人保存、误删 vault、返回错误密码等缺陷,需替换;自行构建原生二进制必须在目标操作系统上进行,并先运行 scripts/build-libsodium.sh 构建 libsodium。
keypaste
notinferredAGPL-3.0活跃维护兼容 KeePass 的密码与密钥管理器,专为与 AI Agent 协作的人设计,通过 MCP 服务让 Agent 安全读取 dotenv 等敏感凭据。
A KeePass-compatible password and secrets manager for people who work with AI agents.
curl -fLO https://dl.keypaste.com/v0.3.0/keypaste-0.3.0-osx-arm64.tar.gz
curl -fLO https://dl.keypaste.com/v0.3.0/keypaste-0.3.0-osx-arm64.tar.gz.sha256
shasum -a 256 -c keypaste-0.3.0-osx-arm64.tar.gz.sha256
tar -xzf keypaste-0.3.0-osx-arm64.tar.gz
mkdir -p ~/.local/bin && mv keypaste keypaste-mcp ~/.local/bin/README 未说明显存或 GPU 要求;已发布二进制为原生可执行文件,无需 .NET 运行时,macOS 需 14 或以上(Apple Silicon),Intel Mac 需自行从源码构建。
兼容 KeePass 的密码与密钥管理器,让 AI agent 只在获得你批准后才拿到密钥
兼容 KeePass 的密码与密钥管理器,专为与 AI Agent 协作的人设计,通过 MCP 服务让 Agent 安全读取 dotenv 等敏感凭据。
核心能力
- 用单个本地 KDBX 4 文件存储,无账号无网络,可与 KeePassXC 双向互操作
- MCP 审批:agent 请求单个字段并给出理由,你选择拒绝、允许一次或永久允许
- `keypaste run` 只把值注入命令环境变量,不写入磁盘
- 按项目组织 dev/staging/prod 多套密钥,prod 必须实时批准
- `.env.keypaste` 只存 `kp://` 引用,可安全提交到仓库
容易踩的坑
暂无 release 数据(可能没有发版,或尚未同步)。
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
What it does
The published v0.3.0 CLI stores logins and environment variables in a local KDBX vault, runs commands with them, and asks you before an agent receives one. Everything else below is in source until the next release, and the desktop app has no public release; FEATURES records what exists where.
As a password manager
- One KDBX 4 file on your disk, with no account and no network. KeePassXC opens and edits the same file, and CI checks both directions against
keepassxc-clion Linux, macOS and Windows. - Logins with a title, username, password, URL and notes, in groups. Search covers titles, usernames and URLs and never reads a password.
- A generator for 8 to 256 characters from a shell-safe alphabet, or passphrases of 6 to 32 words from the EFF list.
keypaste rotatereplaces a password with a generated one and never prints it. - History for every change, restored in one step, and rolling encrypted backups beside the vault.
keypaste importcopies another KDBX file in, or keeps editing it in place.
For developers and their agents
- MCP approval: an agent asks for one field of one entry and gives its reason. You answer Deny, Allow once, or Always allow or Always block for that agent and item, or allow a kind of value for every agent in Settings or for one on its page, and every request lands in a hash-chained audit log.
- Inject-only runs:
keypaste runputs values in a command's environment and nothing on disk. With--allow-run, an agent can run a command you approve and gets back its output with each value replaced, though a command it can edit can still reveal a value (T-35). PRODUCT §2 bounds it: no shell, and you approve the exact command. - Projects: one set of keys per project, with a value for dev, staging and prod. Prod always needs a live answer.
.env.keypaste:KEY=kp://project/profile/KEYreferences and no values, safe to commit.- Scoped tokens for CI, such as
read:acme-api/staging/*: inject-only, and expiring after 30 days by default. - Share links: one field, or an entry's login (username, password and URL), encrypted on your machine, opened 1 to 10 times (once by default) before it expires. keypaste.com serves the links; the command is in source until the next release.
The approval, in the terminal

Rendered from the source's output for the next release, with a scripted MCP client in place of the agent; the published v0.3.0 asks Approve? [y/N] and allows up to 300 seconds. The prompt as text:
────────────────────────────────────────────────────────────
keypaste: an agent is asking for a credential.
agent claude-code (claude-code)
item env/demo/.env
field STRIPE_KEY
the agent says it needs this because:
deploy the billing service to staging
That sentence was written by the agent, not by keypaste. Treat it as a claim.
[d] deny [o] once [a] always [b] block 45s ›
The demo shows a credential request, approval and deploy in about sixty seconds.
You can transport the encrypted file with your existing file-sync service; keypaste has no merge or managed-sync workflow. KDBX compatibility does not mean complete KeePassXC feature coverage. The code is open source under AGPL-3.0.
The published download is pre-1.0 CLI/MCP v0.3.0. Replace v0.2.0: a save racing another program's save could undo it without keeping the lost change in history. Replace v0.1.0: it could also delete a vault through env export, modify the wrong entry through env rm, and return the wrong password through get. CHANGELOG lists what v0.3.0 repairs. Published versions are immutable, so both remain available with those defects.
The desktop app holds the vault unlocked for one session: it answers agents in its own prompt window, launches projects with their variables and locks everything at once. RELEASE defines distribution status, ROADMAP what comes next, and PRODUCT product commitments. Broader ideas are in BACKLOG.
Install
Download the archive and its checksum, verify the hash, then extract it. Each binary is a native executable with no .NET runtime dependency. The Unix instructions move both binaries into ~/.local/bin.
macOS: Apple Silicon
curl -fLO https://dl.keypaste.com/v0.3.0/keypaste-0.3.0-osx-arm64.tar.gz
curl -fLO https://dl.keypaste.com/v0.3.0/keypaste-0.3.0-osx-arm64.tar.gz.sha256
shasum -a 256 -c keypaste-0.3.0-osx-arm64.tar.gz.sha256
tar -xzf keypaste-0.3.0-osx-arm64.tar.gz
mkdir -p ~/.local/bin && mv keypaste keypaste-mcp ~/.local/bin/
macOS 14 or later. This floor follows .NET 10 support; no run backs this floor. Intel Macs have no published binary and require a source build. GitHub offers native Intel runners, but this release matrix does not yet build or test that target.
Linux: x64 and arm64
curl -fLO https://dl.keypaste.com/v0.3.0/keypaste-0.3.0-linux-x64.tar.gz
curl -fLO https://dl.keypaste.com/v0.3.0/keypaste-0.3.0-linux-x64.tar.gz.sha256
sha256sum -c keypaste-0.3.0-linux-x64.tar.gz.sha256
tar -xzf keypaste-0.3.0-linux-x64.tar.gz
mkdir -p ~/.local/bin && mv keypaste keypaste-mcp ~/.local/bin/
For arm64, substitute linux-arm64 in all three filenames. Both are built against glibc 2.35. The release workflow checks the x64 binary on a clean Debian 12 container and checks that it fails on Alpine; the equivalent container check is not implemented for arm64. Alpine and other musl distributions have no published binary; build from source there.
Windows: x64
$a = "keypaste-0.3.0-win-x64.zip"
Invoke-WebRequest -OutFile $a "https://dl.keypaste.com/v0.3.0/$a"
Invoke-WebRequest -OutFile "$a.sha256" "https://dl.keypaste.com/v0.3.0/$a.sha256"
$want = (Get-Content "$a.sha256" -Raw).Split()[0]
if ((Get-FileHash $a -Algorithm SHA256).Hash -ne $want) { throw "checksum mismatch" }
Expand-Archive $a -DestinationPath .
Windows 10 1809 or later. This floor follows .NET 10 support; no run backs this floor.
On Windows, put the extracted binaries in a directory you add to PATH. On macOS and Linux, check that ~/.local/bin is on PATH with command -v keypaste.
Keep the absolute path of keypaste-mcp for your MCP client configuration.
Download verification
The checksum detects a corrupted or incomplete download. It does not authenticate the publisher. The checksum is served from the same origin as the archive, so anyone able to replace one can replace both. The published binaries are unsigned and un-notarized. v0.3.0 also publishes a build attestation that GitHub CLI can check without an account, covering every asset and the release manifest; v0.2.0 and earlier have none. THREATS.md T-21 describes the download trust boundary, and SECURITY.md has the verification steps in one place.
The installation instructions keep downloaded commands visible for review before execution.
Browser downloads set com.apple.quarantine; these command-line download and extraction steps should avoid it. The release runner executed the binary with quarantine deliberately set, but that observation does not establish behavior on every Mac. If macOS blocks the unsigned binary, xattr -d com.apple.quarantine ~/.local/bin/keypaste removes the attribute.
Or build it from source
Building from source lets you inspect the code you compile without relying on a prebuilt binary matching it. Install the SDK pinned in global.json:
git clone https://github.com/notinferred/keypaste
cd keypaste
dotnet build keypaste.slnx -c Release
keypaste lands at artifacts/bin/Keypaste.Cli/release/ (.exe on Windows), and in source it is also the MCP bridge, run as keypaste mcp. This is also the only supported route on Intel Macs, on musl distributions such as Alpine, and on Windows on ARM.
Sixty seconds to a project with no .env in it
keypaste init ~/vault.kdbx
export KEYPASTE_VAULT=~/vault.kdbx
keypaste env pull dev
keypaste run dev -- npm start
Replace your .env in 5 minutes covers import, CI use, sync, export and lost master passwords.
Connecting it to Claude
keypaste-mcp is started by your MCP client and forwards requests without holding a vault. You start keypaste agent, which 0.5.0 renames keypaste approve, in your terminal to unlock the vault and approve requests:
keypaste agent --vault ~/vault.kdbx
If you installed v0.1.0 and have not replaced it yet, configure the client using the manual Claude Code or Claude Desktop instructions, with the absolute path of the downloaded keypaste-mcp.
With v0.2.0 or later, configure clients with:
keypaste setup --vault ~/vault.kdbx
setup configures detected clients through their mcp add command, or prints a configuration block for clients without one. --dry-run prints commands without changing configuration; --remove removes keypaste. v0.1.0 lacks setup; every later release includes it.
Client configuration contains no master password. Connecting keypaste to Claude explains setup, exposure and audit reading.
Using it
keypaste init ~/vault.kdbx
export KEYPASTE_VAULT=~/vault.kdbx
keypaste add github --username me --url https://github.com
keypaste ls
keypaste get github
keypaste get github --show
keypaste rm github --yes
ls prints a names-only group tree. get copies the password to the clipboard and clears it after twenty seconds; --show writes it to stdout instead. Password prompts never echo input. Command data goes to stdout and diagnostics to stderr, so keypaste get x --show can be piped. Set KEYPASTE_VAULT or pass --vault to each command.
In v0.3.0, rm permanently deletes the entry and its history. In 0.5.0, which is not yet published, it moves the entry to the vault's recycle bin, where KeePassXC can see and restore it, unless the vault's recycle bin is switched off, and get --reveal replaces get --show, which is refused. Printing a value with get and explicit env export expose plaintext. The standalone passphrase generator described below is an Unreleased source feature.
Generating one
add and env set generate the secret they store when you pass --generate, and print how much of it there was rather than what it was:
keypaste add github --generate
keypaste add github --generate --length 32 --no-symbols --no-lookalikes
keypaste env set billing STRIPE_KEY --generate
Characters come from an 85-character alphabet: letters, digits and !#%()*+,-./:;=?@[]^_{}~. The punctuation that breaks in a shell, in YAML or in a URL is left out on purpose. Twenty characters is the default, about 128 bits; --length takes 8 to 256. --no-symbols leaves letters and digits, --no-lookalikes drops Il1O0, and both cost entropy to solve a problem the Copy button and keypaste run are there to remove.
New in 0.5.0, not yet published: --words N generates a passphrase instead, drawn from the EFF long word list of 7,776 words vendored into keypaste and pinned by digest. These options and keypaste generate are absent from the published v0.3.0 download. Each word is worth about 12.9 bits, so the six-word minimum is about 78 bits; --words takes 6 to 32, and --separator chooses what goes between them, a full stop by default. A hyphen is refused, because four of the list's words are spelled with one and a hyphen-joined passphrase cannot be split back into the words you counted.
keypaste add github --generate --words 6
keypaste env set billing STRIPE_KEY --generate --words 8 --separator _
keypaste generate --words 6 prints a passphrase and stores nothing. Generation details go to stderr, so a redirect captures only the passphrase. It opens no vault and asks for nothing.
| exit code | meaning |
|---|---|
| 0 | success |
| 1 | usage error |
| 2 | internal or environment error (including no usable clipboard, and an entry name two entries answer to) |
| 3 | vault or entry not found |
| 4 | wrong master password |
| 5 | the audit log is not the file keypaste wrote |
When stdin is not a terminal each prompt consumes one line in order. init takes the new password twice; add and env set take the master password followed by a value unless generating one. While the desktop app or keypaste approve holds the vault they take the value alone, and the holder asks you to allow the change; a line more is refused. In 0.5.0, access --password takes the current master password and then the new one twice; access refuses with 1 before changing anything it would not change safely and with 4 for a wrong current password. Commands that do not open a vault, such as log, need no master password. Consult command help before scripting confirmation or export prompts.
Environment variables
In v0.3.0 each variable is an ordinary entry under env/<project>, with its name as the title and value as the password. In 0.5.0, which is not yet published, a variable is a protected field of an entry tagged env:<project>, and env set and env pull put a new one on the project's entry env/<project>/.env, so the value below is read with keypaste get env/billing/.env --field DATABASE_URL --reveal; an entry of the earlier layout stays an ordinary entry and is no longer a variable. KeePassXC can edit both directly. CI checks interoperability on all three operating systems.
keypaste env pull billing
keypaste env pull billing config/.env.prod --yes --delete-source
keypaste env set billing DATABASE_URL
keypaste env set billing STRIPE_KEY=sk_test_x
keypaste env ls
keypaste env ls billing
keypaste get env/billing/DATABASE_URL --show
keypaste env rm billing STRIPE_KEY --yes
keypaste env export billing --dotenv --stdout
env ls lists projects; adding a project name lists variable names without values. env pull validates the entire file before importing. Malformed input leaves the vault unchanged. Its plan lists new, updated and unchanged variables by name; unchanged values are not rewritten.
The parser accepts export prefixes, comments, three quoting styles and multiline values. A # starts a comment only after a space, so PASSWORD=hunter2#42 retains its suffix. Duplicate keys are errors. ${VAR} and $VAR remain literal to avoid binding the vault to one machine's environment. Double quotes expand \n, \r, \t, \\ and \"; use single quotes for a literal Windows path such as C:\temp.
The KEY=value form exposes the value to shell history and process listings, so keypaste warns on use. Updates retain old values in KeePassXC entry history. Deleting a .env does not erase its storage or backups; see SECURITY.md.
Running things with those variables
keypaste run dev -- npm start
keypaste run prod -- ./deploy.sh
The -- is required. Without it, keypaste run dev npm start cannot be told apart from a project called npm; everything after it belongs to the command, including flags keypaste also understands.
The child inherits your environment with project variables overlaid, and receives the terminal's stdin, stdout and stderr. run opens the vault itself, asking for its password, and closes it before starting the child. In source, keypaste run --session opens nothing and asks for no password: the desktop app or keypaste approve holding the vault unlocked shows the project, its variable names, the command and the directory, and the child starts only if you allow it there. A refusal, a lock, 45 seconds without an answer or nothing holding the vault each end the run with a reason and no child. The child receives a snapshot: later edits or locks do not update or erase its environment.
After startup, keypaste returns the child's exit code. Missing commands return 127 and non-executable commands return 126. keypaste's own failures print a line beginning keypaste run:. Ctrl+C, docker stop and timeout reach the child; keypaste waits for it to exit.
A set is injected whole or not at all. An expired entry, an untitled one, an invalid or repeated name, or names differing only in case prevent injection, and the error lists every offending key and why, never a value, so they can be corrected in KeePassXC. An entry in the recycle bin is not part of the set.
Getting them back out
env export writes plaintext for tools that require a file or for moving credentials elsewhere.
keypaste env export billing .env --dotenv
keypaste env export billing --dotenv --stdout
In v0.3.0, export requires --dotenv. In 0.5.0, keypaste env export billing -p staging > .env.keypaste without it writes one kp:// reference per variable and no value, which keypaste run --env-file .env.keypaste -- <command> resolves; Replace your .env covers profiles and references. With --dotenv, file output warns with the destination path and asks for confirmation; overwriting also requires --force. keypaste reports a .git ancestor and creates owner-readable files on Linux and macOS. Windows has no equivalent permission control and reports that limit. Export refuses to overwrite its source vault or any other KeePass vault, even with --force; in v0.1.0, --force could destroy the vault. Prefer keypaste run when a file is unnecessary.
Export uses single quotes where possible for consistent reading by motdotla/dotenv, python-dotenv, godotenv, Docker Compose v2 and sh. Values containing apostrophes or carriage returns need escapes; keypaste names those keys on stderr because readers differ in escape handling.
Agent access
In v0.3.0 two tools appear in the client: list_entry_names, which returns group paths and entry names and never a value, and request_credential, which asks you to release one field of one entry. In 0.5.0, which is not yet published, a third, request_attachment, asks for one attachment of an entry by its name, a fourth, request_save, asks you to save a value the agent never sees, and every bridge keypaste setup connects also offers run, which runs nothing until you turn it on for that agent.
A credential request requires your approval, a matching rule you wrote in v0.3.0, or in 0.5.0 a kind of value you allowed for every agent and confirmed. Enter your master password only in keypaste agent, keypaste approve in 0.5.0, which you start yourself. Agents cannot trigger a password prompt, avoiding prompts another local program could imitate.
An explicit refusal tells the agent not to retry. Silence for 45 seconds denies the request. In v0.3.0 matching requests can reuse a live approval; in source each is asked again unless its kind of value is allowed. Every call, including denied and malformed calls, is appended to ~/.keypaste/audit.jsonl without the returned value.
v0.3.0's TTL expires its cached approval, and in source setting a kind of value back to Ask stops later releases without asking. Neither erases the client's copies or revokes the password at its issuer. The bridge does not add the released value to its audit record, but agent-written arguments can themselves contain sensitive text; treat the local log as sensitive data. SECURITY.md states these boundaries in full.
In v0.3.0 exposure defaults to the env/ subtree, and only explicit --expose globs in your client configuration widen it. In 0.5.0 an agent sees every project's variables, the custom fields named like environment variables on entries tagged into a project, until you change its settings, and an --expose in the client configuration can only narrow that.
Saying yes in advance
In v0.3.0, a narrow rule in ~/.keypaste/policy.toml releases matching requests without asking you; keypaste policy ls displays its parsed patterns, and the v0.3.0 policy guide explains them.
In 0.5.0 policy.toml is no longer read. Each kind of value an agent can ask for, passwords, custom fields, project variables, card values, identity values, TOTP codes, notes and attachments, is Ask, Allow or Block for every agent, set in the app's Settings and Ask by default. Allow releases without asking you and records each release, and takes effect only once you confirm it; a passkey is always blocked. Agents see each item's title, group, tags and URL, and its username unless Settings hides it. A command is asked about each time, with Allow once only, and only for an agent you turned run on for:
keypaste clients
keypaste clients claude-code --run on
The rules are kept on this computer in ~/.keypaste/agents.toml, sealed with a key the vault holds, so neither a synced vault nor another program editing the file gives an agent more. Agent settings explains them.
Seeing what happened
Every call an agent makes is one line in ~/.keypaste/audit.jsonl, allowed or refused. keypaste log reads it back:
3 records in /home/you/.keypaste/audit.jsonl
time (UTC) agent item decision method
2026-07-26 14:03:09 claude-code - granted exposure
2026-07-26 14:03:11 claude-code env/demo/.env granted prompt
2026-07-26 14:07:44 claude-code env/demo/.env denied prompt
--denied, --client <text> and --since 2h narrow it, and a narrowed view always says so.
Each audit record includes its predecessor's hash. keypaste log verify checks the chain and reports its limits on every pass: a complete recomputed chain and records removed from the end can escape detection.
Approvals explains the prompt. THREATS.md covers prompt injection, unauthenticated clients, approval fatigue, standing approvals and audit tampering.
KeePass and agents explains the local approval design and its relation to browser integration.
Packages
| Roadmap name | Project | Ships as |
|---|---|---|
keypaste-core | src/Keypaste.Core | shared vault library |
keypaste-cli | src/Keypaste.Cli | keypaste |
keypaste-mcp | src/Keypaste.Mcp | the stdio forwarding bridge, inside keypaste as keypaste mcp; v0.3.0 ships it as keypaste-mcp |
keypaste-app | src/Keypaste.App | desktop app; source builds and CI packages, no public release |
Vault format
KDBX4 with Argon2d key derivation (2 iterations, 64 MiB, parallelism 2) and AES-256. keypaste never invents a format and writes no cryptography of its own (docs/PRODUCT.md §2, §3.6): the format layer is KeePassLib, vendored from KeePass 2.61 and reached through a single file, src/Keypaste.Core/Internal/KeePassInterop.cs.
scripts/verify-keepassxc-compat.sh and scripts/verify-keepassxc-writeback.sh check interoperability against a real keepassxc-cli on Linux, macOS and Windows on qualifying pushes to main and on each pull request that changes the code that writes vaults or the gate's own scripts. This is a permanent gate under docs/PRODUCT.md §4.6.
Directories and namespaces use .NET's PascalCase convention; the kebab-case names above are the roadmap's and survive where they are user-visible, in the shipped binary names.
The CLI, MCP server and desktop app share vault and authorization logic in Keypaste.Core (docs/PRODUCT.md §4.3).
Build and test
Local verification needs the .NET SDK pinned in global.json, Git, jq and running Docker for workflow validation with the pinned actionlint image. Process checks use GNU timeout (included with Git Bash/Linux; gtimeout from coreutils on macOS) to bound a stuck child. From PowerShell, run:
./scripts/verify.ps1
From Git Bash, macOS or Linux, run:
bash scripts/verify.sh
The command runs every check but the KeePassXC compatibility gate. A full run validates workflows, restores locked dependencies, checks formatting and builds both solutions plus the separate CLI/desktop consistency project, exercises offline script fixtures and real CLI/MCP process interactions, then runs their Release tests. The PowerShell wrapper selects Git Bash. --list prints the selection and commands without executing them, and --from <profile> resumes after a failure. CLAUDE.md owns the final verification procedure. Other operating systems, NativeAOT and release installation retain their separate gates. To run the CLI after building, use dotnet run --project src/Keypaste.Cli -c Release.
Builds treat warnings as errors and enforce code style. Declare dependencies in Directory.Packages.props and the project, then regenerate the lock files with dotnet restore --force-evaluate over keypaste.slnx, keypaste.app.slnx and tests/Keypaste.Consistency.Tests, with the SDK global.json pins, and commit them. Changes to RuntimeIdentifiers also require regenerated locks; otherwise --locked-mode fails with NU1004.
Do not pass -r to restore. It narrows the runtime identifier set and conflicts with lock files recording all four targets. The projects already declare their RIDs and PublishAot=true; restore with dotnet restore --locked-mode and select a RID only when publishing.
Building a native binary yourself
NativeAOT binaries must be built on their target operating system. Per O-0005, Linux needs clang and zlib1g-dev, macOS needs Xcode command line tools, and Windows needs MSVC C++ build tools with vswhere.exe discoverable. keypaste links libsodium, which scripts/build-libsodium.sh builds first from its signed release; it also needs curl, OpenSSL 3, and make outside Windows.
bash scripts/build-libsodium.sh
dotnet restore keypaste.slnx --locked-mode
dotnet publish src/Keypaste.Cli -c Release -r linux-x64 --no-restore -o out
dotnet publish src/Keypaste.Mcp -c Release -r linux-x64 --no-restore -o out
dotnet publish otherwise restores implicitly with its selected RID, rewriting the locks for one target and breaking the next locked restore. Use --no-restore after a full restore, as release.yml does.
Publishing produces one native file per project; PublishAot=true is already configured. Use osx-arm64 or win-x64 for those platforms. scripts/verify-aot-trim.sh compares publish diagnostics with the accepted vendored-code baseline and rejects new warnings or any warning from src/. Capture output after changes under third_party/:
dotnet publish src/Keypaste.Cli -c Release -r linux-x64 --no-restore -o out > cli.log 2>&1
scripts/verify-aot-trim.sh cli.log
Eleven vendored-code diagnostics are accepted; scripts/aot-trim-baseline.txt lists them. ILC analyzes only changed inputs; if a repeat publish emits none, the script reports that no new analysis occurred.
third_party/Directory.Build.props isolates vendored source from project style checks, and dotnet format excludes third_party/ to preserve upstream mergeability.
To run the KeePassXC compatibility gate locally you need keepassxc-cli on PATH (or KPXC_CLI pointing at it):
bash scripts/verify.sh compat
In PowerShell, use ./scripts/verify.ps1 compat.
The fixture is built by the shipped keypaste binary, so the gate covers the CLI as well as the vault writer. The write-back script builds its own vault and drives both tools in turn: keypaste modifies an entry, then KeePassXC edits and adds env variables that keypaste has to read back.
Found something wrong?
Bugs, missing features and "this made no sense to me" go to the issue tracker. They are read by the person who wrote the thing. A report that says what you ran, what you expected and what happened is worth more than a polished one.
Anything that looks like a security problem goes to [email protected] instead of the tracker. SECURITY.md owns what is in scope, what happens next and how fast.
Security
Report vulnerabilities privately using SECURITY.md.
License
AGPL-3.0. Auditable code is the trust strategy (docs/PRODUCT.md §3.8).