Releases: apms-org/cli
Release list
v11.2.0
Changelog for v11.2.0
This release focuses on improving the overall note taking capability by featuring a in-built note editor and a much better one, instead of the slightly underwhelming older one with many bugs.
Features
Note editor completely rebuilt (UX Overhaul)
The previous note editor was a hand-rolled raw-ANSI input loop that felt like a placeholder. It rendered the entire buffer on a single line with a block cursor character, gave no sense of document structure, and cleared the whole screen on every keystroke, which flickered badly on slow connections. Editing was barely usable: arrow up/down did nothing, there was no undo, no word navigation or deletion, no line numbers, no soft wrapping, no status feedback, and no safety net — hitting Esc immediately threw away whatever you had typed. Multiline notes were effectively impossible to write or review, and the editor advertised intrusive "autocorrect" that rewrote words while you were typing them.
v11.2.0 features a replaced editor with a full-screen Bubble Tea TUI built on the charmbracelet stack already declared in go.mod (bubbletea, bubbles/textarea, lipgloss). The new editor:
- Renders a proper document view with line numbers, soft word wrapping, and smooth auto-scrolling (no full-screen clears, no flicker).
- Shows a header bar with the note name and vault space, a status bar with
Ln/Col, character and word counts plus a modified/clean indicator, and a two-row footer listing every keybinding. - Adds undo/redo (Ctrl+Z / Ctrl+Y) with cursor-position restore, capped at 200 snapshots. Snapshot-based undo captures the pre-edit value and cursor location so undoing a change lands you exactly where the edit happened.
- Implements the full standard editing keymap: arrows, Home/End, Ctrl+A/E line start/end, Ctrl+U delete to start of line, Ctrl+K delete to end of line, Ctrl+W delete word backward, Ctrl+D delete character, Ctrl+T transpose, Alt+U/L/C word case transforms, and Ctrl+V paste from the system clipboard (with bracketed-paste support).
- Protects against accidental data loss: Esc (or Ctrl+C) with unsaved changes now asks for confirmation ("Esc again to discard, any other key to continue") instead of nuking the buffer, and Ctrl+C is treated like Esc instead of silently killing the session.
- Saves with Ctrl+S, exactly as before. The non-interactive fallback (plain line input until an empty line) is preserved for piped/scripted usage.
Removed behavior: The old "autocorrect" (teh -> the, etc.) and automatic bracket-pair insertion were dropped; word transformations are still available intentionally via Alt+U/L/C rather than happening mid-keystroke.
Note editor unit test coverage (Testing)
Added 12 unit tests driving the editor model directly: typing and save, multi-line entry, untouched-content preservation, Esc cancel (immediate without changes, confirm-discard with changes), Ctrl+C parity with Esc, undo/redo including cursor restoration on a wrapped multi-line document, and the modified/clean flag lifecycle. pm's CLI smoke tests were also fixed to build the whole package (go build -o … ..) instead of only main.go, since the main package now spans multiple files.
v11.1.0
Release Notes (APM v11.1.0)
This release of APM focused on encryption bug fixes and making the overall user experience much better with less bugs.
Zero nonce for recovery AES-GCM (Critical)
File: src/vault.go — SetRecoveryKey(), CheckRecoveryKey()
Problem: AES-GCM nonce was initialized as a zero-filled byte slice, enabling nonce reuse attacks that could expose encrypted DEK slots.
Fix: Generate random nonce via io.ReadFull(rand.Reader, nonce), prepend to ciphertext. Legacy zero-nonce format preserved for backward compatibility.
Silent error discards and nil panic in SetRecoveryKey (Critical)
File: src/vault.go — SetRecoveryKey()
Problem: aes.NewCipher and cipher.NewGCM errors were silently discarded. An invalid key would cause a nil pointer dereference (panic).
Fix: All errors from aes.NewCipher, cipher.NewGCM, and io.ReadFull are now checked and returned. SetRecoveryKey now returns an error instead of void.
Silent KDF fallback on AES-GCM error (Critical)
File: src/vault.go — DecryptData()
Problem: All AES-GCM errors were silently dropped by nested if err == nil blocks. Corrupted data could produce garbage instead of an error.
Fix: Extracted a tryDecryptAESGCM() helper that properly propagates errors. Tries the standard Argon2id KDF first, then the legacy KDF. Returns a clear error if both fail.
Recovery key uses single SHA-256 instead of KDF (Medium)
File: src/vault.go — DeriveRecoveryKey()
Problem: Single SHA-256 provides negligible brute-force resistance for user-written recovery keys.
Fix: Now uses Argon2id (time=2, mem=64MB, threads=2). Old SHA-256 preserved as deriveRecoveryKeyLegacy() for backward compatibility.
History HMAC signatures use vault salt (public) as signing key (Critical)
File: src/vault.go — logHistory(), VerifyHistoryEntrySignature()
Problem: Vault salt is stored in plaintext in the vault header. Using it as the HMAC key means history signatures provide zero forgery protection.
Fix: Added an AuthKey field to the Vault struct (never serialized, json:"-"). Derived from Argon2id during decryption with make+copy to avoid defer Wipe() aliasing. logHistory() signs with AuthKey, falling back to Salt for legacy vaults. VerifyHistoryEntrySignature() tries AuthKey first, then Salt for backward compatibility.
MCP get_entry silently drops errors (Medium)
File: src/mcp.go — get_entry handler
Problem: rand.Read, encryptEpisodic, and writeToTemp errors were silently discarded. If rand.Read failed, the ephemeral key would be all zeros.
Fix: All three errors are now checked and returned as CallToolResult errors.
DecryptVaultWithDEK missing profile params (Medium)
File: src/vault.go — DecryptVaultWithDEK()
Problem: Vaults opened via the recovery key path lost crypto profile context, potentially causing re-encryption to use the wrong parameters.
Fix: Added vault.CurrentProfileParams = &profile after unmarshalling.
ImportFromJSON ignores wrong password (Info)
File: src/portability.go — ImportFromJSON()
Problem: A wrong password was silently swallowed. The function then tried to parse the encrypted blob as plaintext JSON, producing a confusing error.
Fix: Added a json.Valid(bytes) check. If the data isn't valid JSON and decryption fails, the decryption error is returned immediately.
MCP temp files never cleaned up (Info)
File: src/mcp.go — writeToTemp(), decrypt_entry
Problem: Encrypted vault entry data was written to temp files that only get deleted when decrypt_entry is called. If never called, files linger on disk.
Fix: Added a goroutine that removes the temp file after 5 minutes as a safety net.
zeroString() does not actually zero memory (Critical)
File: src/autofill/daemon.go
Problem: zeroString() allocated a new backing array, copied the string bytes, and zeroed the copy. The original Go string data remained in heap memory.
Fix: Uses unsafe.StringData and unsafe.Slice to get a mutable pointer to the string's actual backing array and zero it in place.
wipeVaultSecrets() misses most secret types (Critical)
File: src/autofill/daemon.go
Problem: Only cleared 4 of ~20 secret-carrying entry types. Left uncleared: SSH keys, banking CVV/details, documents, certificates, WiFi passwords, medical records, travel docs, cloud credentials, CI/CD secrets, software licenses, recovery codes, contacts, K8s secrets, docker registries, SSH configs, and audio/video/photo content.
Fix: Now clears all secret-containing fields across every entry type.
MCP args parse error silently swallowed (Medium)
File: src/mcp.go — ensureMCPMutationAuthorized()
Problem: json.Unmarshal error was silently discarded with an underscore assignment. Malformed arguments were silently treated as a new transaction.
Fix: The error from json.Unmarshal is now returned to the caller.
os.MkdirAll errors silently ignored (Medium)
Files: src/mcp.go, src/mcp_transactions.go, src/ephemeral_session.go
Problem: Config directory creation errors were silently discarded. If the directory couldn't be created, subsequent file writes would fail with confusing errors.
Fix: Errors are now captured and documented instead of silently discarded.
cleanupCmd leaks orphan shell processes (Medium)
Files: src/session.go, team/session.go
Problem: Background shell commands (sh -c "sleep N && rm -f ...") were never managed or killed. If APM crashes, orphaned sleep processes survive for the full session duration.
Fix: Removed the shell-based cleanup entirely. The existing Go goroutine in CreateSession already handles cleanup natively.
Corrupted session key causes silent rekey (Info)
File: src/session.go — getSessionKey()
Problem: If the stored session key file was corrupted (invalid base64 or wrong length), a new key was silently generated, making all existing sessions undecryptable.
Fix: Now returns an error ("session key file <path> contains invalid key data") instead of silently regenerating.
Mail feature removed (Cleanup)
Files: src/autofill/mail.go (deleted), src/autofill/types.go, src/autofill/daemon.go, src/autofill/paths.go, src/autofill/system_intelligent.go, src/autofill/system_engine.go, src/autofill/system_engine_windows.go, src/autofill/system_engine_stub.go, main.go, src/autofillcmd/commands.go, src/autofillcmd/autostart_stub.go, src/autofillcmd/autostart_windows.go
The Gmail OTP autocomplete feature (mail.go) has been fully removed:
- Deleted
mail.go(SetupGmail,MailConfigured,DisconnectGmail,mailCache, etc.) - Removed
MailOnlyandMailHotkeyfromRequestContextintypes.go - Removed
mailHotkeyfromDaemon.RunOptionsand theDaemonstruct - Removed
mailConfigFilePathfrompaths.go - Updated
SystemEngine.Start()to a single hotkey signature (removed the mailHotkeyparameter) - Removed the
fieldIntentMailOTPconstant, replaced all references withfieldIntentTOTP - Removed
TriggerMailOTPFillForActiveWindowfromcommands.go - Removed
--mail-hotkeyfrom autostart systemd units, launchd plists, and Windows Registry commands - Removed
defaultMailHotkey()and themailHotkeyparameter fromEnableAutofillAutostart - Removed
buildAutocompleteMailCommand()frommain.go
Autocomplete command tree removed (Cleanup)
File: main.go
The entire apm autocomplete command tree has been removed to eliminate confusion between autofill and autocomplete:
- Removed
autocompleteCmd(enable/disable/start/stop/status/window/link-totp) - Removed
setAutocompletePopupDisabled() - Removed
buildAutocompleteFillCommand()wrapper function rootCmd.AddCommandnow only registers theautofillcommand
Autofill system removed entirely (Cleanup)
The entire autofill system has been removed from the project:
- Deleted
src/autofill/andsrc/autofillcmd/directories (all daemon, popup, system engine, matching, profiles, client, commands, and autostart code) - Removed
autofillcmdimport and all call sites frommain.go(UnlockDaemonWithPassword,LockDaemonIfRunning,NewAutofillAndVaultCommands) - Removed
rootCmd.AddCommand(autofillCmd)registration - Removed
docs/autofill_windows.md - Updated README,
docs/index.md,docs/features.md,docs/reference/cli.mdto remove autofill references
Encryption Bug Fixes (Part II)
Fix #1: Zero nonce for master slot AES-GCM (Critical)
File: src/vault.go — EncryptVault(), decryptNewVault()
Problem: The master slot (DEK encrypted under the master-derived key) used a zero nonce via mNonce := make([]byte, masterSlotAEAD.NonceSize()) with no random fill. Every vault save with the same master password produced an identical encrypted DEK slot, breaking AES-GCM's security guarantees.
Fix: Derived the master slot nonce from SHA-256(salt). Since GenerateSalt creates a new random salt on every save, each save gets a unique nonce. No format change required. On decrypt, the search loop tries the salt-derived nonce first, then falls back to the zero nonce for vaults created before the fix.
Fix #2: Wipe() may be compiler-optimized away (Medium)
File: src/utils.go — Wipe()
Problem: Go's dead-code elimination can legally elide the zeroing loop since the slice is only written to and never read afterwards.
Fix: Added runtime.KeepAlive(b) after the loop, which forces the compiler to treat b as still live at that point, preventing optimization.
Fix #3: EncryptData/DecryptData missing Encrypt-then-MAC (Medium)
File: src/vault.go — EncryptData(), DecryptData()
Problem:...
v11.0.0
Release Notes (v11.0.0)
This release has been focused on decluttering APM and finally releasing a version after months of inactivity. For the past 3 months, I had been working on the APM-GUI, now abandoned, because it was a lot of pressure to maintain it along with APM-CLI. However, I also had decided to port this to rust, because of faceID slowness. I realised instead of developing my own FaceID framework, I can use the OS biometric authentication, which is way more secure. Overall, it were a bunch of dumb decisions that has made this release late, and a lot of testing.
Cleanup
- Removed the FaceID framework completely.
- Removed
vocabentirely, as it did not suit APM. - Removed
brutetestcommand, since it was not useful. - Removed the
auditcommand and completely replaced it withlgit. As discussed in #35
Features Added
- Added support for touchID (fingerprint) on macbooks.
- Added
cleanupcommand which fixes your vault automatically. As your vault grows, changes get added and removed, and sometimes vault operations can fail because of unrecognised sections and entries. Thecleanupcommand automatically cleans up everything that is unused, deprecated, or not recognised by asking you permission.
-
Added automatic cleanup. Sometimes vaults can fail for no reason. Hence, while trying to decrypt your vault APM automatically detects unrecognised or outdated vaults and asks to automatically fix your vault.
-
Added the replacement for
audit, thelgitcommand. As already discussed, theauditcommand was underwhelming. It did not support multiple features, like proper signing and proper log view. Thelgitcommand supports multiple options and is like a mini-git.
Extras
- deprecate the
auditcommand by @aaravmaloo in #36
Full Changelog: v10.1.1...v11.0.0
can-v10.2.0
Pre-release Notes (Logs + LGit Overhaul)
This pre-release replaces the deprecated audit flow with a new signed logging system and introduces lgit, a git-style history layer for vault snapshots.
Highlights
- Deprecated
pm auditremoved. - New
pm logscommand for unified logs. - Cryptographic signing + verification badges added to logs.
- New
pm lgitcommand group for history operations, integrity checks, rollback, and cleanup.
New: pm logs
pm logs now displays:
- Vault history
- Audit events
- LGit commits
Each record shows:
[VERIFIED]when signature + chain checks pass[UNVERIFIED]otherwise
New: pm lgit command suite
pm lgit tree– show commit historypm lgit log– alias oftreepm lgit status– compare current vault againstHEADpm lgit show [commit|head]– inspect a commitpm lgit verify– verify signed chain integritypm lgit checkout [commit|head]– restore a snapshotpm lgit undo --steps N– rollback N stepspm lgit squash --keep N– compact historypm lgit prune– remove orphan snapshots
Security improvements
- Log entries are now chain-linked (
prev_hash) and signed. - Verification is available directly in CLI output and via
pm lgit verify. - Signing keys are stored in APM config dir with restricted permissions.
Internal behavior changes
- Vault saves now auto-create signed
lgitSAVEcommits. - Undo/checkout operations restore encrypted vault snapshots and append signed history commits.
Compatibility notes
- Older unsigned or legacy log entries may appear as
[UNVERIFIED]. - Legacy history remains readable; verification supports backward-compatible hash validation.
Known pre-release caveats
- This is a pre-release focused on logging/history architecture changes; users should keep regular backups while testing rollback workflows.
- Existing tooling/scripts that call
pm auditshould be migrated topm logs. - Credit to #35
GitHub release notes
- deprecate the
auditcommand by @aaravmaloo in #36
Full Changelog: v10.1.1...can-v10.2.0
v10.1.1
Fixed a issue where in pm get (specifically targeted to windows), the arrow keys would not work, since pwsh accepts many down and up arrow combinations.
- Windows extended key support changelog:
224,72and0,72for Up
224,80and0,80for Down
Expanded ANSI handling to also accept EscO A/Bin addition to Esc[ A/B.
v10.1.0
APM v10.1 Changelog
Summary
APM v10.1 introduces many new features, ranging from faceid unlocks to a new encryption method. THe update is quite small in my opinion, and hence is a superset of v10. v10.1 introduces the inject feature, the diff command, faceid introduction, and the introduction of being able to encrypt your vault using the xchacha-20-poly1305 encryption method.
All the changes mentioned above will be now mentioned in detail below.
FaceID Introduction
I have been trying since v5 to implement faceID, nonetheless, its finally here! It took me a three weeks to just implement this. I forgor bout it and then when I used it personally, I saw inconsistencies and a very inaccurate recognition system. Then I again spent quite the whole weekend fixing it. It also supports very low quality camera as I have.
The AI model is downloaded locally for privacy reasons, stored in APM_install_dir/faceid/models which is around ~166 MB and is stored as a .onnx file. The same models folder stores the detector, the facial embeddings data and much much more.
FaceID requires OpenCV installed. For compiling and development, the tags have now been introduced while go build. Since installing GoCV and OpenCV and compiling it would be a unnecessary effort for someone who may want to collaborate to other parts of the program, the collaborator can easily do that. the tag faceid is used to compile APM with faceID, and all the builds here are compiled with faceID.
For builds with faceID: go build -tags faceid -o pm
For builds with non-faceID: go build -o pm
diff feature for cloud and working with multiple devices on the same vault
diff is the newest feature for cloud category of APM. While working across multiple devices, the user had to push their changes from one machine then completely remove the old vault and then again get the vault. diff feature completely removes the need for that. The diff function allows the user to get a diff object from the cloud vault and then APM compares it against their local vault. The user is then faced with choices to abort, merge all or merge selected changes .
This improves working with different devices on the same vault, since before you had to tamper with backups of vaults, making sure all changes are pushed, etc.
inject feature to completely remove the need for .env files
.env files are very common across many projects, as a way to share secrets without hardcoding them into your code. Now, inject completely removes the need for .env files, since you can now store all your secrets in the APM vault, and then create a .apminject file which lets APM know which secrets to inject, and what to inject those secrets as into the terminal session.
It is basically setting up all .env variables temporarily in a shell. Then, the user can just type apm inject and APM will path-walk (like git) to find the .apminject file.
xchacha20-poly1305 encryption method compatibility
APM now supports the xchacha20-poly1305 encryption method. (Pretty self-explanatory.)
pm autocomplete mail feature
This feature was originally suggested by #34. APM can now connect to G-mail supported clients, and get the login OTP that corporations send directly through Google OAuth2. This will enable APM to only read mails and it will store them into the local memory. After 8 min, the emails are wiped out of memory and the OTP emails are only stored which take up around ~3 megabytes in memory. the keybind ctrl+shift+p is used to fill in the mail OTP, not to be confused with TOTP.
Extra Notes
- pm autocomplete no longer requiring vault to be unlocked.
- fix to pm autocomplete autostart
PRs
- Add faceid as a option to unlock vault by @aaravmaloo in #25
- Add
injectcommand by @aaravmaloo in #26 - (BENCHMARKS COMING SOON)
Full Changelog: v10.0.0...v10.1.0
v10.0.0-stable
v10.0.0 Changelog
High-level summary
v9.1 delivered a stable CLI password manager with core vault, cloud sync, and TOTP workflows. v10 (Next) shifts the product from “secure storage” toward “secure automation and writing workflows.” The headline change is the introduction of system-level autocomplete/autofill with a Windows daemon, which turns APM into an active assistant that can detect contexts and offer smart completions rather than only storing secrets. Around that, v10 adds a richer note-taking ecosystem based on vocabulary indexing and ranking, a more capable recovery and identity verification stack in the auth area, a first-class .apmignore system for controlling what is uploaded to cloud providers, and runtime permission controls for plugins (PACs). These are not isolated changes; they connect, for example, by making sure automation never leaks excluded data, and by enforcing least-privilege when automation is extended via plugins.
Autocomplete introduction (system autofill)
The biggest functional leap from v9.1 to v10 is that APM now runs an autofill daemon on Windows. Instead of relying on browser extensions, the daemon works at the OS level and listens for a global hotkey (default CTRL+SHIFT+L). When it detects a credential-like context in the active window, it can show popup hints that a match is available. On hotkey press, it resolves the best entry and injects the sequence securely without using the clipboard. This is a shift from v9.1’s “vault is passive until queried” model to “vault is context-aware and proactive.”
Key elements introduced in v10:
- A Windows daemon started via
pm autofill start, with manualstopandstatuscommands. - A global hotkey engine with a default binding but configurable on startup.
- A background context watcher that attempts to infer when a login form is active, enabling “autocomplete available” hints.
- A secure, local-only IPC model (loopback + token) so that the daemon never exposes decrypted secrets to the network.
- The ability to link TOTP entries to domains for smarter OTP matching during autofill flows.
In short, v10 brings APM closer to the behavior users expect from modern password managers, but it does it with APM’s existing security posture and local-first approach.
Autocomplete daemon control and UX
v10 also introduces daemon control commands under pm autocomplete, which separate “daemon lifecycle” from “notes vocabulary.” This avoids confusion and makes the mental model clearer: autocomplete can mean system autofill, while vocab refers to notes indexing. The new command group covers autostart on login, manual start/stop, status checks, and a window subcommand that toggles popup hints. This gives users control over the UX without disabling the core engine. You can keep the daemon enabled for hotkey autofill while disabling popups if you prefer a quiet workflow.
The UX improvements include:
- WPF popup hints with intentional styling, fade-in/out animation, and auto-dismiss behavior.
- Support for disable/enable of the popup hints without turning off the daemon itself.
- Clear status output for autostart state, daemon status, hotkey binding, and profile count.
From a product standpoint, this is more than a feature toggle; it’s a full operational surface that makes the daemon safe to use in daily workflows and transparent enough for advanced users to manage.
Auth improvements
v10’s auth improvements expand the recovery and identity verification model so that a lost master password is no longer a single point of failure. The recovery flow now includes multi-step identity verification with time-limited secure tokens, and extends recovery with optional factors that provide additional resilience and security. This is a significant evolution beyond v9.1’s more basic recovery behaviors.
Key enhancements:
- A formal recovery flow with email verification tokens that are stored hashed (not in plaintext) and expire after a short window.
- Support for recovery keys that unlock the DEK (Data Encryption Key) when paired with verified identity.
- Optional recovery passkeys using WebAuthn to add a local, user-controlled factor.
- Optional one-time recovery codes as a backup factor for users who want printable or offline recovery options.
- Support for quorum recovery flows with trustee shares, allowing threshold-based recovery in higher-assurance setups.
These additions emphasize that recovery should be both secure and practical. v10’s recovery architecture keeps APM’s zero-knowledge guarantees intact while adding a layered, modern identity verification model.
Note-taking improvements
v10 puts real focus on notes as first-class data, not just secondary text attached to entries. The CLI and internal data model now support a “vocabulary-driven” notes experience. That means APM can index and rank words from secure notes, use aliases to normalize terminology, and offer autocomplete suggestions that evolve based on usage. The result is faster searching, more consistent naming, and a smoother writing flow inside the vault.
The improvements cover:
- Vocabulary indexing that can be enabled or disabled independently of the system autofill daemon.
- Commands to view vocab, create aliases, list aliases, remove aliases, adjust ranking, and reindex on demand.
- Automatic reindexing when notes change, keeping the vocabulary current without manual intervention.
- Storage of the vocabulary in compressed form inside the vault to reduce footprint while preserving functionality.
This feature set is more than convenience. It makes APM a better notes tool for long-lived knowledge, especially for users who store secure documentation, server notes, recovery steps, or procedural guides in the vault.
.apmignore support
v10 introduces .apmignore as a first-class control surface for cloud sync. Where v9.1 assumed “everything in the vault is eligible for upload,” v10 allows precise control over what gets serialized to the cloud on a per-space, per-entry, or per-provider basis. This is a practical privacy tool for users who want to keep certain data local, keep vault size lean, or separate personal data from work data when syncing to different providers.
Highlights of .apmignore:
- Ignore whole spaces by name or pattern.
- Ignore entries by
space:type:namewith wildcard support. - Apply provider-specific ignore rules to selectively exclude data from one cloud provider while still syncing it to another.
- Separate vocabulary filtering via the
[vocab]section and theignore:vocabflag, which strips the compressed vocabulary from uploads. - Clear rule syntax with a dedicated guide and example file so teams can standardize usage.
This feature directly answers a common complaint about cloud sync: “I want the vault to sync, but not all of it, and not everywhere.” v10 finally makes that possible without splitting into multiple vaults.
Vocabulary for writing better notes
While related to note-taking improvements, vocabulary deserves its own callout because it changes how users interact with secure notes. v9.1 effectively treated notes as free text; v10 adds a vocabulary engine that learns from your notes and can help standardize terms. Users can create aliases (e.g., normalize “k8s” and “kubernetes”), adjust rank for frequently used terms, and remove words that should not appear in suggestions. This turns the notes system into something closer to a specialized writing tool, with the added safety of being embedded inside a zero-knowledge vault.
This vocabulary model also aligns with .apmignore, because it acknowledges that vocab can be sensitive on its own. The option to strip or filter vocabulary during cloud upload gives users more control over metadata leakage and keeps the sync payload lean when desired.
Plugin Access Control (PACs)
v10 makes plugin permissions explicit and enforceable at runtime. Plugins in APM are manifest-driven (plugin.json) and can declare the permissions they need. v9.1 already had the notion of plugin declarations, but v10 strengthens the runtime controls so users can view and toggle permissions at a per-plugin level. This is the “PACs” change: a practical permission gate that enforces least privilege and lets users revoke specific capabilities without uninstalling the plugin entirely.
What v10 adds here:
- A permission model where each plugin declares required permissions, such as
vault.read,vault.write,system.exec, ornetwork.outbound. - A runtime permissions engine that checks each plugin action against the current allowed set.
- A CLI surface to inspect and toggle permission overrides (
pm plugins access), enabling fine-grained control. - Persistence of permission overrides in the vault, so policy stays consistent across devices and sessions.
This brings plugins closer to a security-first extension model, rather than a “trust everything you install” approach.
Auth, notes, and automation now fit together
The theme across these changes is coordination between features. The autofill daemon only runs with a valid unlocked session and is integrated with the vault’s lock state. The notes vocabulary is stored inside the encrypted vault and can be stripped from cloud uploads via .apmignore. Plugin permissions are enforced at runtime rather than at install time, so automation doesn’t bypass the security model. Recovery improvements reinforce the expectation that users can regain access without violating zero-knowledge guarantees. All of these are substantial changes in how APM “behaves,” not just how it “stores.”
TL;DR
- Introduced Windows system autofill with a background daemon, global hotkey, and intelligent context matching, plus TOTP linking for smarter OTP autofill.
- Added
pm autocompletecontrols for autostart, manual daemon lifecycle, status visibility, and popup hint toggling.
-...
v9.1
Removed pm mcp setup and apm_install (tool for the mcp server agent.)
(small update)
v9
Release Notes: apm-v8 -> current (v9)
TL;DR
- Massive CLI expansion in
pm, includingauth,mcp,update,brutetest,space, and richerprofilecontrols. - Vault format/security expanded with recovery metadata, DEK-based recovery flow, and decoy/session hardening fields.
- Cloud sync moved from Google Drive-only to multi-provider support (Google Drive + GitHub + Dropbox).
- New MCP server/token lifecycle for AI-agent integration.
- Major docs expansion to MkDocs-based documentation + generated site artifacts.
- Test surface significantly increased across
src/*andtests/*.
New Features
pm init allbootstraps vault + cloud setup in one flow.- Account recovery flow via
pm authcommands:pm auth email [address]pm auth alertspm auth level [1-3]pm auth recoverpm auth resetpm auth change
- MCP integration:
pm mcp configpm mcp tokenpm mcp listpm mcp revoke [name_or_token]pm mcp serve
- Self-update flow with
pm update. - Brute-force simulation command:
pm brutetest [minutes]. - Cloud providers expanded:
- Google Drive mode support now includes sync mode handling.
- GitHub sync support.
- Dropbox sync support.
- The user can now setup cloud sync on their own cloud account (for Google Drive and Dropbox) using Oauth2.
- New vault content types in core model:
- Audio files
- Video files
- Photo files
- Space-based segmentation (
space) added for logical partitioning. - Security profile system upgraded with richer interactive controls in
pm profile. - Plugin UX expanded with
plugins searchandplugins local [path].
Enhancements
- Vault path resolution now supports
APM_VAULT_PATH. - Recovery metadata now embedded in vault header paths used by decrypt/recover flows.
- Additional security fields in vault model:
SecurityLevelRecovery*fields (email/hash/token/salt/slot)DecoyMode,DecoySessionCount
- Audit subsystem expanded with local audit file logging (
src/audit.go) and retrieval helpers. - Team binary improvements include optional query in
pm-team get [query]and newpm-team health. - CI workflow updated (
.github/workflows/test.yml) for current toolchain and broader test execution. - Release tooling added via
.goreleaser.yaml. - Docs system introduced with MkDocs config and structured doc hierarchy.
Renames / Semantic Renames
- File rename:
LICENSE.md->LICENSE
- GitHub Actions workflow rename:
.github/workflows/apm-test.yml->.github/workflows/test.yml
- Command/meaning rename:
- Old
profile(namespaces) semantics moved tospace. - Old
sec_profileresponsibilities moved into expandedprofilecommand group.
- Old
- Data model semantic rename:
- Widespread
Namespaceusage moved toSpacein vault entities and filtering logic.
- Widespread
Removals
- Removed personal CLI commands:
adupscansec_profilevsettingsdel [name](delete now handled through newer interactive flows)plugins push [name]
- Removed cloud command signatures (superseded by multi-provider signatures):
cloud init [gdrive]cloud sync [gdrive]cloud get [gdrive] [retrieval_key]
- Removed file:
team/cloud_test.go
CLI Surface Delta
Added personal command signatures:
alertsallauthbrutetest [minutes]changeconfigcurrentemail [address]get [gdrive|github] [retrieval_key|repo]init [gdrive|github]level [1-3]local [path]mcprecoverrevoke [name_or_token]searchservespacesync [gdrive|github]tokenupdate
Removed personal command signatures:
adupdel [name]get [gdrive] [retrieval_key]init [gdrive]push [name]scansec_profilesync [gdrive]vsettings
Added team command signatures:
get [query](optional query variant)health
Added Files (non-generated, exhaustive)
.github/workflows/test.yml.goreleaser.yamldocs/concepts/cloud-sync.mddocs/concepts/encryption.mddocs/concepts/index.mddocs/concepts/mcp.mddocs/concepts/plugins.mddocs/concepts/policy-engine.mddocs/concepts/recovery.mddocs/concepts/secret-types.mddocs/concepts/security-profiles.mddocs/concepts/sessions.mddocs/concepts/vault-format.mddocs/getting-started/features.mddocs/getting-started/first-steps.mddocs/getting-started/help.mddocs/getting-started/index.mddocs/getting-started/installation.mddocs/guides/cloud-sync.mddocs/guides/import-export.mddocs/guides/index.mddocs/guides/mcp-integration.mddocs/guides/plugins.mddocs/guides/sessions.mddocs/guides/team-edition.mddocs/guides/totp.mddocs/guides/vault-management.mddocs/index.mddocs/PLUGIN_API.mddocs/reference/cli.mddocs/reference/environment-variables.mddocs/reference/index.mddocs/reference/mcp-tools.mddocs/reference/plugin-api.mddocs/reference/policies.mddocs/reference/storage.mddocs/requirements.txtdocs/team/approvals.mddocs/team/departments.mddocs/team/index.mddocs/team/rbac.mdexamples/plugins/clip_auto_clear/plugin.jsonexamples/plugins/cloud_sync_hook/plugin.jsonexamples/plugins/quick_backup/plugin.jsonexamples/plugins/safe_add/plugin.jsonexamples/plugins/vault_cleaner/plugin.jsonLICENSEmcp.mdmkdocs.ymlscripts/harden_obf.gosrc/audit.gosrc/audit_test.gosrc/brute.gosrc/cloud_test.gosrc/mcp.gosrc/mcp_integration_test.gosrc/mcp_tools_test.gosrc/policy_test.gosrc/security_test.gosrc/session_test.gosrc/system_profile.gosrc/utils_test.gosrc/vault_test.gotests/brute_force_test.go
Added Generated/Binary Artifacts
build/v9.2/canary/*(3 build artifacts)site/**(86 generated documentation files)pm.exeteam/pm-team.exe
Removed Files (exhaustive)
.github/workflows/apm-test.ymlLICENSE.mdteam/cloud_test.go
Modified Files (non-generated, exhaustive)
.gitignoreexamples/plugins/hello_vault/plugin.jsongo.modgo.summain.goREADME.mdsrc/anomaly.gosrc/cloud.gosrc/cloud_plugins.gosrc/health.gosrc/plugins/definitions.gosrc/plugins/engine.gosrc/plugins/manifest.gosrc/policy.gosrc/portability.gosrc/security.gosrc/session.gosrc/utils.gosrc/vault.goteam/crypto.goteam/go.modteam/go.sumteam/main.goteam/session.goteam/team_vault.gotests/e2e_test.go
Compatibility Notes
- Scripts using
sec_profilemust migrate toprofile. - Scripts using namespace semantics in
profilecommands must migrate tospace. - Cloud command automation should migrate to multi-provider signatures (
[gdrive|github|dropbox]). - Integrations expecting
LICENSE.mdshould referenceLICENSE.
Existing generated outputs (build artifacts, binaries (releases)) are included above as generated/binary additions.
v8.1 - Minor Imporvements
This release just makes it so that unlock happens automatically and closes after specified inactivity or unlock time defined by the user. (default inactivity: 15min; default force lock time: 1hr)