Our Proton Pass plugin loads secrets from Proton Pass using declarative instructions within your .env files.
It shells out to the official Proton Pass CLI (pass-cli) to resolve secret references in the format pass://vault/item/field.
Features
Section titled “Features”- Secret references via
pass://URIs (pass://vault/item/field) - Personal access token login for CI (
PROTON_PASS_PERSONAL_ACCESS_TOKEN): non-interactive, scoped, no full account credentials - Non-interactive password login using environment variables (
PROTON_PASS_PASSWORD,PROTON_PASS_TOTP,PROTON_PASS_EXTRA_PASSWORD) - In-session caching per resolution run
- Helpful error messages with resolution tips
Installation and setup
Section titled “Installation and setup”In a JS/TS project, you may install the @varlock/proton-pass-plugin package as a normal dependency.
Otherwise you can just load it directly from your .env.schema file, as long as you add a version specifier.
See the plugins guide for more instructions on installing plugins.
Install Proton Pass CLI
Section titled “Install Proton Pass CLI”You must have pass-cli installed:
curl -fsSL https://proton.me/download/pass-cli/install.sh | bashSee: Proton Pass CLI overview.
Configure the plugin
Section titled “Configure the plugin”In production/CI you typically want a fully non-interactive login. The plugin supports two authentication methods: a personal access token (recommended) or a username + password.
Personal access token (recommended)
Section titled “Personal access token (recommended)”A personal access token is a scoped, non-interactive credential. It never needs a username, password, or TOTP, which makes it the cleanest option for CI.
Create one with the Proton Pass CLI, then grant it access to the vaults/items it needs:
# Create a token (the full value is only shown once, so save it somewhere safe)pass-cli pat create --name "deploy-bot" --expiration 3m# PROTON_PASS_PERSONAL_ACCESS_TOKEN=pst_xxxx...xxxx::TOKENKEY
# Grant it access to a vault or itempass-cli pat access grant ...# 1. Load the plugin# @plugin(@varlock/proton-pass-plugin)## 2. Initialize Proton Pass plugin instance# @initProtonPass(# id=prod,# personalAccessToken=$PROTON_PASS_PERSONAL_ACCESS_TOKEN# )# ---
# @type=protonPassPersonalAccessToken @sensitive @internalPROTON_PASS_PERSONAL_ACCESS_TOKEN=When a personalAccessToken is provided it takes precedence: the plugin runs pass-cli login
with the token and ignores username/password/totp/extraPassword.
Username + password
Section titled “Username + password”# @initProtonPass(# id=prod,# username=$PROTON_PASS_USERNAME,# password=$PROTON_PASS_PASSWORD,# totp=$PROTON_PASS_TOTP,# extraPassword=$PROTON_PASS_EXTRA_PASSWORD# )# ---
# @type=protonPassPassword @sensitive @internalPROTON_PASS_PASSWORD=
# @type=protonPassTotp @sensitive @internalPROTON_PASS_TOTP=
# @type=protonPassExtraPassword @sensitive @internalPROTON_PASS_EXTRA_PASSWORD=The username is passed as an argument to pass-cli login --interactive <username>.
The password/TOTP/extra password are provided to the CLI via environment variables, as supported by Proton Pass CLI login docs:
login command.
Reducing local login prompts
Section titled “Reducing local login prompts”For local development, especially with multi-process task runners like Turbo, these patterns help reduce repeated prompts:
- Store Proton Pass credentials in local config items (for example
.env.local), wire them into@initProtonPass(...), and encrypt sensitive values using Varlock local encryption. - Reuse an existing
pass-clisession when possible (pass-cli loginonce in your terminal before starting your dev tasks).
Loading secrets
Section titled “Loading secrets”Use the protonPass() resolver function to fetch a field value from a Proton Pass secret reference.
Secret reference syntax (as documented by Proton Pass CLI): secret references.
# Fetch the `password` field from a secret reference:DB_PASSWORD=protonPass(pass://Production/Database/password)When you need multiple plugin instances, use the optional first argument to select the id:
DB_PASSWORD=protonPass(prod, pass://Production/Database/password)Optional secrets
Section titled “Optional secrets”If a secret might not exist, pass allowMissing=true:
OPTIONAL_DB_PASSWORD=protonPass(pass://Production/Database/password, allowMissing=true)When allowed, missing secrets resolve to an empty string ("").
Reference
Section titled “Reference”Root decorators
Section titled “Root decorators”@initProtonPass()
Section titled “@initProtonPass()”Initialize a Proton Pass plugin instance for protonPass() resolver.
Key/value args:
id(optional): instance identifier for multiple instancespersonalAccessToken(optional): personal access token (maps toPROTON_PASS_PERSONAL_ACCESS_TOKEN). When set, takes precedence over username/password.username(optional): login username/email passed topass-cli login --interactivepassword(optional):pass-clipassword (maps toPROTON_PASS_PASSWORD)totp(optional):pass-cliTOTP code (maps toPROTON_PASS_TOTP)extraPassword(optional):pass-cliextra password (maps toPROTON_PASS_EXTRA_PASSWORD)
# @initProtonPass(# id=prod,# personalAccessToken=$PROTON_PASS_PERSONAL_ACCESS_TOKEN# )Resolver functions
Section titled “Resolver functions”protonPass()
Section titled “protonPass()”Fetch a field value from Proton Pass using a secret reference.
Array args:
secretRef(required):pass://vault/item/fieldinstanceId(optional, if 2 args are provided): instance identifier
Key/value args:
allowMissing(optional): iftrue, returns empty string when the secret is missing
# With secret reference (default instance)DB_PASSWORD=protonPass(pass://Production/Database/password)
# With explicit instanceDB_PASSWORD=protonPass(prod, pass://Production/Database/password)Under the hood
Section titled “Under the hood”This resolver uses:
pass-cli item view --output json <secretRef>to fetch the requested fieldpass-cli loginonly when an auth error occurs, then retries the original command. With apersonalAccessTokenit runspass-cli loginwithPROTON_PASS_PERSONAL_ACCESS_TOKENset; otherwise it runspass-cli login --interactive <username>with the password env vars.