feat(awskms): add awskms support for grpc signing#11
Conversation
…med Backend, freeing up the name Signer for the implementors of the Signing interface
Greptile SummaryThis PR wires AWS KMS as a signing backend for the gRPC SignerService, complementing the existing consensus (privval) path. It also applies a consistent
Confidence Score: 5/5Safe to merge; the new awskms gRPC path follows the same cleanup, validation, and error-return conventions as the established consensus path. The cleanup-on-error pattern in BuildGRPC mirrors Build exactly (deferred func checks the named return err). Path resolution for file-backend gRPC keys is now done once in validateGRPC and written back, so newGRPCSigner correctly consumes the absolute path without a second AbsPath call. The awskms.Signer adapter is thin and correct — it reuses the Backend's cached public key and Sign path, and the compile-time interface assertion in signer.go guards all implementations. No logic errors were found in the changed paths. No files require special attention. Important Files Changed
|
…GRPC that main defers on shutdown
…or the consensus signer
|
@greptile review again and update your previous review |
| // Signer is a file-backed Ed25519 key held in memory. | ||
| type Signer struct { | ||
| // Backend is a file-backed Ed25519 key held in memory. | ||
| type Backend struct { |
There was a problem hiding this comment.
did a refactor of the existing implementors of the Backend interface. All of the implementors were named Signer, which as the obvious name for the implementors of the Signing interface. I changed the Backend implementors to be called Backend to free up the Signer name for my new structs.
| // Close contains any logic that should be called on cleanup. | ||
| Close() error |
There was a problem hiding this comment.
not necessarily required until we get grpc signing support for pkcs11 keys, but ai kept flagging the asymmetry where we did not call close on the Signers on exit, so I added this and cleanup on exit of the grpc server that matches cleaning up the backends.
There was a problem hiding this comment.
I don't have full context on the motivation for starting with ed25519 support, but from what I understand this won't have any consumers. Validators don't rely on gRPC signing and we don't have solana relaying support planned yet. For the relayer and attestor we will rely on secp for the release.
| ID string `yaml:"id"` | ||
| Backend Backend `yaml:"backend"` // "file" (default) | "awskms" | ||
| Algorithm string `yaml:"algorithm"` // file: "secp256k1" (default); awskms: "ed25519" (default) | ||
| KeyID string `yaml:"key_id"` // awskms: KMS id, ARN, or alias/<name> |
There was a problem hiding this comment.
| KeyID string `yaml:"key_id"` // awskms: KMS id, ARN, or alias/<name> | |
| AWSKeyID string `yaml:"aws_key_id"` // awskms: KMS id, ARN, or alias/<name> |
| KeyFile string `yaml:"key_file"` | ||
| ID string `yaml:"id"` | ||
| Backend Backend `yaml:"backend"` // "file" (default) | "awskms" | ||
| Algorithm string `yaml:"algorithm"` // file: "secp256k1" (default); awskms: "ed25519" (default) |
There was a problem hiding this comment.
ed26619 is relevant not only to AWS Keys
| // gRPC keys carry their own (small) backend validation rather than sharing | ||
| // the consensus per-backend validators: only file and awskms are supported | ||
| // here, and a gRPC key is bound by id, not chain_ids. | ||
| if k.Backend == "" { |
There was a problem hiding this comment.
imo, we should explicitly fail if it's not specified. Even when the backend is "", we still need a key file path.
| // grpc config. Returns (nil, nil, nil) when no grpc block is configured. | ||
| // The caller owns starting/stopping the server and closing the listener. | ||
| func BuildGRPC(c *config.Config, home string, logger log.Logger) (*grpc.Server, net.Listener, error) { | ||
| func BuildGRPC(c *config.Config, home string, logger log.Logger) (gs *grpc.Server, cleanup func(), lis net.Listener, err error) { |
There was a problem hiding this comment.
Can we wrap all of this into Server with s.Close(), s.Listener(), etc... and return only (*Server, error) ?
| algo = "secp256k1" | ||
| switch be { | ||
| case config.BackendAWSKMS: | ||
| algo = "ed25519" |
There was a problem hiding this comment.
let' move all algo types to const Algo* eg AlgoSecp256k1 (applies to all files)
No description provided.