Skip to content

feat(cli): support inline CA certificates in gRPC connections and config#2721

Merged
javirln merged 6 commits intochainloop-dev:mainfrom
javirln:javirln/cli-ca-content-support
Feb 13, 2026
Merged

feat(cli): support inline CA certificates in gRPC connections and config#2721
javirln merged 6 commits intochainloop-dev:mainfrom
javirln:javirln/cli-ca-content-support

Conversation

@javirln
Copy link
Member

@javirln javirln commented Feb 10, 2026

Store CA certificate content (base64-encoded) in config instead of file paths, enabling portable configurations across environments. The gRPC connection layer now accepts CA content directly via WithCAContent option.

PFM-4423

Store CA certificate content (base64-encoded) in config instead of file
paths, enabling portable configurations across environments. The gRPC
connection layer now accepts CA content directly via WithCAContent option.

Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
@javirln javirln requested review from jiparis and migmartri February 10, 2026 09:11
@javirln javirln self-assigned this Feb 10, 2026
@javirln javirln changed the title feat(cli): support inline CA certificates in gRPC connections feat(cli): support inline CA certificates in gRPC connections and config Feb 10, 2026
Copy link
Member

@migmartri migmartri left a comment

Choose a reason for hiding this comment

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

@javirln we need to make sure new clients work with old configuration and the other way around.

In other words, new clients should be compatible with the deprecated path loading

Add unit tests for CA certificate loading functionality including file
path detection, PEM content loading, base64-encoded content, and option
functions. Tests verify backward compatibility with file paths and new
inline content support.

Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
@javirln
Copy link
Member Author

javirln commented Feb 10, 2026

@javirln we need to make sure new clients work with old configuration and the other way around.

In other words, new clients should be compatible with the deprecated path loading

Yes, it is. I've added tests for that. It will attempt to load the path, and if successful, store it as base64. Otherwise, It will try to load the base64 directly.

@migmartri
Copy link
Member

@javirln we need to make sure new clients work with old configuration and the other way around.
In other words, new clients should be compatible with the deprecated path loading

Yes, it is. I've added tests for that. It will attempt to load the path, and if successful, store it as base64. Otherwise, It will try to load the base64 directly.

I don't mean the storing, but the consumption of an already stored path, just to confirm, is that covered?

Add tests verifying that new clients can consume old configurations with
stored file paths, and that the file path detection correctly routes to
the legacy loading method. Addresses PR feedback on backward compatibility.

Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
@javirln
Copy link
Member Author

javirln commented Feb 10, 2026

@javirln we need to make sure new clients work with old configuration and the other way around.
In other words, new clients should be compatible with the deprecated path loading

Yes, it is. I've added tests for that. It will attempt to load the path, and if successful, store it as base64. Otherwise, It will try to load the base64 directly.

I don't mean the storing, but the consumption of an already stored path, just to confirm, is that covered?

Yes, it's backwards compatible with CAs as paths stored in the configuration from all the tests I could ran.

@javirln javirln marked this pull request as ready for review February 10, 2026 10:03
Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
if caFilePath := viper.GetString(confOptions.controlplaneCA.viperKey); caFilePath != "" {
opts = append(opts, grpcconn.WithCAFile(caFilePath))
if caValue := viper.GetString(confOptions.controlplaneCA.viperKey); caValue != "" {
// Check if the value is a file path, if it is we read the content and encode it to base64, if not we assume it's the content already
Copy link
Member

Choose a reason for hiding this comment

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

Should it use different keys instead of trying to do a os.Stat? Not sure about the security consequences of this.

Copy link
Member Author

@javirln javirln Feb 12, 2026

Choose a reason for hiding this comment

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

If we use different keys, which would take precedence then?

Copy link
Member Author

Choose a reason for hiding this comment

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

As far as I remember os.Stat is safe to use because it does not open the file descriptor. It calls directly the underlying OS to read just the file attributes

Signed-off-by: Javier Rodriguez <javier@chainloop.dev>
Copy link
Member

@migmartri migmartri left a comment

Choose a reason for hiding this comment

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

Just double check what would happen with the ee CLI, if it will keep working

},
RunE: func(cmd *cobra.Command, args []string) error {
// Process CA flags - read file contents and encode to base64 if needed
if err := processCAFlag(confOptions.controlplaneCA); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

btw, how's is this change gonna affect the platform CLI?

Copy link
Member Author

Choose a reason for hiding this comment

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

As we do in other commands being inherited from OSS, we will extend the config save on EE so it handles Platforms' CAs. The changes are in draft already there :)

@javirln javirln merged commit c9d9f5f into chainloop-dev:main Feb 13, 2026
16 of 17 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.

3 participants