Skip to content

Passbolt Provider

The Passbolt provider reads and writes resources in a self-hosted Passbolt server through the community-maintained go-passbolt-cli.

Providerpassbolt (0.19+)
URIpassbolt://[?server=URL][&folder=ID][&template=PATTERN]
AccessRead and write
Best forTeams using a self-hosted Passbolt server
AuthenticationOpenPGP private key and passphrase, through provider credentials or go-passbolt-cli configuration
AvailabilityBuilt into SecretSpec 0.19+
Default storageResource secretspec/{project}/{profile}/{key}, field password

Complete Setup first, then use the provider alias from the project configuration below:

Terminal window
# Store a secret in Passbolt
$ secretspec set DATABASE_URL --provider passbolt_team
# Read it back
$ secretspec get DATABASE_URL --provider passbolt_team
# Resolve the active profile and run a command
$ secretspec run --provider passbolt_team -- npm start
  • SecretSpec 0.19 or newer
  • A Passbolt account with permission to read the selected resources and update resources when using set
  • go-passbolt-cli installed as passbolt on PATH

When the executable has another name or location, set SECRETSPEC_PASSBOLT_CLI_PATH to its path. For example, go install currently names the executable go-passbolt-cli:

Terminal window
export SECRETSPEC_PASSBOLT_CLI_PATH="$(go env GOPATH)/bin/go-passbolt-cli"

Run passbolt verify once when your deployment uses the CLI’s server verification workflow.

SecretSpec 0.19+ declares the OpenPGP private_key and passphrase as provider credentials. Load both from a bootstrap provider instead of putting them in secretspec.toml or the Passbolt URI:

secretspec.toml
[providers]
bootstrap = "keyring://"
[providers.passbolt_team]
uri = "passbolt://?server=https://pass.example.com"
credentials = { private_key = "bootstrap", passphrase = "bootstrap" }
[profiles.production]
DATABASE_URL = { description = "Database URL", providers = ["passbolt_team"] }

Store the two declared credentials once:

Terminal window
$ secretspec config provider login passbolt_team
Enter private_key for provider 'passbolt_team' (source: bootstrap): ****
Enter passphrase for provider 'passbolt_team' (source: bootstrap): ****

The provider passes the private key and passphrase only to the child process’s environment, not its command-line arguments.

For environments without a bootstrap provider, use these fallbacks:

Terminal window
export SECRETSPEC_PASSBOLT_SERVER=https://pass.example.com
export SECRETSPEC_PASSBOLT_PRIVATE_KEY="$(cat private-key.asc)"
export SECRETSPEC_PASSBOLT_PASSPHRASE="$CI_PASSBOLT_PASSPHRASE"

SECRETSPEC_PASSBOLT_PRIVATE_KEY_FILE can select a private-key file instead of an inline key. An explicit private_key provider credential takes precedence; without one, the key-file fallback takes precedence over SECRETSPEC_PASSBOLT_PRIVATE_KEY.

Alternatively, save the server, key, passphrase, and optional MFA settings in the CLI’s own configuration:

Terminal window
passbolt configure \
--serverAddress https://pass.example.com \
--userPrivateKeyFile private-key.asc \
--userPassword "$PASSBOLT_PASSPHRASE"

When none of the provider credentials or SECRETSPEC_PASSBOLT_* fallbacks are set, SecretSpec inherits that CLI configuration.

For MFA accounts, configure go-passbolt-cli for non-interactive TOTP before using it through SecretSpec. The CLI supports TOTP MFA only; accounts whose policy requires Duo or YubiKey cannot authenticate through this provider. An interactive password or TOTP prompt cannot be answered by a provider operation, so SecretSpec reports an actionable error instead of the CLI’s raw end-of-file message.

Credential Environment fallback Available since
private_key SECRETSPEC_PASSBOLT_PRIVATE_KEY 0.19+
passphrase SECRETSPEC_PASSBOLT_PASSPHRASE 0.19+

See the complete provider credential reference for all supported providers and environment fallbacks.

passbolt://[?server=URL][&folder=ID][&template=PATTERN]
  • server overrides the server stored in the CLI configuration or SECRETSPEC_PASSBOLT_SERVER.
  • folder scopes resource-name lookups and creates new convention resources inside that folder.
  • template replaces the complete convention resource name. It supports {project}, {profile}, and {key} and defaults to secretspec/{project}/{profile}/{key}.
passbolt://
passbolt://?server=https://pass.example.com
passbolt://?folder=a9230ec4-5507-4870-b8b5-b3f500587e4c
passbolt://?template=teams/{project}/{profile}/{key}
passbolt://?server=https://pass.example.com&folder=a9230ec4-5507-4870-b8b5-b3f500587e4c&template=teams/{project}/{profile}/{key}
secretspec.toml
[providers]
bootstrap = "keyring://"
[providers.passbolt_team]
uri = "passbolt://?server=https://pass.example.com&folder=a9230ec4-5507-4870-b8b5-b3f500587e4c"
credentials = { private_key = "bootstrap", passphrase = "bootstrap" }
[profiles.production]
DATABASE_URL = { description = "Database URL", providers = ["passbolt_team"] }
API_KEY = { description = "API key", providers = ["passbolt_team"] }

Every convention secret maps to one Passbolt resource:

resource name: secretspec/{project}/{profile}/{key}
field: password

For project storefront, profile production, and key DATABASE_URL, the resource is named secretspec/storefront/production/DATABASE_URL. Exact-name duplicates are rejected as ambiguous; SecretSpec never chooses one arbitrarily.

A custom template may intentionally omit a placeholder, but doing so reduces isolation. Omitting {key}, for example, makes every declaration in that project/profile target the same resource and password field.

A secret’s ref selects an existing Passbolt resource by UUID or exact name. The optional field is one of password (the default), username, uri, or description:

secretspec.toml
[providers]
passbolt_team = "passbolt://?server=https://pass.example.com"
[profiles.production]
STRIPE_SECRET_KEY = {
description = "Stripe key",
providers = ["passbolt_team"],
ref = { item = "a9230ec4-5507-4870-b8b5-b3f500587e4c" }
}
SERVICE_USER = {
description = "Service account user",
providers = ["passbolt_team"],
ref = { item = "Payments service account", field = "username" }
}

UUIDs are recommended because Passbolt permits duplicate names. Reads and writes target the existing resource in place. A write through ref never creates a missing name- or UUID-addressed resource; create and share it in Passbolt first.

These coordinates cover the standard fields exposed by go-passbolt-cli. Passbolt resource types that omit the selected field read as unset, and custom resource-type fields are not addressable through this provider.

SecretSpec 0.19+ can create a manifest from convention resources without reading their values:

Terminal window
secretspec init \
--from "passbolt://?server=https://pass.example.com&folder=a9230ec4-5507-4870-b8b5-b3f500587e4c" \
--project storefront \
--profile production

Discovery requires ?folder= because the CLI cannot safely scope account-wide listings by a resource-name prefix. SecretSpec renders the configured template for that project and profile, lists only that folder, and turns the part represented by {key} into secret names. The template must contain {key} exactly once. Nested matches and duplicates are rejected.

Prefer provider credentials sourced from a CI bootstrap provider. When that is not available, inject the inline private key and passphrase through protected CI variables:

Terminal window
export SECRETSPEC_PASSBOLT_PRIVATE_KEY="$CI_PASSBOLT_PRIVATE_KEY"
export SECRETSPEC_PASSBOLT_PASSPHRASE="$CI_PASSBOLT_PASSPHRASE"
secretspec run --provider "passbolt://?server=https://pass.example.com" -- ./deploy

Grant the CI identity read access only to the resources it needs. Grant update permission only when the job must run set or persist generated values.

  • Provider credentials and inline authentication material are passed through the child environment and are never included in the reported provider URI.
  • go-passbolt-cli currently accepts resource values for create/update only as command-line flags. Values written by secretspec set, check, generation, or import are therefore visible in the passbolt child process’s argv (for example through ps or /proc/<pid>/cmdline) until that process exits. Use the provider read-only when this exposure is unacceptable.
  • Empty writes are rejected because the CLI treats empty update fields as a successful no-op.
  • Name lookups list the configured folder, or the accessible account when no folder is configured. Prefer UUID refs and a folder scope in large accounts.
  • A folder limits lookup and creation, but it is not an independent permission boundary. Passbolt evaluates access to an existing item from that resource’s permissions, which may differ from the folder’s permissions.