Skip to content

Add external secret helper support for key management#36

Merged
pelle merged 11 commits intomainfrom
claude/fix-credential-helper-nkPyT
Feb 23, 2026
Merged

Add external secret helper support for key management#36
pelle merged 11 commits intomainfrom
claude/fix-credential-helper-nkPyT

Conversation

@pelle
Copy link
Copy Markdown
Contributor

@pelle pelle commented Feb 23, 2026

Summary

This PR adds support for external secret helpers to TAP agents, enabling integration with external key management systems (HashiCorp Vault, AWS KMS, 1Password, etc.) as an alternative to storing keys in keys.json.

Key Changes

  • New secret_helper module (tap-agent/src/secret_helper.rs):

    • Implements a git-like secret helper pattern for retrieving private keys from external stores
    • SecretHelperConfig parses and invokes helper commands with a DID argument
    • SecretHelperOutput handles JSON responses with support for hex and base64 encoding
    • discover_agent_dids() scans the TAP directory to find existing agent DIDs
    • Comprehensive test coverage including mock script execution and roundtrip validation
  • Extended KeyManager trait (tap-agent/src/key_manager.rs):

    • Added get_private_key() method to retrieve raw private key bytes and key type
    • New extract_private_key_from_secret() utility function to decode JWK "d" parameters
    • Implemented in both DefaultKeyManager and AgentKeyManager
  • Enhanced AgentKeyManager (tap-agent/src/agent_key_manager.rs):

    • Added get_private_key() method that checks generated_keys first, then falls back to secrets
    • Supports all key types (Ed25519, P256, Secp256k1) with feature-gated validation
    • Includes tests for generated keys, storage-loaded keys, and roundtrip scenarios
  • New TapAgent::from_secret_helper() method (tap-agent/src/agent.rs):

    • Creates agents by invoking the secret helper to fetch keys for a given DID
    • Delegates to existing from_private_key() for agent construction
  • CLI integration across all entry points:

    • tap-http/src/main.rs: Added --secret-helper flag and TAP_SECRET_HELPER env var
    • tap-cli/src/main.rs: Added --secret-helper flag with env var support
    • tap-mcp/src/main.rs: Added --secret-helper flag with env var support
    • All CLIs support DID discovery when no explicit DID is provided
    • Fallback to traditional key storage when secret helper is not configured
  • WASM compatibility (tap-wasm/src/wasm_agent.rs):

    • Updated to use new get_private_key() method instead of get_generated_key()
    • Simplifies key retrieval logic by checking both generated keys and secrets
  • Dependencies:

    • Added hex = "0.4" to tap-agent/Cargo.toml for hex encoding/decoding
    • Added env feature to clap in tap-cli and tap-mcp for environment variable support

Implementation Details

  • Secret helpers are invoked as: <command> [args...] <did>
  • Expected JSON output format: {"private_key": "...", "key_type": "Ed25519", "encoding": "hex"}
  • Supports both hex and base64 encoding for private key material
  • DID discovery reverses the sanitization applied during agent directory creation (_:)
  • All three CLI tools prioritize secret helper over stored keys when configured
  • Comprehensive error handling with descriptive messages for helper failures
  • Feature-gated key type support ensures only enabled algorithms are accepted

https://claude.ai/code/session_01ATXjF1caKB3UmNvxLQajgs

pelle and others added 11 commits February 22, 2026 13:40
Update workspace version and all inter-crate dependency versions from
0.5.0 to 0.6.0. Add clear installation instructions (crates.io, from
source, verify) to all CLI tool READMEs and `cargo add` sections to
library crate READMEs. Reorganize root README Getting Started with
explicit install paths and add tap-mcp to CLI tools listing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a git-like secret helper pattern that allows TAP agents to retrieve
private keys from external secret stores (HashiCorp Vault, AWS KMS, 1Password).

- Add get_private_key(did) to AgentKeyManager and KeyManager trait
- Add secret_helper module with SecretHelperConfig and discover_agent_dids
- Add from_secret_helper() factory on TapAgent
- Add --secret-helper / TAP_SECRET_HELPER flag to tap-cli, tap-http, tap-mcp
- Simplify WASM export_private_key() to use new get_private_key()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Drop file handles and call sync_all() before executing scripts
to prevent "Text file busy" errors on macOS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use write-then-rename pattern for test scripts to avoid "Text file busy"
(ETXTBSY) errors on Linux when exec races with the kernel releasing a
write file descriptor.

https://claude.ai/code/session_01ATXjF1caKB3UmNvxLQajgs
@pelle pelle merged commit e54f962 into main Feb 23, 2026
3 checks passed
pelle pushed a commit that referenced this pull request Feb 23, 2026
Add [Unreleased] section to root CHANGELOG.md and tap-ts/CHANGELOG.md
covering PRs #34-#36: security audit fixes (14 findings including
critical SQL injection), Flattened JWS and X25519 JWE for Veramo
interoperability, and external secret helper for key management.

https://claude.ai/code/session_01U5pusfFsLrcwHqZjFhfb8L
pelle added a commit that referenced this pull request Feb 23, 2026
Add [Unreleased] section to root CHANGELOG.md and tap-ts/CHANGELOG.md
covering PRs #34-#36: security audit fixes (14 findings including
critical SQL injection), Flattened JWS and X25519 JWE for Veramo
interoperability, and external secret helper for key management.

https://claude.ai/code/session_01U5pusfFsLrcwHqZjFhfb8L

Co-authored-by: Claude <noreply@anthropic.com>
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