Skip to content

Tool Backend

The tool backend lets you integrate any CLI-based secrets manager with vaults-syncer without writing custom Go code. A vault of type: tool delegates all operations (list, get, set, delete) to an external program—such as the AWS CLI, the HashiCorp Vault CLI, or any shell script you provide.

Each tool has its own configuration file that you write once and then reference by path from the main config.yaml. This keeps the main config small and makes tool configs shareable and version-controlled independently.


Quick start

1. Write a tool config file

Create a YAML file (e.g. tools/aws-secretsmanager.yaml) that describes the CLI commands for each operation. Ready-made examples are in examples/tools/.

# tools/aws-secretsmanager.yaml
env:
  AWS_DEFAULT_REGION: "us-east-1"

operations:
  list:
    command: aws
    args: [secretsmanager, list-secrets, --output, json]
    output:
      format: json
      path: SecretList
      name_field: Name

  get:
    command: aws
    args: [secretsmanager, get-secret-value, --secret-id, "{{.Name}}", --output, json]
    output:
      format: json
      path: SecretString

  set:
    command: aws
    # Warning: {{.Value}} is passed via argv and may be exposed by process
    # listings or logs. Prefer a wrapper script or tool-specific input method
    # that reads the secret value without putting it on the command line.
    args: [secretsmanager, put-secret-value, --secret-id, "{{.Name}}", --secret-string, "{{.Value}}"]

  delete:
    command: aws
    args: [secretsmanager, delete-secret, --secret-id, "{{.Name}}", --force-delete-without-recovery]

  test:
    command: aws
    args: [sts, get-caller-identity]

2. Reference it in config.yaml

vaults:
  - id: aws_prod
    name: AWS Secrets Manager (prod)
    type: tool
    tool_config: ./tools/aws-secretsmanager.yaml

The tool_config path is resolved relative to the directory of the main config file. Absolute paths are also accepted.


Tool config file reference

Top-level fields

Field Type Description
env map[string]string Environment variables injected into every command. Supports $VAR / ${VAR} expansion at config load time (shell-style defaults such as ${VAR:-default} are not supported).
env_passthrough []string Names of environment variables to forward from the daemon's runtime environment. Values are read at command execution time, so rotated credentials are picked up without restarting.
operations map[string]ToolOperationConfig Command definitions keyed by operation name (list, get, set, delete, test).

Operation fields (operations.<name>)

Field Type Required Description
command string Executable to run (e.g. aws, vault, bash).
args []string Arguments passed to the command. Supports Go template variables (see below).
output ToolOutputConfig Describes how to parse stdout.
success_exit_codes []int Exit codes considered successful. Defaults to [0].

Output fields (operations.<name>.output)

Field Type Description
format string json (default), text, or lines.
path string Dot-notation path into JSON output (e.g. SecretList or data.keys). Empty string = root.
name_field string For list: JSON field within each array item that holds the secret name. Defaults to name. Items that are plain strings are used as-is.

Template variables in args

The args array supports Go template syntax. The following variables are available depending on the operation:

Variable Available in Description
{{.Name}} get, set, delete The secret name being operated on.
{{.Value}} set The secret value to write.

When {{.Value}} is rendered in args, the secret is passed to the child process as a command-line argument. Many systems expose argv values via process listings, audit logs, or crash reports. Prefer a wrapper script or tool-specific input method that can read the value without placing it on the command line.

Example:

get:
  command: vault
  args: [kv, get, -field=value, "secret/{{.Name}}"]

Required operations

Operation Required Description
list Returns all secret names.
get Returns the value of a single secret.
set Optional Creates or updates a secret.
delete Optional Removes a secret.
test Optional Used by TestConnection. Falls back to list if absent.

Output formats

json

The command output is parsed as JSON. Use output.path to navigate to the relevant node (dot notation). For list, the node must be a JSON array; each element may be a plain string or an object with a name_field.

output:
  format: json
  path: SecretList     # navigate to {"SecretList": [...]}
  name_field: Name     # extract item["Name"]

text (get only)

The raw stdout is trimmed and used as the secret value. Useful for tools like vault kv get -field=value.

lines

Each non-empty line of stdout becomes a secret name (for list) or the entire output is the value (for get).


Environment variable injection

Tool configs support two ways to pass environment variables to commands:

env — static values (expanded at load time)

env:
  VAULT_ADDR: "${VAULT_ADDR}"

Values in the env block are expanded once when the config is loaded. Use this for variables whose values are known at daemon startup. If you need a default value, set it directly in the config file or ensure the daemon's environment provides it before startup.

env_passthrough — runtime forwarding

env_passthrough:
  - AWS_ACCESS_KEY_ID
  - AWS_SECRET_ACCESS_KEY
  - AWS_SESSION_TOKEN

env_passthrough reads the named variables from the daemon's environment at the moment each command runs. This means rotated credentials (e.g. an IAM role's short-lived session tokens refreshed by an agent) are automatically picked up without restarting the daemon.

If a listed variable is not set in the daemon's environment, it is silently omitted and does not affect the command.

All variables already present in the daemon's environment are also inherited by child processes automatically; env and env_passthrough let you override or explicitly forward specific variables.


Examples

Pre-built tool configs are provided in examples/tools/:

File Description
aws-secretsmanager.yaml AWS Secrets Manager via the AWS CLI
hashicorp-vault.yaml HashiCorp Vault KV v2 via the vault CLI

Limitations

  • The tool backend executes commands synchronously. Long-running CLIs will block a sync worker for the duration of the command (up to the vault timeout, default 30 s).
  • stdin is not connected; tools that require interactive input are not supported.
  • For set operations, avoid passing secret values as command-line arguments (for example via {{.Value}} in args). Command-line arguments may be exposed via process listings, audit logs, or crash reports. Prefer passing secrets through environment variables or via a wrapper script that writes the value to a temporary file and has the CLI read it from there.
  • The tool backend does not support bidirectional sync unless both get and set operations are defined.