Skip to content

Refactor recipe settings resources to match the feature spec and support Radius.Security/secrets#12181

Closed
sylvainsf wants to merge 2 commits into
radius-project:mainfrom
sylvainsf:fix-12122-security-secrets-recipe-configs
Closed

Refactor recipe settings resources to match the feature spec and support Radius.Security/secrets#12181
sylvainsf wants to merge 2 commits into
radius-project:mainfrom
sylvainsf:fix-12122-security-secrets-recipe-configs

Conversation

@sylvainsf

@sylvainsf sylvainsf commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #12122. Radius.Core/bicepConfigs and Radius.Core/terraformConfigs rejected Radius.Security/secrets for registry/module credentials, accepting only Applications.Core/secretStores. Fixing that surfaced two deeper problems — a naming divergence from the feature spec and a secret-kind coupling in the Bicep auth path — which this PR also corrects.

1. Support Radius.Security/secrets in the recipe secret loader (the bug)

The recipe secret loader was hardcoded to the Applications.Core/secretStores ListSecrets API and never dispatched on the referenced resource type. It now parses the secret resource ID and routes accordingly:

  • Applications.Core/secretStores keeps the existing ListSecrets path, behavior-identical.
  • Radius.Security/secrets is read by locating the backing Kubernetes Secret its recipe materializes (via status.outputResources) and reading the values directly. This is required because a provisioned Radius.Security/secrets has its sensitive data redacted from the database once provisioning succeeds, so the plaintext only lives in the backing Kubernetes Secret.

The Kubernetes client provider is threaded into the loader at both wiring sites (dynamic-rp and the recipe controller config).

2. Refactor: rename ConfigsSettings to match the spec

These resource types were introduced (in #11780) as Radius.Core/terraformConfigs / bicepConfigs based on the earlier branch work by Yetkin/Vishwa, but the authoritative feature spec authored by @zachcasper (terraform-bicep-settings) names them Radius.Core/terraformSettings / bicepSettings. The naming divergence originated here, not in the spec, and the types are not yet referenced on the docs site — so this renames them to match the spec before they ship more widely:

  • TypeSpec models/segments and the environment terraformSettings / bicepSettings properties.
  • Datamodel types, converters, conversions, the frontend validator package, setup routing, the built-in provider manifests, and the embedded OpenAPI metadata mapping.
  • Regenerated clients, fakes, swagger, and bicep-types.

The legacy recipeConfig transport types (datamodel.BicepConfigProperties, datamodel.TerraformConfigProperties) and the Applications.Core/environments path are intentionally untouched — these are new-environment-only resources.

3. Refactor: select Bicep registry auth from the settings resource, not the secret kind

Per the spec, the secret kind is optional and the Bicep auth method comes from the bicepSettings resource. Previously the Bicep driver chose the registry auth client from the secret's kind, so a kind-less Radius.Security/secrets carrying only username/password failed with "invalid type". The bicepSettings.authenticationMethod is now threaded through and used to select the auth client (BasicAuth, AzureWI, AwsIrsa). The Applications.Core/secretStores path leaves the method empty and continues to use the secret store's own type.

Type of change

Contributor checklist

  • Existing and new functional tests, unit tests, integration tests, and end-to-end tests pass locally where runnable (functional test requires a cluster — runs in dynamicrp-noncloud CI).
  • Code generated from TypeSpec is regenerated (make generate).
  • Design documents updated (the spec lives in radius-project/design-notes; this PR aligns the implementation to it).

Tests

  • Unit tests for the type-dispatching loader and the Radius.Security/secrets backing-secret reader.
  • Test_TerraformSettings_SecuritySecret_Credentials — a functional test that provisions a Radius.Security/secrets resource and references it from a terraformSettings resource for private registry credentials, exercising the new loader end-to-end.

Fixes #12122

@sylvainsf sylvainsf force-pushed the fix-12122-security-secrets-recipe-configs branch from cb5e2d1 to d5a9e3a Compare June 19, 2026 22:13
@sylvainsf sylvainsf marked this pull request as ready for review June 19, 2026 22:20
@sylvainsf sylvainsf requested review from a team as code owners June 19, 2026 22:20
Copilot AI review requested due to automatic review settings June 19, 2026 22:20

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.

Pull request overview

This PR aligns the implementation of reusable recipe configuration resources with the feature spec by renaming Radius.Core/*ConfigsRadius.Core/*Settings, and fixes secret-loading so Radius.Security/secrets can be used for Terraform/Bicep registry/module credentials (by dereferencing the backing Kubernetes Secret when necessary).

Changes:

  • Rename Radius.Core/terraformConfigsterraformSettings and Radius.Core/bicepConfigsbicepSettings across TypeSpec, API models/clients, datamodel, controllers, manifests, and functional tests.
  • Update recipe secret loading to dispatch by referenced resource type and support Radius.Security/secrets via backing Kubernetes Secret reads.
  • Thread bicepSettings.authenticationMethod through to choose the correct Bicep registry auth client independent of secret “kind”.

Reviewed changes

Copilot reviewed 46 out of 55 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
typespec/Radius.Core/terraformSettings.tsp Rename Terraform config resource/types to terraformSettings and broaden secret reference docs.
typespec/Radius.Core/main.tsp Update TypeSpec imports to *Settings files.
typespec/Radius.Core/environments.tsp Rename environment refs to terraformSettings / bicepSettings.
typespec/Radius.Core/bicepSettings.tsp Rename Bicep config resource/types to bicepSettings and broaden secret reference docs.
test/functional-portable/dynamicrp/noncloud/resources/testdata/tfbicep-combined-test.bicep Switch combined functional test to terraformSettings/bicepSettings usage.
test/functional-portable/dynamicrp/noncloud/resources/testdata/terraformsettings-securitysecret-test.bicep Add end-to-end functional test using Radius.Security/secrets for Terraform credentials.
test/functional-portable/dynamicrp/noncloud/resources/testdata/terraformsettings-redis-test.bicep Update Terraform functional test template to terraformSettings.
test/functional-portable/dynamicrp/noncloud/resources/testdata/bicepsettings-test.bicep Update Bicep functional test template to bicepSettings.
test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go Rename/extend functional tests to cover new resource names + regression for #12122.
pkg/ucp/initializer/service_test.go Update UCP OpenAPI/type summary assertions for renamed types.
pkg/ucp/initializer/radius_core_openapi.go Update Radius.Core OpenAPI definition mapping to *Settings.
pkg/rp/util/registry.go Choose Bicep registry auth client based on authenticationMethod rather than secret kind.
pkg/rp/util/config.go Update helper fetchers to call *Settings clients.
pkg/recipes/controllerconfig/config.go Thread Kubernetes provider into secrets loader wiring.
pkg/recipes/configloader/security_secrets.go Add loader path to read Radius.Security/secrets via backing Kubernetes Secret.
pkg/recipes/configloader/security_secrets_test.go Unit tests for output-resource discovery + error cases around unsupported secret types.
pkg/recipes/configloader/secrets.go Dispatch secret loading by resource type (secretStores vs Radius.Security/secrets).
pkg/recipes/configloader/environment.go Resolve terraformSettings/bicepSettings and thread auth method into recipe config bridge.
pkg/recipes/configloader/environment_v20250801_bridge_test.go Update env bridge unit tests for renamed clients/resources.
pkg/dynamicrp/options.go Wire Kubernetes provider into secrets loader in dynamic-rp.
pkg/corerp/setup/setup.go Register terraformSettings/bicepSettings resources in Core RP setup.
pkg/corerp/setup/setup_test.go Update handler routing tests for renamed types/paths.
pkg/corerp/setup/operations.go Update RBAC operation names/displays for renamed resources.
pkg/corerp/frontend/controller/environments/v20250801preview/validateconfigref_test.go Update config-ref validation tests for renamed resources.
pkg/corerp/frontend/controller/environments/v20250801preview/createorupdateenvironment.go Validate terraformSettings/bicepSettings refs instead of *Config.
pkg/corerp/frontend/controller/environments/v20250801preview/createorupdateenvironment_test.go Update env create/update tests that referenced old type strings.
pkg/corerp/frontend/controller/bicepsettings/validator.go Move/rename validator package and update types to BicepSettings.
pkg/corerp/frontend/controller/bicepsettings/validator_test.go Update validator tests for renamed datamodel types.
pkg/corerp/datamodel/terraformsettings.go Rename Terraform datamodel types/constants and update secret doc comment.
pkg/corerp/datamodel/recipe_types.go Extend registry secret config with AuthenticationMethod for Bicep driver selection.
pkg/corerp/datamodel/environment_v20250801preview.go Rename env datamodel fields to terraformSettings/bicepSettings.
pkg/corerp/datamodel/converter/terraformsettings_converter.go Rename converter entrypoints for Terraform settings.
pkg/corerp/datamodel/converter/bicepsettings_converter.go Rename converter entrypoints for Bicep settings.
pkg/corerp/datamodel/bicepsettings.go Rename Bicep datamodel types/constants and update secret doc comment.
pkg/corerp/api/v20250801preview/zz_generated_terraformsettings_client.go Regenerated Terraform settings client for renamed resource.
pkg/corerp/api/v20250801preview/zz_generated_responses.go Regenerated response structs for renamed clients/resources.
pkg/corerp/api/v20250801preview/zz_generated_options.go Regenerated options structs for renamed clients.
pkg/corerp/api/v20250801preview/zz_generated_models.go Regenerated models for renamed resources + updated doc strings.
pkg/corerp/api/v20250801preview/zz_generated_client_factory.go Regenerated factory methods for renamed clients.
pkg/corerp/api/v20250801preview/zz_generated_bicepsettings_client.go New regenerated Bicep settings client.
pkg/corerp/api/v20250801preview/zz_generated_bicepconfigs_client.go Remove old regenerated Bicep configs client.
pkg/corerp/api/v20250801preview/terraformsettings_conversion.go Update versioned↔datamodel conversion for Terraform settings.
pkg/corerp/api/v20250801preview/terraformsettings_conversion_test.go Update conversion tests for Terraform settings.
pkg/corerp/api/v20250801preview/fake/zz_generated_terraformsettings_server.go Regenerated fake server transport for Terraform settings client.
pkg/corerp/api/v20250801preview/fake/zz_generated_server_factory.go Update fake server factory wiring for renamed clients.
pkg/corerp/api/v20250801preview/fake/zz_generated_bicepsettings_server.go Regenerated fake server transport for Bicep settings client.
pkg/corerp/api/v20250801preview/environment_conversion.go Update env conversion for new terraformSettings/bicepSettings fields.
pkg/corerp/api/v20250801preview/bicepsettings_conversion.go Update versioned↔datamodel conversion for Bicep settings.
pkg/corerp/api/v20250801preview/bicepsettings_conversion_test.go Update conversion tests for Bicep settings.
hack/bicep-types-radius/generated/radius/radius.core/2025-08-01-preview/types.json Regenerate Bicep type stubs for renamed resources/fields.
hack/bicep-types-radius/generated/index.json Update Bicep types index entries to *Settings.
deploy/manifest/built-in-providers/self-hosted/radius_core.yaml Update built-in provider manifest type keys to *Settings.
deploy/manifest/built-in-providers/dev/radius_core.yaml Update built-in provider manifest type keys to *Settings.
Files not reviewed (7)
  • pkg/corerp/api/v20250801preview/fake/zz_generated_server_factory.go: Generated file
  • pkg/corerp/api/v20250801preview/zz_generated_bicepsettings_client.go: Generated file
  • pkg/corerp/api/v20250801preview/zz_generated_client_factory.go: Generated file
  • pkg/corerp/api/v20250801preview/zz_generated_models.go: Generated file
  • pkg/corerp/api/v20250801preview/zz_generated_models_serde.go: Generated file
  • pkg/corerp/api/v20250801preview/zz_generated_options.go: Generated file
  • pkg/corerp/api/v20250801preview/zz_generated_responses.go: Generated file
Comments suppressed due to low confidence (7)

test/functional-portable/dynamicrp/noncloud/resources/testdata/bicepsettings-test.bicep:25

  • The SecretStore name/namespace in this testdata still uses the old bicepconfig-* identifiers, but Test_BicepSettings_CRUD creates/validates bicepsettings-test-ns / bicepsettings-test-secret. This mismatch will break the functional test (namespace won't exist and RP resource validation will fail).
    test/functional-portable/dynamicrp/noncloud/resources/testdata/bicepsettings-test.bicep:45
  • The environment name/namespace in this template is still bicepconfig-*, but the updated functional test uses bicepsettings-* and only creates the bicepsettings-test-ns namespace. This mismatch will cause the deploy to fail and/or the RP resource validation to not find the expected environment resource.
    test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:34
  • Typo in the test comment: terraformSettingss (double 's') should be terraformSettings.
    test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:95
  • Typo in the test comment: bicepSettingss (double 's') should be bicepSettings.
    test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:153
  • Typo in the test comment: terraformSettingss (double 's') should be terraformSettings.
    test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:233
  • Typo in the test comment: terraformSettingss (double 's') should be terraformSettings.
    test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:234
  • Typo in the test comment: bicepSettingss (double 's') should be bicepSettings.

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 43.45238% with 95 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.96%. Comparing base (bf1015c) to head (9dc7296).

Files with missing lines Patch % Lines
pkg/recipes/configloader/security_secrets.go 41.26% 35 Missing and 2 partials ⚠️
pkg/recipes/configloader/secrets.go 33.33% 12 Missing ⚠️
...erp/api/v20250801preview/environment_conversion.go 0.00% 4 Missing and 4 partials ⚠️
pkg/rp/util/registry.go 46.66% 7 Missing and 1 partial ⚠️
pkg/rp/util/config.go 0.00% 6 Missing ⚠️
...erp/datamodel/converter/bicepsettings_converter.go 0.00% 5 Missing ⚠️
...datamodel/converter/terraformsettings_converter.go 0.00% 5 Missing ⚠️
...ents/v20250801preview/createorupdateenvironment.go 0.00% 2 Missing and 2 partials ⚠️
pkg/recipes/configloader/environment.go 73.33% 3 Missing and 1 partial ⚠️
pkg/corerp/datamodel/bicepsettings.go 0.00% 2 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12181      +/-   ##
==========================================
- Coverage   52.97%   52.96%   -0.01%     
==========================================
  Files         754      755       +1     
  Lines       48686    48776      +90     
==========================================
+ Hits        25791    25835      +44     
- Misses      20469    20509      +40     
- Partials     2426     2432       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

🚀


resource bicepConfig 'Radius.Core/bicepConfigs@2025-08-01-preview' = {
resource bicepSettings 'Radius.Core/bicepSettings@2025-08-01-preview' = {
name: 'tfbicep-combined-bicepconfig'

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.

This bicepSettings resource is named tfbicep-combined-bicepconfig, but the combined functional test expects tfbicep-combined-bicepsettings (terraformsettings_bicepsettings_test.go:283). RPResourceSet validation matches deployed resources by name, so this mismatch will fail the combined test in CI. Rename to tfbicep-combined-bicepsettings.

(Also flagged by the Copilot reviewer on this same line.)


// Test_readBackingSecret verifies that, given a resolved namespace/name, secret values are read from the
// backing Kubernetes Secret and filtered by the requested keys.
func Test_readBackingSecret(t *testing.T) {

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.

Test_readBackingSecret is named as if it covers the backing-secret reader, but it never calls loadSecuritySecret — it only exercises the fake clientset and ParseResource directly. The actual happy path of loadSecuritySecret (kind extraction, key filtering, and the missing-key error) has no unit coverage. Consider driving the test through loadSecuritySecret with a secretsLoader whose KubernetesProvider is backed by the fake clientset, so the production read path is exercised.

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

Does it mean, we need to update refs, docs, samples, etc in other repos due to Config - > Settings change? Looks like it's a breaking change that needs to be coordinated with TPMs.

@nicolejms

Copy link
Copy Markdown
Contributor

@sylvainsf can you improve code coverage numbers. they're pretty low - Patch coverage is 43.45238%

sylvainsf and others added 2 commits July 1, 2026 17:49
…adius.Security/secrets

This change addresses issue radius-project#12122, where Radius.Core/bicepConfigs and
Radius.Core/terraformConfigs rejected Radius.Security/secrets for registry and
module credentials, accepting only Applications.Core/secretStores. While fixing
that, the work revealed two deeper problems, which this change also corrects.

Support Radius.Security/secrets in the recipe secret loader

The recipe secret loader was hardcoded to the Applications.Core/secretStores
ListSecrets API and never dispatched on the referenced resource type. It now
parses the secret resource ID and routes to the correct reader:

- Applications.Core/secretStores keeps the existing ListSecrets path unchanged.
- Radius.Security/secrets is read by locating the backing Kubernetes Secret the
  resource's recipe materializes (via status.outputResources) and reading its
  values directly. This is required because a provisioned Radius.Security/secrets
  has its sensitive data redacted from the database once provisioning succeeds,
  so the plaintext only exists in the backing Kubernetes Secret.

The Kubernetes client provider is threaded into the loader at both wiring sites
(dynamic-rp and the recipe controller config). The Applications.Core path is left
behavior-identical.

Rename Configs -> Settings to match the feature spec

The resource types were introduced as Radius.Core/terraformConfigs and
Radius.Core/bicepConfigs, but the authoritative feature spec authored by
@zachcasper (terraform-bicep-settings) names them Radius.Core/terraformSettings
and Radius.Core/bicepSettings. The naming divergence originated in this repo, not
the spec, and the resource types are not yet referenced on the docs site, so this
renames them to match the spec before they ship more widely:

- TypeSpec models, segments, and the environment properties terraformSettings and
  bicepSettings.
- Datamodel types, converters, conversions, the frontend validator package, setup
  routing, the built-in provider manifests, and the embedded OpenAPI metadata
  mapping.
- Regenerated clients, fakes, swagger, and bicep-types.

The legacy recipeConfig transport types (datamodel.BicepConfigProperties,
datamodel.TerraformConfigProperties) and the Applications.Core/environments path
are intentionally left unchanged; these are new-environment-only resources.

Select Bicep registry auth from the settings resource, not the secret kind

Per the feature spec, the secret kind property is optional and the Bicep
authentication method comes from the bicepSettings resource. Previously the Bicep
driver chose the registry auth client from the secret's kind, so a kind-less
Radius.Security/secrets carrying only username and password failed with
"invalid type". The bicepSettings authenticationMethod is now threaded through and
used to select the auth client (BasicAuth, AzureWI, AwsIrsa), so a kind-less
Radius.Security/secrets works for BasicAuth. The Applications.Core/secretStores
path, which leaves the method empty, continues to use the secret store's own type.

Tests

- Unit tests for the type-dispatching loader and the Radius.Security/secrets
  backing-secret reader.
- A functional test (Test_TerraformSettings_SecuritySecret_Credentials) that
  provisions a Radius.Security/secrets resource and references it from a
  terraformSettings resource for private registry credentials, exercising the new
  loader end-to-end.

Fixes radius-project#12122

Signed-off-by: Sylvain Niles <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Signed-off-by: Sylvain Niles <[email protected]>
@sylvainsf sylvainsf force-pushed the fix-12122-security-secrets-recipe-configs branch from 472b6aa to 9dc7296 Compare July 2, 2026 00:52
@radius-functional-tests

radius-functional-tests Bot commented Jul 2, 2026

Copy link
Copy Markdown

Radius functional test overview

🔍 Go to test action run

Click here to see the test run details
Name Value
Repository sylvainsf/radius
Commit ref 9dc7296
Unique ID funce62d6c23ba
Image tag pr-funce62d6c23ba
  • Dapr: 1.14.4
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.3.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-funce62d6c23ba
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-funce62d6c23ba
  • dynamic-rp test image location: ghcr.io/radius-project/dev/dynamic-rp:pr-funce62d6c23ba
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-funce62d6c23ba
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-funce62d6c23ba
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting ucp-cloud functional tests...
⌛ Starting corerp-cloud functional tests...
✅ ucp-cloud functional tests succeeded
✅ corerp-cloud functional tests succeeded

@sylvainsf

Copy link
Copy Markdown
Contributor Author

Does it mean, we need to update refs, docs, samples, etc in other repos due to Config - > Settings change? Looks like it's a breaking change that needs to be coordinated with TPMs.

No, this is for extensibility namespace, there are no docs for that currently at all. That's on the PM task list.

@sylvainsf

Copy link
Copy Markdown
Contributor Author

Superseded by #12303, which moves this branch off the personal fork to the upstream sylvainsf/fix-12122-security-secrets-recipe-configs branch (same commits, rebased on main, plus the review-comment fixes). Closing in favor of #12303.

@sylvainsf sylvainsf closed this Jul 2, 2026
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.

bicepConfigs / terraformConfigs reject Radius.Security/secrets for registry secrets; only Applications.Core/secretStores accepted

5 participants