-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support AWS KMS for signing and verifying pipelines #2960
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty good, some small improvements to naming of the flags would be good
clicommand/pipeline_upload.go
Outdated
@@ -78,6 +81,7 @@ type PipelineUploadConfig struct { | |||
// Used for signing | |||
JWKSFile string `cli:"jwks-file"` | |||
JWKSKeyID string `cli:"jwks-key-id"` | |||
JWKSKMSKeyID string `cli:"jwks-kms-key-id"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JWKSKMSKeyID string `cli:"jwks-kms-key-id"` | |
SigningAWSKMSKey string `cli:"signing-aws-kms-key"` |
Spit balling here
clicommand/pipeline_upload.go
Outdated
|
||
switch { | ||
case cfg.JWKSKMSKeyID != "": | ||
awscfg, err := config.LoadDefaultConfig( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a small risk that this could resolve credentials in a different order to the how the rest of the agent does it.
But since this is a new feature, and we need to move to this way soon (when v1 of the SDK gets deprecated), I think this is a good place to start using this approach
internal/cryptosigner/aws/kms.go
Outdated
|
||
output, err := sv.client.GetPublicKey(context.Background(), &input) | ||
if err != nil { | ||
return nil, fmt.Errorf(`failed to get public key from KMS: %w`, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this error just gets ignored should we log it?
// needs is setup with the algorithm name to use (see | ||
// https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/kms/types#SigningAlgorithmSpec), | ||
// a key ID to use while the AWS SDK makes network | ||
// requests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit hard to read, but you suggested it's now out of date anyway?
ea8b60e
to
31c09ee
Compare
d57cc5c
to
c97f8a6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits for you
clicommand/agent_start.go
Outdated
// this is currently loaded here to ensure it is ONLY loaded if the agent is using KMS for signing | ||
// this will limit the possible impact of this new SDK on the rest of the agent users | ||
awscfg, err := config.LoadDefaultConfig( | ||
context.Background(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a ctx
in this function, may as well use it
context.Background(), | |
ctx, |
clicommand/agent_start.go
Outdated
case cfg.VerificationJWKSFile != "": | ||
if cfg.VerificationJWKSFile != "" { | ||
var err error | ||
verificationJWKS, err = parseAndValidateJWKS(ctx, "verification", cfg.VerificationJWKSFile) | ||
if err != nil { | ||
l.Fatal("Verification JWKS failed validation: %v", err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant check is redundant:
case cfg.VerificationJWKSFile != "": | |
if cfg.VerificationJWKSFile != "" { | |
var err error | |
verificationJWKS, err = parseAndValidateJWKS(ctx, "verification", cfg.VerificationJWKSFile) | |
if err != nil { | |
l.Fatal("Verification JWKS failed validation: %v", err) | |
} | |
case cfg.VerificationJWKSFile != "": | |
var err error | |
verificationJWKS, err = parseAndValidateJWKS(ctx, "verification", cfg.VerificationJWKSFile) | |
if err != nil { | |
l.Fatal("Verification JWKS failed validation: %v", err) |
clicommand/pipeline_upload.go
Outdated
awscfg, err := config.LoadDefaultConfig( | ||
context.Background(), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awscfg, err := config.LoadDefaultConfig( | |
context.Background(), | |
) | |
awscfg, err := config.LoadDefaultConfig(ctx) |
clicommand/tool_sign.go
Outdated
awscfg, err := config.LoadDefaultConfig( | ||
context.Background(), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awscfg, err := config.LoadDefaultConfig( | |
context.Background(), | |
) | |
awscfg, err := config.LoadDefaultConfig(ctx) |
ErrInvalidKeyID = fmt.Errorf(`invalid key ID`) | ||
) | ||
|
||
type KMS struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type KMS struct { | |
// KMS is a crypto.Signer that uses an AWS KMS key for signing. | |
type KMS struct { |
... or similar.
internal/cryptosigner/aws/kms.go
Outdated
|
||
keyDesc, err := client.GetPublicKey(context.Background(), &kms.GetPublicKeyInput{KeyId: aws.String(kmsKeyID)}) | ||
if err != nil { | ||
return nil, fmt.Errorf(`failed to describe key %q: %w`, kmsKeyID, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We began preferring "
-strings where possible instead of backtick-strings for most uses a while ago. If nothing else, this file is inconsistent with the rest of the PR.
return nil, fmt.Errorf(`failed to describe key %q: %w`, kmsKeyID, err) | |
return nil, fmt.Errorf("failed to describe key %q: %w", kmsKeyID, err) |
internal/cryptosigner/aws/kms.go
Outdated
return pubkey | ||
} | ||
|
||
// This method is an escape hatch for those cases where the user needs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// This method is an escape hatch for those cases where the user needs | |
// GetPublicKey is an escape hatch for those cases where the user needs |
internal/cryptosigner/aws/kms.go
Outdated
return key, nil | ||
} | ||
|
||
// jwa.ES256 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of date?
// jwa.ES256 | |
// Algorithm returns the equivalent of the KMS key's signing algorithm as a JWA key algorithm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice stuff 👍
640a107
to
059b464
Compare
Amazing, I have been through and addressed all your feedback 🙇🏻 |
Description
This adds AWS KMS support to pipeline signing, it is a work in progress and I am pushing this up for some feedback.
Context
To outline how this will look I have put together a list of commands with the new AWS KMS option added.
The updated agent start command with a KMS key alias which is used to sign and verify pipelines.
To upload and sign a pipeline with a specific AWS KMS key specified. Note this can be omitted if your key is configured in the agent.
The updated sign and upload command stored in buildkite with a KMS key alias.
This table provides a mapping for the supported KMS KeySpec to JSON Web Algorithms (JWA).
So to create a KMS key which supports JSON Web Algorithms (JWA)
ES256
we run the following command. Note the--key-usage SIGN_VERIFY
is required to support signing of pipelines.Changes
Testing
go test ./...
). Buildkite employees may check this if the pipeline has run automatically.go fmt ./...
)