Vault runtime
2026-09-15 — current guides and scoped acceptance
Tracking: Vault241 and master247. The canonical credentials guide now links paired owner-only tree examples, frozen CLI 0.22.0/Python 0.17.0 candidate receipts, and runnable retention/host fixtures. Python 0.17.0 is now published with both frozen PyPI archives byte-verified; CLI 0.22.0 npm candidate publication is partial; native R2 publication remains pending. Source docs version 0.1.15, raised code tabs and merged host-guide navigation are preserved; the package version alone is not evidence that this new guide is deployed.
Examples PR49, merged
e5991a0, records actual selected-new-key denial, preserved old access, same-intent
recovery and lost cleanup-response recovery for target and jump. It used a local
real API and isolated bos14 SSH listeners through an explicit owned-home helper
seam. Cleanup passed. It does not establish published-client/hosted-API failure
acceptance, system password mutation or completion of all remote lifecycle work.
UI286 tested genuine local
HTTP/Mongo authorization loss with editor/detail clearing; replacement-session
protection used a synthetic generation change, not fresh OAuth.
UI287 tested committed
scoped-key creation with lost delivery, metadata-only reload recovery, explicit
revocation and explicit replacement. Unknown unresolved issuance remains pending;
there is no recovered original bearer. These local browser proofs are distinct
from production UI acceptance. UI294
source 8f826, deployment 6aa94b, passed export and disabled-retry checks;
UI295 receipts, tests and docs merged as 526713f0 after full CI 34977598363; this evidence merge did not change the production UI runtime. API task 122/source 1058ef4 subsequently passed the retired-task 121
stop gate and production metadata-tree acceptance: CLI first-page/Python
continuation succeeded. The original cleanup attempts were uncertain and are
retained in the unaltered receipt.
A separate reconciliation
finished at 13:58:31Z, recording exact-ID/revision retirement and read404 for both
synthetic entries. Ciphertext retention continues to the captured purge deadlines;
physical purge is not claimed. Python 0.17.0 is published with exact wheel/sdist verification. Initial readback was delayed; original journals were preserved and no attempted file was uploaded twice. A fresh no-cache PyPI install and production metadata-tree check passed: owner verified, schema version 1, page limit 1, zero writes and secret reads. The initial install check was nonzero with suppressed diagnostics and no established cause; its read-only retry succeeded. Independent review records the scope. CLI 0.22.0 npm candidate publication is partial: verified package readbacks are separate from HTTP202 pending visibility, and the latest channel remains unchanged. Publisher96 records upload return separately from verified publication; the scanning procedure requires read-only reconciliation without automatic upload retries. Native R2 publication has not occurred.
The user reports docs 0.1.15 published from 574fd163 (PR596), production deploy 6aa95320 and frozen deploy 6aa9533a, releasing the prior docs hold. This branch preserves that source, including raised code tabs. This guide update itself has not been published.
The retention fixture keeps real October 15 purge deadlines and a held Python reference. Its resumable runner and backup inventory plan do not prove hosted physical purge or Atlas backup erasure. No checkbox closes from this documentation update. Earlier dated observations below remain history.
2026-09-14 — Bindr resource authorization review fix
Independent review of PR481 found that folder access alone permitted filing and displaying independently private or foreign-namespace resources. The candidate now checks the resource on writes and reads, including search. Filing remains namespace-scoped. Accepted Note grants, independent Project grants and existing public catalog policies remain usable; a stored sharing token is never reused as authorization.
Legacy unavailable memberships retain their count and opaque membership ID, but return no resource ID, name, path or Node metadata. Revoking access hides existing membership details. Request-scoped checks use bounded batches. Independent review passed, and the fix is integrated with current main. Validation: the combined 276 tests across nine suites, TypeScript checking and four inventory tests passed; the owned disposable Mongo database was removed. The real HTTP/Mongo suite covers all six resource types, cross-owner grants, revocation, legacy corruption and retirement alongside transactional deletion races. This is an unreleased review candidate, with no shared database migration or deployment. Master247.
2026-09-14 — shared staging reconciliation candidate
Staging #387 now has an isolated candidate combining deployed Bindr membership/tree behavior with main's organizational-reference fences. Canonical and legacy deletion share transactional reference validation, child reparenting and membership cleanup. Canonical member removal retains empty folders; the legacy route retains last-member deletion. This does not add Tasks #301 behavior or enable private Vault delivery.
The compatibility report identifies legacy embedded-member conversion, root/tree checks, name/member indexes and fleet verification required before promotion. Tests use an owned disposable local database. Read-only staging task160 inventory found no legacy arrays, duplicate names/members or tree cycles; canonical indexes already exist. One live Bindr under a retired project has no members, references or live children and is preserved for lifecycle review. The report records a staging conversion no-op with assertions, not a blind schema push. No shared schema apply or deployment is included; review and combined authenticated acceptance remain open.
2026-09-13 — hosted setup review and published rotation clients
Metadata-only setup review UI245 merged at f182b7fce35e3831a7a05cc87511a5078456eb52. Exact-source staging deployment 6aa6f0f5f24f7a00088755f6 and production deployment 6aa6f18ff44f2a0008a4398d passed real WebKit phone and desktop checks without network mocks. Empty selection, metadata readiness, CLI/Python handoff, the current-value warning and selection reset passed; browser secret reads and remote submissions both remained zero. All four owned synthetic entries were retired and reads returned404. Reusable runner, receipts and guide.
CLI 0.18.0 is published to npm/native downloads and Python 0.15.0 to PyPI, with fresh-install and artifact-hash verification. Published-client hosted acceptance now passed all four target/jump rotations against staging433/task155, including a lost committed jump-replacement response recovered in a fresh CLI process. Each step verified restored-key SSH, old-key denial and preserved unrelated authorization bytes. Independent cleanup confirmed two accounts/homes/process sets absent, four bindings released, the owned signing key revoked, eight entries retired/read404 and known local keys absent. The human runner and evidence retain the initial runner key-path failure and same-fixture recovery; this was not an uninterrupted first run. Password probes and reservation wrappers are merged but unreleased. Backend reservation370 and authentication scaffold373 are merged, not deployed; snapshot-aware rollout requires disabling migration on every old writer before deploying the new schema-aware fleet. The remote-delivery design is published; actual selected-value delivery, remote task execution and verified password mutation/recovery remain unfinished.
Provider checks also progressed: AWS context acceptance verifies matching context succeeds and wrong/missing context fails. Dedicated GCP acceptance verifies SDK/adapter roundtrip, AAD rejection, permission denial/recovery and permission cleanup. GCP used explicit short-lived identity impersonation, not the hosted backend/default workload-identity path. Neither check proves second-tenant application authorization, cross-provider migration, backup erasure or production promotion.
Earlier entries below record their status at the time. Use Vault #241 and the master plan for current acceptance gates.
2026-09-13 — explicit host cleanup attestation (under review)
The host credential rotation plan now defines an owner-only cleanup confirmation and single-binding metadata lookup. Exact retries recover a confirmed response; altered proof and changed/released/stale/expired replacements fail closed. Confirmation serializes against subsequent binding replacement and retirement, releasing only the completed historical retention references. The proof is client-attested; this API performs no SSH operation and does not retire shared entries.
Local validation: 159 combined backend Vault tests and typecheck passed, including 12 real HTTP/Mongo supersession and cleanup tests covering response-loss replay, second-owner denial, stale/expired/released bindings, concurrent following replacement and aged GC. Paired CLI/Python key-rotation orchestration and remote acceptance remain separate work under Vault #241. This backend addition is under review, not released or deployed.
2026-09-13 — web file saving accepted on staging and production
Frontend PR241 merged
9cc0c3d after all CI gates passed. Staging deploy 6aa6d8a422ac9800082c0908
and production deploy 6aa6d9a7bd2306000851b791 used that exact source. Real
Chromium desktop/mobile flows passed on both sites: invalid binary input rejected
before upload, masked drafts, explicit save, exact BOM/CRLF bytes, output basename
and no browser secret persistence. Each environment's two synthetic entries were
retired and independently rechecked; zero cleanup failures.
Receipts and procedure distinguish the existing staging and production account contexts. No user keys were read and no staging token was reused on production. Fresh OAuth, second real owner, export/download, full remote setup UI and physical purge are not claimed. Production string-entry acceptance does not establish production host saving or HOTP rollout. Paired CLI/Python and web guide.
2026-09-13 — published npm host saving verified
Fresh registry npm CLI 0.16.0 and PyPI Python 0.13.0 passed nine behavioral
groups on staging c49dc1d / task 152, using the actual npm wrapper and separate
disposable target/jump identities. Selected password descriptors reached the
native client, four entries were saved/bound, both clients replayed the same
identities, and saving failure preserved enrollment. Signed reconnect, restored
fresh two-hop SSH with wrong-key denials and a tracked task passed.
Exact package/task evidence and cleanup confirm two accounts/homes removed, signing keys revoked, four bindings released, four entries retired/read404 and local generated secrets removed. This closes the published npm-FD gate from #241 and #247. Remote password authentication, rotation/revocation product flows and production host saving remain separate. Human procedure.
2026-09-13 — recoverable host credential replacement
Merged, unreleased: Host rotation plan adds a conditional binding replacement and owner-only operation recovery, with paired CLI/Python APIs. Immutable old/new references remain retained while remote cleanup is pending. No SSH changes, delegation or remote revocation are performed. Password rotation and explicit cleanup confirmation remain open under #241 and #247.
Local validation passed: 144 backend Vault tests, followed by all seven focused supersession tests including added expiry/stale-current and concurrent retirement/purge checks; CLI 932 tests; Python 528 tests with 60 skips; paired fresh-process CLI/Python recovery after a dropped committed response. Type checks, Prisma validation, docs build, generated-reference check and rendered CLI/Python tabs passed. Merge, package release, deployment and hosted verification remain separate gates.
2026-09-13 — fresh EKS clients and scheduled cleanup
A fresh isolated EKS Pod passed the source suite and separately installed npm
CLI 0.16.0 / PyPI Python 0.13.0 pagination and HOTP checks, including a
second synthetic owner. The actual registerVaultRuntime timer purged one aged
synthetic retired entry with one redacted audit row; active, expired-only,
future-retention and unreleased-bound controls survived a subsequent tick.
There was no direct collector invocation or production retention change.
Procedure and exact evidence record Pod/image/source hashes, real AWS KMS/Pod Identity, the fresh-exec Node PATH guide correction, and completed cleanup. Owned server/Mongo processes and the temporary database were removed, the namespace was verified absent, exactly three test IAM resources were destroyed, and the SSM tunnel closed. The existing cluster and KMS key remain. This does not establish production physical GC, backup erasure or a second real hosted account.
2026-09-13 — published pagination and HOTP on staging
CLI 0.16.0 and Python 0.13.0, freshly installed from npm/PyPI, passed
207-entry pagination and cross-client continuation against staging c49dc1d,
sole task 152. HOTP checks used real GPG imports, explicit counter ownership,
and two committed response losses per client followed by process-restart replay.
Five HOTP entries and 207 pagination entries were retired; active counts/read
checks confirmed cleanup. The hosted service uses its configured AWS KMS; the
HOTP runner does not independently attest the encryption provider.
Hosted UI d44ca49 on staging.dreamlake.ai made real requests to
staging-api.dreamlake.ai. Desktop and mobile each traversed five pages capped
at 100 entries and displayed all 207 uniquely prefixed synthetic rows. HOTP had
metadata/lifecycle controls only; no secret reads occurred. Its 207 entries were
retired with zero active remaining. A cleanup harness initially sent an empty
DELETE with a JSON content type; a corrected request completed cleanup without
changing product code.
Procedures and sanitized evidence record source, deployment and package provenance. These checks reused an existing authenticated account token. Fresh OAuth login and a second owner were not tested. Production backend pagination/HOTP remain separate. EKS scheduled-GC evidence is recorded above; these hosted retirements do not establish physical purge or backup erasure.
2026-09-13 — hosted enrollment saving and production identity fix
Snapshot verified at 16:09 UTC: staging a11e815, sole task 151, passed
real Nymph enrollment with published native CLI 0.15.0 and PyPI Python 0.12.0.
Ten checks cover separate target/jump credentials, exact password bytes,
CLI/Python replay and independent saving failure, signed reconnect, vault-restored
fresh two-hop SSH, wrong-key denials and a successful tracked run. The two fresh
Unix accounts, signing keys, four bindings and four entries were cleaned up.
Procedure, deployment, package hashes and sanitized evidence distinguish
this from the earlier isolated bos14 test.
The published npm 0.15.0 launcher drops password descriptors above 2. The
released native executable passed; a separately copied unreleased launcher
candidate also passed live replay. These are distinct claims. Password storage
was tested, not remote password authentication. The fixture configured only its
owned manager PATH for uv. Production host saving, automatic rotation/revocation,
physical purge and backup erasure remain separate gates.
Production #330 was promoted without removing target changes: exact 5e4dfa6,
sole task 111, image digest and health verified. Seven fresh npm CLI 0.13.0 /
PyPI Python 0.10.0 compatibility groups passed; six entries were retired/read-404
and one scoped key revoked/reuse-401. The linked evidence includes this separate
production result. It does not replace isolated Mongo race tests.
2026-09-13 — HOTP counter authority
Released in CLI 0.16.0/Python 0.13.0; hosted staging acceptance is recorded above. Production backend acceptance remains separate. HOTP imports default inactive; explicit ownership activation normalizes the pass counter. Owner generation commits an encrypted counter and 24-hour encrypted receipt together. Paired CLI/Python request files preserve immutable retry intent across process restarts. The HOTP guide records released commands, source conventions, tests and remaining production gates.
Earlier recovery/TOTP snapshot: Production API 3b1ad31, task 109, and staging task 147 are deployed with separate managed AWS KMS keys. Production recovery/TOTP acceptance passed with fresh npm CLI 0.13.0 and PyPI Python 0.10.0 installations. The previous released clients also passed compatibility checks. Native downloads and the CLI documentation site are at 0.13.0. Hosted browser entry create, reveal/hide, replacement, retirement and restore passed. Scoped-key UI and entry-expiry controls are deployed and verified on staging and production; current UI source is ec0a24e, including verified entry-write recovery.
Tracking: Vault #241,
master #247.
2026-09-13 — metadata pagination
Merged backend #342 HTTP pages bound Mongo reads to at most 201 matching rows (200 output
plus one continuation probe), with tenant/prefix/retirement/scoped identity filters
applied before the limit. CLI and Python drain pages while preserving existing
complete-list output; explicit page controls return nextCursor. The legacy HTTP
path remains unbounded until UI/older clients migrate. See the
pagination guide for examples and weak-consistency
semantics. Local real Mongo/HTTP acceptance is not deployment evidence.
2026-09-13 — explicit host reference release
Released CLI 0.16 vault unbind and Python 0.13 unbind_host_credential release
an account-owned retention reference using exact binding/entry identities. This
works after host deletion. Retries preserve the original release timestamp;
scoped keys and other accounts cannot release it. Unbinding does not revoke SSH
access or delete an active secret. Retired entries still wait for their existing
purge deadline. Remote rotation and revocation remain separate lifecycle work.
Real HTTP/Mongo CLI/Python checks passed for release/retry and continued active
secret retrieval. Native Mongo tests cover foreign/scoped denial, stale metadata,
host deletion and delayed GC. Backend #339 is merged and deployed on staging in
a11e815; hosted exact-ID release and retirement passed above. CLI/Python unbind is released in 0.16/0.13; production backend deployment
remains separate.
2026-09-13 — real SSH credential-saving snapshot
Bos14 passed synthetic target/jump saving, exact key restoration, fresh two-hop SSH and independent target/jump denial using a candidate wheel. Procedure and sanitized hashes record all cleanup, including 16 retired entries across attempts. The runner uses an owned home directory with StrictModes enabled and a standard venv.
This used isolated native Mongo/test encryption through a reverse tunnel and synthetic enrollment records. It does not prove real Nymph enrollment, AWS KMS, published clients, final PR heads or hosted deployment. This historical snapshot preceded backend #336, CLI #47 and Python #34 releases. The later hosted acceptance above proves real enrollment and published native client saving; it does not change this isolated test's scope.
2026-09-13 — backend developer references
The backend Vault README and TOTP reference now reflect deployed startup wiring, released clients and production acceptance. Local synthetic runner commands remain available. General entry-write receipts are distinguished from OTP import's unknown-outcome handling; durable import recovery is not implied. This is a reference correction only; no runtime or additional acceptance is changed.
2026-09-13 — scheduled entry ciphertext cleanup
The actual runtime timer passed isolated EKS physical-purge acceptance above. Production physical GC and backup erasure remain unproved. The runtime schedules bounded entry cleanup after soft retirement retention. Transactions recheck entry identity/revision and unreleased host bindings, then record a redacted audit with the deletion. The scan cursor advances past bound rows; expired-only and active unbound entries remain untouched. Retention defaults to 30 days and is captured at retirement.
Operator policy and acceptance guide covers configuration, disabling cleanup, audit retention and backup limitations. All 123 Vault tests and server typecheck passed, including real-Mongo overlapping collectors, bound-first-page progress, restore/bind races, audit rollback and recurring first-row failure recovery. Backup erasure and remote credential revocation are not established by this work.
2026-09-13 — current credential guide
The credential guide and linked remote-agent/import pages now distinguish released entry, SSH/TOTP and scoped-key operations from unsupported host enrollment saving, HOTP and remote lifecycle integration. Selected TOTP upload and generation have paired CLI/Python examples. Repeated pre-release status paragraphs were removed; historical remote/EKS evidence remains linked. This documentation correction follows production evidence in #307, #311 and #314–#317; it does not change the runtime or establish additional live acceptance.
2026-09-13 — purged entry identity protection
Production verified at 5e4dfa6, task 111. Replacement and restore compare the immutable
entry ID as well as its name and revision. Revisions restart when a purged name
is reused; a delayed operation for the previous entry must return
REVISION_CONFLICT instead of overwriting or resurrecting it. Receipt-backed
writes use the same check and leave no committed receipt on conflict.
Three deterministic regressions failed against the previous implementation on an isolated Mongo replica set and passed with the fix. All 112 Vault tests and server typecheck passed with isolated frozen dependencies. Entry GC scheduling, binding-aware purge and backup retention remain separate work.
2026-09-13 — entry write recovery
Frontend #237 and PR #238 add recovery after an entry create or replacement loses its response. Pending request IDs survive a browser reload. Check result fetches the committed revision and receipt retention deadline. Open current entry metadata loads the latest state separately; a receipt does not describe later replacements.
The browser records a random request ID and start time before submitting. It saves no entry name, secret value or bearer token with that record. If storage fails, submission is blocked. Submitted values are cleared and writes are never retried automatically. A missing receipt is inconclusive: the write may still be in progress or the receipt may have expired. Copy an ID before forgetting it if it may be needed later. Forgetting removes only the browser's reference.
82 local tests, five Chromium tests, typecheck and production build passed. The
browser fault test commits through the real backend and discards the response,
then reloads and checks the original receipt after a later replacement. It checks
that no write is replayed and no secret is read. All CI checks passed and PR #238
is merged. Staging source ec0a24e passed hosted response-loss/reload recovery:
the receipt showed revision 2 while fresh current metadata showed revision 3.
Creation and receipt lookup used normal browser CORS. The test deliberately
discarded one response after the real replacement committed. Cleanup retired the
entry at revision 4 and confirmed reads returned 404. Production deployed the
same source and passed the same checks, including cleanup at revision 4/read 404.
Deployment and acceptance evidence.
Both tests used existing owned sessions; fresh login and second-owner hosted
browser acceptance remain separate. Ge review/testing is unconfirmed.
Hosted procedure · Synthetic mobile metadata.
How to test
- Submit a synthetic entry or replacement. If its response is lost, close the dialog and reload the Vault page.
- In Entry write recovery, choose Check result beside the saved ID. Compare the receipt revision with Open current entry metadata.
- Copy the request ID if it needs to be retained. Forget request ID requires confirmation and does not undo the write or delete its server receipt.
- Retire the synthetic entry after testing.
2026-09-13 — entry expiry controls
Frontend #235 adds expiry choices to personal Vault entry creation and replacement. Creation supports no expiry or a future UTC timestamp. Replacement keeps the exact stored expiry by default, with explicit choices to set or remove it. Replacement still requires the complete value and the current revision; it never loads the old secret.
Keeping expiry omits the expiresAt field. This preserves subsecond precision and already-expired dates; replacing a value alone cannot reactivate an expired entry. Explicit removal sends null. Revealed values clear at expiry or after 30 seconds, whichever comes first. Expiry does not retire entries or change access-key lifetime.
68 local tests passed, including real-backend expiry, preserve/set/clear and stale
revision rejection. Four Chromium tests, typecheck and production build also passed.
All CI checks passed with a 4 GiB heap scoped to the production-build CI step,
resolving the earlier SSR heap exhaustion. UI PR #236
is merged. Staging source 25a1a2d passed UTC creation, preserve/set/remove,
reveal clearing at expiry and expired-read denial. Replacing an expired value kept
it unreadable; explicit expiry removal restored reads. Cleanup retired the entry
at revision 7 and confirmed reads returned 404. Production deployed the same source
and passed the same checks, including cleanup at revision 7/read 404.
Deployment and acceptance evidence.
Both checks used existing owned sessions; fresh login and second-owner hosted
browser acceptance remain separate.
Hosted procedure · Synthetic mobile metadata. Ge review/testing is unconfirmed. This uses the existing entry-write API; TOTP editing remains a separate UI follow-up.
How to test
- Create a synthetic string entry, choose Set a future expiry, and enter a UTC date/time. Check its metadata after saving.
- Replace the complete value with Keep existing expiry. The timestamp must remain unchanged, including fractional seconds.
- Replace again with Remove expiry. Metadata should show no expiry.
- Set a short future expiry, reveal the value, and wait. The UI should hide it at expiry, and a new read should be denied.
- Retire the synthetic entry after testing. Restore must not extend expiry.
2026-09-13 — scoped access-key UI
Frontend #233 and PR #234 add key management to the personal Vault tab. Select string entries and optional named fields, choose fixed-expiry, one-time or renewable access, then create and save the token. Selection starts empty. Listing entries and keys does not read secret values.
The token is delivered once. Closing the view, refreshing keys, hiding the page or changing authentication clears it. Copies remain in the clipboard. Lost responses retain the issuance request ID for metadata reconciliation; revoke the matching key before explicitly creating a replacement. No write is retried automatically. Renewal preserves scopes and lifetime limits. Revocation requires confirmation. TOTP selection remains in CLI/Python.
Local validation passed 52 transport/component/real-Mongo HTTP tests, three
Chromium desktop/mobile tests, TypeScript, the production build and full CI.
Frontend PR #234 is merged.
Staging source 5e174d6 passed real-browser issuance with selected fields,
reveal/clear, renewal and confirmed revocation. Excluded fields returned 404;
revoked tokens returned 401. Test keys were revoked and entries retired.
Production deployed the same 5e174d6 source and passed the same hosted browser
checks. Its test key was revoked (401) and entry retired (404). Backend production
task 109 and staging task 147 remained unchanged. Ge review/testing is unconfirmed.
Deployment and acceptance evidence.
Hosted acceptance procedure. Existing-session tests do not establish fresh OAuth login or second-owner hosted browser acceptance. A synthetic scoped-key row was checked at mobile size after clearing the token. Mobile metadata screenshot.
How to test
- Open your personal Vault tab and select Manage access keys.
- Confirm nothing is selected. Choose a test entry and, for a named-field entry, enter only the field names to share. Blank fields grant the whole entry.
- Create a renewable key, reveal or copy its token, then clear it. Confirm the selected field is readable and an unselected field is unavailable.
- Renew the key, then revoke it with confirmation. Further reads should fail.
- Refresh metadata after an uncertain creation; match its request ID and revoke that key before creating a replacement. Never expect a replay to return a token.
2026-09-13 — scheduled access-key metadata cleanup
Issue #312 wires terminal access-key cleanup into the enabled Vault runtime. One pass per minute per process removes at most 100 records by default, after the existing 30-day retention period. Active keys and retained issuance receipts remain available. Deletion rechecks eligibility, including changes after candidate selection.
The worker logs a fixed result code and aggregate count, recovers after transient errors, and waits for an active pass before closing Mongo. Existing policy settings control batch size and retention. Entry ciphertext, host access and tenant guard records have separate cleanup requirements.
How to test
Integration tests create an isolated local Mongo replica set with synthetic values. They check global batching, concurrent collectors, retention/replay, active-key preservation and an eligibility change between selection and deletion. Scheduler tests check no overlap, shutdown and redacted failure recovery. All 17 focused tests and full CI passed; #313 is merged.
Staging rollout 34750951729
completed on task 147, source 3b1ad31, with the running image digest verified.
Two scheduled passes ran 60.009 seconds apart. Active-key access remained valid,
and active, revoked and consumed issuance records replayed without returning new
tokens. Cleanup revoked the fixture keys (401) and retired its entry (404).
Both live passes deleted zero records; aged deletion was tested only in isolated
Mongo fixtures. Live retention was not shortened and records were not backdated.
Production rollout 34751624060 completed on task 109 with the same source and a verified running image digest. Two passes ran 60.002 seconds apart, preserving active-key access and issuance replay for active, revoked and consumed records. Both passes deleted zero records. All fixture keys were revoked (401) and the entry retired (404). Ge review/testing remains unconfirmed. Evidence · Hosted test procedure.
2026-09-13 — browser conditional writes
The API now allows If-Match through CORS. This fixes browser replacement,
retirement and restore, which previously failed preflight before reaching Vault.
PR #309 passed full CI;
all six focused CORS tests passed, including three regressions that failed before
the fix. Arbitrary headers remain disallowed.
The hosted production browser passed create, explicit reveal/hide, replacement, confirmed retirement and restore. The restored value matched the replacement. Final retirement reached revision 5; an independent authenticated API read returned 404. This used one synthetic string entry and the existing signed-in owner session. Fresh login, a second owner and other UI features were not covered.
The same source dfee12b passed staging rollout 34749386321
(task 146) and production rollout 34749886763
(task 108). Six preflight/authenticated API checks passed in each environment,
including stale-revision rejection and retirement/restore. Both synthetic API
fixtures were retired and reads returned 404. Running image digests matched ECR.
Staging browser OAuth stopped at new-account setup; no account was created.
See the deployment and acceptance evidence.
How to test
- Open your account's Vault page and create an entry with a synthetic string.
- Reveal and hide it, then replace the value. Verify the revision increases.
- Retire the entry, restore it, and reveal the preserved replacement.
- Retire the test entry again. Its metadata should show Retired, and reads should fail.
The CLI documentation and its 0.13.0 snapshot are published at 848a72, including the corrected release availability text from CLI #44. The version manifest and rendered page version were checked on both URLs. The Netlify site has no Git build connection, so the snapshot was uploaded from the same production build.
Track delivery and deployment evidence in #308.
2026-09-13 — production recovery and TOTP acceptance
Deployment 34747817398
promoted the staging-verified backend 1fe1cb2 to production task 107.
The canary, final bake and cleanup completed successfully, and the running image
was verified. The production KMS key and its runtime role were retained.
Seven production check groups passed first with locally built release clients,
then with fresh npm CLI 0.13.0 and PyPI Python 0.10.0 installations. Both clients recovered receipts after dropped
committed responses, and replay preserved later replacements. Selected GPG TOTP
imports excluded unselected entries and adjacent passwords; generated codes
matched independent HMAC calculations. Scoped-access denial, metadata redaction,
expiry, retirement and restore passed. Each run retired its six synthetic entries
(read 404) and revoked its scoped key (reuse 401).
The previously released CLI 0.12.0 and Python 0.9.0 GitHub wheel passed nine
compatibility checks against this backend, including selected-only SSH imports,
revision conflicts, scoped-key isolation, one-time retrieval, metadata and
retirement/restore. Both synthetic entries were retired and the key revoked.
Release preparation merged in CLI #41
and Python #31. All eight CLI
platforms built with embedded-WASM checks; the installed Python wheel passed
102 focused OTP/import/recovery tests. Python 0.10.0 is published on PyPI,
with wheel and sdist hashes matching the tested artifacts. The matching GitHub release
is also published with verified wheel and sdist hashes. Versioned CLI
downloads and all nine npm packages passed checksum read-back verification.
The native latest pointer is 0.13.0; a fresh macOS ARM64 download passed
checksum, version and command-help checks. This check did not change the user’s
installed launcher. Release tracking: CLI #40
and Python #30.
A fresh Linux x64 pod also completed the full official install.sh bootstrap
into its default home. The installed launcher reported 0.13.0; its binary
matched the release manifest, and write-status/OTP command-help checks passed.
The pod had no mounted service-account token or credentials and created no
authentication file. The owned pod and namespace were removed, and the dedicated
SSM tunnel and local port were closed. The existing test cluster was retained.
See the production evidence and repeatable procedure. Authenticated second-owner receipt isolation, remaining UI coverage, project integration, HOTP, remaining lifecycle/garbage collection and Ge review/testing remain open.
2026-09-13 — recovery and TOTP verified on staging
Backend #293,
CLI #39 and
Python #29 are merged,
including the Python destination/authentication and write-uncertainty fixes.
Deployment 34745495993
completed on staging task 145, using its existing managed AWS KMS key.
Seven hosted check groups passed with merged source clients. Both clients recovered receipts after dropped committed responses; identical replays preserved later replacements. Selected GPG TOTP imports excluded unselected entries and adjacent passwords, and generated codes matched independent HMAC calculations. Scoped credentials could not write entries, query receipts or generate codes. Metadata redaction, expiry, retirement and restore checks passed. Cleanup retired all six final-run entries (read 404) and revoked the scoped key (reuse 401).
The runner and evidence in #303
pin backend 1fe1cb2, CLI 66bcb32 and Python 6fa1fc9. The recorded run used
source checkouts. It does not validate published packages, production, browser
login/CORS or receipt isolation between two authenticated owners. The cross-owner
path and scoped-key denial checks do not replace that second-owner test.
Independent review passed TypeScript, 102 server Vault tests, 94 Python
OTP/recovery regressions, 16 CLI tests and real HTTP/Mongo/GPG/client acceptance.
Reviewed heads were server 30b6a1d, CLI 4b93666 and Python 3c96af5.
These counts describe the focused independent review, not the full project suites.
Account UI #230 is also merged; its local browser evidence is separate from hosted UI acceptance. The production result above supersedes the staging-only rollout status. Project integration, HOTP, remaining credential lifecycle/garbage collection and Ge review/testing remain open in #241.
2026-09-13 — entry write recovery merged
Merged and production-verified; client release status is recorded above. Server #292, CLI #38 and Python #28 add recovery for an entry create/replace whose response was lost.
Keep a non-secret request ID before submitting a write. The server commits the entry and its receipt together. Looking up the ID returns the original committed metadata without revealing the secret. Retrying the identical input and revision with the same ID returns that receipt; it does not overwrite a newer value. Changed input or revision conflicts. Only the owning account can query receipts.
Updated clients require the receipt-capable server. These examples apply to the merged development versions, not CLI 0.12.0 or Python 0.9.0:
secure-secret-producer | dreamlake vault add -n alice/service --stdin --request-id service-write-001
dreamlake vault write-status --request-id service-write-001from dreamlake.vault import VaultWriteError
request_id = "service-write-001" # retain before submission
try:
client.vault.add("alice/service", secret, request_id=request_id)
except VaultWriteError as error:
if error.outcome != "unknown":
raise
receipt = client.vault.write_status(request_id=request_id)Receipts expire after 30 days. Missing status does not prove failure, and an ID must not be blindly reused after retention expires. Status lookup does not decrypt through KMS; replay validates the request using an encrypted HMAC key. Receipts retain metadata and the keyed fingerprint, not another copy of the entry value. Retirement/restore and OTP generation recovery are separate work.
Independent checks passed in isolated checkouts: server TypeScript, 64 server
Vault tests, 10 CLI tests and 42 Python tests. A real native Mongo/HTTP test drove
both clients through dropped committed responses, replay, later-write preservation,
conflicts, tenant denial, diagnostic redaction and byte preservation. Its temporary
fixture was shut down. Reviewed source: server 51eff62, CLI f5fbba1, Python
399b917; merged source matches those implementations.
Production acceptance and client release status are recorded above. Ge testing remains unconfirmed.
2026-09-13 — production acceptance passed
Production API b85854c passed hosted checks with npm CLI 0.12.0 and the
checksum-verified Python 0.9.0 GitHub release wheel. The separate production
KMS key encrypts stored entries under the production runtime role.
Verification used synthetic SSH material:
- CLI uploaded only the selected profile; Python separately uploaded only the selected key and preserved its bytes. Unselected entries were not uploaded.
- Both clients read the same entries. Equal-value retries kept the revision; replacement required the explicit current revision.
- A one-time key returned only its selected field and then denied reuse. That key could not authenticate ordinary host API requests.
- Anonymous and invalid-token requests were denied. Raw list responses contained no credential values or ciphertext.
- Retirement denied subsequent reads; explicit restore preserved the profile.
Cleanup revoked the scoped key and retired both synthetic entries, with reads
returning 404. No personal SSH keys were uploaded. Retirement retains ciphertext
under the existing policy. Evidence is recorded in
infra/vault/production-acceptance.json.
Deployment 34743943704 completed successfully after the canary and final observation periods. Project/UI integration, OTP upload/generation, host credential lifecycle and garbage collection remain open in #241. Python 0.9.0 is available from GitHub Releases; PyPI publication remains pending. Ge review and testing have not been confirmed.
2026-09-12 — production key readiness
Production now has its own managed KMS key with automatic rotation. Its runtime
role can generate data keys and decrypt only with that key, with the Vault
encryption context present. The key and role policy are recorded in
infra/vault/production.json.
An isolated ECS task used the staging-verified API image and the production task
role. It verified its AWS identity, encrypted and decrypted a synthetic value,
and rejected an altered encryption context. It received no application database
or login credentials. The first attempt stopped during image pull; one retry
with the same image and task definition passed and exited 0. The temporary task
definition was deregistered and deletion requested. Results are recorded in
infra/vault/production-kms-verification.json.
Production API revision d6914a5 remains on task definition 105, with Vault
disabled. This check establishes production KMS readiness; API deployment and
hosted acceptance still remain. Ge review/testing is also pending.
2026-09-12 — staging acceptance passed
PR #287 corrected
account resolution. The signed-in account now accesses Vault through the hosted
staging API. Verification used npm CLI 0.12.0 and the Python 0.9.0 GitHub
release wheel, whose SHA-256 matched its release metadata.
The checks passed with synthetic SSH material:
- CLI uploaded only the selected profile; Python separately uploaded only the selected key and preserved its bytes. Unselected profiles, keys and jump-host references did not trigger additional uploads.
- Both clients read the same entries. Equal-value retries kept revision 1; replacement required the explicit current revision and advanced it to 2.
- A one-time key returned only the selected field, then denied reuse. It could not authenticate ordinary host API requests.
- Anonymous and invalid-token requests were denied. Raw list responses contained neither credential values nor ciphertext.
Cleanup revoked the scoped key and retired both synthetic entries; subsequent
reads returned 404. Restoring the synthetic profile also passed; it was retired
again after the raw metadata check. Retirement retains ciphertext under the existing retention
policy. No personal SSH keys were uploaded. The recorded results are in
infra/vault/staging-acceptance.json.
This verifies the staged API with released clients. Production activation, project/UI integration, OTP upload and the remaining Vault checklist remain open. Ge review and testing are recorded separately.
2026-09-12 — hosted account validation
PR #284 resolved
the index-name conflict. Staging deployed API revision 55f037d as task definition
vuer-dreamlake-staging:143; the canary rollout completed, health returned 200,
and unauthenticated Vault requests returned 401.
The hosted check used npm CLI 0.12.0 and the Python 0.9.0 wheel from GitHub
Releases, with its release checksum verified. The signed-in account could use
/auth/me and host APIs, but Vault returned 401 before the first upload. No
entries or access keys were created by this attempt.
Normal login omits optional User.deletedAt and Namespace.orgId fields.
Vault's Prisma queries required explicit nulls, excluding these records.
PR #287 accepts
missing or null fields while retaining denial for deleted accounts, deleted
namespaces and organization-owned namespaces. Hosted selected-import and scoped-key
acceptance subsequently passed after that correction was deployed, as recorded above.
2026-09-12 — staging startup failure
The first staging activation failed before serving Vault routes. The isolated
startup diagnostic passed MongoDB connectivity, replica-set validation and the
real AWS KMS round trip. Index creation then failed with IndexOptionsConflict:
Prisma had already created the same indexes with different names.
ECS was rolled back to task definition vuer-dreamlake-staging:141. The service
reached steady state and /health returned 200. The staging enable flag is
false; hosted Vault acceptance remains pending.
Fix #284 reuses existing index names while retaining the required index constraints. It does not drop or rebuild deployed indexes. Tests cover Prisma-created index names, uniqueness and incompatible index options. Deployment must pass startup and selected-import checks before staging activation is recorded here.
2026-09-12 — main API startup integration
The main API now mounts the existing vault route factory when explicitly enabled.
It uses the same DATABASE_URL as the account database, owns its native Mongo
connection, and closes that connection on shutdown or failed startup. Mongo
replica-set checks, required indexes and a KMS encryption round trip must succeed
before startup completes. Database and provider failures return a redacted startup
error.
Vault routes retain their own authentication so both account JWTs and scoped
vault access keys work. Scoped keys do not gain access to ordinary JWT-only routes.
SKIP_AUTH=true cannot enable unauthenticated vault access.
Operator configuration
The ECS workflow passes these GitHub Environment variables to the API:
| Variable | Value |
|---|---|
DREAMLAKE_VAULT_ENABLED | true to opt in; defaults to false. |
DREAMLAKE_VAULT_KMS_PROVIDER | aws-kms or gcp-kms. |
DREAMLAKE_VAULT_KMS_KEY_ID | Managed key ARN or GCP crypto-key resource name. |
DREAMLAKE_VAULT_KMS_REGION | Required AWS KMS region. |
Cloud access uses workload identity. The runtime identity needs access to the selected key before activation. The existing database URI and JWT configuration remain required; no static cloud credentials are added by this change.
Validation and activation
Tests cover disabled startup, invalid configuration, owned connection cleanup, redacted Mongo/KMS failures, JWT/scoped-key separation, single-use keys, native Mongo persistence and cross-tenant read denial. Fixtures use isolated local Mongo and synthetic KMS transports. They do not establish hosted KMS readiness.
Staging was checked at task definition vuer-dreamlake-staging:141, image
f0f9ef7: health returned 200, /v1/vault/entries returned 404 and the task had no
vault environment settings. This change does not activate staging or production.
The staging managed key is provisioned with automatic rotation. A one-off ECS
task using dreamlake-staging-role passed a real KMS encryption/decryption round
trip and rejected an altered encryption context. It used the existing staging
image without application credentials. The task exited 0 and its temporary task
definition was deregistered. Resource identifiers and the scoped role policy are
recorded in infra/vault/staging.json.
Deployment and selected-import checks against the hosted API remain before claiming activation.