Skip to content

feat(config): interpolate environment values in ref templates - #409

Closed
sidux wants to merge 1 commit into
cachix:mainfrom
sidux:feat/provider-ref-env-placeholders
Closed

sidux wants to merge 1 commit into
cachix:mainfrom
sidux:feat/provider-ref-env-placeholders

Conversation

@sidux

@sidux sidux commented Aug 31, 2026

Copy link
Copy Markdown

Summary

  • add {env:NAME} placeholders to provider alias reference templates
  • validate environment variable names and report missing or non-UTF-8 values before provider access
  • include expanded environment values in cache fingerprints
  • document the one-pass expansion and non-secret-only safety boundary

Motivation

Provider coordinates sometimes include a non-secret namespace selected by the current developer, tenant, or runtime. Existing templates support {project}, {profile}, and {key}, but an environment-selected namespace otherwise requires generating a manifest or duplicating provider aliases.

This adds an explicit environment placeholder without changing composed-secret semantics. Environment values are expanded once and remain opaque. Because native coordinates can appear in diagnostics and audit records, they must not contain secret values.

Review path

  • docs/src/content/docs/concepts/references.mdx defines the public behavior and safety boundary.
  • secretspec/src/config.rs validates and expands placeholders, with focused parser and runtime tests.
  • secretspec/src/plan.rs fingerprints expanded coordinates so environment changes invalidate cached routes.

Validation

  • devenv test
  • devenv shell cargo clippy --workspace --exclude secretspec-php-native
  • devenv shell cargo fmt --all -- --check
  • devenv shell npm --prefix docs run build

Allow provider aliases to use explicit {env:NAME} placeholders for non-secret native coordinates. Include expanded values in cache fingerprints so cached routes follow environment changes.
@domenkozar

Copy link
Copy Markdown
Member

We're not going to support env vars in references. What's the use case / workflow you want to support?

@sidux

sidux commented Aug 31, 2026

Copy link
Copy Markdown
Author

@domenkozar The use case is a committed manifest where part of a secret’s path is developer-specific and non-secret. We want to avoid generating local manifests or duplicating provider aliases.

@domenkozar

Copy link
Copy Markdown
Member

@domenkozar The use case is a committed manifest where part of a secret’s path is developer-specific and non-secret. We want to avoid generating local manifests or duplicating provider aliases.

Could you expand on that? I'm not sure I understand the full motivation. Happy to help!

@sidux

sidux commented Aug 31, 2026

Copy link
Copy Markdown
Author

Sure. Imagine each developer has their own credentials for a shared database:

/my-app/staging/developers/alice/database-password
/my-app/staging/developers/bob/database-password

Allowing each developer to provide the identifier through their environment would make it possible to commit a shared spec such as:
/my-app/staging/developers/{env:DEVELOPER_ID}/database-password

This avoids having to generate and maintain a local-only spec file for each developer.

@domenkozar

Copy link
Copy Markdown
Member

Sure. Imagine each developer has their own credentials for a shared database:

/my-app/staging/developers/alice/database-password
/my-app/staging/developers/bob/database-password

Allowing each developer to provide the identifier through their environment would make it possible to commit a shared spec such as: /my-app/staging/developers/{env:DEVELOPER_ID}/database-password

This avoids having to generate and maintain a local-only spec file for each developer.

Okay so inside the secrets provider, each developer has a password who's item name depends on the developer username?

@domenkozar

Copy link
Copy Markdown
Member

After digging through provider resolution, global aliases already use the same ProviderAlias implementation as project aliases, so their ref templates can expand {project}, {profile}, and {key}. The missing piece was letting a project select such an alias by default without repeating it on every secret or profile.

I implemented that in #410:

# secretspec.toml — 0.21+
[defaults]
providers = ["developer"]

Each developer can then configure the alias globally:

# ~/.config/secretspec/config.toml
[defaults.providers.developer]
uri = "awsps://developer@us-east-1"
ref = { item = "/{project}/{profile}/developers/alice/{key}" }

Bob would use the same alias name with bob in his own config. The committed project manifest stays identical for everyone.

The resolution order remains --provider, SECRETSPEC_PROVIDER, secret providers, profile defaults, project defaults, then the user-global default provider. Project [defaults] deliberately supports only providers; applying one value or requiredness rule to every secret would be surprising.

This handles the motivating use case without {env:NAME} interpolation, which would make routing depend on ambient process state and complicate reproducibility, caching, and auditing. I think #409 can be closed in favor of #410.

@domenkozar

domenkozar commented Aug 31, 2026 •

Copy link
Copy Markdown
Member

Closing this one for now, as we won't be adding environment variables to templating, let's continue exploring best way to support your workflow!

@domenkozar domenkozar closed this Aug 31, 2026
@sidux
sidux deleted the feat/provider-ref-env-placeholders branch September 1, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants