Pass
GPG-encrypted password store using the pass CLI (passwordstore.org). Emits OpenTelemetry spans for get, put, and list so vault reads are visible in traces, including reads during model and workflow runs where the host emits nothing. Span attributes carry the vault name, key name, and backend only — never secret values or error messages.
2026.08.28.1
Changed: Normalized the extension license to Apache-2.0 and corrected the copyright holder to "Sean Escriva". Extensions that previously shipped an MIT LICENSE.md are now Apache-2.0, consistent with the repository root and every other extension. No code or behavioral changes.
Upgrade note: License text only. No API, schema, or runtime behavior changed.
2026.08.26.3
Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry
quality scorer can resolve dependencies and score the extension. An earlier
release used a bare "zod" import-map specifier, which published but scored as
unscored.
Changed: Retained explicit compilerOptions.strict in deno.json. No
behavioral or schema changes.
GPG-encrypted password store using the pass CLI
Config Fields
| Field | Type | Description |
|---|---|---|
| storeDir? | string | PASSWORD_STORE_DIR override (defaults to ~/.password-store) |
| prefix? | string | Key prefix for namespacing secrets (defaults to 'swamp'). |
| extraEnv | array | Additional environment variable names to forward to the pass subprocess. |
2026.08.26.3
Fixed: Restored inline npm:zod@4.4.3 import specifiers so the registry
quality scorer can resolve dependencies and score the extension. An earlier
release used a bare "zod" import-map specifier, which published but scored as
unscored.
Changed: Retained explicit compilerOptions.strict in deno.json. No
behavioral or schema changes.
2026.08.26.1
Changed: Normalized deno.json configuration for repo-wide consistency:
added explicit compilerOptions.strict and migrated zod dependency to the
import map (bare "zod" specifier instead of inline npm:zod@4.4.3). No
behavioral changes — runtime resolution is identical.
2026.08.25.1
Changed: Updated labels for improved extension discoverability. Added cross-cutting category labels (security, observability, finops, infrastructure, networking, compliance, devops, ai, incident-response) where applicable.
updated labels
2026.08.23.1
Fixed: README's Usage section documented invented CLI flags/subcommands
(--vault, --key, --value) that don't exist. Corrected to the real
swamp vault put/read-secret/list-keys command forms.
Changed: Documentation only — no code changes otherwise. Added a
## Troubleshooting section covering the narrowed subprocess environment
(ENV_ALLOWLIST plus clearEnv: true, with extraEnv as the escape hatch),
the find-exit-code-vs-empty-store distinction in list, assertSafeKey,
and the breaking prefix-migration behavior from 2026.04.22.1 (prefix: ""
to read legacy unprefixed secrets).
2026.08.21.1
Fixed: list() no longer reports a missing or unreadable password store
directory as an empty listing. Previously, if the underlying find
subprocess failed for any reason — a bad storeDir, permissions, find not
being installed — the provider silently returned [], indistinguishable
from a store that legitimately has no secrets yet. It now throws an error
naming the directory and the find exit code/stderr.
Changed: When the pass CLI exits non-zero, the thrown error now names
the subcommand that failed (e.g. pass show swamp/my-key exited with code 1: Error: swamp/my-key is not in the password store.) instead of just the
exit code and bare stderr. Secret values passed on stdin to insert are
still redacted before the error is constructed, as before.
2026.08.20.1
Upgrade note: Bumped zod from 4.3.6 to 4.4.3. No behavioral changes — dependency version alignment only.
2026.07.27.1
Changed: Bump @opentelemetry/api 1.9.0 → 1.9.1
2026.07.26.2
Added: OpenTelemetry spans on get, put, and list, named pass get,
pass put, and pass list. Attributes: vault.name, vault.secret_key,
vault.prefix when a prefix is configured, rpc.system, rpc.service,
rpc.method, and vault.keys_returned on list.
This closes a real observability gap rather than duplicating the host. swamp
emits swamp.vault.* spans when a human runs a swamp vault subcommand, with
no attributes at all — and emits nothing when a model or workflow resolves a
vault expression. A secret read during a run was invisible in traces. These
spans appear on both paths.
The extension uses @opentelemetry/api only and never constructs a
TracerProvider. With no provider configured the tracer is a no-op and the cost is
a few property lookups.
There are deliberately no spans around the pass or find invocations. Each
public method is exactly one subprocess call, so a child span would be a renamed
duplicate of its parent, and keeping span code out of the exec helper means no
edit can attach argv or stdin — which hold the plaintext — to a span.
Changed: Error messages no longer echo a submitted secret value. If pass
fails an insert and quotes the value back on stderr, that value is replaced
with [redacted] before the message is thrown. The swamp host publishes thrown
error messages into its own span as a status description, an exception.message,
and a stack trace, so an echoed value reached the trace backend regardless of
what this extension recorded.
Note on what spans deliberately omit: spans record error.type and an ERROR
status on failure, and never recordException and never a status description. A
pass error message is the CLI's stderr, which this extension does not control,
and the host already publishes it once. Recording key names is intentional — a
vault span without the key is close to useless for debugging — so treat key names
as visible to anyone with access to your trace backend and do not encode
sensitive information in them.
2026.07.26.2
Added: OpenTelemetry spans on get, put, and list, named pass get,
pass put, and pass list. Attributes: vault.name, vault.secret_key,
vault.prefix when a prefix is configured, rpc.system, rpc.service,
rpc.method, and vault.keys_returned on list.
This closes a real observability gap rather than duplicating the host. swamp
emits swamp.vault.* spans when a human runs a swamp vault subcommand, with
no attributes at all — and emits nothing when a model or workflow resolves a
vault expression. A secret read during a run was invisible in traces. These
spans appear on both paths.
The extension uses @opentelemetry/api only and never constructs a
TracerProvider. With no provider configured the tracer is a no-op and the cost is
a few property lookups.
There are deliberately no spans around the pass or find invocations. Each
public method is exactly one subprocess call, so a child span would be a renamed
duplicate of its parent, and keeping span code out of the exec helper means no
edit can attach argv or stdin — which hold the plaintext — to a span.
Changed: Error messages no longer echo a submitted secret value. If pass
fails an insert and quotes the value back on stderr, that value is replaced
with [redacted] before the message is thrown. The swamp host publishes thrown
error messages into its own span as a status description, an exception.message,
and a stack trace, so an echoed value reached the trace backend regardless of
what this extension recorded.
Note on what spans deliberately omit: spans record error.type and an ERROR
status on failure, and never recordException and never a status description. A
pass error message is the CLI's stderr, which this extension does not control,
and the host already publishes it once. Recording key names is intentional — a
vault span without the key is close to useless for debugging — so treat key names
as visible to anyone with access to your trace backend and do not encode
sensitive information in them.
updated labels
2026.07.26.1
Fixed: Secrets with leading or trailing whitespace came back altered. The
CLI output was passed through trim(), which strips spaces and tabs at both
ends, not just the line terminator the CLI adds. Only a single trailing newline
is removed now, so " padded " round-trips intact.
Fixed: Keys were not validated, so get("../../other/secret") escaped the
configured prefix and read — or with put, overwrote — a secret outside the
namespace the config pinned the caller to. Keys containing . or .. path
segments, empty path segments (a//b, trailing/), absolute keys, empty keys,
and keys starting with - (which pass would parse as a flag) are now rejected
before the CLI runs.
Changed: The pass subprocess no longer inherits the entire parent
environment. It previously received a copy of every variable in the calling
process, handing pass and every GPG agent hook it invokes any AWS key,
database URL, or API token that happened to be set. Only variables that pass
or GPG need are forwarded: HOME, PATH, USER, LOGNAME, TMPDIR, SHELL,
the locale variables, GNUPGHOME, GPG_AGENT_INFO, GPG_TTY, SSH_AUTH_SOCK,
TERM, the display and session variables pinentry needs (DISPLAY,
WAYLAND_DISPLAY, XAUTHORITY, DBUS_SESSION_BUS_ADDRESS,
PINENTRY_USER_DATA, XDG_*), and the PASSWORD_STORE_* settings. The find
subprocess used by list is narrowed the same way.
Added: extraEnv, a list of additional environment variable names to
forward to the subprocess. Use it if an unusual GPG or pinentry setup needs a
variable outside the default set.
Upgrade note: If your GPG or pinentry setup depends on an environment
variable outside that list, pass operations will fail where they previously
worked. Add the variable name to extraEnv in your vault config to restore it,
and open an issue so it can be considered for the default list.
Known limitation: A secret whose own final character is a newline cannot be distinguished from the terminator the CLI appends, so that byte is still lost. This is inherent to reading secrets from a line-oriented CLI.
Modified 1 vaults
2026.07.18.2
Changed: Version bump only, no code changes.
2026.07.18.1
Changed: Renamed the manifest tags: field to labels: — the schema's
actual field name. No runtime or install behavior change.
2026.07.18.1
Changed: Renamed the manifest tags: field to labels: — the schema's
actual field name. No runtime or install behavior change.
updated labels
Modified 1 vaults
- Has README or module doc2/2earned
- README has a code example1/1earned
- README is substantive1/1earned
- Most symbols documented1/1earned
- No slow types (deprecated)1/1earned
- Dependencies pass trust audit2/2earned
- Has description1/1earned
- Platform support declared (or universal)2/2earned
- License declared1/1earned
- Verified public repository2/2earned