Skip to content

Add gcpkms keystore implementation - #2338

Open
AmrMohamedRezk wants to merge 2 commits into
mainfrom
gcp_kms
Open

Add gcpkms keystore implementation#2338
AmrMohamedRezk wants to merge 2 commits into
mainfrom
gcp_kms

Conversation

@AmrMohamedRezk

@AmrMohamedRezk AmrMohamedRezk commented Aug 24, 2026

Copy link
Copy Markdown

CCIP-13120 https://smartcontract-it.atlassian.net/browse/CCIP-13120

Add a Google Cloud KMS keystore backend

Adds keystore/gcpkms, a keystore.Reader + keystore.Signer implementation backed by Google Cloud KMS, alongside the existing AWS backend in keystore/kms.

Copilot AI lite review requested due to automatic review settings August 24, 2026 14:04
@AmrMohamedRezk
AmrMohamedRezk requested review from a team as code owners August 24, 2026 14:04
@github-actions

Copy link
Copy Markdown
Contributor

👋 AmrMohamedRezk, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

✅ API Diff Results - github.com/smartcontractkit/chainlink-common/keystore

✅ Compatible Changes (1)

package github (1)
  • com/smartcontractkit/chainlink-common/keystore/gcpkms — ➕ Added

📄 View full apidiff report

Comment thread keystore/reader.go
// Reader is the interface for reading keys from the keystore.
// GetKeys returns all keys in the keystore if no names are provided, or the keys with the given names.
// Keys are sorted by name in lexicographic order.
// The order of returned keys is implementation-specific; callers must not rely on a particular ordering.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm this seems like a breaking change, can we not satisfy this requirement (maybe sort client side)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No that shouldn't break any existing behavior. The old AWS behavior is as is. The new behavior doesn't, this is just to make sure clients don't always assume it's lexicographic order regardless of the backend.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Google Cloud KMS-backed keystore.Reader and keystore.Signer.

Changes:

  • Adds GCP KMS client, keystore, and in-memory fake.
  • Supports key discovery, version resolution, public-key retrieval, and signing.
  • Adds tests and updates dependencies and ordering documentation.

Review findings:

  • Critical (2 votes): AsymmetricSignResponse.Name is referenced in fake_client.go, causing compilation errors.
  • Critical (2 votes): keystore.go references the nonexistent AsymmetricSignResponse.Name field.
  • Moderate (2 votes): Signers using parent CryptoKey names may resolve a different version than the one used for retrieved metadata.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Summary
keystore/reader.go Updates key ordering documentation.
keystore/go.sum Records dependency checksums.
keystore/go.mod Adds Google Cloud dependencies.
keystore/gcpkms/keystore.go Implements GCP KMS key retrieval and signing.
keystore/gcpkms/keystore_test.go Tests GCP KMS behavior and edge cases.
keystore/gcpkms/fake_client.go Provides an in-memory KMS test client.
keystore/gcpkms/client.go Wraps the Google Cloud KMS SDK.
Suppressed comments (3)

keystore/gcpkms/client.go:97

  • ListCryptoKeyVersions also uses the unspecified BASIC view. The resolver requires each listed version's Algorithm and CreateTime, but BASIC responses omit those fields; a parent-key lookup therefore sees an unspecified algorithm and errors before it can sign or list the key. Request CryptoKeyVersionView_FULL here.
	iter := c.client.ListCryptoKeyVersions(ctx, &kmspb.ListCryptoKeyVersionsRequest{Parent: cryptoKeyName})

keystore/gcpkms/client.go:92

  • ListCryptoKeys is called with the default BASIC/unspecified view. Cloud KMS does not populate the metadata this implementation reads in signingKeyNames (Purpose and VersionTemplate) in that view; in a real key ring those fields remain zero/nil, so asymmetric signing keys can be skipped as non-signing. Request CryptoKeyView_FULL (or fetch the metadata explicitly) before relying on these fields.
	iter := c.client.ListCryptoKeys(ctx, &kmspb.ListCryptoKeysRequest{Parent: keyRingName})

keystore/gcpkms/keystore.go:305

  • Sorting only the discovery path makes this backend violate the Reader contract that existed before this PR (keystore/reader.go:27): an explicit allowlist is returned in caller order here, while the in-memory and AWS readers sort it lexicographically. Please preserve the shared API guarantee by sorting keyNames for both paths instead of weakening Reader's contract.
		// Cloud KMS does not guarantee a listing order; sort for a stable response.
		sort.Strings(keyNames)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +243 to +247
return &kmspb.AsymmetricSignResponse{
Name: req.Name,
Signature: derSig,
SignatureCrc32C: wrapperspb.Int64(crc32c(derSig)),
VerifiedDigestCrc32C: true,
Comment on lines +367 to +369
if sig.Name != versionName {
return keystore.SignResponse{}, fmt.Errorf("signing response has name %q, expected %q", sig.Name, versionName)
}
Comment on lines +326 to +329
createdAt := resolved.version.CreateTime.AsTime()
keys = append(keys, keystore.GetKeyResponse{
KeyInfo: keystore.NewKeyInfo(keyName, resolved.keyType, createdAt, publicKeyBytes, []byte{}),
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants