npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@varlock/pass-plugin

v0.0.5

Published

Varlock plugin to load secrets from pass (the standard unix password manager)

Readme

@varlock/pass-plugin

npm version GitHub stars license

This package is a Varlock plugin that enables loading secrets from pass (the standard unix password manager) into your configuration.

Features

  • Zero-config - Works with your existing pass store out of the box
  • GPG-backed encryption - Leverages pass's native GPG security model
  • Auto-infer entry paths from environment variable names
  • Bulk loading with passBulk() via @setValuesBulk to load all entries under a path
  • Multiple store instances for accessing different pass stores
  • Name prefixing with namePrefix option for scoped entry access
  • Custom store paths via storePath option (overrides PASSWORD_STORE_DIR)
  • allowMissing option for graceful handling of optional secrets
  • In-session caching - Each entry is decrypted only once per resolution
  • Helpful error messages with resolution tips

Installation

If you are in a JavaScript based project and have a package.json file, you can either install the plugin explicitly:

npm install @varlock/pass-plugin

And then register the plugin without any version number:

# @plugin(@varlock/pass-plugin)

Otherwise just set the explicit version number when you register it:

# @plugin(@varlock/[email protected])

See our Plugin Guide for more details.

Prerequisites

You must have pass installed on your system:

# macOS
brew install pass

# Ubuntu/Debian
sudo apt-get install pass

# Fedora/RHEL
sudo yum install pass

# Arch
pacman -S pass

Your password store must be initialized (pass init "Your GPG Key ID"). See the pass documentation for setup details.

The plugin does not fail at load time if pass is not installed - it only fails when you actually try to access a secret.

Setup

After registering the plugin, initialize it with the @initPass root decorator.

Basic setup

For most use cases, no configuration is needed:

# @plugin(@varlock/pass-plugin)
# @initPass()

This uses the default ~/.password-store directory and your existing GPG configuration.

Custom store path

If your password store is in a non-standard location:

# @plugin(@varlock/pass-plugin)
# @initPass(storePath=/path/to/custom/store)

Name prefixing

Use namePrefix to automatically prepend a path prefix to all entry lookups:

# @plugin(@varlock/pass-plugin)
# @initPass(namePrefix=production/app/)
# ---

# Fetches "production/app/DATABASE_PASSWORD"
DATABASE_PASSWORD=pass()

Multiple instances

Access multiple password stores:

# @plugin(@varlock/pass-plugin)
# @initPass(id=personal)
# @initPass(id=team, storePath=/shared/team-store)
# ---

MY_TOKEN=pass(personal, "tokens/github")
SHARED_KEY=pass(team, "api-keys/stripe")

Loading secrets

Once initialized, use the pass() resolver function to fetch secrets.

Basic usage

# @plugin(@varlock/pass-plugin)
# @initPass()
# ---

# Auto-infer entry path from variable name
DATABASE_PASSWORD=pass()

# Explicit entry path
STRIPE_KEY=pass("services/stripe/live-key")

# Nested entries
DB_CREDS=pass("production/database/credentials")

When called without arguments, pass() uses the config item key as the entry path in the pass store.

Handling optional secrets

Use allowMissing when a secret may not exist in the store:

# Won't error if the entry doesn't exist - returns empty string instead
OPTIONAL_KEY=pass("monitoring/datadog-key", allowMissing=true)

Multiline entries

By default, pass() returns only the first line of the entry (the password), matching pass's own convention where the password lives on line 1 and metadata follows on subsequent lines. This is the same behavior as pass -c (copy to clipboard).

To retrieve the full multiline content, use multiline=true:

# Only returns the first line (the password)
DB_PASSWORD=pass("production/database")

# Returns all lines (password + metadata)
DB_FULL_ENTRY=pass("production/database", multiline=true)

Example entry (pass show production/database):

mysecretpassword
URL: https://db.example.com
Username: admin
Port: 5432
  • pass("production/database") returns mysecretpassword
  • pass("production/database", multiline=true) returns the full content

Bulk loading secrets

Use passBulk() with @setValuesBulk to fetch all entries under a directory in your pass store in one go:

# @plugin(@varlock/pass-plugin)
# @initPass()
# @setValuesBulk(passBulk("services"))
# ---

# These will be populated from entries under services/ in the pass store
# e.g., services/STRIPE_KEY, services/DATABASE_URL
STRIPE_KEY=
DATABASE_URL=

passBulk() lists all entries under the given path prefix, fetches each one (first line only, matching the pass() default), and returns a JSON map of { "entryPath": "password", ... }.

# Load everything from the store root
# @setValuesBulk(passBulk())

# Load from a specific subdirectory
# @setValuesBulk(passBulk("production/api"))

# With a named instance
# @setValuesBulk(passBulk(team, "shared"))

Reference

Root decorators

@initPass()

Initialize a pass plugin instance.

Parameters:

  • storePath?: string - Custom password store path (overrides PASSWORD_STORE_DIR, defaults to ~/.password-store)
  • namePrefix?: string - Prefix automatically prepended to all entry paths
  • id?: string - Instance identifier for multiple instances (defaults to _default)

Resolver functions

pass()

Fetch a secret from the pass store.

Signatures:

  • pass() - Auto-infers entry path from variable name
  • pass(entryPath) - Fetch by explicit entry path
  • pass(instanceId, entryPath) - Fetch from a specific instance
  • pass(entryPath, allowMissing=true) - Fetch with graceful missing handling
  • pass(entryPath, multiline=true) - Fetch the full multiline content

Returns: The first line (password) of the pass entry by default, or the full content if multiline=true.

passBulk()

Fetch all entries under a directory in the pass store at once. Intended for use with @setValuesBulk.

Lists entries via pass ls, then fetches each one in parallel. Each entry returns the first line only (matching the pass() default).

Signatures:

  • passBulk() - Load all entries from the store root
  • passBulk(pathPrefix) - Load entries under a specific path prefix
  • passBulk(instanceId, pathPrefix) - Load from a named instance with prefix

Returns: JSON string of { "entryPath": "firstLineValue", ... } pairs.


How it works

Under the hood, the plugin:

  1. Executes pass show <path> as a subprocess for each secret
  2. Leverages your existing GPG agent for passphrase caching (you may be prompted for your GPG passphrase on first access)
  3. Caches decrypted values in memory for the duration of a single resolution session (no secrets are persisted)
  4. For bulk operations, lists entries with pass ls and fetches them in parallel

Since the plugin delegates entirely to the pass CLI, it respects all of your existing GPG and pass configuration, including:

  • GPG agent passphrase caching
  • Multiple GPG key recipients
  • Git-backed password stores
  • Custom PASSWORD_STORE_DIR settings

Troubleshooting

pass command not found

  • Install pass using your system package manager (see Prerequisites)
  • Ensure pass is in your PATH

Entry not found

  • Verify the entry exists: pass show <path>
  • List available entries: pass ls
  • Check for typos in the entry path
  • If using namePrefix, remember it's prepended automatically

GPG decryption failed

  • Ensure your GPG key is available: gpg --list-keys
  • Start the GPG agent: gpgconf --launch gpg-agent
  • You may need to enter your GPG passphrase

Password store not initialized

  • Run pass init "Your GPG Key ID" to initialize the store
  • See pass init --help for details

Resources