HashiCorp Vault KMS Plugin Implementation Plan
Overview
This plan outlines the implementation of a HashiCorp Vault Key Management Service (KMS) plugin for TrustWeave. The plugin will be implemented as the kms/plugins/hashicorp module and will integrate with Vault’s Transit secrets engine to provide cryptographic key operations for DID and Verifiable Credential workflows.
Background
HashiCorp Vault is a popular open-source secrets management platform that provides:
- Transit Engine: Cryptographic operations (encryption, signing, key generation)
- Key Management: Centralized key lifecycle management
- Multi-cloud Support: Works on-premises and in cloud environments
- Policy-based Access Control: Fine-grained access control via Vault policies
Vault Transit Engine Capabilities
The Transit engine supports the following key types:
- ed25519: Ed25519 signing keys
- ecdsa-p256: ECDSA P-256 (NIST P-256)
- ecdsa-p384: ECDSA P-384 (NIST P-384)
- ecdsa-p521: ECDSA P-521 (NIST P-521)
- ecdsa-p256k1: ECDSA secp256k1 (Bitcoin/Ethereum curve)
- rsa-2048: RSA 2048-bit keys
- rsa-3072: RSA 3072-bit keys
- rsa-4096: RSA 4096-bit keys
Note: Vault Transit does NOT support BLS12-381.
Implementation Tasks
1. Module Structure and Dependencies
Task: Create kms/plugins/hashicorp module with build configuration
Files:
kms/plugins/hashicorp/build.gradle.kts
Dependencies:
trustweave-commontrustweave-kms- Vault Java client library (e.g.,
com.bettercloud:vault-java-driveror direct HTTP client) - HTTP client (OkHttp or similar)
- JSON serialization (Jackson or Kotlinx Serialization)
Acceptance Criteria:
- Module compiles successfully
- All dependencies resolved
- Module included in
settings.gradle.kts
2. Configuration Class
Task: Implement VaultKmsConfig data class with builder pattern
Files:
kms/plugins/hashicorp/src/main/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKmsConfig.kt
Features:
- Vault server address (required)
- Authentication methods:
- Token authentication (default)
- AppRole authentication (roleId + secretId)
- Environment variable support (
VAULT_ADDR,VAULT_TOKEN,VAULT_NAMESPACE)
- Transit engine path (default: “transit”)
- Namespace support (for Vault Enterprise)
- Engine version (default: 2)
Builder Pattern:
1
2
3
4
5
6
VaultKmsConfig.builder()
.address("http://localhost:8200")
.token("hvs.xxx")
.transitPath("transit")
.namespace("admin")
.build()
Environment Variable Support:
VAULT_ADDR- Vault server addressVAULT_TOKEN- Authentication tokenVAULT_NAMESPACE- Vault namespace (Enterprise)VAULT_TRANSIT_PATH- Transit engine path (optional, defaults to “transit”)
Acceptance Criteria:
- Configuration can be created from builder
- Configuration can be loaded from environment variables
- Configuration can be created from options map
- Validation ensures required fields are present
3. Algorithm Mapping
Task: Implement AlgorithmMapping utilities for TrustWeave ↔ Vault Transit mapping
Files:
kms/plugins/hashicorp/src/main/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/AlgorithmMapping.kt
Mappings:
Algorithm.Ed25519→"ed25519"Algorithm.Secp256k1→"ecdsa-p256k1"Algorithm.P256→"ecdsa-p256"Algorithm.P384→"ecdsa-p384"Algorithm.P521→"ecdsa-p521"Algorithm.RSA.RSA_2048→"rsa-2048"Algorithm.RSA.RSA_3072→"rsa-3072"Algorithm.RSA.RSA_4096→"rsa-4096"
Functions:
toVaultKeyType(algorithm: Algorithm): String- Convert TrustWeave algorithm to Vault key typefromVaultKeyType(keyType: String): Algorithm?- Parse Vault key type to TrustWeave algorithmresolveKeyName(keyId: String, config: VaultKmsConfig): String- Resolve key name for Vault API
Acceptance Criteria:
- All supported algorithms map correctly
- Unsupported algorithms throw appropriate exceptions
- Key name resolution handles various formats
4. Vault Client Factory
Task: Implement VaultKmsClientFactory for creating Vault HTTP clients
Files:
kms/plugins/hashicorp/src/main/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKmsClientFactory.kt
Features:
- HTTP client creation with proper authentication
- Token-based authentication
- AppRole authentication (if configured)
- Namespace header support (Vault Enterprise)
- Error handling and retry logic
Vault API Endpoints (Transit engine):
POST /v1/{transitPath}/keys/{keyName}- Create keyGET /v1/{transitPath}/keys/{keyName}- Get key infoPOST /v1/{transitPath}/keys/{keyName}/config- Update key configPOST /v1/{transitPath}/sign/{keyName}- Sign dataGET /v1/{transitPath}/keys/{keyName}/{version}- Get public key
Acceptance Criteria:
- Client created with correct authentication
- Namespace headers added when configured
- Proper error handling for authentication failures
5. Vault Key Management Service
Task: Implement VaultKeyManagementService implementing KeyManagementService interface
Files:
kms/plugins/hashicorp/src/main/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKeyManagementService.kt
Supported Algorithms:
- Ed25519
- secp256k1
- P-256, P-384, P-521
- RSA-2048, RSA-3072, RSA-4096
Methods Implementation:
getSupportedAlgorithms():- Return set of supported algorithms
generateKey(algorithm, options):- Use Vault Transit API:
POST /v1/{transitPath}/keys/{keyName} - Extract key name from options or generate UUID
- Set key type based on algorithm
- Retrieve public key after creation
- Return
KeyHandlewith key name, algorithm, and public key JWK
- Use Vault Transit API:
getPublicKey(keyId):- Use Vault Transit API:
GET /v1/{transitPath}/keys/{keyName} - Extract public key from response
- Convert to JWK format
- Return
KeyHandle
- Use Vault Transit API:
sign(keyId, data, algorithm):- Use Vault Transit API:
POST /v1/{transitPath}/sign/{keyName} - Base64 encode input data
- Specify hash algorithm (SHA-256, SHA-384, SHA-512 based on key type)
- Return signature bytes
- Use Vault Transit API:
deleteKey(keyId):- Use Vault Transit API:
DELETE /v1/{transitPath}/keys/{keyName} - Return true if successful, false if key doesn’t exist
- Use Vault Transit API:
Key Naming:
- Keys are identified by name in Vault Transit
- Format:
{transitPath}/keys/{keyName} - Key names should be URL-safe
Public Key Format:
- Vault Transit returns public keys in PEM format
- Convert PEM to JWK for
KeyHandle.publicKeyJwk
Error Handling:
- Map Vault API errors to TrustWeave exceptions
404→KeyNotFoundException403→TrustWeaveExceptionwith access denied message400→UnsupportedAlgorithmExceptionorTrustWeaveException
Acceptance Criteria:
- All
KeyManagementServicemethods implemented - Proper error handling and exception mapping
- Public keys converted to JWK format
- Algorithm advertisement working correctly
6. Vault Key Management Service Provider
Task: Implement VaultKeyManagementServiceProvider for SPI registration
Files:
kms/plugins/hashicorp/src/main/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKeyManagementServiceProvider.kt
Features:
- Provider name:
"vault"or"hashicorp-vault" - Advertise supported algorithms
- Create
VaultKeyManagementServicefrom options - Support configuration from options map or environment variables
Acceptance Criteria:
- Provider discoverable via ServiceLoader
- Configuration loaded correctly
- Service created successfully
7. SPI Registration
Task: Create SPI registration file
Files:
kms/plugins/hashicorp/src/main/resources/META-INF/services/org.trustweave.kms.spi.KeyManagementServiceProvider
Content:
1
org.trustweave.hashicorpkms.VaultKeyManagementServiceProvider
Acceptance Criteria:
- Provider automatically discovered when module is on classpath
8. Unit Tests
Task: Create comprehensive unit tests
Files:
kms/plugins/hashicorp/src/test/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKmsConfigTest.ktkms/plugins/hashicorp/src/test/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/AlgorithmMappingTest.ktkms/plugins/hashicorp/src/test/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKeyManagementServiceTest.ktkms/plugins/hashicorp/src/test/kotlin/com/geoknoesis/TrustWeave/hashicorpkms/VaultKeyManagementServiceProviderTest.kt
Test Coverage:
- Configuration creation and validation
- Algorithm mapping (all supported algorithms)
- Key generation for each algorithm
- Public key retrieval
- Signing operations
- Error handling (key not found, authentication failures)
- Provider discovery and creation
Mocking Strategy:
- Mock Vault HTTP client responses
- Use testcontainers or local Vault instance for integration tests (optional)
Acceptance Criteria:
- All tests pass
- Good test coverage (>80%)
- Tests run without requiring actual Vault instance
9. Integration with Build System
Task: Update root settings to include new module
Files:
settings.gradle.kts
Changes:
- Add
"kms/plugins/hashicorp"toinclude()list
Acceptance Criteria:
- Module included in build
- Module compiles successfully
10. Documentation
Task: Create comprehensive documentation
Files:
docs/integrations/hashicorp-vault-kms.md
Sections:
- Overview
- Installation
- Configuration
- Basic configuration
- Authentication methods (Token, AppRole)
- Environment variables
- Namespace support (Enterprise)
- Algorithm Support
- Supported algorithms table
- Vault Transit key types
- Usage Examples
- Key generation
- Signing
- Public key retrieval
- Key rotation
- Vault Setup
- Enabling Transit engine
- Creating policies
- Key naming conventions
- Error Handling
- Best Practices
- Troubleshooting
Update:
docs/integrations/README.md- Add Vault KMS to integrations list
Acceptance Criteria:
- Complete documentation with examples
- Clear configuration instructions
- Troubleshooting guide included
Vault Transit Engine API Reference
Key Creation
1
2
3
4
5
6
7
8
POST /v1/transit/keys/{keyName}
{
"type": "ed25519",
"convergent_encryption": false,
"derived": false,
"exportable": false,
"allow_plaintext_backup": false
}
Get Key Info
1
GET /v1/transit/keys/{keyName}
Response includes:
keys: Map of key versionslatest_version: Latest key versiontype: Key typepublic_key: Public key in PEM format
Sign Data
1
2
3
4
5
6
POST /v1/transit/sign/{keyName}
{
"input": "base64-encoded-data",
"hash_algorithm": "sha2-256",
"marshaling_algorithm": "asn1"
}
Get Public Key
1
GET /v1/transit/keys/{keyName}/{version}
Algorithm Support Matrix
| TrustWeave Algorithm | Vault Transit Key Type | Hash Algorithm | Notes |
|---|---|---|---|
| Ed25519 | ed25519 |
N/A (direct signing) | Native Ed25519 support |
| secp256k1 | ecdsa-p256k1 |
sha2-256 |
Blockchain-compatible |
| P-256 | ecdsa-p256 |
sha2-256 |
FIPS-compliant |
| P-384 | ecdsa-p384 |
sha2-384 |
FIPS-compliant |
| P-521 | ecdsa-p521 |
sha2-512 |
FIPS-compliant |
| RSA-2048 | rsa-2048 |
sha2-256 |
Legacy support |
| RSA-3072 | rsa-3072 |
sha2-256 |
Higher security |
| RSA-4096 | rsa-4096 |
sha2-256 |
Maximum security |
Authentication Methods
1. Token Authentication (Default)
1
2
3
4
val config = VaultKmsConfig.builder()
.address("http://localhost:8200")
.token("hvs.xxx")
.build()
2. AppRole Authentication
1
2
3
4
5
6
val config = VaultKmsConfig.builder()
.address("http://localhost:8200")
.appRolePath("approle")
.roleId("xxx")
.secretId("yyy")
.build()
3. Environment Variables
1
2
3
export VAULT_ADDR=http://localhost:8200
export VAULT_TOKEN=hvs.xxx
export VAULT_NAMESPACE=admin
Key Naming Conventions
Vault Transit uses key names (not IDs) to identify keys. Recommendations:
- Use descriptive names:
did-issuer-key,vc-signing-key - Include algorithm in name:
ed25519-main-key - Use hierarchical naming:
production/issuer/ed25519-key - Avoid special characters (use hyphens, underscores)
Vault Policy Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Policy for TrustWeave KMS operations
path "transit/keys/*" {
capabilities = ["create", "read", "update", "delete"]
}
path "transit/keys/+/config" {
capabilities = ["update"]
}
path "transit/sign/*" {
capabilities = ["create", "update"]
}
path "transit/keys/+/+" {
capabilities = ["read"]
}
Testing Strategy
Unit Tests
- Mock Vault HTTP responses
- Test algorithm mappings
- Test configuration parsing
- Test error handling
Integration Tests (Optional)
- Use Testcontainers with Vault container
- Test against real Vault instance
- Verify end-to-end key operations
Dependencies
Required
trustweave-commontrustweave-kms- HTTP client (OkHttp or similar)
- JSON library (Jackson or Kotlinx Serialization)
Optional
- Vault Java client library (if using existing client)
- Testcontainers (for integration tests)
Implementation Order
- Module structure and dependencies
- Configuration class
- Algorithm mapping
- Vault client factory
- Key management service (core implementation)
- Service provider
- SPI registration
- Unit tests
- Build system integration
- Documentation
Success Criteria
- ✅ All TrustWeave algorithms supported (except BLS12-381)
- ✅ Token and AppRole authentication working
- ✅ Environment variable configuration supported
- ✅ Proper error handling and exception mapping
- ✅ Public keys converted to JWK format
- ✅ Comprehensive test coverage
- ✅ Complete documentation
- ✅ Module compiles and integrates successfully
Future Enhancements
- Key rotation support using Vault’s key versioning
- Key export support (if exportable keys enabled)
- Convergent encryption support
- Integration with Vault’s PKI engine
- Support for Vault’s KMIP secrets engine