toolhive icon indicating copy to clipboard operation
toolhive copied to clipboard

Add --from-secret and --from-env flags to set-build-env

Open JAORMX opened this issue 3 weeks ago • 1 comments

Summary

Implement secure credential handling for build environment variables during protocol builds (npx://, uvx://, go://). This allows users to reference ToolHive secrets or shell environment variables instead of storing sensitive values in the configuration file.

Closes the implementation portion of the proposal in #2859

Large PR Justification

  • Feature + Tests: ~350 lines are unit tests for the new functionality
  • Interface changes must be atomic: The Provider interface requires all implementations to be updated simultaneously to avoid build failures
  • Three-source resolution is interdependent: The --from-secret, --from-env, and literal value paths share validation, conflict detection, and build-time resolution logic that cannot be meaningfully separated

New Features

--from-secret flag

Reference a ToolHive secret by name. The secret is validated to exist at configuration time and resolved at build time.

thv secret set npm-registry "https://:[email protected]"
thv config set-build-env --from-secret NPM_CONFIG_REGISTRY npm-registry

--from-env flag

Read value from the shell environment at build time. Useful for CI/CD where secrets are injected via environment.

thv config set-build-env --from-env GITHUB_TOKEN
# At build time, $GITHUB_TOKEN is read from the shell

Configuration Model

Three separate sections keep sensitive values out of the config file:

build_env:
  GOPRIVATE: "github.com/myorg/*"  # Literal values only

build_env_from_secrets:
  NPM_CONFIG_REGISTRY: "npm-registry"  # Secret name, not value

build_env_from_shell:
  - GITHUB_TOKEN  # Variable name only

Security

Property Description
No cleartext secrets Config stores references, not values
Validation at config time --from-secret validates secret exists
Validation at build time Secret values checked for dangerous characters
Multi-stage isolation Credentials only in builder stage, not final image

Multi-Stage Build Isolation

All protocol build templates use multi-stage Docker builds. The BuildEnv variables are only set in the builder stage:

Template Final Stage Copies Only
npx.tmpl node_modules, package.json, package-lock.json
uvx.tmpl /opt/uv-tools
go.tmpl /app/mcp-server binary

Changes

  • pkg/config/config.go: Add BuildEnvFromSecrets and BuildEnvFromShell fields
  • pkg/config/interface.go: Add provider interface methods
  • pkg/config/buildenv.go: Add helper functions and conflict checking
  • cmd/thv/app/config_buildenv.go: Add --from-secret and --from-env flags
  • pkg/runner/protocol.go: Resolve values from all 3 sources at build time
  • pkg/config/buildenv_test.go: Add unit tests

Test plan

  • [x] task lint passes
  • [x] task test passes
  • [ ] Manual testing of --from-secret workflow
  • [ ] Manual testing of --from-env workflow

🤖 Generated with Claude Code

JAORMX avatar Dec 02 '25 23:12 JAORMX

Codecov Report

:x: Patch coverage is 39.77273% with 106 lines in your changes missing coverage. Please review. :white_check_mark: Project coverage is 56.58%. Comparing base (a5ff43f) to head (3e5e8b7). :warning: Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
pkg/config/interface.go 0.00% 48 Missing :warning:
pkg/runner/protocol.go 13.04% 35 Missing and 5 partials :warning:
pkg/config/buildenv.go 78.04% 9 Missing and 9 partials :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2860      +/-   ##
==========================================
- Coverage   56.66%   56.58%   -0.08%     
==========================================
  Files         322      322              
  Lines       31279    31449     +170     
==========================================
+ Hits        17723    17796      +73     
- Misses      12038    12117      +79     
- Partials     1518     1536      +18     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Dec 02 '25 23:12 codecov[bot]

✅ Large PR justification has been provided. The size review has been dismissed and this PR can now proceed with normal review.

github-actions[bot] avatar Dec 03 '25 11:12 github-actions[bot]