Skip to content

CNTRLPLANE-3237: Introduce KMSProviderConfig in encryption-config Secret - #2163

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:masterfrom
ardaguclu:kms-v2-provider-config
May 6, 2026
Merged

openshift-merge-bot[bot] merged 1 commit into
openshift:masterfrom
ardaguclu:kms-v2-provider-config

Conversation

@ardaguclu

@ardaguclu ardaguclu commented Apr 17, 2026

Copy link
Copy Markdown
Member

This is continuation of #2186 for the work that is described openshift/enhancements#1960

This PR carries the kms-provider-config into encryption-config Secret.

@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 17, 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 17, 2026
@openshift-ci-robot

openshift-ci-robot commented Apr 17, 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 is continuation of #2161 for the work that is described openshift/enhancements#1960

This PR introduces KMSProviderConfig which will be used as the internal representation of the API fields. This field will be serialized and carried from key_controller -> state_controller -> 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.

@coderabbitai

coderabbitai Bot commented Apr 17, 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

Migrates KMS config storage from secret annotations to secret Data fields, introduces per-key KMS provider configs, renames KMSConfigurationKMSEncryptionConfig, adds KMSProviderConfig types/fields, updates serialization/deserialization and controller flows to collect and include provider configs when creating encryption-config secrets.

Changes

Cohort / File(s) Summary
State & types
pkg/operator/encryption/state/types.go, pkg/operator/encryption/secrets/types.go
Rename KeyState.KMSConfigurationKMSEncryptionConfig; add KeyState.KMSProviderConfig, introduce KMSProviderConfig and VaultProviderConfig types; replace EncryptionSecretKMSConfig annotation constant with EncryptionSecretKMSEncryptionConfig and EncryptionSecretKMSProviderConfig data keys.
Secret serialization/deserialization
pkg/operator/encryption/secrets/secrets.go, pkg/operator/encryption/secrets/secrets_test.go
ToKeyState/FromKeyState now read/write KMS encryption and provider configs from/to secret.Data[...] keys instead of annotations; updated error messages and tests to match new keys.
Encryption-config secret creation
pkg/operator/encryption/encryptionconfig/secret.go, pkg/operator/encryption/encryptionconfig/config.go, pkg/operator/encryption/encryptionconfig/config_test.go
Extend ToSecret signature to accept kmsProviderConfigs map; populate secret.Data with marshaled provider configs keyed by <EncryptionSecretKMSProviderConfig>-<keyID>; update KMS handling to use KMSEncryptionConfig.
Controllers: key & state
pkg/operator/encryption/controllers/key_controller.go, pkg/operator/encryption/controllers/state_controller.go, pkg/operator/encryption/controllers/key_controller_test.go, pkg/operator/encryption/controllers/state_controller_test.go
Key controller populates KMSEncryptionConfig and KMSProviderConfig (per-key KMS socket via kms-%d.sock); state controller adds collectKMSProviderConfigs and passes provider configs into applyEncryptionConfigSecret; tests updated to assert provider config presence in secret.Data.
Test helpers & fixtures
pkg/operator/encryption/controllers/helpers_test.go, pkg/operator/encryption/deployer/unionrevisionedpod_test.go, pkg/operator/encryption/observer/observe_encryption_config_test.go, pkg/operator/encryption/testing/helpers.go
Updated test call sites to new ToSecret(..., kmsProviderConfigs) signature; test helpers now write KMS encryption config and provider config into secret.Data and parameterize per-key socket paths (kms-<keyID>.sock).
Config generation & normalization
pkg/operator/encryption/encryptionconfig/config.go, pkg/operator/encryption/config_test.go, pkg/operator/encryption/encryptionconfig/config_test.go, pkg/operator/encryption/statemachine/transition_test.go
KMS provider construction now deep-copies KMSEncryptionConfig, names providers with createKMSProviderName(...), and test fixtures normalize per-key KMS socket endpoints to match key IDs.
Deployer / union tests
pkg/operator/encryption/deployer/unionrevisionedpod_test.go
Updated helper encryptionCfgToSecret call to new ToSecret(..., nil) form.
E2E
test/e2e-encryption/encryption_test.go
After migration, added assertions that encryption-key and encryption-config secrets include provider-config data entries (EncryptionSecretKMSProviderConfig and versioned key).

Sequence Diagram

sequenceDiagram
    participant KeyCtrl as Key Controller
    participant StateCtrl as State Controller
    participant Collector as collectKMSProviderConfigs
    participant ToSecret as encryptionconfig.ToSecret
    participant Secrets as secrets.FromKeyState
    participant Kube as Kubernetes API

    KeyCtrl->>KeyCtrl: generateKeySecret (KMS mode)
    KeyCtrl->>KeyCtrl: set ks.KMSEncryptionConfig and ks.KMSProviderConfig
    KeyCtrl->>Secrets: FromKeyState(ks)
    Secrets-->>KeyCtrl: Secret with Data[KMS encryption/config, KMS provider/config]

    StateCtrl->>Collector: collectKMSProviderConfigs(desiredState)
    Collector-->>StateCtrl: map[keyID]KMSProviderConfig

    StateCtrl->>ToSecret: ToSecret(ns,name,encryptionCfg,kmsProviderConfigs)
    ToSecret->>ToSecret: marshal provider configs into secret.Data[...] per keyID
    ToSecret-->>StateCtrl: Secret with provider configs in Data

    StateCtrl->>Kube: apply Secret
    Kube-->>StateCtrl: Secret created/updated
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 8 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ❓ Inconclusive PR contains standard Go testing.T tests, not Ginkgo-style tests, making the Ginkgo-focused check criteria inapplicable to the actual test code. Clarify whether codebase uses Ginkgo or standard Go testing, then adapt check criteria accordingly for either framework's best practices.
✅ Passed checks (8 passed)
Check name Status Explanation
Stable And Deterministic Test Names ✅ Passed No Ginkgo BDD-style tests found; all tests use standard Go testing.T with static, deterministic names.
Microshift Test Compatibility ✅ Passed PR does not add new Ginkgo e2e tests. Only unit tests in pkg/operator/encryption are modified.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The new e2e test file uses standard Go testing patterns (testing.T), not Ginkgo patterns (It, Describe, Context, When). The SNO compatibility check applies only to Ginkgo e2e tests, so it is not applicable to this PR.
Topology-Aware Scheduling Compatibility ✅ Passed PR introduces KMS configuration data structures and serialization in Secrets without adding any Pod scheduling constraints, affinity rules, or topology-dependent specifications.
Ote Binary Stdout Contract ✅ Passed PR does not violate OTE Binary Stdout Contract; init() contains only scheme registration without stdout writes, and fmt.Printf calls are isolated to test blocks.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The new e2e test file is a standard Go test function without IPv4 hardcoded addresses, IPv4-only logic, or external connectivity requirements, making it compatible with IPv4/IPv6 and disconnected networks.
Title check ✅ Passed The PR title clearly and specifically describes the main change: introducing KMSProviderConfig in the encryption-config Secret. It directly reflects the primary objective and is concise and readable.
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.

@openshift-ci
openshift-ci Bot requested review from dgrisonnet and p0lyn0mial April 17, 2026 06:17
@openshift-ci-robot

openshift-ci-robot commented Apr 17, 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 is continuation of #2161 for the work that is described openshift/enhancements#1960

This PR introduces KMSProviderConfig which will be used as the internal representation of the API fields. This field will be serialized and carried from key_controller -> state_controller -> plugin lifecycle.

Summary by CodeRabbit

  • Bug Fixes

  • Improved KMS encryption configuration storage to use dedicated secret data fields instead of annotations for better reliability.

  • Features

  • Added support for per-key KMS socket endpoints, enabling more flexible KMS instance management.

  • Enhanced KMS provider configuration with explicit Vault integration settings for improved security controls.

  • Tests

  • Extended test coverage for KMS configuration handling and provider setup validation.

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.

@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.

🧹 Nitpick comments (4)
test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml (2)

54-253: Consider templating to reduce duplication in the test asset.

The 10 nearly-identical container definitions differ only in the container name and socket path number. While this is a test asset and correctness is not affected, this repetition is error-prone to maintain.

If the templating system supports it (Go templates are used based on {{ .Image }}), consider generating the containers programmatically:

{{- range $i := seq 1 10 }}
        - name: kms-plugin-{{ $i }}
          image: {{ $.Image }}
          ...
          args:
            - |
              rm -f /var/run/kmsplugin/kms-{{ $i }}.sock
              exec /usr/local/bin/mock-kms-plugin -listen-addr=unix:///var/run/kmsplugin/kms-{{ $i }}.sock -config-file-path=/etc/softhsm-config.json
{{- end }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml` around
lines 54 - 253, Replace the ten near-identical container blocks (names like
kms-plugin-1..kms-plugin-10 and socket paths /var/run/kmsplugin/kms-#.sock) with
a Go-template range loop that iterates from 1 to 10, uses the loop index for the
container name and socket filename, and references the image as $.Image; keep
the same securityContext, command, args (but with the index substituted), and
volumeMounts (socket, softhsm-config with subPath, softhsm-tokens) inside the
loop so the behavior remains identical while removing duplication.

57-58: Consider replacing privileged: true with specific capabilities or removing it if unnecessary.

All 10 plugin containers and the init container use privileged: true, but their operations—listening on Unix sockets, reading configuration files, and accessing mounted volumes—do not require privileged mode. For a test environment, replacing this with specific capabilities (e.g., CAP_CHOWN) or a non-privileged security context would align with least-privilege principles. If socket creation and file access work without elevated privileges, remove the securityContext entirely.

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

In `@test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml` around
lines 57 - 58, The DaemonSet uses securityContext with privileged: true for the
init container and all plugin containers; change this to follow least-privilege
by removing the privileged setting or replacing it with narrow POSIX
capabilities (e.g., add a securityContext.capabilities.add list with only needed
capabilities like CAP_CHOWN) or a readOnlyRootFilesystem / runAsNonRoot setup if
possible; update the initContainer and container specs (look for securityContext
and privileged: true entries) to either remove the entire securityContext when
not needed or explicitly list minimal capabilities and non-root settings so
sockets and file access still work without full privileged mode.
pkg/operator/encryption/testing/helpers.go (1)

24-29: Test constants duplicate production constants.

These local constants duplicate values from pkg/operator/encryption/secrets/types.go. While this avoids import cycles, it creates a maintenance burden if the values change.

Consider adding a comment noting these must stay in sync with secrets.EncryptionSecretKMSEncryptionConfig and secrets.EncryptionSecretKMSProviderConfig.

🤖 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 24 - 29, The test
constants (encryptionSecretKeyDataForTest,
encryptionSecretMigratedTimestampForTest,
encryptionSecretMigratedResourcesForTest,
encryptionSecretKMSEncryptionConfigForTest,
encryptionSecretKMSProviderConfigForTest) duplicate production values; add a
clear comment above these declarations stating they must remain in sync with the
production symbols in pkg/operator/encryption/secrets (specifically
secrets.EncryptionSecretKMSEncryptionConfig and
secrets.EncryptionSecretKMSProviderConfig) to avoid drift and explain why the
duplication exists (to avoid import cycles).
pkg/operator/encryption/controllers/key_controller.go (1)

280-289: Hardcoded KMS provider configuration noted.

The TODO comment indicates these values will be replaced by API when ready. For Tech Preview, this is acceptable, but consider:

  1. These hardcoded values will need to be parameterized before GA
  2. The image reference uses a personal/support account registry path which may not be suitable for production
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/operator/encryption/controllers/key_controller.go` around lines 280 -
289, The code currently assigns hardcoded KMS values in ks.KMSProviderConfig
using state.KMSProviderConfig and state.VaultProviderConfig (fields Image,
VaultAddress, VaultNamespace, TransitKey, TransitMount); replace these hardcoded
literals with configurable sources (e.g., read from controller config, CR spec,
environment variables or a ConfigMap/Secret) and fall back to safe defaults only
for Tech Preview, ensure the image string is not a personal registry (make it
configurable and validate it) and update/remove the TODO accordingly so the
values are injected rather than baked into the key_controller.go logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/operator/encryption/controllers/key_controller.go`:
- Around line 280-289: The code currently assigns hardcoded KMS values in
ks.KMSProviderConfig using state.KMSProviderConfig and state.VaultProviderConfig
(fields Image, VaultAddress, VaultNamespace, TransitKey, TransitMount); replace
these hardcoded literals with configurable sources (e.g., read from controller
config, CR spec, environment variables or a ConfigMap/Secret) and fall back to
safe defaults only for Tech Preview, ensure the image string is not a personal
registry (make it configurable and validate it) and update/remove the TODO
accordingly so the values are injected rather than baked into the
key_controller.go logic.

In `@pkg/operator/encryption/testing/helpers.go`:
- Around line 24-29: The test constants (encryptionSecretKeyDataForTest,
encryptionSecretMigratedTimestampForTest,
encryptionSecretMigratedResourcesForTest,
encryptionSecretKMSEncryptionConfigForTest,
encryptionSecretKMSProviderConfigForTest) duplicate production values; add a
clear comment above these declarations stating they must remain in sync with the
production symbols in pkg/operator/encryption/secrets (specifically
secrets.EncryptionSecretKMSEncryptionConfig and
secrets.EncryptionSecretKMSProviderConfig) to avoid drift and explain why the
duplication exists (to avoid import cycles).

In `@test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml`:
- Around line 54-253: Replace the ten near-identical container blocks (names
like kms-plugin-1..kms-plugin-10 and socket paths /var/run/kmsplugin/kms-#.sock)
with a Go-template range loop that iterates from 1 to 10, uses the loop index
for the container name and socket filename, and references the image as $.Image;
keep the same securityContext, command, args (but with the index substituted),
and volumeMounts (socket, softhsm-config with subPath, softhsm-tokens) inside
the loop so the behavior remains identical while removing duplication.
- Around line 57-58: The DaemonSet uses securityContext with privileged: true
for the init container and all plugin containers; change this to follow
least-privilege by removing the privileged setting or replacing it with narrow
POSIX capabilities (e.g., add a securityContext.capabilities.add list with only
needed capabilities like CAP_CHOWN) or a readOnlyRootFilesystem / runAsNonRoot
setup if possible; update the initContainer and container specs (look for
securityContext and privileged: true entries) to either remove the entire
securityContext when not needed or explicitly list minimal capabilities and
non-root settings so sockets and file access still work without full privileged
mode.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 74d7db0f-ae9d-4fe6-adb1-90b5bb8f25cc

📥 Commits

Reviewing files that changed from the base of the PR and between d2db42c and d9bafe1.

📒 Files selected for processing (18)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/controllers/state_controller_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/encryptionconfig/config.go
  • pkg/operator/encryption/encryptionconfig/config_test.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/observer/observe_encryption_config_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/statemachine/transition_test.go
  • pkg/operator/encryption/testing/helpers.go
  • test/e2e-encryption/encryption_test.go
  • test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml

@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from d9bafe1 to 585e22b Compare April 17, 2026 06:29
@openshift-ci-robot

openshift-ci-robot commented Apr 17, 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 is continuation of #2161 for the work that is described openshift/enhancements#1960

This PR introduces KMSProviderConfig which will be used as the internal representation of the API fields. This field will be serialized and carried from key_controller -> state_controller -> plugin lifecycle.

Summary by CodeRabbit

  • Bug Fixes

  • KMS configuration now stored in secret data fields (not annotations) for more reliable encryption-key handling.

  • Features

  • Per-key KMS socket endpoints enabling distinct KMS endpoints per key.

  • Per-key KMS provider configs added, including Vault provider settings to support provider-specific configuration.

  • Tests

  • Expanded unit and e2e tests to validate per-key endpoints and provider-config data written into secrets.

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.

@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

🤖 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 66-75: The new code drops the legacy annotation-backed KMS secret
read path, causing migration breakage; update the ToKeyState logic in secrets.go
so that after attempting to unmarshal EncryptionSecretKMSEncryptionConfig from
s.Data it falls back to checking the legacy annotation (the previous KMS
encryption config stored on the Secret's annotations), unmarshal that into
apiserverconfigv1.KMSConfiguration and set key.KMSEncryptionConfig, and only
return the "KMSEncryptionConfig can not be nil" error if both the Data field and
the legacy annotation are absent or both fail to parse; reference the
EncryptionSecretKMSEncryptionConfig symbol, s.Data / s.Annotations,
key.KMSEncryptionConfig and state.KeyState when making the change.
- Around line 135-149: FromKeyState currently allows serializing a key secret
with ks.Mode == state.KMS even when ks.KMSEncryptionConfig is nil, which breaks
round-trip with ToKeyState; update FromKeyState to validate and reject invalid
KMS states before writing: if ks.Mode == state.KMS and ks.KMSEncryptionConfig ==
nil return a clear error instead of producing a secret, and keep the existing
serialization of KMSEncryptionConfig and KMSProviderConfig
(EncryptionSecretKMSEncryptionConfig, EncryptionSecretKMSProviderConfig) only
when those fields are non-nil; reference the FromKeyState function, ks.Mode,
KMSEncryptionConfig, KMSProviderConfig, and the constants used for secret keys
when implementing the check and error return.
🪄 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: Pro Plus

Run ID: 446c51cf-2cc5-43fb-8ddc-4a15e21f75ff

📥 Commits

Reviewing files that changed from the base of the PR and between d9bafe1 and 585e22b.

📒 Files selected for processing (13)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/controllers/state_controller_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/observer/observe_encryption_config_test.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/state/types.go
  • pkg/operator/encryption/testing/helpers.go
  • test/e2e-encryption/encryption_test.go
✅ Files skipped from review due to trivial changes (4)
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/controllers/helpers_test.go
  • test/e2e-encryption/encryption_test.go
  • pkg/operator/encryption/controllers/key_controller_test.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/operator/encryption/observer/observe_encryption_config_test.go
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/controllers/state_controller_test.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/secrets/secrets.go Outdated
@ardaguclu

Copy link
Copy Markdown
Member Author

@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from 585e22b to e143c1e Compare April 17, 2026 16:13
@openshift-ci-robot

openshift-ci-robot commented Apr 17, 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 is continuation of #2161 for the work that is described openshift/enhancements#1960

This PR introduces KMSProviderConfig which will be used as the internal representation of the API fields. This field will be serialized and carried from key_controller -> state_controller -> plugin lifecycle.

Summary by CodeRabbit

  • Bug Fixes

  • KMS configuration is now stored in secret data fields (not annotations) for more reliable encryption-key handling.

  • Features

  • Per-key KMS socket endpoints so each key can use its own KMS socket.

  • Per-key KMS provider configs (including Vault provider settings) baked into secrets to support provider-specific options.

  • Tests

  • Expanded unit and e2e tests to validate per-key endpoints and provider-config data in secrets.

  • Chores

  • Test KMS mock updated to run dedicated per-socket plugin instances.

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.

@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.

♻️ Duplicate comments (1)
pkg/operator/encryption/secrets/secrets.go (1)

135-149: ⚠️ Potential issue | 🟠 Major

Reject invalid KMS key states before writing the secret.

ToKeyState rejects KMS secrets without KMSEncryptionConfig (lines 73-75), but FromKeyState still serializes ks.Mode == state.KMS with that field potentially unset. This makes the conversion non-round-trippable and lets callers persist a secret this package cannot read back.

🛡️ Proposed fix
+	if ks.Mode == state.KMS && ks.KMSEncryptionConfig == nil {
+		return nil, fmt.Errorf("KMSEncryptionConfig cannot be nil when mode is KMS")
+	}
+
 	if ks.KMSEncryptionConfig != nil {
 		kmsEncCfgJSON, err := json.Marshal(ks.KMSEncryptionConfig)
 		if err != nil {
 			return nil, err
 		}
 		s.Data[EncryptionSecretKMSEncryptionConfig] = kmsEncCfgJSON
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/operator/encryption/secrets/secrets.go` around lines 135 - 149,
FromKeyState currently allows serializing ks with ks.Mode == state.KMS even when
ks.KMSEncryptionConfig is nil, producing secrets that ToKeyState cannot read
back; update FromKeyState to validate and reject invalid KMS states before
writing the secret by returning an error when ks.Mode == state.KMS and
ks.KMSEncryptionConfig == nil (and likewise validate any other required KMS
fields such as KMSProviderConfig if your domain requires it) instead of
proceeding to marshal and set
EncryptionSecretKMSEncryptionConfig/EncryptionSecretKMSProviderConfig in s.Data.
🧹 Nitpick comments (1)
test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml (1)

54-253: Consider templating the repeated container definitions.

The 10 container blocks are nearly identical, differing only in the container name and socket index. While acceptable for a test asset, this creates maintenance burden if you need to change shared parameters (image, volumeMounts, securityContext).

Since this YAML already uses Go templating ({{ .Index }}, {{ .Image }}), you could reduce duplication by templating the containers as well:

♻️ Proposed refactor using Go range template
       containers:
-        - name: kms-plugin-1
-          image: {{ .Image }}
-          imagePullPolicy: IfNotPresent
-          securityContext:
-            privileged: true
-          command:
-            - /bin/sh
-            - -c
-          args:
-            - |
-              rm -f /var/run/kmsplugin/kms-1.sock
-              exec /usr/local/bin/mock-kms-plugin -listen-addr=unix:///var/run/kmsplugin/kms-1.sock -config-file-path=/etc/softhsm-config.json
-          volumeMounts:
-            - name: socket
-              mountPath: /var/run/kmsplugin
-            - name: softhsm-config
-              mountPath: /etc/softhsm-config.json
-              subPath: softhsm-config.json
-            - name: softhsm-tokens
-              mountPath: /var/lib/softhsm/tokens
-        - name: kms-plugin-2
-        ... (repeat for 3-10)
+{{- range $i := list 1 2 3 4 5 6 7 8 9 10 }}
+        - name: kms-plugin-{{ $i }}
+          image: {{ $.Image }}
+          imagePullPolicy: IfNotPresent
+          securityContext:
+            privileged: true
+          command:
+            - /bin/sh
+            - -c
+          args:
+            - |
+              rm -f /var/run/kmsplugin/kms-{{ $i }}.sock
+              exec /usr/local/bin/mock-kms-plugin -listen-addr=unix:///var/run/kmsplugin/kms-{{ $i }}.sock -config-file-path=/etc/softhsm-config.json
+          volumeMounts:
+            - name: socket
+              mountPath: /var/run/kmsplugin
+            - name: softhsm-config
+              mountPath: /etc/softhsm-config.json
+              subPath: softhsm-config.json
+            - name: softhsm-tokens
+              mountPath: /var/lib/softhsm/tokens
+{{- end }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml` around
lines 54 - 253, Refactor the repeated kms-plugin-* container blocks into a Go
template range to eliminate duplication: create a slice (e.g., .Plugins or
.NumPlugins) and iterate (range) to render each container using a template body
that sets name as "kms-plugin-{{index}}" and socket paths like
/var/run/kmsplugin/kms-{{index}}. Keep shared fields (image / Image,
imagePullPolicy, securityContext, command, args, volumeMounts, softhsm-config
subPath) inside the templated block so one change updates all; update any
references to container names or sockets (e.g., kms-plugin-1..kms-plugin-10 and
-listen-addr=unix:///var/run/kmsplugin/kms-<index>.sock) to use the template
index variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@pkg/operator/encryption/secrets/secrets.go`:
- Around line 135-149: FromKeyState currently allows serializing ks with ks.Mode
== state.KMS even when ks.KMSEncryptionConfig is nil, producing secrets that
ToKeyState cannot read back; update FromKeyState to validate and reject invalid
KMS states before writing the secret by returning an error when ks.Mode ==
state.KMS and ks.KMSEncryptionConfig == nil (and likewise validate any other
required KMS fields such as KMSProviderConfig if your domain requires it)
instead of proceeding to marshal and set
EncryptionSecretKMSEncryptionConfig/EncryptionSecretKMSProviderConfig in s.Data.

---

Nitpick comments:
In `@test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml`:
- Around line 54-253: Refactor the repeated kms-plugin-* container blocks into a
Go template range to eliminate duplication: create a slice (e.g., .Plugins or
.NumPlugins) and iterate (range) to render each container using a template body
that sets name as "kms-plugin-{{index}}" and socket paths like
/var/run/kmsplugin/kms-{{index}}. Keep shared fields (image / Image,
imagePullPolicy, securityContext, command, args, volumeMounts, softhsm-config
subPath) inside the templated block so one change updates all; update any
references to container names or sockets (e.g., kms-plugin-1..kms-plugin-10 and
-listen-addr=unix:///var/run/kmsplugin/kms-<index>.sock) to use the template
index variable.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 04563983-6d64-435c-b21a-0f1e31caf275

📥 Commits

Reviewing files that changed from the base of the PR and between 585e22b and e143c1e.

📒 Files selected for processing (18)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/controllers/state_controller_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/encryptionconfig/config.go
  • pkg/operator/encryption/encryptionconfig/config_test.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/observer/observe_encryption_config_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/statemachine/transition_test.go
  • pkg/operator/encryption/testing/helpers.go
  • test/e2e-encryption/encryption_test.go
  • test/library/encryption/kms/assets/k8s_mock_kms_plugin_daemonset.yaml
✅ Files skipped from review due to trivial changes (3)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/statemachine/transition_test.go
🚧 Files skipped from review as they are similar to previous changes (10)
  • pkg/operator/encryption/encryptionconfig/config_test.go
  • pkg/operator/encryption/observer/observe_encryption_config_test.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/encryptionconfig/config.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • test/e2e-encryption/encryption_test.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/testing/helpers.go
  • pkg/operator/encryption/controllers/key_controller.go

@ardaguclu

Copy link
Copy Markdown
Member Author

/retest

@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from e143c1e to 66123fd Compare April 20, 2026 04:43

@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.

🧹 Nitpick comments (1)
pkg/operator/encryption/state/types.go (1)

43-44: Clarify the KMSEncryptionConfig field comment.

On Line 43, “Encoded” is misleading: this field holds typed config, while encoding happens during secret serialization.

Proposed wording tweak
-	// Encoded KMSEncryptionConfig that stores the KMS related fields
+	// KMSEncryptionConfig stores KMS encryption-related fields.
 	KMSEncryptionConfig *apiserverconfigv1.KMSConfiguration
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/operator/encryption/state/types.go` around lines 43 - 44, The comment for
the KMSEncryptionConfig field is misleading by saying "Encoded"; update the
comment on KMSEncryptionConfig (type *apiserverconfigv1.KMSConfiguration) to
state that it holds the typed KMS configuration (KMS-related fields) and that
any encoding/serialization is performed later when storing in a Secret, e.g.,
"Typed KMS configuration (apiserverconfigv1.KMSConfiguration);
encoding/serialization occurs when persisted to a Secret."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/operator/encryption/state/types.go`:
- Around line 43-44: The comment for the KMSEncryptionConfig field is misleading
by saying "Encoded"; update the comment on KMSEncryptionConfig (type
*apiserverconfigv1.KMSConfiguration) to state that it holds the typed KMS
configuration (KMS-related fields) and that any encoding/serialization is
performed later when storing in a Secret, e.g., "Typed KMS configuration
(apiserverconfigv1.KMSConfiguration); encoding/serialization occurs when
persisted to a Secret."

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 94e98970-9ef2-4cff-8b60-a432226cd703

📥 Commits

Reviewing files that changed from the base of the PR and between e143c1e and 66123fd.

📒 Files selected for processing (13)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/controllers/state_controller_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/observer/observe_encryption_config_test.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/state/types.go
  • pkg/operator/encryption/testing/helpers.go
  • test/e2e-encryption/encryption_test.go
✅ Files skipped from review due to trivial changes (2)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/controllers/key_controller.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/secrets/types.go
  • test/e2e-encryption/encryption_test.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/controllers/state_controller_test.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/testing/helpers.go

@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 (2)
pkg/operator/encryption/controllers/state_controller_test.go (2)

756-761: Avoid brittle raw JSON string comparison for provider config.

This assertion can fail on harmless JSON formatting/order changes. Prefer unmarshalling both expected/actual and comparing structured values.

Proposed test hardening
+import "encoding/json"
...
- providerConfigKey := secrets.EncryptionSecretKMSProviderConfig + "-1"
- expectedProviderConfig := `{"vault":{"image":"quay.io/org/vault-kms-plugin@sha256:abc123","vaultAddress":"https://vault.example.com:8200","transitKey":"my-transit-key","transitMount":"transit"}}`
- if string(actualSecret.Data[providerConfigKey]) != expectedProviderConfig {
- 	ts.Errorf("unexpected kms-provider-config-1 in encryption-config secret: %s", actualSecret.Data[providerConfigKey])
- }
+providerConfigKey := secrets.EncryptionSecretKMSProviderConfig + "-1"
+expected := &state.KMSProviderConfig{
+	Vault: &state.VaultProviderConfig{
+		Image:        "quay.io/org/vault-kms-plugin@sha256:abc123",
+		VaultAddress: "https://vault.example.com:8200",
+		TransitKey:   "my-transit-key",
+		TransitMount: "transit",
+	},
+}
+actual := &state.KMSProviderConfig{}
+if err := json.Unmarshal(actualSecret.Data[providerConfigKey], actual); err != nil {
+	ts.Fatalf("failed to unmarshal kms provider config: %v", err)
+}
+if diff := cmp.Diff(expected, actual); diff != "" {
+	ts.Errorf("unexpected kms provider config (-want,+got): %s", diff)
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/operator/encryption/controllers/state_controller_test.go` around lines
756 - 761, The test currently compares the KMS provider config by raw JSON
string (expectedProviderConfig) which is brittle; change it to unmarshal both
the expectedProviderConfig and the actualSecret.Data[providerConfigKey] into
structured values (e.g., map[string]interface{} or a small struct) and compare
them using reflect.DeepEqual or cmp.Diff. Locate the variables
providerConfigKey, expectedProviderConfig and actualSecret.Data in the test
function in state_controller_test.go, replace the string equality check with
JSON unmarshalling of both sides, and update the ts.Errorf to print a clear diff
or the mismatched structured values when the comparison fails.

1352-1354: Strengthen TestCollectKMSProviderConfigs by asserting full config equality.

Current checks only verify config.Vault != nil; they won’t catch wrong values being collected for a key. Add a cmp.Diff(vaultConfig, config) assertion per key.

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

In `@pkg/operator/encryption/controllers/state_controller_test.go` around lines
1352 - 1354, In TestCollectKMSProviderConfigs, strengthen the per-key assertion
by replacing the lone nil-check of config.Vault with a full equality check
against the expected vaultConfig: call cmp.Diff(vaultConfig, config) and if the
diff is non-empty call t.Errorf("unexpected Vault config for key %q: %s", key,
diff). Ensure the test file imports github.com/google/go-cmp/cmp (add the import
if missing) and keep the existing nil-check or fold it into the cmp-based
assertion so mismatches (not just nil) are reported.
🤖 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/controllers/key_controller.go`:
- Around line 280-289: The controller is writing hardcoded Vault provider config
into secrets via ks.KMSProviderConfig (state.KMSProviderConfig ->
VaultProviderConfig) inside generateKeySecret; remove the hardcoded struct
assignment and instead populate ks.KMSProviderConfig from the
operator/API-server observed configuration (or leave it nil/omitted until the
real config is available), adding a nil-check before writing secrets to avoid
persisting placeholder values like the mock image or ":latest" tag; update
generateKeySecret to accept or look up the real KMS config (e.g., via a
passed-in config object or operator config getter) and write only validated
fields.

---

Nitpick comments:
In `@pkg/operator/encryption/controllers/state_controller_test.go`:
- Around line 756-761: The test currently compares the KMS provider config by
raw JSON string (expectedProviderConfig) which is brittle; change it to
unmarshal both the expectedProviderConfig and the
actualSecret.Data[providerConfigKey] into structured values (e.g.,
map[string]interface{} or a small struct) and compare them using
reflect.DeepEqual or cmp.Diff. Locate the variables providerConfigKey,
expectedProviderConfig and actualSecret.Data in the test function in
state_controller_test.go, replace the string equality check with JSON
unmarshalling of both sides, and update the ts.Errorf to print a clear diff or
the mismatched structured values when the comparison fails.
- Around line 1352-1354: In TestCollectKMSProviderConfigs, strengthen the
per-key assertion by replacing the lone nil-check of config.Vault with a full
equality check against the expected vaultConfig: call cmp.Diff(vaultConfig,
config) and if the diff is non-empty call t.Errorf("unexpected Vault config for
key %q: %s", key, diff). Ensure the test file imports
github.com/google/go-cmp/cmp (add the import if missing) and keep the existing
nil-check or fold it into the cmp-based assertion so mismatches (not just nil)
are reported.
🪄 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: Pro Plus

Run ID: 03e1083e-9634-45ba-bd9b-3956a8377abd

📥 Commits

Reviewing files that changed from the base of the PR and between 66123fd and 03cb2c7.

📒 Files selected for processing (13)
  • pkg/operator/encryption/controllers/helpers_test.go
  • pkg/operator/encryption/controllers/key_controller.go
  • pkg/operator/encryption/controllers/key_controller_test.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/controllers/state_controller_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/encryptionconfig/secret.go
  • pkg/operator/encryption/observer/observe_encryption_config_test.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/state/types.go
  • pkg/operator/encryption/testing/helpers.go
  • test/e2e-encryption/encryption_test.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/operator/encryption/controllers/key_controller_test.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • pkg/operator/encryption/observer/observe_encryption_config_test.go
  • pkg/operator/encryption/deployer/unionrevisionedpod_test.go
  • pkg/operator/encryption/controllers/helpers_test.go
  • test/e2e-encryption/encryption_test.go
  • pkg/operator/encryption/secrets/types.go
  • pkg/operator/encryption/secrets/secrets.go
  • pkg/operator/encryption/testing/helpers.go
  • pkg/operator/encryption/controllers/state_controller.go
  • pkg/operator/encryption/encryptionconfig/secret.go

Comment thread pkg/operator/encryption/controllers/key_controller.go Outdated
@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch 2 times, most recently from 353e782 to 572df00 Compare April 20, 2026 12:31
@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from 572df00 to b4ec83a Compare April 21, 2026 07:33
@ardaguclu

ardaguclu commented Apr 21, 2026

Copy link
Copy Markdown
Member Author

/retitle CNTRLPLANE-3237: Introduce KMSProviderConfig

@openshift-ci openshift-ci Bot changed the title WIP: CNTRLPLANE-3237: Introduce KMSProviderConfig CNTRLPLANE-3237: Introduce KMSProviderConfig Apr 21, 2026
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 21, 2026
@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from 6c8ddbb to 6292f49 Compare May 4, 2026 06:40
@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 May 4, 2026
@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch 2 times, most recently from ed082b3 to 639dafc Compare May 4, 2026 07:19
@ardaguclu

Copy link
Copy Markdown
Member Author

/retest

@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch 2 times, most recently from 7d56954 to 0a01a8c Compare May 5, 2026 06:01
@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 May 5, 2026
@ardaguclu

Copy link
Copy Markdown
Member Author

These are the fake bumps that all seems to be working;

})

// Collect KMS provider configs from read keys (which already include the write key).
// The same keyID appears across multiple resources (e.g. secrets and configmaps),

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.

please explain why we have duplicates.

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.

I've updated the documentation to better explain the duplication. Does it make sense?

Comment thread pkg/operator/encryption/kms/helpers.go Outdated

// ProviderConfigKeyID extracts the keyID from a kms-provider-config data key.
// Returns the keyID and true if the key matches the "kms-provider-config-<keyID>" pattern.
func ProviderConfigKeyID(dataKey string) (string, bool) {

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.

KeyIDFromProviderConfigSecretDataKey ?

Comment thread pkg/operator/encryption/kms/helpers.go Outdated
var providerConfigKeyRegex = regexp.MustCompile(`^kms-provider-config-(\d+)$`)

// ProviderConfigDataKey constructs the data key for storing a KMS provider config in the encryption-config Secret.
func ProviderConfigDataKey(keyID string) string {

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.

ToProviderConfigSecretDataKeFor ?

Comment thread pkg/operator/encryption/kms/helpers.go Outdated
corev1 "k8s.io/api/core/v1"
)

const providerConfigDataKeyFormat = "kms-provider-config-%s"

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.

here we accept any string.

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.

Validation is added by parsing keyID to integer.

Comment thread pkg/operator/encryption/kms/helpers.go Outdated

const providerConfigDataKeyFormat = "kms-provider-config-%s"

var providerConfigKeyRegex = regexp.MustCompile(`^kms-provider-config-(\d+)$`)

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.

but here we say the keyID can a number

Comment thread pkg/operator/encryption/kms/helpers.go Outdated

// ProviderConfigDataKey constructs the data key for storing a KMS provider config in the encryption-config Secret.
func ProviderConfigDataKey(keyID string) string {
return fmt.Sprintf(providerConfigDataKeyFormat, keyID)

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.

so maybe this function should validate the keyID ?

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.

Integer parsing logic is added.

}

encryption := apiServer.Spec.Encryption
// TODO: we'll allow updating some values such as timeout via unsupportedconfig overrides.

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'd remove it for now.

},
}

func TestRoundtrip(t *testing.T) {

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.

does this test validate a RoundTrip from encryptiondata.ToSecret to encryptiondata.FromSecret?

if not maybe worth adding a test like that that would ensure the cfg is preserved.

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.

Good idea. Added.

Comment thread pkg/operator/encryption/kms/helpers.go Outdated

const providerConfigDataKeyFormat = "kms-provider-config-%s"

var providerConfigKeyRegex = regexp.MustCompile(`^kms-provider-config-(\d+)$`)

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.

maybe using strings.CutPrefix would be simpler ?

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, it would be simpler. Added.

kmsProviders = map[string]*configv1.KMSConfig{}
}
if _, exists := kmsProviders[key.Key.Name]; !exists {
kmsProviders[key.Key.Name] = key.KMSConfig.Provider

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.

should we compare if the cfg we already collected is the same as the new one ?

@ardaguclu ardaguclu May 5, 2026

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.

I think this is a good idea. But that would change the signature of FromEncryptionState function, since we should return error if there is any discrepancy.

Would it make sense we move forward as is to unblock Fabio and I'll add this check in followup PR by updating the signature;

func FromEncryptionState(encryptionState map[schema.GroupResource]state.GroupResourceState) (*Config, error) {

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.

or if you prefer, I can fix it in this PR as a separate commit.

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'm ok with a follow-up PR.

@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from 0a01a8c to 5d6162f Compare May 5, 2026 11:51
Comment thread pkg/operator/encryption/kms/helpers.go Outdated
return "", false
}
if _, err := strconv.ParseUint(keyID, 10, 64); err != nil {
return "", false

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.

Maybe we should return error here

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.

yes, i think we should.

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 expect the keyID to be of specific format if present.

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. We filter out the other unrelated data keys. If we detect kms-provider-config-keyid, we will extract key id. If key id is not uint64 integer, we error out.

@ardaguclu

Copy link
Copy Markdown
Member Author

unrelated
/retest

return &Config{Encryption: encryptionConfig}, nil
var kmsProviders map[string]*configv1.KMSConfig
for key, value := range encryptionConfigSecret.Data {
keyID, ok := kms.KeyIDFromProviderConfigSecretDataKey(key)

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 explain why not all data field will have keyID?

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.

Added a documentation

}

for keyID, providerConfig := range secretData.KMSProviders {
providerJSON, err := encoding.EncodeKMSConfig(providerConfig)

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.

encodedProvider ?

for keyID, providerConfig := range secretData.KMSProviders {
providerJSON, err := encoding.EncodeKMSConfig(providerConfig)
if err != nil {
return nil, fmt.Errorf("failed to encode KMS provider config for key %s: %v", keyID, err)

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.

%w

// ToProviderConfigSecretDataKeyFor constructs the data key for storing a KMS provider config in the encryption-config Secret.
// The keyID must be a valid non-negative integer string.
func ToProviderConfigSecretDataKeyFor(keyID string) (string, error) {
if _, err := strconv.ParseUint(keyID, 10, 64); err != 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.

I think this is ok because keyID is uint64, right ?

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, keyID is uint64

latestKeyID, internalReason, needed := needsNewKey(grKeys, currentMode, externalReason, encryptedGRs)

@ardaguclu
ardaguclu force-pushed the kms-v2-provider-config branch from 5d6162f to 41146d7 Compare May 6, 2026 08:06
@p0lyn0mial

Copy link
Copy Markdown
Contributor

/lgtm

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

openshift-ci Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ardaguclu, 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:

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 May 6, 2026
@ardaguclu

Copy link
Copy Markdown
Member Author

unrelated
/retest

@openshift-ci

openshift-ci Bot commented May 6, 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.

@openshift-merge-bot
openshift-merge-bot Bot merged commit 32460ef into openshift:master May 6, 2026
6 checks passed
@ardaguclu
ardaguclu deleted the kms-v2-provider-config branch May 6, 2026 11:38
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