Skip to content

feat(backend): source mock identity client/principal id from Key Vault secret (AROSLSRE-2006) - #6811

Merged
openshift-merge-bot[bot] merged 5 commits into
Azure:mainfrom
raelga:rael/mimock-kv-secret-indirection
Sep 9, 2026
Merged

feat(backend): source mock identity client/principal id from Key Vault secret (AROSLSRE-2006)#6811
openshift-merge-bot[bot] merged 5 commits into
Azure:mainfrom
raelga:rael/mimock-kv-secret-indirection

Conversation

@raelga

@raelga Rael Garcia (raelga) commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

AROSLSRE-2057, part of AROSLSRE-2006.

What

Adds backend support for reading the mock identity's clientId and principalId from Key Vault secrets mounted through CSI, using the same volume as the mock identity certificate.

The new --insecure-azure-managed-identity-mock-client-id-path and --insecure-azure-managed-identity-mock-principal-id-path flags read the files once at startup. Helm uses these flags when miMockClientIdSecretName and miMockPrincipalIdSecretName are configured. Both secret names default to empty, so the static-value path remains the default.

Why

The mock identity IDs are duplicated in configuration. Recreating the service principal changes its principalId, leaving those copies stale.

The goal is to publish and refresh the IDs through the existing privileged identity/RBAC automation and have workloads read them from Key Vault. This keeps Graph lookups out of the backend and cluster-service deployment identities.

This PR adds the backend consumer support only. It does not yet remove the stale-config risk end to end.

Testing

Unit tests in backend/cmd/root_test.go cover direct-value/file-path validation and file resolution. The Helm fixture covers the Key Vault path with both secret names configured, including precedence over static IDs.

Validation commands: go build ./..., go vet ./..., and go test ./cmd/... from backend; make materialize from config.

Special notes for your reviewer

This PR does not publish or enable the secrets, migrate cluster-service, remove static values, or change tenantId. Backend needs a controlled restart after the mounted IDs change because it reads the files once at startup.

Follow-ups under AROSLSRE-2006:

  • AROSLSRE-2058: publish and refresh the ID secrets in the consuming Key Vaults.
  • AROSLSRE-2059: enable backend consumption and handle restarts after ID changes.
  • AROSLSRE-2060: add cluster-service support and deployment wiring.
  • AROSLSRE-2061: remove static values once every consumer has migrated.

Related: AROSLSRE-1997, AROSLSRE-1999.

PR Checklist

  • PR is scoped to a single task (no mixed concerns)
  • Title follows Conventional Commits format
  • Summary explains the "Why" behind the change
  • Linked to relevant ticket/issue
  • Screenshots included (if dashboards or other UI changes)
  • Self-reviewed the diff
  • CI/CD checks are passing (ignore Tide)
  • Draft PR used for WIP (if applicable)
  • Commit history is clean (rebased/squashed)
  • Tricky code blocks are commented
  • Specific reviewers tagged
  • All comment threads resolved before merge

If E2E tests are included:

  • E2E tests follow Principles of Good E2E Test Case Design
  • If new E2E use case is covered (via a new test or new check/verifier), demonstrate that the test is able to detect a defect/error and fail with proper error message and logs which communicates nature of the problem.

@openshift-ci

openshift-ci Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The CLI help text for the mock principal-id flag references an incorrect/non-existent flag name and should be updated to match the new client-id/client-id-path options.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds an opt-in mechanism for backend to source the mock managed identity’s client ID and principal ID from Key Vault secrets mounted via the CSI driver (read once at startup), avoiding outages caused by stale statically-configured IDs after Service Principal recreation.

Changes:

  • Introduces --insecure-azure-managed-identity-mock-client-id-path and --insecure-azure-managed-identity-mock-principal-id-path flags, plus startup-time file resolution and validation.
  • Extends backend Helm chart + values to optionally mount and consume the new Key Vault secrets (falling back to existing static values when unset).
  • Adds unit tests covering mutual-exclusion validation and file resolution/trim behavior.
File summaries
File Description
config/rendered/dev/pers/westus3.yaml Adds empty default fields for secret-name-based mock MI ID sourcing.
config/rendered/dev/perf/westus3.yaml Adds empty default fields for secret-name-based mock MI ID sourcing.
config/rendered/dev/dev/westus3.yaml Adds empty default fields for secret-name-based mock MI ID sourcing.
config/rendered/dev/cspr/westus3.yaml Adds empty default fields for secret-name-based mock MI ID sourcing.
config/rendered/dev/ci01/centralus.yaml Adds empty default fields for secret-name-based mock MI ID sourcing.
config/rendered/dev/ci00/centralus.yaml Adds empty default fields for secret-name-based mock MI ID sourcing.
config/config.yaml Defines new config defaults and documents behavior.
config/config.schema.json Adds schema entries/descriptions for the new config fields.
backend/values.yaml Wires new config fields into chart values for optional secret mounting.
backend/deploy/templates/backend.service-key-vault.secretproviderclass.yaml Optionally adds Key Vault secret objects for mock MI client/principal ID.
backend/deploy/templates/backend.deployment.yaml Conditionally uses -path flags vs raw values depending on secret-name presence.
backend/cmd/root.go Adds new flags, validates mutual exclusion, and resolves ID values from files at startup.
backend/cmd/root_test.go Adds tests for validation and file-based resolution.
Review details
  • Files reviewed: 13/13 changed files
  • Comments generated: 1
  • Review effort level: Lite

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

Comment thread backend/cmd/root.go
Copilot AI review requested due to automatic review settings September 3, 2026 13:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The Helm SecretProviderClass currently mounts the new miMock secrets even when MI Mock isn’t enabled (e.g., missing miMock.certName), which can break backend pod startup in misconfigured environments.

Review details

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

backend/deploy/templates/backend.service-key-vault.secretproviderclass.yaml:23

  • The client-id Key Vault secret is mounted whenever miMock.clientIdSecretName is set, even if MI Mock itself is not enabled (e.g., miMock.certName is empty). That can cause the CSI mount/pod startup to fail due to missing secrets despite MI Mock flags not being used. Gate this secret on the same MI Mock enablement signal as the deployment (at least miMock.certName).
    backend/deploy/templates/backend.service-key-vault.secretproviderclass.yaml:29
  • The principal-id Key Vault secret is mounted whenever miMock.principalIdSecretName is set, even if MI Mock is not enabled (e.g., missing miMock.certName). This can break pod startup by requiring secrets that won't be used. Gate this secret on MI Mock enablement (at least miMock.certName).
  • Files reviewed: 13/13 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@raelga

Copy link
Copy Markdown
Collaborator Author

/retest-required

e2e-parallel failed with 11 unrelated test failures (private KeyVault, external auth config, breakglass session, subnet/NSG reuse, control-plane z-stream upgrade, nodepool downgrade, etc.) spanning completely different feature areas than this PR's change. Checked job-history for this job: only 2/15 recent runs succeeded across the board, confirming this is pre-existing infra flakiness, not something introduced here. This PR's change is inert by default (new secretName config fields are empty, so no new code path is exercised).

@raelga

Copy link
Copy Markdown
Collaborator Author

/retest-required

Second failure was a provisioning-stage infra flake unrelated to this PR: failed post-install: resource Job/multicluster-engine/finalize-mce-config not ready ... context deadline exceeded during ACM Helm rollout. Retrying.

@raelga

Copy link
Copy Markdown
Collaborator Author

/retest-required

Third failure: provisioning succeeded this time, but 3 tests failed in the private-networking area (private KeyVault, private KAS reachability, aggregated advanced features) — unrelated to this PR's backend change. Checked job-history: this e2e-parallel job is broadly flaky right now (2/15 recent PR runs succeeded), consistent with known infra issues, not something introduced here. Retrying.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new Helm branch lacks a committed fixture, and lifecycle documentation overstates automatic secret refresh behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 13/13 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread backend/deploy/templates/backend.deployment.yaml
Comment thread backend/cmd/root.go
Copilot AI review requested due to automatic review settings September 4, 2026 11:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

Core behavior is covered by unit and Helm fixtures; the remaining CLI help-text mismatch is non-blocking.

Review details

Suppressed comments (1)

backend/cmd/root.go:145

  • This help text says the raw principal-ID flag is required, but validation also accepts --insecure-azure-managed-identity-mock-principal-id-path. Mention both alternatives so valid mixed raw/path configurations are not documented as invalid.
			"'--insecure-azure-managed-identity-mock-principal-id' and '--insecure-azure-managed-identity-mock-tenant-id' flags. "+
  • Files reviewed: 15/15 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI review requested due to automatic review settings September 7, 2026 09:37
@raelga
Rael Garcia (raelga) force-pushed the rael/mimock-kv-secret-indirection branch from b25447f to e94274b Compare September 7, 2026 09:37
@raelga

Copy link
Copy Markdown
Collaborator Author

Rebased onto main to resolve the conflict. The conflict was in the rendered configs only: #6809 rotated the ci00/ci01/cspr/dev/perf/pers miMockClientId/miMockPrincipalId values on main (INT outage fix from the recreated mock identity Service Principal), while this branch still had the pre-rotation values from when it was cut. Rebased cleanly, kept main's current rotated IDs and this PR's new empty-by-default miMockClientIdSecretName/miMockPrincipalIdSecretName fields, and re-ran config materialize to confirm the rendered output matches.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The migration precedence is not tested, and related CLI help describes contradictory flag requirements.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 15/15 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread backend/testdata/helmtest_backend_mi_mock_ids_from_kv_secret.yaml Outdated
Comment thread backend/cmd/root.go
@raelga
Rael Garcia (raelga) force-pushed the rael/mimock-kv-secret-indirection branch from e94274b to b8c2f78 Compare September 7, 2026 17:18
@raelga

Copy link
Copy Markdown
Collaborator Author

/retest

Copilot AI review requested due to automatic review settings September 8, 2026 10:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The implementation is backward-compatible, internally consistent, and adequately covered by unit and Helm fixture tests.

Review details
  • Files reviewed: 15/15 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@raelga

Copy link
Copy Markdown
Collaborator Author

/test e2e-parallel

Rael Garcia (raelga) and others added 5 commits September 9, 2026 09:16
… secret (AROSLSRE-2006)

Adds --insecure-azure-managed-identity-mock-client-id-path and
--insecure-azure-managed-identity-mock-principal-id-path flags to backend,
mirroring the existing certificate-bundle-path convention. When set, the
value is read once from the mounted file at startup instead of being passed
as a raw static value.

This lets backend's Helm chart mount the mock identity's clientId/principalId
as Key Vault secrets (via the CSI driver, same mechanism already used for its
certificate) instead of duplicating them as static config in config.yaml.
That static duplication is what caused the INT outage worked in this session:
the mock identity Service Principal's principalId changed when it was
recreated, and the stale config value orphaned its Key Vault RBAC grant.

Wiring:
- backend/values.yaml: new miMock.clientIdSecretName/principalIdSecretName,
  empty by default (opt-in, fully backward compatible).
- backend.service-key-vault.secretproviderclass.yaml: mounts the two new
  secrets when their names are set, same pattern as the existing
  mi-mock-cert-bundle secret.
- backend.deployment.yaml: uses the new -path flags when the secret names
  are set, falls back to the existing raw miMock.clientId/principalId
  otherwise.
- config.yaml/config.schema.json: new empty-by-default fields.

Verified backward compatibility: with the new fields left empty (the
default), make materialize regenerates byte-identical Helm fixtures.
Verified the new path: temporarily setting test secret names and
re-running make materialize produces the expected -path flags and
SecretProviderClass entries (reverted before committing).

Deliberately does not touch cluster-service (its binary lives in a separate
upstream repo, not this one) or the privileged e2e-subscription-rbac-grants
pipeline that would need to publish these secrets to Key Vault going
forward. Both are tracked as follow-ups on AROSLSRE-2006, along with the
sdp-pipelines overlay cleanup once backend can source these dynamically.
…text (AROSLSRE-2006)

The --insecure-azure-managed-identity-mock-principal-id help text referenced
a non-existent flag (--azure-mi-mock-principal-client-id), a pre-existing
typo carried forward when I copied the text for the new -path variant.
Points at the actual client-id flags (raw and -path) instead.
…ection (AROSLSRE-2006)

- Correct the resolveInsecureManagedIdentityMockIDsFromFiles doc comment: it
  resolves once at process startup only, a running pod does not pick up a
  later CSI secret rotation without a restart.
- Gate the miMock clientIdSecretName/principalIdSecretName CSI mount blocks
  in the SecretProviderClass template inside the same certName check as the
  cert bundle, so a config with a secret name set but MI Mock not otherwise
  enabled doesn't break pod startup via a missing-secret CSI mount.
- Add a Helm test fixture exercising both miMockClientIdSecretName and
  miMockPrincipalIdSecretName set together, covering the new -path flags and
  their SecretProviderClass entries.
…ity KV secret indirection (AROSLSRE-2006)

- Update the enabling flag, certificate-bundle-path flag, raw client-id flag,
  and tenant-id flag help text to consistently mention the '-path' alternative
  wherever it references the client-id/principal-id flags, matching what
  validate() actually accepts.
- Set non-empty sentinel static clientId/principalId values in the KV-secret
  helm test fixture to exercise the migration precedence: with both the
  static values and the secret names configured, the rendered output must
  still only contain the '-path' flags.
Rebased AROSLSRE-2006 branch onto latest upstream/main. Rendered configs
needed regeneration via make -C config materialize to pick up unrelated
upstream changes (e.g. dataPlaneHAProxyImage) plus this PR's own
miMockClientIdSecretName/miMockPrincipalIdSecretName fields.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@raelga
Rael Garcia (raelga) force-pushed the rael/mimock-kv-secret-indirection branch from 03c5b2d to bf43afd Compare September 9, 2026 09:19
Copilot AI review requested due to automatic review settings September 9, 2026 09:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The implementation is backward compatible, consistently wired, and covered by focused Go and Helm tests.

Review details
  • Files reviewed: 15/15 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@raelga

Copy link
Copy Markdown
Collaborator Author

/test images
/test e2e-images

@raelga

Copy link
Copy Markdown
Collaborator Author

/test e2e-parallel

@raelga

Copy link
Copy Markdown
Collaborator Author

cc Gerd Oberlechner (@geoberle) Jan-Hendrik Boll (@janboll) Miguel Soriano (@miguelsorianod) — this has been open for a few days waiting on /lgtm (backend/OWNERS approvers). All CI is green (e2e-parallel currently re-running after a rebase onto main, all other checks pass), all Copilot review comments have been addressed and resolved. Would appreciate a look when you have a moment.

@raelga

Copy link
Copy Markdown
Collaborator Author

/test e2e-parallel

The actual test suite passed fully (63 passed, 0 failed) on this run. The overall job was marked FAILURE solely because the aro-hcp-gather-observability post-test step (renders Grafana/Prometheus dashboards for the run's own log artifacts) errored — unrelated to test correctness or this PR's diff. Retrying to get a clean required-check run.

@roivaz

Copy link
Copy Markdown
Collaborator

/lgtm

@openshift-ci

openshift-ci Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: raelga, roivaz

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-merge-bot
openshift-merge-bot Bot merged commit f63b646 into Azure:main Sep 9, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants