community.general.proton_pass lookup – Fetch secrets from Proton Pass via the pass-cli command-line tool.

Note

This lookup plugin is part of the community.general collection (version 13.2.0).

You might already have this collection installed if you are using the ansible package. It is not included in ansible-core. To check whether it is installed, run ansible-galaxy collection list.

To install it, use: ansible-galaxy collection install community.general. You need further requirements to be able to use this lookup plugin, see Requirements for details.

To use it in a playbook, specify: community.general.proton_pass.

New in community.general 13.2.0

Synopsis

  • Retrieves secrets stored in Proton Pass by calling the pass-cli binary on the Ansible control machine.

  • When only one item title is given, returns a dictionary of all extra fields for that item so the caller can access individual secrets by key.

  • When a field name is also given, returns the field value as a string directly, without parsing JSON.

  • Every lookup invokes pass-cli directly — no in-process caching — so each call always reflects the current vault state.

Requirements

The below requirements are needed on the local controller node that executes this lookup.

Terms

Parameter

Comments

Terms

list / elements=string / required

One or more Proton Pass item titles to look up.

If exactly two terms are given and field is not set, the second term is interpreted as a field name and a plain string is returned instead of a dictionary.

Keyword parameters

This describes keyword parameters of the lookup. These are the values key1=value1, key2=value2 and so on in the following examples: lookup('community.general.proton_pass', key1=value1, key2=value2, ...) and query('community.general.proton_pass', key1=value1, key2=value2, ...)

Parameter

Comments

agent_reason

string

Human-readable reason string required by Proton Pass when authenticating with an agent token (as opposed to a personal account PAT).

Maps to the PROTON_PASS_AGENT_REASON environment variable consumed by pass-cli. Must be between 1 and 300 characters.

Agent tokens are the recommended authentication mechanism for CI/CD pipelines and automated processes — they are scoped to specific vaults, carry an expiration date, and produce an encrypted audit log. Create one with pass-cli agent create <NAME> --expiration 1m --vault <VAULT_NAME>.

Default: ""

Configuration:

cli_path

string

Path to the pass-cli binary.

When not set, pass-cli is resolved from PATH.

Default: "pass-cli"

Configuration:

  • INI entry:

    [proton_pass_lookup]
    cli_path = pass-cli
    
  • Environment variable: ANSIBLE_PROTON_PASS_CLI_PATH

  • Variable: ansible_proton_pass_cli_path

debug

boolean

When true, displays the raw pass-cli JSON via Ansible’s warning output.

Useful for diagnosing field extraction failures across pass-cli versions.

Note that this can show sensitive information. Use only when absolutely necessary and ensure the sensitive output is not logged.

Choices:

  • false ← (default)

  • true

field

string

Field name to retrieve. When set, the lookup returns a plain string instead of a dictionary, equivalent to passing the field as the second positional term.

When both a second positional term and field are supplied, field takes precedence.

Default: ""

pat

string

Personal Access Token used for non-interactive authentication.

Format is pst_<token>::<key>.

When provided, the plugin runs pass-cli login --pat <value> before the first item lookup if no active session is detected.

Default: ""

Configuration:

  • INI entry:

    [proton_pass_lookup]
    pat = ""
    
  • Environment variable: ANSIBLE_PROTON_PASS_PAT

  • Variable: ansible_proton_pass_pat

timeout

integer

Timeout in seconds for each pass-cli subprocess invocation.

Default: 30

Configuration:

vault

string

Name of the Proton Pass vault to query.

When omitted, pass-cli searches across all vaults accessible to the authenticated account; this may raise an error when the item title is not unique across vaults.

Default: ""

Configuration:

  • INI entry:

    [proton_pass_lookup]
    vault = ""
    
  • Environment variable: ANSIBLE_PROTON_PASS_VAULT

  • Variable: ansible_proton_pass_vault

Note

Configuration entries listed above for each entry type (Ansible variable, environment variable, and so on) have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up. The entry types are also ordered by precedence from low to high priority order. For example, an ansible.cfg entry (further up in the list) is overwritten by an Ansible variable (further down in the list).

Notes

Note

  • When keyword and positional parameters are used together, positional parameters must be listed before keyword parameters: lookup('community.general.proton_pass', term1, term2, key1=value1, key2=value2) and query('community.general.proton_pass', term1, term2, key1=value1, key2=value2)

  • Two non-interactive authentication paths are available.

  • Agent tokens (recommended for CI/CD) are scoped to specific vaults, carry an expiration date, and produce an encrypted audit log — create one with pass-cli agent create <NAME> --expiration 1m --vault <VAULT>, then supply the token via pat / ANSIBLE_PROTON_PASS_PAT and set agent_reason / ANSIBLE_PROTON_PASS_AGENT_REASON to a short description of why the automation is accessing the vault.

  • Personal Access Tokens PAT grant full account access and should be reserved for interactive or development use — generate one in the Proton Pass web app under Account > Security > Access and authentication > Personal Access Tokens. PAT format is pst_<token>::<key>.

  • Authenticate once interactively with pass-cli login before running playbooks when neither an agent token nor a PAT is configured.

  • Set debug=true on the lookup call to display the raw pass-cli JSON via Ansible’s warning output — useful for diagnosing field extraction failures across pass-cli versions.

  • All Proton Pass item types are supported: Login, Note, Credit Card, Wi-Fi, Identity, SSH Key, Custom, and Alias. Standard fields for each type (for example username/password for Login, ssid/password for Wi-Fi, private_key/public_key for SSH Key) are included in the returned dictionary alongside any custom extra fields.

  • For Login items the urls field is returned as a list of strings.

  • In Proton Pass, create one item per host. Add every secret as an extra hidden field whose name exactly matches the key your playbooks reference (for example api_token, gpg_keyphrase).

  • Sections (extra_sections) are supported — fields nested inside a section are merged into the same flat dict as top-level extra fields.

Examples

# Prerequisites — authenticate once on the control machine:
#   pass-cli login --pat pst_<token>::<key>
# Or export for non-interactive / CI use:
#   export ANSIBLE_PROTON_PASS_PAT='pst_<token>::<key>'
# Or configure ansible.cfg (applies to all lookups in the project):
#   [proton_pass_lookup]
#   vault = myproject

# --- All-fields mode: returns a dict of all extra fields ---

- name: Load all secrets for the current host
  ansible.builtin.set_fact:
    host_secrets: "{{ lookup('community.general.proton_pass', inventory_hostname, vault='myproject') }}"

- name: Use a field from the loaded dict
  ansible.builtin.debug:
    msg: "Token: {{ host_secrets.api_token }}"

# --- Single-field mode: returns a plain string ---

- name: Fetch one field via second positional term
  ansible.builtin.debug:
    msg: "{{ lookup('community.general.proton_pass', 'my_host', 'api_token', vault='myproject') }}"

- name: Fetch one field via keyword argument
  ansible.builtin.debug:
    msg: "{{ lookup('community.general.proton_pass', 'my_host', field='api_token', vault='myproject') }}"

# --- Multiple items, same field ---

- name: Fetch gpg_keyphrase from two items
  ansible.builtin.debug:
    msg: "{{ lookup('community.general.proton_pass', 'host_a', 'host_b', field='gpg_keyphrase', vault='myproject') }}"

# --- Drop-in replacement for ansible-vault secrets ---
# Place in group_vars/all/secrets.yaml (plain YAML, safe to commit):
#
#   secrets:
#     host_a: "{{ lookup('community.general.proton_pass', 'host_a', vault='myproject') }}"
#     host_b: "{{ lookup('community.general.proton_pass', 'host_b', vault='myproject') }}"
#
# Existing role tasks continue to work without modification:
#   "{{ secrets[inventory_hostname].some_secret }}"

# --- Vault configured globally in ansible.cfg — no vault= kwarg needed ---
- name: Lookup when ansible.cfg sets [proton_pass_lookup] vault
  ansible.builtin.debug:
    msg: "{{ lookup('community.general.proton_pass', 'my_host', 'api_token') }}"

# --- Agent token authentication (recommended for CI/CD) ---
# Create the agent first (one-time setup):
#   pass-cli agent create ci-runner --expiration 1m --vault myproject
# Then configure ansible.cfg:
#   [proton_pass_lookup]
#   vault = myproject
#   agent_reason = ansible playbook run
# And set the token in the environment (or ansible.cfg):
#   export ANSIBLE_PROTON_PASS_PAT='<agent-token>'
- name: Lookup using an agent token
  ansible.builtin.debug:
    msg: "{{ lookup('community.general.proton_pass', 'my_host', 'api_token',
             pat=lookup('env', 'ANSIBLE_PROTON_PASS_PAT'),
             agent_reason='nightly deployment pipeline') }}"

Return Value

Key

Description

Return value

list / elements=any

A list with one element per input term.

In single-field mode (field set or two-term shorthand), each element is the plain-text value of the requested field.

In all-fields mode, each element is a flat dictionary mapping standard item-type fields (username/password for login, ssid/password for wi-fi, private_key/public_key for ssh-key, etc.) and every custom extra field to its string value.

Returned: success

Authors

  • Jean Khawand (@jeankhawand)