Feature Request: Add AWS KMS signing backend
Summary
Add an AWS KMS signing backend so the FireFly Signer can sign Ethereum transactions using keys stored in AWS KMS, without the key material ever leaving the KMS hardware.
Motivation
Currently, FireFly Signer only supports a file-based wallet (fileWallet) where signing keys live on disk. For enterprise and regulated deployments (financial services, tokenised assets, etc.), there is a strong requirement to use hardware-backed key management:
- Key isolation: the private key never exists in process memory or on disk — signing happens inside KMS.
- FIPS 140-2 Level 3 compliance: KMS is FIPS-validated, which institutional auditors require.
- Key rotation without restart: KMS keys can be rotated at the AWS level without touching the signer.
- Audit trail: every signing operation is logged in CloudTrail with the KMS key ID.
- IRSA integration: on EKS, the signer pod can use IAM Roles for Service Accounts to authenticate to KMS — no long-lived credentials.
AWS KMS supports asymmetric keys on the ECC_SECGP256K1 curve (the secp256k1 curve used by Ethereum), so KMS can produce valid Ethereum signatures.
Proposed Implementation
I have a working implementation ready as a PR. It adds:
-
pkg/kmswallet/ — a new KMSWallet type that implements the existing ethsigner.Wallet interface. Internally it:
- Calls
kms:GetPublicKey at startup to derive the Ethereum address from the KMS public key.
- Calls
kms:Sign with MessageType: Digest and SigningAlgorithm: ECDSA_SHA_256 for each signing request.
- Parses the DER-encoded ECDSA signature to extract R and S.
- Recovers the Y-parity (V) by trying both 27 and 28 and checking which recovers to the known public key (KMS does not return a recovery ID).
-
pkg/kmswallet/kmssigner.go — a kmsSigner that implements the secp256k1.Signer and secp256k1.SignerDirect interfaces, so it slots into the existing transaction signing path without changes.
-
Config section kmsWallet alongside fileWallet:
kmsWallet:
enabled: true
keyId: <kms-key-id-or-alias>
region: <aws-region>
endpoint: <optional-for-localstack-testing>
When kmsWallet.enabled is true, it takes precedence over fileWallet. Defaults to false (backwards-compatible).
Design Decisions
- V recovery by trial: KMS returns a DER ECDSA signature without a recovery ID. The implementation tries both parities (V=27, V=28) and checks which one recovers to the KMS public key's address. This is the same approach used by other KMS-backed Ethereum signers.
- Pre-hashed messages: the signer receives the already-hashed (Keccak-256) transaction payload and passes it to KMS as a
Digest. KMS does not re-hash it.
- Backwards-compatible:
fileWallet remains the default. kmsWallet is opt-in.
- No multi-key support (yet): the initial implementation supports one KMS key per signer instance (one address in
eth_accounts). Multi-key support can be added later by mapping addresses to KMS key IDs.
Testing
The PR includes the implementation and passes all existing tests. I plan to add integration tests with LocalStack (via the endpoint config) in a follow-up if there's interest from maintainers.
Open Questions for Maintainers
- Is there appetite for this feature in the project? I'm happy to maintain it long-term.
- Would you prefer the V-recovery approach, or should we explore whether KMS can return the recovery ID via a different API?
- Any preference on the config structure — should
kmsWallet be under a broader wallets section, or is a top-level section fine?
Feature Request: Add AWS KMS signing backend
Summary
Add an AWS KMS signing backend so the FireFly Signer can sign Ethereum transactions using keys stored in AWS KMS, without the key material ever leaving the KMS hardware.
Motivation
Currently, FireFly Signer only supports a file-based wallet (
fileWallet) where signing keys live on disk. For enterprise and regulated deployments (financial services, tokenised assets, etc.), there is a strong requirement to use hardware-backed key management:AWS KMS supports asymmetric keys on the
ECC_SECGP256K1curve (the secp256k1 curve used by Ethereum), so KMS can produce valid Ethereum signatures.Proposed Implementation
I have a working implementation ready as a PR. It adds:
pkg/kmswallet/— a newKMSWallettype that implements the existingethsigner.Walletinterface. Internally it:kms:GetPublicKeyat startup to derive the Ethereum address from the KMS public key.kms:SignwithMessageType: DigestandSigningAlgorithm: ECDSA_SHA_256for each signing request.pkg/kmswallet/kmssigner.go— akmsSignerthat implements thesecp256k1.Signerandsecp256k1.SignerDirectinterfaces, so it slots into the existing transaction signing path without changes.Config section
kmsWalletalongsidefileWallet:When
kmsWallet.enabledis true, it takes precedence overfileWallet. Defaults to false (backwards-compatible).Design Decisions
Digest. KMS does not re-hash it.fileWalletremains the default.kmsWalletis opt-in.eth_accounts). Multi-key support can be added later by mapping addresses to KMS key IDs.Testing
The PR includes the implementation and passes all existing tests. I plan to add integration tests with LocalStack (via the
endpointconfig) in a follow-up if there's interest from maintainers.Open Questions for Maintainers
kmsWalletbe under a broaderwalletssection, or is a top-level section fine?