Skip to content

feat(kms): sign/verify support #35

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

Merged
merged 5 commits into from
Apr 13, 2025
Merged

Conversation

DanielHougaard
Copy link
Member

@DanielHougaard DanielHougaard commented Apr 4, 2025

This PR introduces sign and verify support to the Go SDK.

Additionally I slightly improved our error handling to

  1. Include request ID's for easier debugging
  2. Handle zod responses (422) separately from the normal error handling flow. We now extract the entire zod error and return it as the message in a stringified version.

This PR depends on Infisical/infisical#3357.

Summary by CodeRabbit

  • New Features

    • Expanded Key Management Service capabilities for secure key creation, deletion, and retrieval by name.
    • Introduced operations for data signing, signature verification, public key retrieval, and listing available signing algorithms.
    • Enhanced error reporting with improved diagnostics, including request identifiers for clearer feedback.
  • Tests

    • Added comprehensive tests to verify the new key management and signing functionalities.

Copy link

coderabbitai bot commented Apr 4, 2025

Walkthrough

The pull request significantly expands the key management system by adding new operations for key creation, deletion, retrieval (by name), and data signing/verification. It introduces multiple new request and response types, updated interfaces, and dedicated structs separating key management and signing operations. Enhanced error handling has been implemented via new fields and utility functions. Additionally, comprehensive API functions and tests ensure proper integration and flow through REST endpoints.

Changes

File(s) Change Summary
kms.go Enhanced KMS: added new option types (e.g., KmsSignDataOptions), result types (e.g., KmsSignDataResult), updated interfaces (KmsKeysInterface, KmsSigningInterface), and restructured structs (Kms, KmsKeys, KmsSigning) to support expanded key and signing operations.
packages/api/kms/{create_key,delete_key,get_public_key,get_signing_algorithms,sign_data,verify_data,get_key_by_name}.go Introduced new API functions: CallKmsCreateKeyV1, CallKmsDeleteKeyV1, CallKmsGetPublicKeyV1, CallKmsGetSigningAlgorithmsV1, CallKmsSignDataV1, CallKmsVerifyDataV1, and CallKmsGetKeyByNameV1 with comprehensive error handling.
packages/api/kms/models.go Added many new request and response types for signing, verification, key creation, deletion, and key retrieval, plus a detailed KmsKey structure.
packages/errors/api.go Updated APIError by adding a new ReqId field and modified error message formatting in NewAPIErrorWithResponse.
packages/util/helper.go Enhanced error handling in TryParseErrorBody and added TryExtractReqId to extract request identifiers from error responses.
test/kms_signing_test.go Added a comprehensive test for the KMS signing flow covering key creation, signing, verification, public key retrieval, and deletion.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant KmsKeys
    participant API
    Client->>KmsKeys: Create Key (CallKmsCreateKeyV1)
    KmsKeys->>API: POST /v1/kms/keys
    API-->>KmsKeys: Return Created Key
    Client->>KmsKeys: Get Key By Name (CallKmsGetKeyByNameV1)
    KmsKeys->>API: GET /v1/kms/keys/key-name/{name}?projectId={id}
    API-->>KmsKeys: Return Key Details
    Client->>KmsKeys: Delete Key (CallKmsDeleteKeyV1)
    KmsKeys->>API: DELETE /v1/kms/keys/{keyId}
    API-->>KmsKeys: Confirm Deletion
Loading
sequenceDiagram
    participant Client
    participant KmsSigning
    participant API
    Client->>KmsSigning: Sign Data (CallKmsSignDataV1)
    KmsSigning->>API: POST /v1/kms/keys/{keyId}/sign
    API-->>KmsSigning: Return Signature
    Client->>KmsSigning: Verify Data (CallKmsVerifyDataV1)
    KmsSigning->>API: POST /v1/kms/keys/{keyId}/verify
    API-->>KmsSigning: Return Verification Result
    Client->>KmsSigning: List Signing Algorithms (CallKmsGetSigningAlgorithmsV1)
    KmsSigning->>API: GET /v1/kms/keys/{keyId}/signing-algorithms
    API-->>KmsSigning: Return Algorithms List
    Client->>KmsSigning: Get Public Key (CallKmsGetPublicKeyV1)
    KmsSigning->>API: GET /v1/kms/keys/{keyId}/public
    API-->>KmsSigning: Return Public Key
Loading

Poem

I'm a hopping rabbit with coding delight,
Chewing on bytes and functions all day and night.
My burrow of code now sparkles with keys,
With tests and API calls that aim to please.
I nibble on bugs and skip errors away,
Celebrating fresh changes in a carrot ballet!
Hop on, dear code—make every day play!

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (2)
test/kms_signing_test.go (1)

3-12: Missing import for os package.

If you implement the suggested changes to use environment variables, you'll need to add the os package to your imports.

import (
	"context"
	"crypto/rand"
	"encoding/base64"
	"fmt"
+	"os"
	"strings"
	"testing"

	infisical "github.com/infisical/go-sdk"
)
kms.go (1)

149-151: Avoid recreating pointers for Keys() and Signing().
Currently, the Kms struct stores keys and signing fields, but these methods return fresh instances each time instead of using the stored pointers. Consider referencing the existing fields to avoid duplication:

 func (f *Kms) Keys() KmsKeysInterface {
-    return &KmsKeys{client: f.client}
+    return f.keys
 }

 func (f *Kms) Signing() KmsSigningInterface {
-    return &KmsSigning{client: f.client}
+    return f.signing
 }

Also applies to: 153-155

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f36081 and ba5cf96.

📒 Files selected for processing (11)
  • kms.go (2 hunks)
  • packages/api/kms/create_key.go (1 hunks)
  • packages/api/kms/delete_key.go (1 hunks)
  • packages/api/kms/get_public_key.go (1 hunks)
  • packages/api/kms/get_signing_algorithms.go (1 hunks)
  • packages/api/kms/models.go (1 hunks)
  • packages/api/kms/sign_data.go (1 hunks)
  • packages/api/kms/verify_data.go (1 hunks)
  • packages/errors/api.go (2 hunks)
  • packages/util/helper.go (2 hunks)
  • test/kms_signing_test.go (1 hunks)
🧰 Additional context used
🧬 Code Definitions (6)
packages/api/kms/verify_data.go (2)
packages/api/kms/models.go (2)
  • KmsVerifyDataV1Request (33-38)
  • KmsVerifyDataV1Response (40-44)
packages/errors/api.go (1)
  • NewAPIErrorWithResponse (47-61)
packages/api/kms/get_public_key.go (2)
packages/api/kms/models.go (2)
  • KmsGetPublicKeyV1Request (54-56)
  • KmsGetPublicKeyV1Response (58-60)
packages/errors/api.go (1)
  • NewAPIErrorWithResponse (47-61)
packages/api/kms/delete_key.go (2)
packages/api/kms/models.go (2)
  • KmsDeleteKeyV1Request (85-87)
  • KmsDeleteKeyV1Response (89-91)
packages/errors/api.go (1)
  • NewAPIErrorWithResponse (47-61)
test/kms_signing_test.go (1)
kms.go (7)
  • Kms (49-53)
  • KmsCreateKeyOptions (19-19)
  • KmsListSigningAlgorithmsOptions (16-16)
  • KmsSignDataOptions (13-13)
  • KmsVerifyDataOptions (14-14)
  • KmsGetPublicKeyOptions (17-17)
  • KmsDeleteKeyOptions (20-20)
packages/api/kms/get_signing_algorithms.go (2)
packages/api/kms/models.go (2)
  • KmsListSigningAlgorithmsV1Request (46-48)
  • KmsListSigningAlgorithmsV1Response (50-52)
packages/errors/api.go (1)
  • NewAPIErrorWithResponse (47-61)
kms.go (7)
client.go (1)
  • InfisicalClient (21-41)
packages/api/kms/create_key.go (1)
  • CallKmsCreateKeyV1 (10-27)
packages/api/kms/delete_key.go (1)
  • CallKmsDeleteKeyV1 (12-29)
packages/api/kms/sign_data.go (1)
  • CallKmsSignDataV1 (12-29)
packages/api/kms/verify_data.go (1)
  • CallKmsVerifyDataV1 (12-29)
packages/api/kms/get_signing_algorithms.go (1)
  • CallKmsGetSigningAlgorithmsV1 (13-29)
packages/api/kms/get_public_key.go (1)
  • CallKmsGetPublicKeyV1 (12-28)
🪛 golangci-lint (1.64.8)
test/kms_signing_test.go

26-26: Error return value of rand.Read is not checked

(errcheck)

🪛 GitHub Check: Build
test/kms_signing_test.go

[failure] 26-26:
Error return value of rand.Read is not checked (errcheck)

🔇 Additional comments (28)
packages/util/helper.go (3)

87-88: Good addition of ReqId field for better error tracking

The inclusion of a ReqId field in the ErrorResponse struct enhances error traceability by capturing a unique identifier for each request, which is especially useful for debugging in distributed systems.


90-93: Special handling for validation errors

Good approach to return the entire response body for HTTP 422 (Unprocessable Entity) status codes. This preserves validation error details that might have a different structure than standard error responses.


106-124: Well-implemented ReqId extraction function

The TryExtractReqId function follows good practices:

  • Performs null and error checks before processing
  • Uses a minimal struct for unmarshaling only what's needed
  • Handles errors gracefully

While there's some code duplication with TryParseErrorBody, the separation allows for more flexibility in how error components are extracted.

packages/errors/api.go (3)

17-17: Good addition of ReqId field to APIError struct

The inclusion of the ReqId field in the APIError struct is consistent with the changes in helper.go and enhances error tracking capabilities.


22-23: Improved error message with request ID

Including the request ID in the formatted error message improves debuggability by providing a unique identifier that can be used to trace errors through logs and monitoring systems.

Also applies to: 27-28


49-50: Good integration of request ID extraction

Properly leveraging the new TryExtractReqId utility function to populate the APIError struct with the request ID from the response.

Also applies to: 59-59

packages/api/kms/sign_data.go (3)

1-9: Good package and import organization

The package declaration and imports are well-organized. The imports include only what's necessary for the functionality provided.


10-11: Good use of constant for operation name

Using a constant for the operation name ensures consistency throughout the code and makes it easier to update if needed.


12-29: Well-implemented KMS sign data function

The function follows best practices:

  • Initializes an empty response structure
  • Properly constructs the request with correct URL formatting
  • Handles both request errors and API errors appropriately
  • Returns the result with proper error handling

The implementation is clean and follows the standard pattern used in the SDK.

packages/api/kms/get_public_key.go (3)

1-9: Good package and import organization

The package declaration and imports are well-organized, including only what's necessary for the function's implementation.


10-11: Good use of constant for operation name

Using a constant for the operation name ensures consistency across the codebase and makes it easier to update if needed.


12-28: Well-implemented KMS public key retrieval function

The function follows the same robust pattern as other API calls in the SDK:

  • Initializes an empty response structure
  • Makes the HTTP GET request with proper URL formatting
  • Handles both request errors and API errors appropriately
  • Returns the populated response with proper error handling

This implementation is clean, consistent with the SDK's patterns, and properly handles error cases.

packages/api/kms/delete_key.go (1)

12-29: Verify handling of nil httpClient parameter.

The function doesn't check if httpClient is nil before using it. This could potentially lead to a panic if a nil client is passed.

Consider adding a nil check at the beginning of the function:

func CallKmsDeleteKeyV1(httpClient *resty.Client, request KmsDeleteKeyV1Request) (KmsDeleteKeyV1Response, error) {
+	if httpClient == nil {
+		return KmsDeleteKeyV1Response{}, errors.NewRequestError(callKmsDeleteKeyOperationV1, fmt.Errorf("httpClient cannot be nil"))
+	}
	kmsDeleteKeyResponse := KmsDeleteKeyV1Response{}
	
	res, err := httpClient.R().
		SetResult(&kmsDeleteKeyResponse).
		SetBody(request).
		Delete(fmt.Sprintf("/v1/kms/keys/%s", request.KeyId))
packages/api/kms/create_key.go (1)

10-27: Verify handling of nil httpClient parameter.

The function doesn't check if httpClient is nil before using it. This could potentially lead to a panic if a nil client is passed.

Consider adding a nil check at the beginning of the function:

func CallKmsCreateKeyV1(httpClient *resty.Client, request KmsCreateKeyV1Request) (KmsCreateKeyV1Response, error) {
+	if httpClient == nil {
+		return KmsCreateKeyV1Response{}, errors.NewRequestError(callKmsCreateKeyOperationV1, fmt.Errorf("httpClient cannot be nil"))
+	}
	kmsCreateKeyResponse := KmsCreateKeyV1Response{}
	
	res, err := httpClient.R().
		SetResult(&kmsCreateKeyResponse).
		SetBody(request).
		Post("/v1/kms/keys")
packages/api/kms/verify_data.go (2)

12-29: Verify handling of nil httpClient parameter.

The function doesn't check if httpClient is nil before using it. This could potentially lead to a panic if a nil client is passed.

Consider adding a nil check at the beginning of the function:

func CallKmsVerifyDataV1(httpClient *resty.Client, request KmsVerifyDataV1Request) (KmsVerifyDataV1Response, error) {
+	if httpClient == nil {
+		return KmsVerifyDataV1Response{}, errors.NewRequestError(callKmsVerifyDataOperationV1, fmt.Errorf("httpClient cannot be nil"))
+	}
	kmsVerifyDataResponse := KmsVerifyDataV1Response{}
	
	res, err := httpClient.R().
		SetResult(&kmsVerifyDataResponse).
		SetBody(request).
		Post(fmt.Sprintf("/v1/kms/keys/%s/verify", request.KeyId))

17-18:

❓ Verification inconclusive

Check for redundant KeyId in request body.

The KeyId is included in both the URL path and potentially in the request body (through SetBody(request)). This might be redundant if the backend API doesn't expect it in both places.


🏁 Script executed:

#!/bin/bash
# Check how the request is processed in the backend

# Find references to the verify endpoint in the codebase
rg -A 3 "keys/.*?/verify" --glob "*.go"

Length of output: 342


Backend Redundancy Check – Validate the Inclusion of KeyId

The endpoint URL is constructed with the KeyId, but the entire request object (via SetBody(request)) is also sent in the body. This raises the possibility that the KeyId might be redundantly present. Before proceeding, please verify that the backend API is intended to extract the KeyId solely from the URL. If the API does not require the KeyId in the request body, consider removing it from the body to avoid any potential conflicts or confusion.

packages/api/kms/get_signing_algorithms.go (1)

13-29: Looks consistent and correct.
This function follows the established pattern for REST calls, properly handles errors, and returns a well-defined response.

kms.go (10)

13-20: Type aliasing for request structs looks good.
These aliases cleanly expose the API request types without requiring direct imports from the api package.


22-28: Result type aliases are well-defined.
Exporting these aliases similarly keeps the codebase modular and consistent.


29-39: Interfaces provide clear abstraction layers.
The methods in KmsKeysInterface and KmsSigningInterface are well-scoped for key-management and signing operations.


45-47: Structural changes for Kms and KmsKeys are coherent.
Introducing these fields and structs sets the foundation for extended KMS functionality in a maintainable way.

Also applies to: 49-59


63-71: Create/Delete methods are properly implemented.
They follow the same error-handling pattern as other KMS functions, returning typed results.

Also applies to: 73-81


83-91: SignData method is straightforward and aligns with project conventions.
It makes a single API call and surfaces errors appropriately.


93-101: VerifyData method follows the same reliable pattern.
Error handling is consistent, and it returns typed results for clarity.


103-111: ListSigningAlgorithms method is well-structured.
It correctly delegates to the API call, providing minimal overhead and consistent error handling.


113-121: GetPublicKey method is properly wired.
No issues with returning the public key string or handling errors.


158-162: Constructor is consistent and clear.
This neatly instantiates and wires up the new Kms fields.

packages/api/kms/models.go (1)

21-103: Data struct definitions are well-formed.
Each request/response type is clearly documented and mapped, making it easy to consume in higher-level code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (7)
packages/api/kms/get_key_by_name.go (1)

12-28: Consider handling empty or invalid request parameters.
While this function is straightforward, if ProjectId or KeyName are empty or invalid, it may result in unexpected behavior or server-side errors. Validating these fields before constructing the URL could improve robustness.

 func CallKmsGetKeyByNameV1(httpClient *resty.Client, request KmsGetKeyByNameV1Request) (KmsGetKeyV1Response, error) {
+   if request.ProjectId == "" || request.KeyName == "" {
+       return KmsGetKeyV1Response{}, fmt.Errorf("project ID and key name must not be empty")
+   }
    kmsGetKeyByNameResponse := KmsGetKeyV1Response{}
    ...
packages/api/kms/get_key_by_id.go (1)

12-28: Validate request fields to avoid invalid queries.
Just like in the get-by-name function, consider verifying that ProjectId and KeyId are non-empty before sending the request to reduce risk of reliance on server-side validation alone.

 func CallKmsGetKeyByIdV1(httpClient *resty.Client, request KmsGetKeyByIdV1Request) (KmsGetKeyV1Response, error) {
+   if request.ProjectId == "" || request.KeyId == "" {
+       return KmsGetKeyV1Response{}, fmt.Errorf("project ID and key ID must not be empty")
+   }
    kmsGetKeyByIdResponse := KmsGetKeyV1Response{}
    ...
packages/api/kms/models.go (5)

21-26: Clarify the encoding and usage of Data and IsDigest
Consider adding documentation on whether Data is raw or base64-encoded when IsDigest is true. Aligning this with the verify request (which mandates base64-encoded data) can help avoid confusion.


28-32: Specify the encoding of Signature
If the Signature is base64-encoded, it would be prudent to add a comment or use a field tag clarifying the encoding. This helps standardize usage across signing and verifying.


59-61: Clarify PublicKey format
Consider documenting whether the returned public key is PEM, base64, or another standard format. This helps downstream code parse and use it correctly.


63-80: Consider enumerations for KeyUsage and EncryptionAlgorithm
Relying on raw string fields (e.g., "sign-verify", "encrypt-decrypt", or "rsa-4096") may be error-prone. Defining constants or enums for valid values could improve maintainability and reduce runtime errors.


108-118: Consider typed fields or enumerations for KeyUsage
While KmsKey mirrors the request structures closely, using typed constants for KeyUsage and EncryptionAlgorithm would help prevent invalid assignments. Otherwise, this struct is well-defined for capturing key metadata.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between af1d7f3 and 480a04a.

📒 Files selected for processing (4)
  • kms.go (2 hunks)
  • packages/api/kms/get_key_by_id.go (1 hunks)
  • packages/api/kms/get_key_by_name.go (1 hunks)
  • packages/api/kms/models.go (1 hunks)
🧰 Additional context used
🧬 Code Definitions (3)
packages/api/kms/get_key_by_id.go (1)
packages/api/kms/models.go (2)
  • KmsGetKeyByIdV1Request (99-102)
  • KmsGetKeyV1Response (104-106)
packages/api/kms/get_key_by_name.go (1)
packages/api/kms/models.go (2)
  • KmsGetKeyByNameV1Request (94-97)
  • KmsGetKeyV1Response (104-106)
kms.go (10)
packages/api/kms/models.go (13)
  • KmsEncryptDataV1Request (3-6)
  • KmsDecryptDataV1Request (12-15)
  • KmsSignDataV1Request (21-26)
  • KmsVerifyDataV1Request (34-39)
  • KmsListSigningAlgorithmsV1Request (47-49)
  • KmsGetPublicKeyV1Request (55-57)
  • KmsCreateKeyV1Request (63-80)
  • KmsDeleteKeyV1Request (86-88)
  • KmsGetKeyByNameV1Request (94-97)
  • KmsGetKeyByIdV1Request (99-102)
  • KmsVerifyDataV1Response (41-45)
  • KmsSignDataV1Response (28-32)
  • KmsKey (108-118)
client.go (1)
  • InfisicalClient (21-41)
packages/api/kms/create_key.go (1)
  • CallKmsCreateKeyV1 (10-27)
packages/api/kms/delete_key.go (1)
  • CallKmsDeleteKeyV1 (12-29)
packages/api/kms/get_key_by_name.go (1)
  • CallKmsGetKeyByNameV1 (12-28)
packages/api/kms/get_key_by_id.go (1)
  • CallKmsGetKeyByIdV1 (12-28)
packages/api/kms/sign_data.go (1)
  • CallKmsSignDataV1 (12-29)
packages/api/kms/verify_data.go (1)
  • CallKmsVerifyDataV1 (12-29)
packages/api/kms/get_signing_algorithms.go (1)
  • CallKmsGetSigningAlgorithmsV1 (13-29)
packages/api/kms/get_public_key.go (1)
  • CallKmsGetPublicKeyV1 (12-28)
🔇 Additional comments (31)
packages/api/kms/get_key_by_name.go (1)

1-11: Package and imports are consistent.
No issues found regarding the package name api or the imported libraries. They are aligned with the existing project structure and are suitable for this functionality.

packages/api/kms/get_key_by_id.go (1)

1-11: Package and imports are consistent.
Similarly, the package name api and imported libraries are in line with the rest of the codebase. There are no immediate issues here.

kms.go (17)

9-31: Type aliases are straightforward.
These type aliases provide readability by exposing the underlying request/response structs from the api package as higher-level options/results. No issues observed with these mappings.


33-38: Interface methods for key retrieval are clearly named.
The methods GetByName and GetById in KmsKeysInterface are self-explanatory and align with the new API calls. Ensure that the implementing methods log or handle possible user input edge cases internally (e.g., empty fields).


40-45: KmsSigningInterface design is consistent.
Listing algorithms, retrieving public keys, signing, and verifying data are logically grouped. The interface is concise and well-defined.


51-52: "Keys()" and "Signing()" methods add clarity.
Exposing KmsKeysInterface and KmsSigningInterface through separate methods clarifies grouping of operations around keys vs. signing features.


55-59: Struct fields match the interface references.
Kms holds references to KmsKeys and KmsSigning for easy access. This is a clean pattern for organizing related functionalities.


61-67: KmsKeys & KmsSigning struct definitions are minimal and consistent.
No immediate concerns; each struct holding a client is aligned with the established pattern.


69-77: Create key function is straightforward.
Delegating to api.CallKmsCreateKeyV1 is consistent with the rest of the project. No issues noted.


79-87: Delete key function is consistent.
Checks if an error occurred, then returns properly. No concerns.


89-97: GetByName method references the newly introduced API call.
Code structure matches the pattern established in the create/delete functions, returning res.Key if no error occurs.


99-107: GetById method references the new call by ID.
Logic is analogous to GetByName. It keeps the method consistent with the rest of the code.


109-117: SignData is properly delegated.
Returns the entire api.KmsSignDataV1Response rather than just the signature, allowing flexibility for other fields like KeyId or SigningAlgorithm.


119-127: VerifyData is delegated similarly.
Returns api.KmsVerifyDataV1Response. Consistent usage with the other calls.


129-137: ListSigningAlgorithms leverages the single-purpose API.
Method returns a list of algorithms directly, preserving the server’s response shape. Straightforward approach.


139-147: GetPublicKey retrieves the string from the API.
Returns the PublicKey field from res with minimal overhead.


175-177: Keys() method defers creation lazily.
The function re-initializes KmsKeys on each call but can rely on an internal pointer approach. Fine for typical usage.


179-181: Signing() method follows the same pattern as Keys().
Provides a consistent approach for obtaining the signing interface.


183-189: NewKms constructor organizes the client and sub-interfaces.
Initialization approach is straightforward and consistent with the rest of the code.

packages/api/kms/models.go (12)

20-20: No visible code changes on line 20
It appears to be an empty or whitespace change.


34-39: Ensure consistent base64 usage for signature
KmsVerifyDataV1Request states Data must be base64-encoded. Please confirm if Signature also requires base64 encoding, and consider adding a clarifying comment or validation.


41-45: Looks good
Definition for KmsVerifyDataV1Response is clear and straightforward.


47-49: Straightforward structure
The request is concise and appears correct for listing signing algorithms by key.


51-53: No issues found
KmsListSigningAlgorithmsV1Response looks clear.


55-57: All good
KmsGetPublicKeyV1Request is self-explanatory; the KeyId is appropriately modeled.


82-84: Straightforward response
KmsCreateKeyV1Response is clearly structured.


86-88: LGTM
KmsDeleteKeyV1Request is concise and matches typical patterns for delete requests.


90-92: No issues
KmsDeleteKeyV1Response properly returns the deleted key details.


94-97: General request
KmsGetKeyByNameV1Request is well-defined for retrieving keys by name within a project.


99-102: Looks correct
KmsGetKeyByIdV1Request structures the parameters for retrieving keys by ID.


104-106: All good
KmsGetKeyV1Response properly wraps the returned KmsKey.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/api/kms/get_key_by_name.go (1)

12-18: Consider validating request parameters before making the API call.

If request.KeyName or request.ProjectId are empty, the function might attempt to construct an invalid URL. Including a short validation check before invoking httpClient.R() can gracefully handle potential invalid inputs, preventing downstream issues.

 func CallKmsGetKeyByNameV1(httpClient *resty.Client, request KmsGetKeyByNameV1Request) (KmsGetKeyV1Response, error) {
+   if request.KeyName == "" || request.ProjectId == "" {
+       return KmsGetKeyV1Response{}, fmt.Errorf("missing required parameters: key name and project ID must be specified")
+   }

    kmsGetKeyByNameResponse := KmsGetKeyV1Response{}
    ...
 }
kms.go (1)

32-36: Suggest adding a GetById method.

The KmsKeysInterface currently supports key retrieval by name but not by direct identifier. Consider adding a GetById(options KmsGetKeyOptions) (KmsGetKeyResult, error) method for scenarios where only a key ID is available.

packages/api/kms/models.go (1)

48-54: Use consistent naming for request fields.

The KmsListSigningAlgorithmsV1Request uses KeyId while other requests sometimes use KeyID or KeyId in the struct tags. Confirm usage consistency across all KMS operation requests to reduce confusion.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 480a04a and 121ae1b.

📒 Files selected for processing (3)
  • kms.go (2 hunks)
  • packages/api/kms/get_key_by_name.go (1 hunks)
  • packages/api/kms/models.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/api/kms/get_key_by_name.go (3)
packages/api/kms/models.go (2)
  • KmsGetKeyByNameV1Request (95-98)
  • KmsGetKeyV1Response (100-102)
packages/errors/request.go (1)
  • NewRequestError (17-22)
packages/errors/api.go (1)
  • NewAPIErrorWithResponse (47-59)
kms.go (8)
client.go (1)
  • InfisicalClient (21-41)
packages/api/kms/create_key.go (1)
  • CallKmsCreateKeyV1 (10-27)
packages/api/kms/delete_key.go (1)
  • CallKmsDeleteKeyV1 (12-29)
packages/api/kms/get_key_by_name.go (1)
  • CallKmsGetKeyByNameV1 (12-28)
packages/api/kms/sign_data.go (1)
  • CallKmsSignDataV1 (12-29)
packages/api/kms/verify_data.go (1)
  • CallKmsVerifyDataV1 (12-29)
packages/api/kms/get_signing_algorithms.go (1)
  • CallKmsGetSigningAlgorithmsV1 (13-29)
packages/api/kms/get_public_key.go (1)
  • CallKmsGetPublicKeyV1 (12-28)
🔇 Additional comments (7)
packages/api/kms/get_key_by_name.go (1)

19-25: Error handling is consistent with the project's pattern.

The function correctly wraps typical request and response errors using NewRequestError and NewAPIErrorWithResponse. This aligns with existing error-handling conventions in the codebase, providing clear context for debugging.

kms.go (4)

9-23: Type aliases provide clarity.

Aliasing API request structs (e.g. KmsSignDataOptions) makes the code more readable and avoids lengthy references. This approach preserves strong typing and is easy to maintain.


87-95: Positive separation of concerns for GetByName.

Using a dedicated method to retrieve a key by name keeps the interface specific and reduces confusion with other retrieval logic (e.g., by ID). This maintains good clarity, especially when working with different key identification schemes.


163-169: Expose Keys() and Signing() for flexible usage.

Returning concrete interface implementations from Keys() and Signing() is a clean way to modularize KMS functionalities. This design fosters good layering and easy discovery within client code.


172-176: Constructor approach aligns with standard Go patterns.

NewKms instantiates “keys” and “signing” sub-clients, encouraging compositional usage. This pattern ensures future expansions can be neatly integrated.

packages/api/kms/models.go (2)

104-114: Good coverage of key properties.

The KmsKey struct captures a wide range of attributes, including usage type, encryption algorithm, and organizational details. This thorough approach likely supports essential KMS interactions without further expansions.


21-26:

❓ Verification inconclusive

Confirm correct base64 usage for the Data field.

When IsDigest is false, ensure that calling code consistently base64-encodes the full payload. Otherwise, double-encoding or raw data usage might lead to signature errors at runtime.


🏁 Script executed:

#!/bin/bash
# Searches for call sites of KmsSignDataV1Request
# and checks if the 'Data' field is base64-encoded.
rg -A 3 'KmsSignDataV1Request'

Length of output: 816


Action Required: Validate Base64 Encoding for Data Field

  • In packages/api/kms/models.go (lines 21–26), the KmsSignDataV1Request struct includes a Data field that should be base64-encoded when IsDigest is false.
  • In the call site CallKmsSignDataV1 (in packages/api/kms/sign_data.go), please ensure that the full payload is properly base64-encoded before the request is sent. Failure to do so could result in either double-encoding or passing raw data, leading to signature errors at runtime.

@DanielHougaard DanielHougaard merged commit d3160af into main Apr 13, 2025
2 checks passed
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.

2 participants