Skip to content

Commit 5b1627d

Browse files
authored
ARCH-332 Part 2 KMS ed25519 support (#1778)
* Wip * Try region * Revert "Try region" This reverts commit a7122b9. * Cli client * Wip ed25519 * Apply rename * Switch to stdlib * Follow up from previous PR * Add ed25519 to the fake * Comments * Lint
1 parent 7777312 commit 5b1627d

10 files changed

Lines changed: 312 additions & 107 deletions

File tree

keystore/admin.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func (ks *keystore) CreateKeys(ctx context.Context, req CreateKeysRequest) (Crea
243243
created := ksCopy[keyReq.KeyName].createdAt
244244
k := ksCopy[keyReq.KeyName]
245245
responses = append(responses, CreateKeyResponse{
246-
KeyInfo: newKeyInfo(keyReq.KeyName, keyReq.KeyType, created, k.publicKey, k.metadata),
246+
KeyInfo: NewKeyInfo(keyReq.KeyName, keyReq.KeyType, created, k.publicKey, k.metadata),
247247
})
248248
}
249249

keystore/cli/cli.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,9 @@ func loadKeystoreSignerReader(ctx context.Context, cmd *cobra.Command) (interfac
410410
// Check if KMS mode is enabled
411411
kmsProfile := os.Getenv("KEYSTORE_KMS_PROFILE")
412412
if kmsProfile != "" {
413-
client, err := kms.NewClient(kmsProfile)
413+
client, err := kms.NewClient(ctx, kms.ClientOptions{
414+
Profile: kmsProfile,
415+
})
414416
if err != nil {
415417
return nil, fmt.Errorf("create KMS client: %w", err)
416418
}

keystore/go.mod

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ module github.com/smartcontractkit/chainlink-common/keystore
33
go 1.25.3
44

55
require (
6-
github.com/aws/aws-sdk-go v1.55.5
6+
github.com/aws/aws-sdk-go-v2 v1.41.1
7+
github.com/aws/aws-sdk-go-v2/config v1.28.4
8+
github.com/aws/aws-sdk-go-v2/service/kms v1.49.5
79
github.com/ethereum/go-ethereum v1.16.2
810
github.com/jmoiron/sqlx v1.4.0
911
github.com/lib/pq v1.10.9
@@ -18,6 +20,17 @@ require (
1820
require (
1921
github.com/XSAM/otelsql v0.37.0 // indirect
2022
github.com/apache/arrow-go/v18 v18.3.1 // indirect
23+
github.com/aws/aws-sdk-go-v2/credentials v1.17.45 // indirect
24+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19 // indirect
25+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
26+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
27+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
28+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
29+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4 // indirect
30+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.5 // indirect
31+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4 // indirect
32+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0 // indirect
33+
github.com/aws/smithy-go v1.24.0 // indirect
2134
github.com/bahlo/generic-list-go v0.2.0 // indirect
2235
github.com/beorn7/perks v1.0.1 // indirect
2336
github.com/bits-and-blooms/bitset v1.20.0 // indirect
@@ -59,7 +72,6 @@ require (
5972
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
6073
github.com/jackc/pgtype v1.14.4 // indirect
6174
github.com/jackc/pgx/v4 v4.18.3 // indirect
62-
github.com/jmespath/go-jmespath v0.4.0 // indirect
6375
github.com/json-iterator/go v1.1.12 // indirect
6476
github.com/klauspost/compress v1.18.0 // indirect
6577
github.com/klauspost/cpuid/v2 v2.2.10 // indirect

keystore/go.sum

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,34 @@ github.com/apache/arrow-go/v18 v18.3.1 h1:oYZT8FqONiK74JhlH3WKVv+2NKYoyZ7C2ioD4D
1414
github.com/apache/arrow-go/v18 v18.3.1/go.mod h1:12QBya5JZT6PnBihi5NJTzbACrDGXYkrgjujz3MRQXU=
1515
github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE=
1616
github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw=
17-
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
18-
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
17+
github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
18+
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
19+
github.com/aws/aws-sdk-go-v2/config v1.28.4 h1:qgD0MKmkIzZR2DrAjWJcI9UkndjR+8f6sjUQvXh0mb0=
20+
github.com/aws/aws-sdk-go-v2/config v1.28.4/go.mod h1:LgnWnNzHZw4MLplSyEGia0WgJ/kCGD86zGCjvNpehJs=
21+
github.com/aws/aws-sdk-go-v2/credentials v1.17.45 h1:DUgm5lFso57E7150RBgu1JpVQoF8fAPretiDStIuVjg=
22+
github.com/aws/aws-sdk-go-v2/credentials v1.17.45/go.mod h1:dnBpENcPC1ekZrGpSWspX+ZRGzhkvqngT2Qp5xBR1dY=
23+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19 h1:woXadbf0c7enQ2UGCi8gW/WuKmE0xIzxBF/eD94jMKQ=
24+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.19/go.mod h1:zminj5ucw7w0r65bP6nhyOd3xL6veAUMc3ElGMoLVb4=
25+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
26+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
27+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
28+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
29+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
30+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
31+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
32+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
33+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4 h1:tHxQi/XHPK0ctd/wdOw0t7Xrc2OxcRCnVzv8lwWPu0c=
34+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.4/go.mod h1:4GQbF1vJzG60poZqWatZlhP31y8PGCCVTvIGPdaaYJ0=
35+
github.com/aws/aws-sdk-go-v2/service/kms v1.49.5 h1:DKibav4XF66XSeaXcrn9GlWGHos6D/vJ4r7jsK7z5CE=
36+
github.com/aws/aws-sdk-go-v2/service/kms v1.49.5/go.mod h1:1SdcmEGUEQE1mrU2sIgeHtcMSxHuybhPvuEPANzIDfI=
37+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.5 h1:HJwZwRt2Z2Tdec+m+fPjvdmkq2s9Ra+VR0hjF7V2o40=
38+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.5/go.mod h1:wrMCEwjFPms+V86TCQQeOxQF/If4vT44FGIOFiMC2ck=
39+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4 h1:zcx9LiGWZ6i6pjdcoE9oXAB6mUdeyC36Ia/QEiIvYdg=
40+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4/go.mod h1:Tp/ly1cTjRLGBBmNccFumbZ8oqpZlpdhFf80SrRh4is=
41+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0 h1:s7LRgBqhwLaxcocnAniBJp7gaAB+4I4vHzqUqjH18yc=
42+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0/go.mod h1:9XEUty5v5UAsMiFOBJrNibZgwCeOma73jgGwwhgffa8=
43+
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
44+
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
1945
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
2046
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
2147
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -173,10 +199,6 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f
173199
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
174200
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
175201
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
176-
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
177-
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
178-
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
179-
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
180202
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
181203
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
182204
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
@@ -511,7 +533,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
511533
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
512534
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
513535
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
514-
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
515536
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
516537
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
517538
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

keystore/keystore.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ type KeyInfo struct {
151151
Metadata []byte
152152
}
153153

154-
// newKeyInfo is a private constructor that ensures all fields are set explicitly.
155-
func newKeyInfo(name string, keyType KeyType, createdAt time.Time, publicKey []byte, metadata []byte) KeyInfo {
154+
// NewKeyInfo is a constructor that ensures all fields are set explicitly.
155+
func NewKeyInfo(name string, keyType KeyType, createdAt time.Time, publicKey []byte, metadata []byte) KeyInfo {
156156
return KeyInfo{
157157
Name: name,
158158
KeyType: keyType,

keystore/kms/client.go

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,62 @@
11
package kms
22

33
import (
4-
"errors"
4+
"context"
55
"fmt"
66

7-
"github.com/aws/aws-sdk-go/aws/session"
8-
kmslib "github.com/aws/aws-sdk-go/service/kms"
7+
"github.com/aws/aws-sdk-go-v2/aws"
8+
"github.com/aws/aws-sdk-go-v2/config"
9+
"github.com/aws/aws-sdk-go-v2/service/kms"
910
)
1011

1112
// Client is an interface that defines the methods for interacting with AWS KMS. We only expose
1213
// the methods that are needed for our use case, which is to get a public key and sign data.
1314
//
14-
// These methods are directly copied from the kms.Client interface in the AWS SDK for Go v1.
15-
// // https://pkg.go.dev/github.com/aws/aws-sdk-go@v1.55.7/service/kms
15+
// These methods are based on the AWS SDK for Go v2 KMS client interface.
16+
// https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/kms
1617
type Client interface {
17-
GetPublicKey(input *kmslib.GetPublicKeyInput) (*kmslib.GetPublicKeyOutput, error)
18-
Sign(input *kmslib.SignInput) (*kmslib.SignOutput, error)
19-
DescribeKey(input *kmslib.DescribeKeyInput) (*kmslib.DescribeKeyOutput, error)
20-
ListKeys(input *kmslib.ListKeysInput) (*kmslib.ListKeysOutput, error)
18+
GetPublicKey(ctx context.Context, input *kms.GetPublicKeyInput, opts ...func(*kms.Options)) (*kms.GetPublicKeyOutput, error)
19+
Sign(ctx context.Context, input *kms.SignInput, opts ...func(*kms.Options)) (*kms.SignOutput, error)
20+
DescribeKey(ctx context.Context, input *kms.DescribeKeyInput, opts ...func(*kms.Options)) (*kms.DescribeKeyOutput, error)
21+
ListKeys(ctx context.Context, input *kms.ListKeysInput, opts ...func(*kms.Options)) (*kms.ListKeysOutput, error)
2122
}
2223

23-
// NewClient constructs a new kmslib.KMS instance using the provided AWS profile. This adheres to
24-
// the KMSClient interface, allowing for signing and public key retrieval using AWS KMS.
25-
// The region is automatically read from the AWS profile configuration.
26-
func NewClient(awsProfile string) (Client, error) {
27-
if awsProfile == "" {
28-
return nil, errors.New("AWSProfile is required")
24+
// ClientOptions contains options for creating a KMS client.
25+
type ClientOptions struct {
26+
// Profile is the AWS profile name to use (for local development).
27+
// If empty, uses default credential chain (IRSA, EC2 instance profiles, etc.).
28+
Profile string
29+
// Region is the AWS region. If empty, will be read from profile or environment.
30+
Region string
31+
}
32+
33+
// NewClient constructs a new KMS client using AWS SDK v2.
34+
// If Profile is specified, it uses profile-based authentication (for local dev).
35+
// Otherwise, it uses the default credential chain (IRSA in production, EC2 instance profiles, etc.).
36+
func NewClient(ctx context.Context, opts ClientOptions) (Client, error) {
37+
var cfg aws.Config
38+
var err error
39+
40+
if opts.Profile != "" {
41+
// Use profile-based config
42+
cfg, err = config.LoadDefaultConfig(ctx,
43+
config.WithSharedConfigProfile(opts.Profile),
44+
)
45+
if err != nil {
46+
return nil, fmt.Errorf("failed to load AWS config with profile %s: %w", opts.Profile, err)
47+
}
48+
} else {
49+
// Use default credential chain
50+
cfg, err = config.LoadDefaultConfig(ctx)
51+
if err != nil {
52+
return nil, fmt.Errorf("failed to load AWS config: %w", err)
53+
}
2954
}
30-
sess, err := session.NewSessionWithOptions(session.Options{
31-
SharedConfigState: session.SharedConfigEnable,
32-
Profile: awsProfile,
33-
})
34-
if err != nil {
35-
return nil, fmt.Errorf("failed to create AWS session: %w", err)
55+
56+
// Set region if provided
57+
if opts.Region != "" {
58+
cfg.Region = opts.Region
3659
}
37-
return kmslib.New(sess), nil
60+
61+
return kms.NewFromConfig(cfg), nil
3862
}

0 commit comments

Comments
 (0)