Skip to content

Feature request: extensible secret resolution in config dynamic strings (pass, 1Password, etc.) #430

@stig

Description

@stig

Currently ECA config supports ${env:VAR} to substitute environment variables in config values. This works well when paired with shell init sourcing, but for GUI apps (ECA Desktop) there's a gap -- they don't read shell init files, so you need a LaunchAgent or similar workaround.

It would be nice to support a generalised secret resolver pattern, e.g. ${cmd:pass show eca/my-key} or ${<backend>:<path>} where the backend is extensible.

Some concrete backends that would be useful:

pass (password-store)

"key": "${pass:eca/deepseek-key}"

Runs pass show eca/deepseek-key, GPG prompts via gpg-agent / pinentry-mac. One passphrase entry per session.

1Password CLI

"key": "${op://vault/Item/credential}"

Runs op read op://vault/Item/credential -- same syntax as op inject. Useful for users already on the 1Password ecosystem.

arbitrary command

"key": "${cmd:some-tool get xyz}"

Generic fallback -- runs the command, uses stdout.

The key benefit: no env var middleman, no LaunchAgents, no shell init timing races. The config file declares where the secret lives and ECA resolves it at load time, regardless of which editor/Desktop it's running in.

Implementation sketch:

  • Support ${pass:<path>} mapping to pass show <path> (stripped trailing newline).
  • Support ${op:<ref>} mapping to op read <ref>.
  • On failure (non-zero exit / empty output), log a warning but don't crash.
  • The pattern could be implemented as a plugin system for extensibility, or simply hardcoded for the most common backends.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions