Skip to content

CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState - #2186

Merged
openshift-merge-bot[bot] merged 2 commits into
openshift:masterfrom
ardaguclu:kms-provider-config-keystate
Apr 29, 2026
Merged

openshift-merge-bot[bot] merged 2 commits into
openshift:masterfrom
ardaguclu:kms-provider-config-keystate

Conversation

@ardaguclu

@ardaguclu ardaguclu commented Apr 28, 2026

Copy link
Copy Markdown
Member

This PR solely focuses on populating the kms-provider-config into Key Secret as well as KeyState for the work that is described openshift/enhancements#1960

Currently kms-provider-config is not wired to encryption-config Secret that to be used to carry the data to plugin lifecycle.

Summary by CodeRabbit

  • New Features

    • Persist and validate KMS provider configuration inside encryption secrets; added support to read provider config from a dedicated config Secret.
    • Added KMS provider API types and Vault provider support (Transit mount/key, AppRole auth, optional TLS).
  • Tests

    • Expanded tests to cover KMS provider config serialization, deserialization, presence/absence checks, and roundtrip consistency.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Apr 28, 2026
@openshift-ci-robot

openshift-ci-robot commented Apr 28, 2026

Copy link
Copy Markdown

@ardaguclu: This pull request references CNTRLPLANE-3237 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

This PR is subset of #2163. This PR solely focuses on populating the kms-provider-config into Key Secret as well as KeyState.

Currently kms-provider-config is not wired to encryption-config Secret that to be used to carry the data to plugin lifecycle.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
openshift-ci Bot requested review from dgrisonnet and p0lyn0mial April 28, 2026 08:20
@coderabbitai

coderabbitai Bot commented Apr 28, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

KMS encryption support now carries provider-specific configuration through the system: new API types for KMS provider (Vault), a helper to read provider config from a dedicated Secret, state and secret serializers were extended to persist/validate provider config, and controller/tests updated to use and verify that config.

Changes

Cohort / File(s) Summary
API: KMS provider model & loader
pkg/operator/encryption/api/api.go, pkg/operator/encryption/api/api_from_fake_secret.go
Adds KMSConfigAPI and Vault-specific types; introduces constants for the provider-config secret and GetKMSProviderConfigFromSecret(...) which reads/unmarshals provider config JSON from a fixed Secret.
State model
pkg/operator/encryption/state/types.go
Adds Provider *KMSProviderConfig to KMSConfig, defines KMSProviderConfig (wraps *api.KMSConfigAPI), and new helper KeyState.HasKMSProviderConfig().
Secret keys
pkg/operator/encryption/secrets/types.go
Adds exported constant EncryptionSecretKMSProviderConfig ("encryption.apiserver.operator.openshift.io-kms-provider-config") for the provider-config data key.
Secret (de)serialization
pkg/operator/encryption/secrets/secrets.go, pkg/operator/encryption/secrets/secrets_test.go
ToKeyState validates and unmarshals the provider-config JSON from secret data; FromKeyState JSON-marshals KMS.Provider into the new data key when present. Tests updated to include provider in roundtrip expectations.
Controller & tests
pkg/operator/encryption/controllers/key_controller.go, pkg/operator/encryption/controllers/key_controller_test.go
Controller fetches provider config from the configured Secret and sets ks.KMS.Provider before secret generation. Tests seed provider-config secret, expect an extra get:secrets:openshift-config action, and validate presence/absence and exact JSON content of the provider-config data key.
Test helpers
pkg/operator/encryption/testing/helpers.go
Adds fixtures and constructors for KMSProviderConfig, KMSConfigAPI (Vault-based test data), and CreateKMSProviderConfigSecret() used in tests.

Sequence Diagram(s)

sequenceDiagram
    participant Controller
    participant SecretsAPI
    participant KMSSecret as "KMS Provider Secret"
    participant APIHelper as "GetKMSProviderConfigFromSecret()"
    participant KeyState
    Controller->>SecretsAPI: Get(secret: openshift-config/<name>)
    SecretsAPI-->>KMSSecret: returns Secret(with data.config)
    Controller->>APIHelper: parse secret.data[config]
    APIHelper-->>Controller: KMSConfigAPI (or error)
    Controller->>KeyState: set ks.KMS.Provider = KMSConfigAPI
    Controller->>KeyState: FromKeyState() → marshals provider JSON into secret data
    KeyState-->>SecretsAPI: create/update encryption key Secret (with provider-config)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 11 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (11 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: introducing KMSProviderConfig into KeyState, which is the central focus of all changes across multiple files and test updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed This check is not applicable to the provided pull request. The custom check specifically addresses Ginkgo test names (using It(), Describe(), Context(), When() syntax), but this PR contains only standard Go testing package tests (using func TestXxx(t *testing.T) syntax). The test scenarios in both key_controller_test.go and secrets_test.go use descriptive, static strings as names (e.g., "full kms", "sparse kms", "creates a new KMS key when switching from AESCBC to KMS") with no dynamic content like timestamps, UUIDs, generated identifiers, or runtime-specific values.
Test Structure And Quality ✅ Passed Test files demonstrate proper structure with table-driven patterns, meaningful helper functions for setup, and focused assertions validating KMS provider behavior without indefinite waits or missing cleanup.
Microshift Test Compatibility ✅ Passed The PR modifies only standard Go unit tests (testing.T-based) in key_controller_test.go and secrets_test.go, not Ginkgo e2e tests which use It(), Describe(), Context(), When() patterns.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR does not introduce Ginkgo e2e tests; only modifies unit tests using Go's standard testing package.
Topology-Aware Scheduling Compatibility ✅ Passed This PR modifies only Go library code for KMS encryption configuration with no scheduling constraints, topology assumptions, or deployment manifests affecting OpenShift topologies.
Ote Binary Stdout Contract ✅ Passed PR introduces KMS config handling code with no stdout writes in process-level code; all error handling uses fmt.Errorf; no init/main functions or top-level side effects detected.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR does not add Ginkgo e2e tests. Modified test files use standard Go unit tests with the testing package, not Ginkgo-style tests with IPv4 assumptions or external connectivity requirements.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/operator/encryption/testing/helpers.go (1)

117-118: Don’t ignore marshal errors in test fixture generation.

Line 117 currently discards json.Marshal errors; this can mask fixture regressions.

Proposed fix
-	providerConfigJSON, _ := json.Marshal(providerConfig)
+	providerConfigJSON, err := json.Marshal(providerConfig)
+	if err != nil {
+		panic(err)
+	}
 	secret.Data[encryptionSecretKMSProviderConfigForTest] = providerConfigJSON
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/operator/encryption/testing/helpers.go` around lines 117 - 118, The code
currently ignores the error from json.Marshal(providerConfig) before assigning
providerConfigJSON into secret.Data[encryptionSecretKMSProviderConfigForTest];
change this to capture the error (err := json.Marshal(...)), check it, and
fail/propagate instead of discarding it — e.g., if this helper accepts testing.T
use t.Fatalf("marshal providerConfig: %v", err), or if it returns an error
propagate it up; then only assign providerConfigJSON to
secret.Data[encryptionSecretKMSProviderConfigForTest] when err == nil.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/operator/encryption/secrets/secrets.go`:
- Around line 78-88: The current reader in
pkg/operator/encryption/secrets/secrets.go rejects KMS secrets missing
EncryptionSecretKMSProviderConfig but other code can write secrets with a nil
ProviderConfig, causing roundtrip failures; update the parsing in the block that
handles s.Data[EncryptionSecretKMSProviderConfig] so that if the key is absent
or empty you do NOT return an error but instead leave key.KMS.ProviderConfig as
nil (or populate it with a default) and continue; when the field exists, still
json.Unmarshal into a state.KMSProviderConfig and assign to
key.KMS.ProviderConfig, and keep the existing error wrapping for malformed JSON.

---

Nitpick comments:
In `@pkg/operator/encryption/testing/helpers.go`:
- Around line 117-118: The code currently ignores the error from
json.Marshal(providerConfig) before assigning providerConfigJSON into
secret.Data[encryptionSecretKMSProviderConfigForTest]; change this to capture
the error (err := json.Marshal(...)), check it, and fail/propagate instead of
discarding it — e.g., if this helper accepts testing.T use t.Fatalf("marshal
providerConfig: %v", err), or if it returns an error propagate it up; then only
assign providerConfigJSON to
secret.Data[encryptionSecretKMSProviderConfigForTest] when err == nil.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a3734530-d955-4377-b024-ef9209a63bf8

📥 Commits

Reviewing files that changed from the base of the PR and between 1576bc0 and 8560739.

📒 Files selected for processing (7)
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/secrets/secrets_test.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/state/types.go
  • pkg/operator/encryption/testing/helpers.go

Comment thread pkg/operator/encryption/secrets/secrets.go
Comment thread pkg/operator/encryption/state/types.go Outdated
@@ -48,6 +49,27 @@ type KeyState struct {
type KMSConfig struct {
// Encoded EncryptionConfig that stores the KMS related fields
EncryptionConfig *apiserverconfigv1.KMSConfiguration

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.

we could rename this to Encryption - could be a new PR.

Comment thread pkg/operator/encryption/state/types.go Outdated
EncryptionConfig *apiserverconfigv1.KMSConfiguration

// ProviderConfig stores KMS provider specific configurations
ProviderConfig *KMSProviderConfig

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.

then this could be Provider

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Provider is nicer indeed.

Comment thread pkg/operator/encryption/state/types.go Outdated
// TODO: These fields are mimicked from https://github.com/openshift/api/pull/2805
// When API PR merges, *v1.KMSConfig will inherently support store fields,
// so that we can remove these internal structs.
KMSPluginImage string `json:"kmsPluginImage,omitempty"`

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.

I would wait until the API definitions land before introducing these changes.

Comment thread pkg/operator/encryption/state/types.go Outdated
}

// KMSProviderConfig stores KMS provider details.
// This type does not only store the API definitions but also carries internally

@p0lyn0mial p0lyn0mial Apr 28, 2026

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.

what other fields will be stored here ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Credential Secret/ConfigMap mapping will be stored additionally.

Comment thread pkg/operator/encryption/state/types.go Outdated
type KMSProviderConfig struct {
// KMSProviderConfig is directly derived from the KMSConfig in o/api.
// Therefore, all the KMS provider details in o/api is represented here.
*v1.KMSConfig

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.

how about pulling in the o/api PR in this PR ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done. Second commit uses the o/api PR

@ardaguclu
ardaguclu force-pushed the kms-provider-config-keystate branch from 8560739 to 2a88752 Compare April 28, 2026 10:02
@ardaguclu

Copy link
Copy Markdown
Member Author

/hold
this PR contains fake o/api bump

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 28, 2026
s.Data[EncryptionSecretKMSEncryptionConfig] = kmsEncCfgJSON
}

if ks.KMS != nil && ks.KMS.ProviderConfig != nil {

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.

HasKMSProviderConfig ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/operator/encryption/controllers/key_controller_test.go (1)

366-374: KMS provider-config tests only verify {} today.

Because the KMS APIServer fixture has no populated Spec.Encryption.KMS, these checks won’t catch regressions that drop/reshape actual provider fields. Add at least one scenario with non-empty KMS config and assert roundtrip on decoded struct content.

Also applies to: 435-443, 520-528, 722-778, 809-816

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/operator/encryption/controllers/key_controller_test.go` around lines 366
- 374, The tests in key_controller_test.go only assert the KMS provider-config
equals an empty JSON object by marshalling state.KMSProviderConfig{}, which
misses regressions; add at least one test case where the APIServer fixture's
Spec.Encryption.KMS is populated with non-empty fields, ensure the controller
writes that non-empty provider config into
actualSecret.Data["encryption.apiserver.operator.openshift.io-kms-provider-config"],
decode/unmarshal the secret bytes back into the same struct type
(state.KMSProviderConfig) and assert field-level equality (roundtrip) rather
than string equality to catch reshaping; update the analogous checks at the
other noted ranges (435-443, 520-528, 722-778, 809-816) to include non-empty
scenarios and roundtrip assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@go.mod`:
- Line 142: The go.mod replace directive "replace github.com/openshift/api =>
github.com/flavianmissi/api v0.0.0-20260424105406-3d4bd99d6aa0" must be removed
or replaced with an upstream commit/tag to avoid using a personal fork; edit the
replace line in go.mod (the replace directive) to either delete it entirely or
point to an official github.com/openshift/api version (a specific tag or commit
hash) and re-run go mod tidy to update go.sum, or keep the forked replace only
in a local, uncommitted workspace if this change is exploratory.

In `@pkg/operator/encryption/secrets/secrets_test.go`:
- Around line 132-138: The test is constructing state.KMSProviderConfig with
fields that don't exist; update the literal to either leave ProviderConfig
nil/empty if the test doesn't need values, or build the nested v1.KMSConfig
properly: set ProviderConfig to &state.KMSProviderConfig{KMSConfig:
&v1.KMSConfig{Type: v1.KMSProviderTypeVault, Vault:
&v1.VaultKMSConfig{KMSPluginImage: "...", VaultAddress: "...", VaultNamespace:
"...", TransitMount: "...", TransitKey: "..."}}} so the Vault-specific fields
live under Vault (v1.VaultKMSConfig) rather than directly on
state.KMSProviderConfig; apply the same change to the other occurrence
referenced in the comment.

---

Nitpick comments:
In `@pkg/operator/encryption/controllers/key_controller_test.go`:
- Around line 366-374: The tests in key_controller_test.go only assert the KMS
provider-config equals an empty JSON object by marshalling
state.KMSProviderConfig{}, which misses regressions; add at least one test case
where the APIServer fixture's Spec.Encryption.KMS is populated with non-empty
fields, ensure the controller writes that non-empty provider config into
actualSecret.Data["encryption.apiserver.operator.openshift.io-kms-provider-config"],
decode/unmarshal the secret bytes back into the same struct type
(state.KMSProviderConfig) and assert field-level equality (roundtrip) rather
than string equality to catch reshaping; update the analogous checks at the
other noted ranges (435-443, 520-528, 722-778, 809-816) to include non-empty
scenarios and roundtrip assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 465b5ca6-2647-4900-83fe-e55592b3532a

📥 Commits

Reviewing files that changed from the base of the PR and between 8560739 and 2a88752.

⛔ Files ignored due to path filters (43)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_dns.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_kmsencryption.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/envtest-releases.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/types_pacemakercluster.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/etcd/v1alpha1/types_pacemakercluster.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/etcd/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_ingress.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/quota/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/security/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/security/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/security/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (8)
  • go.mod
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/secrets/secrets_test.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/state/types.go
  • pkg/operator/encryption/testing/helpers.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/operator/encryption/testing/helpers.go
  • pkg/operator/encryption/secrets/secrets.go

Comment thread go.mod Outdated
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
)

replace github.com/openshift/api => github.com/flavianmissi/api v0.0.0-20260424105406-3d4bd99d6aa0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check the go.mod file around line 142
head -150 go.mod | tail -20

Repository: openshift/library-go

Length of output: 1082


🏁 Script executed:

# Also get the full replace directives to understand the context
grep -n "^replace" go.mod

Repository: openshift/library-go

Length of output: 167


🏁 Script executed:

# Check if there are any comments or documentation about why this fork is used
rg -i "flavianmissi|openshift/api" --type go --type md -C 2

Repository: openshift/library-go

Length of output: 50377


🏁 Script executed:

# Check git history to see if there's context about this change
git log --oneline -20 -- go.mod 2>/dev/null || echo "Git history not available"

Repository: openshift/library-go

Length of output: 106


🏁 Script executed:

# Check if there are any comments or documentation about the Vault KMS change
rg -i "vault|kms|flavianmissi" --type go --type md -B 2 -A 2 | head -50

Repository: openshift/library-go

Length of output: 3111


🏁 Script executed:

# Check recent PR or commit context
git log --oneline --all | grep -i "vault\|kms\|api\|flavian" | head -20

Repository: openshift/library-go

Length of output: 1342


Remove the fork override or pin it to a specific upstream commit.

The replace directive redirects github.com/openshift/api to a personal fork (github.com/flavianmissi/api), which introduces supply-chain and reproducibility risk in a shared branch. While the version is pinned to a pseudoversion rather than floating master, the use of a personal fork as a core API dependency requires clear justification. The commit message "Fake bump o/api to get Vault KMS" suggests this is exploratory work that shouldn't be merged. Either use an upstream github.com/openshift/api commit/tag or keep such overrides local and uncommitted during development.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@go.mod` at line 142, The go.mod replace directive "replace
github.com/openshift/api => github.com/flavianmissi/api
v0.0.0-20260424105406-3d4bd99d6aa0" must be removed or replaced with an upstream
commit/tag to avoid using a personal fork; edit the replace line in go.mod (the
replace directive) to either delete it entirely or point to an official
github.com/openshift/api version (a specific tag or commit hash) and re-run go
mod tidy to update go.sum, or keep the forked replace only in a local,
uncommitted workspace if this change is exploratory.

Comment thread pkg/operator/encryption/secrets/secrets_test.go Outdated
@ardaguclu

ardaguclu commented Apr 28, 2026

Copy link
Copy Markdown
Member Author

/retitle WIP: CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState

@openshift-ci openshift-ci Bot changed the title CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState WIP: CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState Apr 28, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 28, 2026
@ardaguclu
ardaguclu force-pushed the kms-provider-config-keystate branch 3 times, most recently from 20ff99b to eb6d1f3 Compare April 28, 2026 13:17
@ardaguclu

ardaguclu commented Apr 28, 2026

Copy link
Copy Markdown
Member Author

/retitle CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState

@ardaguclu

Copy link
Copy Markdown
Member Author

/hold cancel

@openshift-ci openshift-ci Bot changed the title WIP: CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState CNTRLPLANE-3237: Introduce KMSProviderConfig in KeyState Apr 28, 2026
@openshift-ci openshift-ci Bot removed do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Apr 28, 2026
@ardaguclu
ardaguclu force-pushed the kms-provider-config-keystate branch from eb6d1f3 to 80735b3 Compare April 28, 2026 13:20
Comment thread pkg/operator/encryption/api/api.go Outdated
@@ -0,0 +1,284 @@
// TODO: This API definitions are copied from https://github.com/openshift/api/pull/2805

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.

nit: could we create a new api pkg for it ? for example pkg/operator/encryption/api ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It would be indeed better

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Moved

}

func (c *keyController) getCurrentModeAndExternalReason(ctx context.Context) (state.Mode, string, error) {
func (c *keyController) getCurrentModeAndExternalReason(ctx context.Context) (state.Mode, string, *v1.APIServerEncryption, error) {

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.

getCurrentModeReasonAndEncryptionConfig ?

return "", "", nil, err
}

encryption := &apiServer.Spec.Encryption

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.

do we have to return a pointer ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No we don't have to. Updated.

reason := encryptionConfig.Encryption.Reason
switch currentMode := state.Mode(apiServer.Spec.Encryption.Type); currentMode {
switch currentMode := state.Mode(encryption.Type); currentMode {
case state.AESCBC, state.AESGCM, state.KMS, state.Identity: // secretbox is disabled for now

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.

could we check encryption.KMS for nil here ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, better. Updated

ExternalReason: externalReason,
}
if currentMode == state.KMS {
if apiServerEncryption == nil || apiServerEncryption.KMS == nil {

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.

then we could drop this checks.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Dropped


func (c *keyController) checkAndCreateKeys(ctx context.Context, syncContext factory.SyncContext, encryptedGRs []schema.GroupResource) error {
currentMode, externalReason, err := c.getCurrentModeAndExternalReason(ctx)
currentMode, externalReason, apiServerEncryption, err := c.getCurrentModeAndExternalReason(ctx)

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.

encryptionConfiguration ?

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.

apiEncryptionConfiguration ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated for apiEncryptionConfiguration

@ardaguclu
ardaguclu force-pushed the kms-provider-config-keystate branch from 8bb5034 to 87b5035 Compare April 29, 2026 12:58
@ardaguclu

Copy link
Copy Markdown
Member Author

/hold cancel

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 29, 2026
@ardaguclu
ardaguclu force-pushed the kms-provider-config-keystate branch from 87b5035 to db7cc6f Compare April 29, 2026 13:14
if err := json.Unmarshal(v, providerConfig); err != nil {
return state.KeyState{}, fmt.Errorf("secret %s/%s has invalid %s data: %w", s.Namespace, s.Name, EncryptionSecretKMSProviderConfig, err)
}
// KMSConfig is non-nil here; initialized by the encryption config branch above

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the secret has a EncryptionSecretKMSProviderConfig key, but lacks a EncryptionSecretKMSEncryptionConfig key, then KMSConfig could be nil (and we'd panic here).

Probably not something that can happen, but maybe we can be defensive about it and initialize key.KMSConfig before the if-else clauses - and add a comment that the allocation would be wasted if the secret doesn't have the KMS keys (which is fine).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Something like:

diff --git a/pkg/operator/encryption/secrets/secrets.go b/pkg/operator/encryption/secrets/secrets.go
index f16198107..aa0fa417d 100644
--- a/pkg/operator/encryption/secrets/secrets.go
+++ b/pkg/operator/encryption/secrets/secrets.go
@@ -64,12 +64,14 @@ func ToKeyState(s *corev1.Secret) (state.KeyState, error) {
        case state.AESCBC, state.AESGCM, state.SecretBox, state.Identity:
                key.Mode = keyMode
        case state.KMS:
+               // This allocation will be wasted if KMS keys are not present in the secret, but that should not happen
+               key.KMSConfig = &state.KMSConfig{}
                if v, ok := s.Data[EncryptionSecretKMSEncryptionConfig]; ok && len(v) > 0 {
                        kmsConfiguration := &apiserverconfigv1.KMSConfiguration{}
                        if err := json.Unmarshal(v, kmsConfiguration); err != nil {
                                return state.KeyState{}, fmt.Errorf("secret %s/%s has invalid %s data: %w", s.Namespace, s.Name, EncryptionSecretKMSEncryptionConfig, err)
                        }
-                       key.KMSConfig = &state.KMSConfig{Encryption: kmsConfiguration}
+                       key.KMSConfig.Encryption = kmsConfiguration
                } else {
                        // encryption.apiserver.operator.openshift.io-kms-encryption-config data field is required for KMS
                        // encryption mode.
@@ -80,7 +82,6 @@ func ToKeyState(s *corev1.Secret) (state.KeyState, error) {
                        if err := json.Unmarshal(v, providerConfig); err != nil {
                                return state.KeyState{}, fmt.Errorf("secret %s/%s has invalid %s data: %w", s.Namespace, s.Name, EncryptionSecretKMSProviderConfig, err)
                        }
-                       // KMSConfig is non-nil here; initialized by the encryption config branch above
                        key.KMSConfig.Provider = providerConfig
                } else {
                        // encryption.apiserver.operator.openshift.io-kms-provider-config data field is required for KMS

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated.

if ks.HasKMSProvider() {
providerJSON, err := json.Marshal(ks.KMSConfig.Provider)
if err != nil {
return nil, err

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: we could annotate the error here and on the check above (for the EncryptionConfiguration) to say what exactly failed to be serialized

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated.


if ks.Mode == state.KMS && (!ks.HasKMSEncryption() || !ks.HasKMSProvider()) {
return nil, fmt.Errorf("%s or %s can not be empty, when mode is KMS", EncryptionSecretKMSEncryptionConfig, EncryptionSecretKMSProviderConfig)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: we could move this up and avoid some processing if we're in a bad state

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated. Please let me know about the state.

}

func (c *keyController) getCurrentModeAndExternalReason(ctx context.Context) (state.Mode, string, error) {
func (c *keyController) getCurrentModeReasonAndEncryptionConfig(ctx context.Context) (state.Mode, string, v1.APIServerEncryption, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we have a reason for this not to be a pointer?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It was. I updated after #2186 (comment)

@ardaguclu
ardaguclu force-pushed the kms-provider-config-keystate branch from 2c40672 to 635b6b7 Compare April 29, 2026 14:44

@bertinatto bertinatto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

@p0lyn0mial

Copy link
Copy Markdown
Contributor

/lgtm

@ardaguclu

Copy link
Copy Markdown
Member Author

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 29, 2026

@bertinatto bertinatto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Apr 29, 2026
@openshift-ci

openshift-ci Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ardaguclu, bertinatto, p0lyn0mial

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [bertinatto,p0lyn0mial]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 29, 2026
@openshift-ci

openshift-ci Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

@ardaguclu: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ardaguclu

Copy link
Copy Markdown
Member Author

It failed but this requires changes in test step. I will fix it in a followup PR
/hold cancel

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Apr 29, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit d45f1f2 into openshift:master Apr 29, 2026
6 checks passed
@ardaguclu
ardaguclu deleted the kms-provider-config-keystate branch April 29, 2026 17:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants