A gRPC service for cryptographic key management, digital signing, and authenticated encryption. Designed as a Root of Trust backend for card and POS payment systems.
Built with Go standard library crypto primitives. No external key management dependencies.
Request flow: Client → gRPC Interceptors → Service Layer → KeyStore / HSM / Audit
| Component | Responsibility |
|---|---|
| gRPC Interceptors | Recovery, logging, rate limiting, auth |
| KeyManagement | Key generation, rotation, deactivation, streaming events |
| Signing | Sign, verify, batch sign (worker pool), bidirectional streaming |
| Encryption | AES-256-GCM encrypt/decrypt with AAD, HKDF key derivation |
| Audit | Async structured logging via buffered channel |
| KeyStore | Key storage with sync.RWMutex (memory + persistent) |
| HSM | Hardware security module interface with software fallback |
| Service | RPCs |
|---|---|
| KeyManagement | GenerateKey, GetPublicKey, ListKeys, RotateKey, DeactivateKey, WatchKeyEvents (stream) |
| Signing | Sign, Verify, BatchSign (worker pool), StreamSign (bidirectional) |
| Encryption | Encrypt, Decrypt (AES-256-GCM + AAD), DeriveKey (HKDF) |
| Audit | QueryAudit, StreamAudit (stream) |
- ECDSA P-256/P-384 for key generation and signing
- AES-256-GCM with random nonce for authenticated encryption
- HKDF-SHA256 for key derivation from root keys
sync.RWMutexon key store (concurrent reads, exclusive writes)- Worker pool for BatchSign (bounded by
runtime.NumCPU()) - Fan-out to streaming subscribers via buffered channels
- Async audit logger decoupled from request path
- Graceful shutdown with
signal.NotifyContext+ timeout
- Go 1.24+
- protoc with
protoc-gen-goandprotoc-gen-go-grpc - grpcurl (for manual testing)
make build
./bin/vault-server| Variable | Default | Description |
|---|---|---|
VAULT_GRPC_ADDR |
:50051 |
Listen address |
VAULT_AUTH_TOKEN |
dev-token |
Bearer token for auth |
VAULT_DATA_DIR |
(empty) | Set to enable persistent key storage |
VAULT_RATE_LIMIT_RPS |
100 |
Requests per second limit |
VAULT_AUDIT_BUFFER |
1024 |
Audit log channel buffer size |
VAULT_TLS_CERT |
(empty) | TLS certificate path |
VAULT_TLS_KEY |
(empty) | TLS key path |
make docker
docker compose upAll RPCs require a bearer token in the authorization metadata header.
grpcurl -plaintext \
-H "authorization: Bearer dev-token" \
-d '{"algorithm": 1}' \
localhost:50051 vault.v1.KeyManagementService/GenerateKey# Sign (data is base64-encoded)
grpcurl -plaintext \
-H "authorization: Bearer dev-token" \
-d '{"key_id": "<KEY_ID>", "data": "aGVsbG8gd29ybGQ="}' \
localhost:50051 vault.v1.SigningService/Sign
# Verify
grpcurl -plaintext \
-H "authorization: Bearer dev-token" \
-d '{"key_id": "<KEY_ID>", "data": "aGVsbG8gd29ybGQ=", "signature": "<SIG>"}' \
localhost:50051 vault.v1.SigningService/Verifygrpcurl -plaintext \
-H "authorization: Bearer dev-token" \
-d '{"key_id": "<KEY_ID>", "plaintext": "c2VjcmV0", "aad": "Y29udGV4dA=="}' \
localhost:50051 vault.v1.EncryptionService/Encryptgrpcurl -plaintext \
-H "authorization: Bearer dev-token" \
-d '{"root_key_id": "<KEY_ID>", "context": "dHhuLWtleQ==", "length": 32}' \
localhost:50051 vault.v1.EncryptionService/DeriveKeygrpcurl -plaintext \
-H "authorization: Bearer dev-token" \
-d '{"key_id": "<KEY_ID>"}' \
localhost:50051 vault.v1.KeyManagementService/RotateKeygrpcurl -plaintext \
-H "authorization: Bearer dev-token" \
localhost:50051 vault.v1.KeyManagementService/ListKeysmake test # all tests with race detector
make bench # crypto benchmarks
make test-cover # generate coverage report| Package | Description |
|---|---|
cmd/vault-server |
Entrypoint and wiring |
internal/crypto |
ECDSA, AES-GCM, HKDF primitives |
internal/keystore |
Key storage (memory + persistent) |
internal/hsm |
HSM provider interface |
internal/audit |
Async structured audit logger |
internal/interceptor |
gRPC interceptors |
internal/server |
gRPC service implementations |
proto/vault/v1 |
Protobuf definitions |
gen/vault/v1 |
Generated Go code |