From d758e9f6dfb137a7a24ba98319fe6c6571a828e5 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:01:44 -0700 Subject: [PATCH 01/19] add secret store scenario extension feature specs Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 229 ++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 resources/2024-07-secretstore-feature-spec.md diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md new file mode 100644 index 00000000..4b098ab5 --- /dev/null +++ b/resources/2024-07-secretstore-feature-spec.md @@ -0,0 +1,229 @@ +# Extend the use-cases of `Applications.Core/secretStores` + +* **Status**: Pending +* **Author**: Will Tsai (@willtsai) + +## Target customers +**Developers and operators** who are building and managing microservice applications, are using Radius to deploy applications and wish to effortlessly and securely manage the secrets for use in their environments and applications. + +## Existing customer problem + +Currently, Radius provides an `Applications.Core/secretStores` resource type that allows developers to store and retrieve secrets in a secure and reliable way. The `secretStores` resource type can be referenced and used by the following Radius resources today: +- `Applications.Core/gateways` to manage [TLS certificates for HTTPS connections](https://docs.radapp.io/guides/author-apps/networking/tls/) +- `Applications.Core/environments` for authentication into [private Recipe registries](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/), [custom Terraform Providers](https://docs.radapp.io/guides/recipes/terraform/howto-custom-provider/), and in [Recipe configurations](https://github.com/radius-project/radius/blob/594faf60683351e4be2dee7309ebc369dfac26ad/test/functional-portable/corerp/noncloud/resources/testdata/corerp-resources-terraform-postgres.bicep#L32). + +As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables by configuring each custom Recipe in order to propagate secrets to my application developers. + +As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. + +## Desired customer experience outcome + + +As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. + +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource defintion so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. + +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Extenders` or `Applications.Volumes` resource defintion so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. + +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*` or `Applications.Messaging/*` resource defintion so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. + +### Detailed Customer Experience + + + +Step 1: Operator creates and deploys `Applications.Core/secretStores` resources containing the secret data required for authenticating into resources that their developers may use. + +```bicep +resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { + name: 'authcreds' + properties:{ + application: application + type: 'credentials' // this can change based on detailed tech design + data: { + 'username': { + value: username + } + 'password': { + value: password + } + 'uri': { + value: uri + } + 'connectionString': { + value: connectionString + } + } + } +} +``` + +```bicep +resource azurekeyvaultsecrets 'Applications.Core/secretStores@2023-10-01-preview' = { + name: 'azurekeyvaultsecrets' + properties:{ + application: application + type: 'generic' // this can change based on detailed tech design + data: { + 'name': { + value: secret1 + } + 'version': { + value: 1 + } + 'encoding': { + value: 'base64' + } + 'alias': { + value: secretalias + } + } + } +} +``` + +Step 2: Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition to inject secrets as environment variables into their container at deploy time. + +```bicep +resource demo 'Applications.Core/containers@2023-10-01-preview' = { + name: 'demo' + properties: { + application: application + container: { + image: 'ghcr.io/radius-project/samples/demo:latest' + env:{ + // validate accuracy of referencing the values from the secret store + DB_CONNECTION: authcreds.properties.data.connectionString + } + ports: { + web: { + containerPort: 3000 + } + } + } + } +} +``` + +Step 3: Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` or `Applications.Volumes` resource definition to securely manage secrets for use in their application. + +```bicep +resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { + name: 'twilio' + properties: { + application: application + environment: environment + recipe: { + name: 'twilio' + } + secrets: { + // validate accuracy of referencing the values from the secret store + password: authcreds.properties.data.password + } + } +} +``` + +```bicep +resource volume 'Applications.Core/volumes@2023-10-01-preview' = { + name: 'myvolume' + properties: { + application: app.id + kind: 'azure.com.keyvault' + resource: keyvault.id + secrets: { + mysecret: { + // validate accuracy of referencing the values from the secret store + name: azurekeyvaultsecrets.properties.data.name + version: azurekeyvaultsecrets.properties.data.version + alias: azurekeyvaultsecrets.properties.data.alias + encoding: azurekeyvaultsecrets.properties.data.encoding + } + } + } +} +``` + +Step 4: Developer references the `Applications.Core/secretStores` resource in their `Applications.Datastores/*` or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. + +```bicep +resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { + name: 'db' + properties: { + environment: environment + application: app.id + resourceProvisioning: 'manual' + host: substring(cosmosAccount.properties.documentEndpoint, 0, lastIndexOf(cosmosAccount.properties.documentEndpoint, ':')) + port: int(split(substring(cosmosAccount.properties.documentEndpoint,lastIndexOf(cosmosAccount.properties.documentEndpoint, ':') + 1), '/')[0]) + database: cosmosAccount::database.name + username: '' + resources: [ + { id: cosmosAccount.id } + ] + secrets: { + // validate accuracy of referencing the values from the secret store + connectionString: authcreds.properties.data.connectionString + password: authcreds.properties.data.password + } + } +} +``` + +```bicep +resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { + name: 'rabbitmq' + properties: { + environment: environment + application: app.id + resourceProvisioning: 'manual' + queue: 'radius-queue' + host: rmqHost + port: rmqPort + vHost: vHost + username: rmqUsername + secrets: { + // validate accuracy of referencing the values from the secret store + password: authcreds.properties.data.password + } + } +} +``` + +Step 5: Developer deploys the resources to Radius and the secrets required for authentication are injected into the container, extender, volume, datastore, or messaging resource at deploy time. + +## Key investments + + +### Feature 1: Add functionality to reference `Applications.Core/secretStores` in `Applications.Core/containers` resources + +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Core/containers` resource definitions under the `properties.container.env` field so that secrets can be injected as environment variables into their container at deploy time. + +### Feature 2: Add functionality to reference `Applications.Core/secretStores` in `Applications.Core/*` resources + +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their core resources (namely `Applications.Core/extenders` and `Applications.Core/volumes`) so that secrets can be securely managed for use in their application to authenticate into those resources. + +### Feature 3: Add functionality to reference `Applications.Core/secretStores` in portable resources + +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their portable resources (namely `Applications.Datastores/*` and `Applications.Messaging/*`) so that secrets can be securely managed for use in their application to authenticate into those resources. + +## Key dependencies and risks + + + + + +**Dependency: ability to reference values from `Applications.Core/secretStores`.** This feature is dependent on the ability to reference values from `Applications.Core/secretStores`, which should be doable given the existing functionality of referencing secret values for TLS Termination in `Applications.Core/gateways`. + +**Risk: use of secrets in core and portable resources.** This pattern of referencing and leveraging secrets in core and portable resources might not be a common or desirable pattern for users. We will validate this by opening up this feature spec for discussion with the community. + +## Key assumptions to test and questions to answer + + + +**Assumption: operators can create and deploy `Applications.Core/secretStores` resources.** We assume that operators create and manage secrets on behalf of developers, which are encapsulated in `Applications.Core/secretStores` resources. The developers can subsequently reference these resources in their application resources to securely manage secrets for use in their applications. We will validate this assumption by opening up this feature spec for discussion with the community. + +## Current state + +- Feature request tracking this scenario: https://github.com/radius-project/radius/issues/5520 +- Pull request (work in progress) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 \ No newline at end of file From 1338afec6a4829f2510ace89d1eef522f17dc24a Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:05:14 -0700 Subject: [PATCH 02/19] spelling corrections Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- .github/config/en-custom.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/config/en-custom.txt b/.github/config/en-custom.txt index 8d424819..aa7f7424 100644 --- a/.github/config/en-custom.txt +++ b/.github/config/en-custom.txt @@ -686,4 +686,6 @@ roundtrips reimplement keyspace upsert -TTL \ No newline at end of file +TTL +Tsai +willtsai \ No newline at end of file From c0ebedb2365b81891d5b07e222726154f6f51b41 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:06:08 -0700 Subject: [PATCH 03/19] spelling corrections Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 4b098ab5..5da39c7a 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -21,11 +21,11 @@ As an application developer, I cannot reference a `secretStores` resource in the As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource defintion so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource definition so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Extenders` or `Applications.Volumes` resource defintion so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Extenders` or `Applications.Volumes` resource definition so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*` or `Applications.Messaging/*` resource defintion so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*` or `Applications.Messaging/*` resource definition so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. ### Detailed Customer Experience From 443523e4895f1da7a13c0e71c6d67de2ba1ee178 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:39:59 -0700 Subject: [PATCH 04/19] add content Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 5da39c7a..49cb035c 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -3,10 +3,10 @@ * **Status**: Pending * **Author**: Will Tsai (@willtsai) -## Target customers +## Target users **Developers and operators** who are building and managing microservice applications, are using Radius to deploy applications and wish to effortlessly and securely manage the secrets for use in their environments and applications. -## Existing customer problem +## Existing user problem Currently, Radius provides an `Applications.Core/secretStores` resource type that allows developers to store and retrieve secrets in a secure and reliable way. The `secretStores` resource type can be referenced and used by the following Radius resources today: - `Applications.Core/gateways` to manage [TLS certificates for HTTPS connections](https://docs.radapp.io/guides/author-apps/networking/tls/) @@ -16,8 +16,7 @@ As an operator, I can create a `secretStores` resource to securely manage secret As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. -## Desired customer experience outcome - +## Desired user experience outcome As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. @@ -27,15 +26,33 @@ As a developer, I can reference an `Applications.Core/secretStores` in my `Appli As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*` or `Applications.Messaging/*` resource definition so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. -### Detailed Customer Experience - - +### Detailed User Experience Step 1: Operator creates and deploys `Applications.Core/secretStores` resources containing the secret data required for authenticating into resources that their developers may use. -```bicep +```diff +resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { + name: 'authcreds' + properties:{ + application: application + type: 'generic' + data: { + 'username': { + value: username + } + 'password': { + value: password + } + 'uri': { + value: uri + } + 'connectionString': { + value: connectionString + } + } + } +}, + resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { name: 'authcreds' properties:{ @@ -219,7 +236,7 @@ Add the ability for developers to reference values from their `Applications.Core ## Key assumptions to test and questions to answer - + **Assumption: operators can create and deploy `Applications.Core/secretStores` resources.** We assume that operators create and manage secrets on behalf of developers, which are encapsulated in `Applications.Core/secretStores` resources. The developers can subsequently reference these resources in their application resources to securely manage secrets for use in their applications. We will validate this assumption by opening up this feature spec for discussion with the community. From 613151593b990388760fb067e3cd42329c9118cf Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:44:58 -0700 Subject: [PATCH 05/19] add content Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 49cb035c..ffb7a875 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -35,29 +35,7 @@ resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { name: 'authcreds' properties:{ application: application - type: 'generic' - data: { - 'username': { - value: username - } - 'password': { - value: password - } - 'uri': { - value: uri - } - 'connectionString': { - value: connectionString - } - } - } -}, - -resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { - name: 'authcreds' - properties:{ - application: application - type: 'credentials' // this can change based on detailed tech design ++ type: 'credentials' // this can change based on detailed tech design data: { 'username': { value: username From 38a8ee3530b91d014792f45094bbcc1bcdebc34a Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:42:49 -0700 Subject: [PATCH 06/19] address feedback on proposed examples Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 108 ++++++++++++++---- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index ffb7a875..6b9b849e 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -30,12 +30,12 @@ As a developer, I can reference an `Applications.Core/secretStores` in my `Appli Step 1: Operator creates and deploys `Applications.Core/secretStores` resources containing the secret data required for authenticating into resources that their developers may use. -```diff +```bicep resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { name: 'authcreds' properties:{ application: application -+ type: 'credentials' // this can change based on detailed tech design + type: 'generic' // this can change based on detailed tech design data: { 'username': { value: username @@ -80,7 +80,9 @@ resource azurekeyvaultsecrets 'Applications.Core/secretStores@2023-10-01-preview Step 2: Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition to inject secrets as environment variables into their container at deploy time. -```bicep +> The example below follows the implementation that is currently proposed in https://github.com/radius-project/radius/pull/7744 + +```diff resource demo 'Applications.Core/containers@2023-10-01-preview' = { name: 'demo' properties: { @@ -88,8 +90,14 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { container: { image: 'ghcr.io/radius-project/samples/demo:latest' env:{ - // validate accuracy of referencing the values from the secret store - DB_CONNECTION: authcreds.properties.data.connectionString ++ DB_CONNECTION: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'username' ++ } ++ } ++ } } ports: { web: { @@ -103,7 +111,7 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { Step 3: Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` or `Applications.Volumes` resource definition to securely manage secrets for use in their application. -```bicep +```diff resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { name: 'twilio' properties: { @@ -113,14 +121,20 @@ resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { name: 'twilio' } secrets: { - // validate accuracy of referencing the values from the secret store - password: authcreds.properties.data.password ++ password: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } } } } ``` -```bicep +```diff resource volume 'Applications.Core/volumes@2023-10-01-preview' = { name: 'myvolume' properties: { @@ -129,11 +143,38 @@ resource volume 'Applications.Core/volumes@2023-10-01-preview' = { resource: keyvault.id secrets: { mysecret: { - // validate accuracy of referencing the values from the secret store - name: azurekeyvaultsecrets.properties.data.name - version: azurekeyvaultsecrets.properties.data.version - alias: azurekeyvaultsecrets.properties.data.alias - encoding: azurekeyvaultsecrets.properties.data.encoding ++ name: { ++ valueFrom: { ++ secretRef: { ++ source: azurekeyvaultsecrets.id ++ key: 'name' ++ } ++ } ++ } ++ version: { ++ valueFrom: { ++ secretRef: { ++ source: azurekeyvaultsecrets.id ++ key: 'version' ++ } ++ } ++ } ++ alias: { ++ valueFrom: { ++ secretRef: { ++ source: azurekeyvaultsecrets.id ++ key: 'alias' ++ } ++ } ++ } ++ encoding: { ++ valueFrom: { ++ secretRef: { ++ source: azurekeyvaultsecrets.id ++ key: 'encoding' ++ } ++ } ++ } } } } @@ -142,7 +183,7 @@ resource volume 'Applications.Core/volumes@2023-10-01-preview' = { Step 4: Developer references the `Applications.Core/secretStores` resource in their `Applications.Datastores/*` or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. -```bicep +```diff resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { name: 'db' properties: { @@ -157,15 +198,28 @@ resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { { id: cosmosAccount.id } ] secrets: { - // validate accuracy of referencing the values from the secret store - connectionString: authcreds.properties.data.connectionString - password: authcreds.properties.data.password ++ connectionString: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'connectionString' ++ } ++ } ++ } ++ password: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } } } } ``` -```bicep +```diff resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { name: 'rabbitmq' properties: { @@ -178,14 +232,20 @@ resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { vHost: vHost username: rmqUsername secrets: { - // validate accuracy of referencing the values from the secret store - password: authcreds.properties.data.password ++ password: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } } } } ``` -Step 5: Developer deploys the resources to Radius and the secrets required for authentication are injected into the container, extender, volume, datastore, or messaging resource at deploy time. +Step 5: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables or used as credentials for authentication into the extender, volume, datastore, or messaging resource at deploy time. ## Key investments @@ -208,7 +268,9 @@ Add the ability for developers to reference values from their `Applications.Core -**Dependency: ability to reference values from `Applications.Core/secretStores`.** This feature is dependent on the ability to reference values from `Applications.Core/secretStores`, which should be doable given the existing functionality of referencing secret values for TLS Termination in `Applications.Core/gateways`. +**Dependency: ability to reference values from `Applications.Core/secretStores`.** This feature is dependent on the ability to reference values from `Applications.Core/secretStores`, which should be doable given the existing functionality of referencing secret values for TLS Termination in `Applications.Core/gateways`. + +> The TLS certificate data secret in `Applications.Core/gateways` is referenced today by `tls: { certificateFrom: secretstore.id }`. As a part of implementation we should evaluate if the `valueFrom: { secretRef: { ... } }` pattern proposed here is an acceptable deviation from the previous pattern implemented for `gateways`. **Risk: use of secrets in core and portable resources.** This pattern of referencing and leveraging secrets in core and portable resources might not be a common or desirable pattern for users. We will validate this by opening up this feature spec for discussion with the community. From 796b4a9eabaabe1a2140d4845550de4e89cebe29 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:00:49 -0700 Subject: [PATCH 07/19] address review feedback Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 143 +++++++++++++++++- 1 file changed, 135 insertions(+), 8 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 6b9b849e..199885bb 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -1,6 +1,5 @@ # Extend the use-cases of `Applications.Core/secretStores` -* **Status**: Pending * **Author**: Will Tsai (@willtsai) ## Target users @@ -14,12 +13,16 @@ Currently, Radius provides an `Applications.Core/secretStores` resource type tha As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables by configuring each custom Recipe in order to propagate secrets to my application developers. +As an operator, I cannot reference a `secretStores` resource in the Recipes I create in order to securely manage secrets to be used in the Recipe configurations. Instead, I'm having to store my secrets in plain text within the `secrets` field of my Recipe's `output` object. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my Recipes. + As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. ## Desired user experience outcome As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. +As an operator, I can reference an `Applications.Core/secretStores` in my Recipes so that I no longer have to store secrets as plain text in the `secrets` field of my Recipe's `output` object for authentication, etc. + As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource definition so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Extenders` or `Applications.Volumes` resource definition so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. @@ -28,14 +31,17 @@ As a developer, I can reference an `Applications.Core/secretStores` in my `Appli ### Detailed User Experience -Step 1: Operator creates and deploys `Applications.Core/secretStores` resources containing the secret data required for authenticating into resources that their developers may use. +Step 1: Operator creates or references an existing `Applications.Core/secretStores` resource containing the secret data required for authenticating into resources that their developers may use. + +Creating a new `secretStore` resource: ```bicep resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { name: 'authcreds' properties:{ application: application - type: 'generic' // this can change based on detailed tech design + // today the type is an enum, see https://github.com/radius-project/radius/pull/7816 + type: 'generic' data: { 'username': { value: username @@ -54,12 +60,16 @@ resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { } ``` +Referencing an existing `secretStore` resource: + ```bicep resource azurekeyvaultsecrets 'Applications.Core/secretStores@2023-10-01-preview' = { - name: 'azurekeyvaultsecrets' + name: 'existing-azurekeyvault-secrets' properties:{ application: application - type: 'generic' // this can change based on detailed tech design + resource: 'secret-app-existing-secret' + // today the type is an enum, see https://github.com/radius-project/radius/pull/7816 + type: 'generic' data: { 'name': { value: secret1 @@ -78,9 +88,79 @@ resource azurekeyvaultsecrets 'Applications.Core/secretStores@2023-10-01-preview } ``` +Step 2: Operator references the `Applications.Core/secretStores` resource in their Recipe's `output` object to securely pass secrets as outputs to Radius that can be used in provisioning and deploying the resource using the Recipe. + +Bicep example: +```diff +param context object + +@description('The ID of the subnet where the Azure Cache for Redis will be deployed') +param subnetID string = '' + +@description('The location of the Azure Cache for Redis') +param location string = resourceGroup().location + +resource redis 'Microsoft.Cache/redis@2022-05-01' = { + name: 'redis-${uniqueString(context.resource.id)}' + location: location + properties: { + sku: { + capacity: 1 + family: 'P' + name: 'Premium' + } + enableNonSslPort: true + minimumTlsVersion: '1.2' + subnetId: subnetID == '' ? null : subnetID + } +} + +output result object = { + values: { + host: redis.properties.hostName + port: redis.properties.port + username: '' + } + secrets: { ++ password: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } + } +} +``` + +Terraform example: +```diff +output "result" { + description = "Output of the recipe. These values will be used to configure connections." + + value = { + values = { + host = memory_db.cluster_endpoint_address + port = memory_db.cluster_endpoint_port + } + secrets = { ++ password = { ++ valueFrom = { ++ secretRef = { ++ source = authcreds.id ++ key = "password" ++ } ++ } ++ } + } + } +} +``` + Step 2: Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition to inject secrets as environment variables into their container at deploy time. -> The example below follows the implementation that is currently proposed in https://github.com/radius-project/radius/pull/7744 +> The example below follows the implementation that has been completed in https://github.com/radius-project/radius/pull/7744 ```diff resource demo 'Applications.Core/containers@2023-10-01-preview' = { @@ -245,7 +325,38 @@ resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { } ``` -Step 5: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables or used as credentials for authentication into the extender, volume, datastore, or messaging resource at deploy time. +Step 5: The developer specifies the `Applications.Core/secretStores` resource as a parameter to the Bicep resource that requires the secret. + +```bicep +param secretStore object = authcreds + +resource demo 'Applications.Core/containers@2023-10-01-preview' = { + name: 'demo' + properties: { + application: application + container: { + image: 'ghcr.io/radius-project/samples/demo:latest' + env:{ + DB_CONNECTION: { + valueFrom: { + secretRef: { + source: secretStore.id + key: 'username' + } + } + } + } + ports: { + web: { + containerPort: 3000 + } + } + } + } +} +``` + +Step 6: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables or used as credentials for authentication into the extender, volume, datastore, or messaging resource at deploy time. ## Key investments @@ -262,6 +373,12 @@ Add the ability for developers to reference values from their `Applications.Core Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their portable resources (namely `Applications.Datastores/*` and `Applications.Messaging/*`) so that secrets can be securely managed for use in their application to authenticate into those resources. +> We should revisit the overall plan for provisioning types we plan to support on portable resources before implementing this change. There are some changes with UDT that haven't been solidified yet. + +### Feature 4: Add functionality to reference `Applications.Core/secretStores` objects as a parameter to a Bicep resource + +Add the ability for developers to specify the `Applications.Core/secretStores` resource as a parameter of the `object` type to the Bicep resource that requires the secret so that secrets can be passed as parameters into a Radius Bicep resource. + ## Key dependencies and risks @@ -280,7 +397,17 @@ Add the ability for developers to reference values from their `Applications.Core **Assumption: operators can create and deploy `Applications.Core/secretStores` resources.** We assume that operators create and manage secrets on behalf of developers, which are encapsulated in `Applications.Core/secretStores` resources. The developers can subsequently reference these resources in their application resources to securely manage secrets for use in their applications. We will validate this assumption by opening up this feature spec for discussion with the community. +**Assumption: the `Applications.secretStores` resource type can be referenced as a parameter to a Bicep resource.** We assume that the `Applications.secretStores` resource type can be referenced as a parameter to a Bicep resource so that secrets can be passed as object parameters into a Radius Bicep resource. We will validate this assumption by investigating the feasibility of this approach during tech design. + ## Current state - Feature request tracking this scenario: https://github.com/radius-project/radius/issues/5520 -- Pull request (work in progress) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 \ No newline at end of file +- Pull request (work in progress) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 + +## Design Review Notes + +- Considerations for `Applications.Core/secretstores` resource `type` values -- *this has been addressed by [PR #7816](https://github.com/radius-project/radius/pull/7816) and referenced in this feature spec doc* +- Discussion around whether `Applications.Core/secretStores` is right, specifically whether it should be part of `Applications.Core` or whether it should be part of UCP (something like `System.Resources/secretStores`) -- *this is a larger discussion beyond the scope of this particular feature spec* +- Scenario that allows for secrets to be passed as parameters into a Radius Bicep resource is missing -- *this scenario was added* +- Need scenarios for referencing `Applications.Core/secretStores` in Radius Recipes -- *this scenario was added* +- Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- TODO \ No newline at end of file From 8bed4df0e9edad8df821ed6a3ca35243ca4550dc Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:31:37 -0700 Subject: [PATCH 08/19] add recipes scenario Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 199885bb..472d027d 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -158,7 +158,7 @@ output "result" { } ``` -Step 2: Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition to inject secrets as environment variables into their container at deploy time. +Step 3: Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition to inject secrets as environment variables into their container at deploy time. > The example below follows the implementation that has been completed in https://github.com/radius-project/radius/pull/7744 @@ -189,7 +189,7 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { } ``` -Step 3: Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` or `Applications.Volumes` resource definition to securely manage secrets for use in their application. +Step 4: Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` or `Applications.Volumes` resource definition to securely manage secrets for use in their application. ```diff resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { @@ -261,7 +261,7 @@ resource volume 'Applications.Core/volumes@2023-10-01-preview' = { } ``` -Step 4: Developer references the `Applications.Core/secretStores` resource in their `Applications.Datastores/*` or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. +Step 5: Developer references the `Applications.Core/secretStores` resource in their `Applications.Datastores/*` or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. ```diff resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { @@ -325,7 +325,7 @@ resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { } ``` -Step 5: The developer specifies the `Applications.Core/secretStores` resource as a parameter to the Bicep resource that requires the secret. +Step 6: The developer specifies the `Applications.Core/secretStores` resource as a parameter to the Bicep resource that requires the secret. ```bicep param secretStore object = authcreds @@ -356,7 +356,7 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { } ``` -Step 6: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables or used as credentials for authentication into the extender, volume, datastore, or messaging resource at deploy time. +Step 7: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables or used as credentials for authentication into the extender, volume, datastore, or messaging resource at deploy time. If the resource is deployed using a Recipe, the secrets are securely passed as outputs to Radius by the Recipe for use in provisioning and deploying the resource. ## Key investments @@ -379,6 +379,10 @@ Add the ability for developers to reference values from their `Applications.Core Add the ability for developers to specify the `Applications.Core/secretStores` resource as a parameter of the `object` type to the Bicep resource that requires the secret so that secrets can be passed as parameters into a Radius Bicep resource. +### Feature 5: Add functionality to reference `Applications.Core/secretStores` in Recipes + +Add the ability for operators to reference values from their `Applications.Core/secretStores` resources in their Recipe's `output` object so that secrets can be securely passed as outputs to Radius that can be used in provisioning and deploying the resource using the Recipe. + ## Key dependencies and risks From 7c6543cacd75b47717cd29d8dfcc7b09d1793702 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:34:36 -0700 Subject: [PATCH 09/19] address feedback Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 472d027d..ca57aeff 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -414,4 +414,4 @@ Add the ability for operators to reference values from their `Applications.Core/ - Discussion around whether `Applications.Core/secretStores` is right, specifically whether it should be part of `Applications.Core` or whether it should be part of UCP (something like `System.Resources/secretStores`) -- *this is a larger discussion beyond the scope of this particular feature spec* - Scenario that allows for secrets to be passed as parameters into a Radius Bicep resource is missing -- *this scenario was added* - Need scenarios for referencing `Applications.Core/secretStores` in Radius Recipes -- *this scenario was added* -- Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- TODO \ No newline at end of file +- Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- *addressed in the spec* \ No newline at end of file From 6a05f7e736e62070f9d9bca50cb1a9b2bec8aa35 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 1 Nov 2024 15:35:35 -0700 Subject: [PATCH 10/19] address feedback Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index ca57aeff..2cd63df0 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -406,7 +406,7 @@ Add the ability for operators to reference values from their `Applications.Core/ ## Current state - Feature request tracking this scenario: https://github.com/radius-project/radius/issues/5520 -- Pull request (work in progress) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 +- Pull request (merged) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 ## Design Review Notes From 247b9153ba9ff25726552d387312c19c653af1d0 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 16 Jan 2025 16:42:42 -0800 Subject: [PATCH 11/19] address review feedback Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 322 +++++++----------- 1 file changed, 123 insertions(+), 199 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 2cd63df0..bd581049 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -2,45 +2,116 @@ * **Author**: Will Tsai (@willtsai) -## Target users +## Topic Summary + + +This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. + +### Top level goals + +- Enable developers to reference `Applications.Core/secretStores` in all core and portable Radius resources so that secrets can be securely managed for use in their applications. + +### Non-goals (out of scope) + +- The ability to [reference secret stores in a Recipe](https://github.com/radius-project/roadmap/issues/59) is out of scope for this feature spec, i.e. *As an operator, I can reference an `Applications.Core/secretStores` in my Recipes so that I no longer have to store secrets as plain text in the `secrets` field of my Recipe's `output` object for authentication, etc.* +- Today the `type` property in the `Applications.Core/secretStores` is an enum -- this feature spec does not propose to change the existing [implementation](https://github.com/radius-project/radius/pull/7816) of the `type` property in the `Applications.Core/secretStores` resource type. + +## User profile and challenges + +- The primary user for this feature is the **developer** who is building and managing microservice applications. +- The secondary user would be the **operator** who is creating and managing the `Applications.Core/secretStores` resources on behalf of the developers. + +### User persona(s) + **Developers and operators** who are building and managing microservice applications, are using Radius to deploy applications and wish to effortlessly and securely manage the secrets for use in their environments and applications. -## Existing user problem +### Challenge(s) faced by the user + + +Today, developers have no way to reference secrets in their Radius resources other than in gateways and containers, and thus have to store secrets in plain text within the `properties.secrets` field for each resource. + +Operators may have to do extra work to inject secrets as environment variables in order to propagate secrets without needing the developers to store secrets in plain text. + +### Positive user outcome + + +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource definitions so that Radius may securely manage secrets for use in my application to authenticate into those resources. + +As an operator, I want to ensure that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. Today, these secrets have to be stored in plain text within resources. + +## Key scenarios + + +### Scenario 1: Secrets are stored and then mounted as environment-variables in a container + +Barry is a developer who is building a microservice application that requires a database connection string to authenticate into a Cosmos DB instance. Barry wants to securely manage the database connection string for his application and thus creates a `Applications.Core/secretStores` resource containing the database connection string. Barry then references the `Applications.Core/secretStores` resource in his `Applications.Core/containers` resource definition so that Radius will inject the database connection string as an environment variable into his container at deploy time. + +### Scenario 2: Secrets are stored and then mounted as files-on-disk in a container. + +Maya is a developer who is building a microservice application that requires a TLS certificate to authenticate into a RabbitMQ instance. Maya wants to securely manage the TLS certificate for her application and thus creates a `Applications.Core/secretStores` resource containing the TLS certificate. Maya then references the `Applications.Core/secretStores` resource in her `Applications.Core/volumes` resource definition so that Radius will write the TLS certificate into a file on disk and mount that volume into her container at deploy time. + +### Scenario 3: Secrets are stored and used internally by the Radius infrastructure or some other piece of automation (not application code). + +Aditi is a developer who is building a microservice application that requires a password to authenticate into a Twilio extender. She wants to securely manage the password for her application and thus creates a `Applications.Core/secretStores` resource containing the password. Aditi then references the `Applications.Core/secretStores` resource in her `Applications.Core/extenders` resource definition so that Radius will use the password internally to authenticate into the Twilio extender at deploy time. + +## Key dependencies and risks + + + + + +**Dependency: ability to reference values from `Applications.Core/secretStores`.** This feature is dependent on the ability to reference values from `Applications.Core/secretStores`, which should be doable given the existing functionality of referencing secret values for TLS Termination in `Applications.Core/gateways`. + +> The TLS certificate data secret in `Applications.Core/gateways` is referenced today by `tls: { certificateFrom: secretstore.id }` while the implementation for referencing secret stores in `Applications.Core/containers` is `env: { DB_CONNECTION: { valueFrom: { secretRef: { source: secretstore.id, key: 'username' } } } }`. This is by design, see the design document [here](https://github.com/radius-project/design-notes/blob/main/resources/2024-06-support-secretstores-env.md). + +## Key assumptions to test and questions to answer + + + +**Assumption: operators can create and deploy `Applications.Core/secretStores` resources.** We assume that operators create and manage secrets on behalf of developers, which are encapsulated in `Applications.Core/secretStores` resources. The developers can subsequently reference these resources in their application resources to securely manage secrets for use in their applications. We will validate this assumption by opening up this feature spec for discussion with the community. + +## Current state + +- Feature request tracking this scenario: https://github.com/radius-project/radius/issues/5520 +- Pull request (merged) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 + +## Details of user problem + Currently, Radius provides an `Applications.Core/secretStores` resource type that allows developers to store and retrieve secrets in a secure and reliable way. The `secretStores` resource type can be referenced and used by the following Radius resources today: - `Applications.Core/gateways` to manage [TLS certificates for HTTPS connections](https://docs.radapp.io/guides/author-apps/networking/tls/) +- `Applications.Core/containers` to inject secrets as [environment variables into a container](https://docs.radapp.io/reference/resource-schema/core-schema/container-schema/#container) at deploy time - `Applications.Core/environments` for authentication into [private Recipe registries](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/), [custom Terraform Providers](https://docs.radapp.io/guides/recipes/terraform/howto-custom-provider/), and in [Recipe configurations](https://github.com/radius-project/radius/blob/594faf60683351e4be2dee7309ebc369dfac26ad/test/functional-portable/corerp/noncloud/resources/testdata/corerp-resources-terraform-postgres.bicep#L32). -As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables by configuring each custom Recipe in order to propagate secrets to my application developers. - -As an operator, I cannot reference a `secretStores` resource in the Recipes I create in order to securely manage secrets to be used in the Recipe configurations. Instead, I'm having to store my secrets in plain text within the `secrets` field of my Recipe's `output` object. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my Recipes. +As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables in order to propagate secrets to my application developers. -As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. +As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. ## Desired user experience outcome -As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. +[existing feature] As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in accessing private Recipes. This is a supported scenario in an existing feature, specifically for private [Bicep](https://docs.radapp.io/guides/recipes/howto-private-bicep-registry/) and [Terraform](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/) Recipes. -As an operator, I can reference an `Applications.Core/secretStores` in my Recipes so that I no longer have to store secrets as plain text in the `secrets` field of my Recipe's `output` object for authentication, etc. +[existing feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/gateways` resource definition so that Radius can set up the gateway with the TLS certificate required for HTTPS connections. This is a supported scenario in an existing feature, see [here](https://docs.radapp.io/guides/author-apps/networking/tls/#step-3-add-a-gateway). -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource definition so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. +[existing feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource definition so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. This is a supported scenario in an existing feature, see [here](https://docs.radapp.io/reference/resource-schema/core-schema/container-schema/#container). -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Extenders` or `Applications.Volumes` resource definition so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. +[proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Volumes` resource definition so that Radius will write the secret into a file on disk and mount that volume into the container at deploy time. I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*` or `Applications.Messaging/*` resource definition so that I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. +[proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Extenders` resource definition so that Radius will use the password internally to authenticate into the resource at deploy time. I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. + +[future feature] As a developer, I can specify a `Applications.Core/secretStores` in my custom user-defined resource once the [user-defined types](https://github.com/radius-project/design-notes/blob/main/architecture/2024-07-user-defined-types.md) feature is implemented. ### Detailed User Experience -Step 1: Operator creates or references an existing `Applications.Core/secretStores` resource containing the secret data required for authenticating into resources that their developers may use. +Step 1: Operator or developer creates or references an existing `Applications.Core/secretStores` resource containing the secret data required for authenticating into resources that their developers may use. -Creating a new `secretStore` resource: +Creating a new `secretStore` resource in the `app.bicep` application definition: ```bicep resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { name: 'authcreds' properties:{ application: application - // today the type is an enum, see https://github.com/radius-project/radius/pull/7816 type: 'generic' data: { 'username': { @@ -60,108 +131,14 @@ resource authcreds 'Applications.Core/secretStores@2023-10-01-preview' = { } ``` -Referencing an existing `secretStore` resource: +Step 2: Developer references stored secrets to: (a) mount as environment-variables in a container, (b) mount as files-on-disk in a container, or (c) use internally by the Radius infrastructure or some other piece of automation (not application code). -```bicep -resource azurekeyvaultsecrets 'Applications.Core/secretStores@2023-10-01-preview' = { - name: 'existing-azurekeyvault-secrets' - properties:{ - application: application - resource: 'secret-app-existing-secret' - // today the type is an enum, see https://github.com/radius-project/radius/pull/7816 - type: 'generic' - data: { - 'name': { - value: secret1 - } - 'version': { - value: 1 - } - 'encoding': { - value: 'base64' - } - 'alias': { - value: secretalias - } - } - } -} -``` - -Step 2: Operator references the `Applications.Core/secretStores` resource in their Recipe's `output` object to securely pass secrets as outputs to Radius that can be used in provisioning and deploying the resource using the Recipe. - -Bicep example: -```diff -param context object - -@description('The ID of the subnet where the Azure Cache for Redis will be deployed') -param subnetID string = '' - -@description('The location of the Azure Cache for Redis') -param location string = resourceGroup().location - -resource redis 'Microsoft.Cache/redis@2022-05-01' = { - name: 'redis-${uniqueString(context.resource.id)}' - location: location - properties: { - sku: { - capacity: 1 - family: 'P' - name: 'Premium' - } - enableNonSslPort: true - minimumTlsVersion: '1.2' - subnetId: subnetID == '' ? null : subnetID - } -} - -output result object = { - values: { - host: redis.properties.hostName - port: redis.properties.port - username: '' - } - secrets: { -+ password: { -+ valueFrom: { -+ secretRef: { -+ source: authcreds.id -+ key: 'password' -+ } -+ } -+ } - } -} -``` - -Terraform example: -```diff -output "result" { - description = "Output of the recipe. These values will be used to configure connections." - - value = { - values = { - host = memory_db.cluster_endpoint_address - port = memory_db.cluster_endpoint_port - } - secrets = { -+ password = { -+ valueFrom = { -+ secretRef = { -+ source = authcreds.id -+ key = "password" -+ } -+ } -+ } - } - } -} -``` - -Step 3: Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition to inject secrets as environment variables into their container at deploy time. +(a) Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition within the `app.bicep` to inject secrets as environment variables into their container at deploy time. > The example below follows the implementation that has been completed in https://github.com/radius-project/radius/pull/7744 +Add a reference to the secret store in the container resource within the `app.bicep` application definition: + ```diff resource demo 'Applications.Core/containers@2023-10-01-preview' = { name: 'demo' @@ -189,30 +166,7 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { } ``` -Step 4: Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` or `Applications.Volumes` resource definition to securely manage secrets for use in their application. - -```diff -resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { - name: 'twilio' - properties: { - application: application - environment: environment - recipe: { - name: 'twilio' - } - secrets: { -+ password: { -+ valueFrom: { -+ secretRef: { -+ source: authcreds.id -+ key: 'password' -+ } -+ } -+ } - } - } -} -``` +(b) Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/volumes` resource definition within the `app.bicep` application definition to write the secret into a file on disk and mount that volume into their container at deploy time. ```diff resource volume 'Applications.Core/volumes@2023-10-01-preview' = { @@ -261,7 +215,30 @@ resource volume 'Applications.Core/volumes@2023-10-01-preview' = { } ``` -Step 5: Developer references the `Applications.Core/secretStores` resource in their `Applications.Datastores/*` or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. +(c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` `Applications.Datastores/*`, or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: + +```diff +resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { + name: 'twilio' + properties: { + application: application + environment: environment + recipe: { + name: 'twilio' + } + secrets: { ++ password: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } + } + } +} +``` ```diff resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { @@ -325,38 +302,7 @@ resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { } ``` -Step 6: The developer specifies the `Applications.Core/secretStores` resource as a parameter to the Bicep resource that requires the secret. - -```bicep -param secretStore object = authcreds - -resource demo 'Applications.Core/containers@2023-10-01-preview' = { - name: 'demo' - properties: { - application: application - container: { - image: 'ghcr.io/radius-project/samples/demo:latest' - env:{ - DB_CONNECTION: { - valueFrom: { - secretRef: { - source: secretStore.id - key: 'username' - } - } - } - } - ports: { - web: { - containerPort: 3000 - } - } - } - } -} -``` - -Step 7: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables or used as credentials for authentication into the extender, volume, datastore, or messaging resource at deploy time. If the resource is deployed using a Recipe, the secrets are securely passed as outputs to Radius by the Recipe for use in provisioning and deploying the resource. +Step 3: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables, written to a file on a volume and mounted to the container, or used as credentials for authentication into the extender, datastore, or messaging resource at deploy time. ## Key investments @@ -383,35 +329,13 @@ Add the ability for developers to specify the `Applications.Core/secretStores` r Add the ability for operators to reference values from their `Applications.Core/secretStores` resources in their Recipe's `output` object so that secrets can be securely passed as outputs to Radius that can be used in provisioning and deploying the resource using the Recipe. -## Key dependencies and risks - - - - - -**Dependency: ability to reference values from `Applications.Core/secretStores`.** This feature is dependent on the ability to reference values from `Applications.Core/secretStores`, which should be doable given the existing functionality of referencing secret values for TLS Termination in `Applications.Core/gateways`. - -> The TLS certificate data secret in `Applications.Core/gateways` is referenced today by `tls: { certificateFrom: secretstore.id }`. As a part of implementation we should evaluate if the `valueFrom: { secretRef: { ... } }` pattern proposed here is an acceptable deviation from the previous pattern implemented for `gateways`. - -**Risk: use of secrets in core and portable resources.** This pattern of referencing and leveraging secrets in core and portable resources might not be a common or desirable pattern for users. We will validate this by opening up this feature spec for discussion with the community. - -## Key assumptions to test and questions to answer - - - -**Assumption: operators can create and deploy `Applications.Core/secretStores` resources.** We assume that operators create and manage secrets on behalf of developers, which are encapsulated in `Applications.Core/secretStores` resources. The developers can subsequently reference these resources in their application resources to securely manage secrets for use in their applications. We will validate this assumption by opening up this feature spec for discussion with the community. - -**Assumption: the `Applications.secretStores` resource type can be referenced as a parameter to a Bicep resource.** We assume that the `Applications.secretStores` resource type can be referenced as a parameter to a Bicep resource so that secrets can be passed as object parameters into a Radius Bicep resource. We will validate this assumption by investigating the feasibility of this approach during tech design. - -## Current state - -- Feature request tracking this scenario: https://github.com/radius-project/radius/issues/5520 -- Pull request (merged) for adding secretstore references into container env variables: https://github.com/radius-project/radius/pull/7744 - ## Design Review Notes -- Considerations for `Applications.Core/secretstores` resource `type` values -- *this has been addressed by [PR #7816](https://github.com/radius-project/radius/pull/7816) and referenced in this feature spec doc* -- Discussion around whether `Applications.Core/secretStores` is right, specifically whether it should be part of `Applications.Core` or whether it should be part of UCP (something like `System.Resources/secretStores`) -- *this is a larger discussion beyond the scope of this particular feature spec* -- Scenario that allows for secrets to be passed as parameters into a Radius Bicep resource is missing -- *this scenario was added* -- Need scenarios for referencing `Applications.Core/secretStores` in Radius Recipes -- *this scenario was added* -- Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- *addressed in the spec* \ No newline at end of file +- [x] Considerations for `Applications.Core/secretstores` resource `type` values -- *this has been addressed by [PR #7816](https://github.com/radius-project/radius/pull/7816) and referenced in this feature spec doc* +- [x] Discussion around whether `Applications.Core/secretStores` is right, specifically whether it should be part of `Applications.Core` or whether it should be part of UCP (something like `System.Resources/secretStores`) -- *this is a larger discussion beyond the scope of this particular feature spec* +- [x] Scenario that allows for secrets to be passed as parameters into a Radius Bicep resource is missing -- *this scenario was added* +- [x] Need scenarios for referencing `Applications.Core/secretStores` in Radius Recipes -- *this scenario was added* +- [x] Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- *addressed in the spec* +- [] More clarity needed on the actual features that need to be implemented as the spec is somewhere in between vision doc and user scenarios descriptions. The document needs to clearly identify feature gaps and the priority order for addressing them in order for it to be actionable. +- [] The recipes section should be separated into its own design document to provide more specific and actionable guidance. +- [] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. \ No newline at end of file From bfaa9cec55d819fb119c4688b40fd0c6623ffc63 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 16 Jan 2025 16:54:24 -0800 Subject: [PATCH 12/19] address review feedback Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index bd581049..f4ed0701 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -307,28 +307,16 @@ Step 3: Developer deploys the resources to Radius and the secrets required are e ## Key investments -### Feature 1: Add functionality to reference `Applications.Core/secretStores` in `Applications.Core/containers` resources +### Feature 1: Add functionality to reference `Applications.Core/secretStores` to write into mounted `Applications.Core/volumes` resources -Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Core/containers` resource definitions under the `properties.container.env` field so that secrets can be injected as environment variables into their container at deploy time. +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Core/volumes` resources so that secrets can be securely managed for use in their application to be written to the volume and mounted at deploy time by Radius. -### Feature 2: Add functionality to reference `Applications.Core/secretStores` in `Applications.Core/*` resources +### Feature 2: Add functionality to reference `Applications.Core/secretStores` to enable Radius to use internally for authentication into resources -Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their core resources (namely `Applications.Core/extenders` and `Applications.Core/volumes`) so that secrets can be securely managed for use in their application to authenticate into those resources. - -### Feature 3: Add functionality to reference `Applications.Core/secretStores` in portable resources - -Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their portable resources (namely `Applications.Datastores/*` and `Applications.Messaging/*`) so that secrets can be securely managed for use in their application to authenticate into those resources. +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their Radius resources (namely `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*`) so that secrets can be securely managed for use by Radius to authenticate into those resources. > We should revisit the overall plan for provisioning types we plan to support on portable resources before implementing this change. There are some changes with UDT that haven't been solidified yet. -### Feature 4: Add functionality to reference `Applications.Core/secretStores` objects as a parameter to a Bicep resource - -Add the ability for developers to specify the `Applications.Core/secretStores` resource as a parameter of the `object` type to the Bicep resource that requires the secret so that secrets can be passed as parameters into a Radius Bicep resource. - -### Feature 5: Add functionality to reference `Applications.Core/secretStores` in Recipes - -Add the ability for operators to reference values from their `Applications.Core/secretStores` resources in their Recipe's `output` object so that secrets can be securely passed as outputs to Radius that can be used in provisioning and deploying the resource using the Recipe. - ## Design Review Notes - [x] Considerations for `Applications.Core/secretstores` resource `type` values -- *this has been addressed by [PR #7816](https://github.com/radius-project/radius/pull/7816) and referenced in this feature spec doc* @@ -336,6 +324,6 @@ Add the ability for operators to reference values from their `Applications.Core/ - [x] Scenario that allows for secrets to be passed as parameters into a Radius Bicep resource is missing -- *this scenario was added* - [x] Need scenarios for referencing `Applications.Core/secretStores` in Radius Recipes -- *this scenario was added* - [x] Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- *addressed in the spec* -- [] More clarity needed on the actual features that need to be implemented as the spec is somewhere in between vision doc and user scenarios descriptions. The document needs to clearly identify feature gaps and the priority order for addressing them in order for it to be actionable. -- [] The recipes section should be separated into its own design document to provide more specific and actionable guidance. -- [] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. \ No newline at end of file +- [x] More clarity needed on the actual features that need to be implemented as the spec is somewhere in between vision doc and user scenarios descriptions. The document needs to clearly identify feature gaps and the priority order for addressing them in order for it to be actionable. +- [x] The recipes section should be separated into its own design document to provide more specific and actionable guidance. +- [x] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. \ No newline at end of file From 016887434b417e6ca60e6c34125cfcf127729c96 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 16 Jan 2025 16:56:39 -0800 Subject: [PATCH 13/19] spellcheck fixes Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- .github/config/en-custom.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/config/en-custom.txt b/.github/config/en-custom.txt index 0fd2f051..7fe7226f 100644 --- a/.github/config/en-custom.txt +++ b/.github/config/en-custom.txt @@ -907,4 +907,6 @@ SecOps kube workspace's Authorizer -KRM \ No newline at end of file +KRM +Aditi +Twilio \ No newline at end of file From ded70186f2f9705f6372d535ff4de7b02103841d Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 16 Jan 2025 16:58:17 -0800 Subject: [PATCH 14/19] spellcheck fixes Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- .github/config/en-custom.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/config/en-custom.txt b/.github/config/en-custom.txt index 7fe7226f..3d20b10d 100644 --- a/.github/config/en-custom.txt +++ b/.github/config/en-custom.txt @@ -775,6 +775,7 @@ kustomize usecase gitops predefine +KRM secretsStores DriverWithSecrets FindSecretIds @@ -907,6 +908,5 @@ SecOps kube workspace's Authorizer -KRM Aditi Twilio \ No newline at end of file From 3be6c6680704cbe23716ff4ef4f7423043f4463a Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Wed, 22 Jan 2025 17:30:59 -0800 Subject: [PATCH 15/19] address feedback from Jan 21 Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 108 ++++++++++-------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index f4ed0701..b86bcf1e 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -5,7 +5,7 @@ ## Topic Summary -This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. +This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. ### Top level goals @@ -35,7 +35,7 @@ Operators may have to do extra work to inject secrets as environment variables i ### Positive user outcome -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource definitions so that Radius may securely manage secrets for use in my application to authenticate into those resources. +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource definitions so that Radius may securely manage secrets for use in my application to authenticate into those resources. As an operator, I want to ensure that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. Today, these secrets have to be stored in plain text within resources. @@ -46,9 +46,9 @@ As an operator, I want to ensure that the developers I support can securely leve Barry is a developer who is building a microservice application that requires a database connection string to authenticate into a Cosmos DB instance. Barry wants to securely manage the database connection string for his application and thus creates a `Applications.Core/secretStores` resource containing the database connection string. Barry then references the `Applications.Core/secretStores` resource in his `Applications.Core/containers` resource definition so that Radius will inject the database connection string as an environment variable into his container at deploy time. -### Scenario 2: Secrets are stored and then mounted as files-on-disk in a container. +### Scenario 2: Secrets are stored and then mounted as files-on-volume in a container. -Maya is a developer who is building a microservice application that requires a TLS certificate to authenticate into a RabbitMQ instance. Maya wants to securely manage the TLS certificate for her application and thus creates a `Applications.Core/secretStores` resource containing the TLS certificate. Maya then references the `Applications.Core/secretStores` resource in her `Applications.Core/volumes` resource definition so that Radius will write the TLS certificate into a file on disk and mount that volume into her container at deploy time. +Maya is a developer who is building a microservice application that requires a TLS certificate to authenticate into a RabbitMQ instance. Maya wants to securely manage the TLS certificate for her application and thus creates a `Applications.Core/secretStores` resource containing the TLS certificate. Maya then references the `Applications.Core/secretStores` resource in her `Applications.Core/containers` resource definition under the `volumes` object so that Radius will write the TLS certificate into a file on disk/memory and mount that volume into her container at deploy time. ### Scenario 3: Secrets are stored and used internally by the Radius infrastructure or some other piece of automation (not application code). @@ -83,9 +83,9 @@ Currently, Radius provides an `Applications.Core/secretStores` resource type tha - `Applications.Core/containers` to inject secrets as [environment variables into a container](https://docs.radapp.io/reference/resource-schema/core-schema/container-schema/#container) at deploy time - `Applications.Core/environments` for authentication into [private Recipe registries](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/), [custom Terraform Providers](https://docs.radapp.io/guides/recipes/terraform/howto-custom-provider/), and in [Recipe configurations](https://github.com/radius-project/radius/blob/594faf60683351e4be2dee7309ebc369dfac26ad/test/functional-portable/corerp/noncloud/resources/testdata/corerp-resources-terraform-postgres.bicep#L32). -As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables in order to propagate secrets to my application developers. +As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables in order to propagate secrets to my application developers. -As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/extenders`, `Applications.Core/volumes`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. +As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. ## Desired user experience outcome @@ -95,7 +95,7 @@ As an application developer, I cannot reference a `secretStores` resource in the [existing feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers` resource definition so that Radius will inject secrets as environment variables into my container at deploy time so that credentials can be provided to the container for authentication, etc. This is a supported scenario in an existing feature, see [here](https://docs.radapp.io/reference/resource-schema/core-schema/container-schema/#container). -[proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Volumes` resource definition so that Radius will write the secret into a file on disk and mount that volume into the container at deploy time. I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. +[proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.containers` resource definition under the `volumes` object so that Radius will write the secret into a file on disk/memory and mount that volume into the container at deploy time. I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. [proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Extenders` resource definition so that Radius will use the password internally to authenticate into the resource at deploy time. I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. @@ -166,54 +166,59 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { } ``` -(b) Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/volumes` resource definition within the `app.bicep` application definition to write the secret into a file on disk and mount that volume into their container at deploy time. +(b) Developer references the `Applications.Core/secretStores` resource in their `Applications.Core/containers` resource definition under the `volumes` object within the `app.bicep` application definition to write the secret into a file on disk/memory with a specified file path and name, then mount that volume into their container at deploy time. ```diff -resource volume 'Applications.Core/volumes@2023-10-01-preview' = { - name: 'myvolume' +resource demo 'Applications.Core/containers@2023-10-01-preview' = { + name: 'demo' properties: { - application: app.id - kind: 'azure.com.keyvault' - resource: keyvault.id - secrets: { - mysecret: { -+ name: { -+ valueFrom: { -+ secretRef: { -+ source: azurekeyvaultsecrets.id -+ key: 'name' -+ } -+ } -+ } -+ version: { -+ valueFrom: { -+ secretRef: { -+ source: azurekeyvaultsecrets.id -+ key: 'version' -+ } -+ } -+ } -+ alias: { -+ valueFrom: { -+ secretRef: { -+ source: azurekeyvaultsecrets.id -+ key: 'alias' -+ } -+ } -+ } -+ encoding: { -+ valueFrom: { -+ secretRef: { -+ source: azurekeyvaultsecrets.id -+ key: 'encoding' -+ } -+ } -+ } + application: application + container: { + image: 'ghcr.io/radius-project/samples/demo:latest' + ports: { + web: { + containerPort: 3000 + } } + volumes: { + ephemeralVolume: { + kind: 'ephemeral' + mountPath: '/tmpfs' + managedStore: 'memory' ++ secrets: { ++ filePath: '/path/to/secret' // default is /var/run/secrets/ ++ fileName: 'secretfile.txt' // default is secretfile.txt ++ username: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'username' ++ } ++ } ++ } ++ } + } + persistentVolume: { + kind: 'persistent' + source: volume.id ++ secrets: { ++ filePath: '/path/to/secret' // default is /var/run/secrets/ ++ fileName: 'secretfile.txt' // default is secretfile.txt ++ username: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'username' ++ } ++ } ++ } ++ } + } } } } ``` +> Note: the`secrets`, `filePath`, and `fileName` properties are just a proprosal and may change during tech design. They should also be optional for the `volumes` property in `Applications.Core/containers` to write the secret into a file on disk/memory with a specified file path and name, with the default being `/var/run/secrets/` and `secretfile.txt` respectively. (c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` `Applications.Datastores/*`, or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: @@ -307,9 +312,9 @@ Step 3: Developer deploys the resources to Radius and the secrets required are e ## Key investments -### Feature 1: Add functionality to reference `Applications.Core/secretStores` to write into mounted `Applications.Core/volumes` resources +### Feature 1: Add functionality to reference `Applications.Core/secretStores` to write into volumes mounted onto `Applications.Core/containers` resources -Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Core/volumes` resources so that secrets can be securely managed for use in their application to be written to the volume and mounted at deploy time by Radius. +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Core/containers` resources within the `volumes` property so that secrets can be securely managed for use in their application to be written to the volume and mounted at deploy time by Radius. ### Feature 2: Add functionality to reference `Applications.Core/secretStores` to enable Radius to use internally for authentication into resources @@ -326,4 +331,7 @@ Add the ability for developers to reference values from their `Applications.Core - [x] Add more information on customers bringing in their own secrets, secrets stores resource currently supporting only k8s secrets -- *addressed in the spec* - [x] More clarity needed on the actual features that need to be implemented as the spec is somewhere in between vision doc and user scenarios descriptions. The document needs to clearly identify feature gaps and the priority order for addressing them in order for it to be actionable. - [x] The recipes section should be separated into its own design document to provide more specific and actionable guidance. -- [x] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. \ No newline at end of file +- [x] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. +- [x] Revisit the mounting to volumes case to ensure it aligns with existing implementations of volumes in containers. +- [ ] Add ability to reference secrets in Dapr resources +- [ ] Add ability to reference secrets in custom UDT resources \ No newline at end of file From 323740022b5540128df60fd07af25b352074605d Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Thu, 23 Jan 2025 16:05:36 -0800 Subject: [PATCH 16/19] address feedback from Jan 21 Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index b86bcf1e..5889335d 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -5,7 +5,7 @@ ## Topic Summary -This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. +This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, and `Applications.Dapr/*` resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. ### Top level goals @@ -35,7 +35,7 @@ Operators may have to do extra work to inject secrets as environment variables i ### Positive user outcome -As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource definitions so that Radius may securely manage secrets for use in my application to authenticate into those resources. +As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, and `Applications.Dapr/*` resource definitions so that Radius may securely manage secrets for use in my application to authenticate into those resources. As an operator, I want to ensure that the developers I support can securely leverage secrets I manage on their behalf for use in their application resources. Today, these secrets have to be stored in plain text within resources. @@ -82,11 +82,14 @@ Currently, Radius provides an `Applications.Core/secretStores` resource type tha - `Applications.Core/gateways` to manage [TLS certificates for HTTPS connections](https://docs.radapp.io/guides/author-apps/networking/tls/) - `Applications.Core/containers` to inject secrets as [environment variables into a container](https://docs.radapp.io/reference/resource-schema/core-schema/container-schema/#container) at deploy time - `Applications.Core/environments` for authentication into [private Recipe registries](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/), [custom Terraform Providers](https://docs.radapp.io/guides/recipes/terraform/howto-custom-provider/), and in [Recipe configurations](https://github.com/radius-project/radius/blob/594faf60683351e4be2dee7309ebc369dfac26ad/test/functional-portable/corerp/noncloud/resources/testdata/corerp-resources-terraform-postgres.bicep#L32). +- `Applications.Dapr/*` to reference [Dapr Secrets for use in Dapr components](https://docs.radapp.io/guides/author-apps/dapr/how-to-dapr-secrets/) -As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types. Thus, I have to do extra work to inject secrets as environment variables in order to propagate secrets to my application developers. +As an operator, I can create a `secretStores` resource to securely manage secrets for use in the Radius Environments I provide for my developers, which is handy to allow for authentication into private Recipe registries and custom Terraform Providers. However, the `secretStores` resource type is not yet supported by the `Applications.Core/extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, and `Applications.Dapr/*` resource types. Thus, I have to do extra work to inject secrets as environment variables in order to propagate secrets to my application developers. As an application developer, I cannot reference a `secretStores` resource in the `Applications.Core/extenders`, `Applications.Datastores/*`, and `Applications.Messaging/*` resource types to securely manage secrets for use in my application. Instead, I'm having to store my secrets in plain text within the `properties.secrets` field for each resource. This is a critical gap in the secret management capabilities of Radius that is hindering my ability to securely manage secrets for use in my containers. +As an application developer using Dapr components, I cannot reference a Radius `secretStores` resource in the `Applications.Dapr/*` resource types to securely manage secrets for use in my application. Instead, I'm having to create a Dapr secret store and manage the secrets in the Dapr secret store to be able to reference it in my `Applications.Dapr/*` resource. This limitation forces me to manage all my Dapr-related secrets in a Dapr secret store when I already have a Radius `secretStores` resource that I could use to manage all my secrets in one place. + ## Desired user experience outcome [existing feature] As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in accessing private Recipes. This is a supported scenario in an existing feature, specifically for private [Bicep](https://docs.radapp.io/guides/recipes/howto-private-bicep-registry/) and [Terraform](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/) Recipes. @@ -99,6 +102,8 @@ As an application developer, I cannot reference a `secretStores` resource in the [proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Extenders` resource definition so that Radius will use the password internally to authenticate into the resource at deploy time. I no longer have to store secrets as plain text in the `properties.secrets` field of my resource for authentication, etc. +[proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Dapr/*` resource definition so that Radius will use the Radius secret store to manage secrets for use in my Dapr components. I no longer have to create a Dapr secret store and manage the secrets in the Dapr secret store to be able to reference it in my `Applications.Dapr/*` resource. + [future feature] As a developer, I can specify a `Applications.Core/secretStores` in my custom user-defined resource once the [user-defined types](https://github.com/radius-project/design-notes/blob/main/architecture/2024-07-user-defined-types.md) feature is implemented. ### Detailed User Experience @@ -218,10 +223,11 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { } } ``` -> Note: the`secrets`, `filePath`, and `fileName` properties are just a proprosal and may change during tech design. They should also be optional for the `volumes` property in `Applications.Core/containers` to write the secret into a file on disk/memory with a specified file path and name, with the default being `/var/run/secrets/` and `secretfile.txt` respectively. +> Note: the`secrets`, `filePath`, `fileName` properties and default values are just proposals and may be changed during tech design. They should also be optional for the `volumes` property in `Applications.Core/containers` to write the secret into a file on disk/memory with a specified file path and name, with the proposed defaults being `/var/run/secrets/` and `secretfile.txt` respectively. -(c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders` `Applications.Datastores/*`, or `Applications.Messaging/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: +(c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Dapr/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: +In an extender resource: ```diff resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { name: 'twilio' @@ -245,6 +251,7 @@ resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { } ``` +In a datastore resource: ```diff resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { name: 'db' @@ -281,6 +288,7 @@ resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { } ``` +In a messaging resource: ```diff resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { name: 'rabbitmq' @@ -307,6 +315,36 @@ resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { } ``` +In a Dapr resource: +```diff +resource config 'Applications.Dapr/configurationStores@2023-10-01-preview' = { + name: 'configstore' + properties: { + environment: environment + application: app.id + resourceProvisioning: 'manual' + type: 'configuration.redis' + metadata: { + redisHost: { + value: '' + } + redisPassword: { ++ value: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } + } + } + version: 'v1' + } +} +``` +> Note: The proposal here is to follow the same `valueFrom` syntax as the `Applications.Core/containers` resource type for referencing Radius Secrets in the `Applications.Dapr/*` resource type, which deviates from the Dapr Secrets reference pattern that exists today. We'll leave it up to the technical design to decide whether to follow the existing Dapr Secrets reference pattern or to follow the `Applications.Core/containers` reference pattern. + Step 3: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables, written to a file on a volume and mounted to the container, or used as credentials for authentication into the extender, datastore, or messaging resource at deploy time. ## Key investments @@ -322,6 +360,12 @@ Add the ability for developers to reference values from their `Applications.Core > We should revisit the overall plan for provisioning types we plan to support on portable resources before implementing this change. There are some changes with UDT that haven't been solidified yet. +### Feature 3: Add functionality to reference `Applications.Core/secretStores` to enable Radius to manage secrets for use in Dapr components + +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Dapr/*` resources so that secrets can be securely managed for use in their Dapr components. + +> We need to reconcile the existing Dapr Secrets reference pattern with the `Applications.Core/containers` reference pattern before implementing this change. + ## Design Review Notes - [x] Considerations for `Applications.Core/secretstores` resource `type` values -- *this has been addressed by [PR #7816](https://github.com/radius-project/radius/pull/7816) and referenced in this feature spec doc* @@ -333,5 +377,5 @@ Add the ability for developers to reference values from their `Applications.Core - [x] The recipes section should be separated into its own design document to provide more specific and actionable guidance. - [x] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. - [x] Revisit the mounting to volumes case to ensure it aligns with existing implementations of volumes in containers. -- [ ] Add ability to reference secrets in Dapr resources +- [x] Add ability to reference secrets in Dapr resources - [ ] Add ability to reference secrets in custom UDT resources \ No newline at end of file From 85a24ff1d7e5b80d22302f99579f8818a75cb82b Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:20:33 -0800 Subject: [PATCH 17/19] add dapr and udt use cases Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 60 ++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index 5889335d..f97ce537 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -54,6 +54,10 @@ Maya is a developer who is building a microservice application that requires a T Aditi is a developer who is building a microservice application that requires a password to authenticate into a Twilio extender. She wants to securely manage the password for her application and thus creates a `Applications.Core/secretStores` resource containing the password. Aditi then references the `Applications.Core/secretStores` resource in her `Applications.Core/extenders` resource definition so that Radius will use the password internally to authenticate into the Twilio extender at deploy time. +### Scenario 4: Secrets are stored then used by User-Defined Types (UDTs) + +Kenneth is a developer who is building a microservice application that requires a password to authenticate into a custom user-defined resource. He wants to securely manage the password for his application and thus creates a `Applications.Core/secretStores` resource containing the password. Kenneth then references the `Applications.Core/secretStores` resource in his custom user-defined resource definition so that Radius may use the secret to set up authentication for the custom user-defined resource at deploy time. + ## Key dependencies and risks @@ -90,6 +94,8 @@ As an application developer, I cannot reference a `secretStores` resource in the As an application developer using Dapr components, I cannot reference a Radius `secretStores` resource in the `Applications.Dapr/*` resource types to securely manage secrets for use in my application. Instead, I'm having to create a Dapr secret store and manage the secrets in the Dapr secret store to be able to reference it in my `Applications.Dapr/*` resource. This limitation forces me to manage all my Dapr-related secrets in a Dapr secret store when I already have a Radius `secretStores` resource that I could use to manage all my secrets in one place. +As an application developer using custom user-defined resources, I cannot specify a `secretStores` resource in my custom user-defined resource to securely manage secrets for use in my custom UDT resource and application. + ## Desired user experience outcome [existing feature] As an operator, I can define an `Applications.Core/secretStores` resource and deploy it along with an Environment so that the developers I support can securely leverage secrets I manage on their behalf for use in accessing private Recipes. This is a supported scenario in an existing feature, specifically for private [Bicep](https://docs.radapp.io/guides/recipes/howto-private-bicep-registry/) and [Terraform](https://docs.radapp.io/guides/recipes/terraform/howto-private-registry/) Recipes. @@ -227,7 +233,7 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { (c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Dapr/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: -In an extender resource: +**In an extender resource:** ```diff resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { name: 'twilio' @@ -251,7 +257,7 @@ resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { } ``` -In a datastore resource: +**In a datastore resource:** ```diff resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { name: 'db' @@ -288,7 +294,7 @@ resource db 'Applications.Datastores/mongoDatabases@2023-10-01-preview' = { } ``` -In a messaging resource: +**In a messaging resource:** ```diff resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { name: 'rabbitmq' @@ -315,7 +321,7 @@ resource rabbitmq 'Applications.Messaging/rabbitmqQueues@2023-10-01-preview' = { } ``` -In a Dapr resource: +**In a Dapr resource:** ```diff resource config 'Applications.Dapr/configurationStores@2023-10-01-preview' = { name: 'configstore' @@ -343,9 +349,41 @@ resource config 'Applications.Dapr/configurationStores@2023-10-01-preview' = { } } ``` -> Note: The proposal here is to follow the same `valueFrom` syntax as the `Applications.Core/containers` resource type for referencing Radius Secrets in the `Applications.Dapr/*` resource type, which deviates from the Dapr Secrets reference pattern that exists today. We'll leave it up to the technical design to decide whether to follow the existing Dapr Secrets reference pattern or to follow the `Applications.Core/containers` reference pattern. +> Note: The proposal here is to follow the same `valueFrom` syntax as the `Applications.Core/containers` resource type for referencing Radius Secrets in the `Applications.Dapr/*` resource type, which deviates from the [Dapr Secrets reference pattern](https://docs.radapp.io/guides/author-apps/dapr/how-to-dapr-secrets/) that exists today to reference Dapr Secret Stores. We'll leave it up to the technical design to decide whether to follow the existing Dapr Secrets reference pattern or to follow the `Applications.Core/containers` reference pattern for Radius Secret Store resources. -Step 3: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables, written to a file on a volume and mounted to the container, or used as credentials for authentication into the extender, datastore, or messaging resource at deploy time. +**In a custom UDT resource:** +```diff +resource customtype 'Applications.Core/udt@2023-10-01-preview' = { + name: 'customtype' + properties: { + application: application + environment: environment + env:{ ++ URI: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'uri' ++ } ++ } ++ } + } + secrets: { ++ password: { ++ valueFrom: { ++ secretRef: { ++ source: authcreds.id ++ key: 'password' ++ } ++ } ++ } + } + } +} +``` +> Note: This scenario is a future feature since UDT is not fully implemented yet, nor is its schema finalized. The proposal here is to follow the same `valueFrom` syntax as the `Applications.Core/containers` resource type for referencing Radius Secrets in the `Applications.Core/udt` resource type, but this may change during tech design and implementation. + +Step 3: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables, written to a file on a volume and mounted to the container, used as credentials for authentication into the extender, datastore, messaging, or Dapr resource at deploy time, or used in the custom UDT resource at deploy time. ## Key investments @@ -364,7 +402,13 @@ Add the ability for developers to reference values from their `Applications.Core Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their `Applications.Dapr/*` resources so that secrets can be securely managed for use in their Dapr components. -> We need to reconcile the existing Dapr Secrets reference pattern with the `Applications.Core/containers` reference pattern before implementing this change. +> We need to reconcile the existing [Dapr Secrets reference pattern](https://docs.radapp.io/guides/author-apps/dapr/how-to-dapr-secrets/) with the `Applications.Core/containers` reference pattern before implementing this change. + +### Feature 4: Add functionality to reference `Applications.Core/secretStores` to enable Radius to manage secrets for use in custom UDT resources + +Add the ability for developers to reference values from their `Applications.Core/secretStores` resources in their custom UDT resources so that secrets can be securely managed for use in their custom UDT resources. + +> This feature is a future feature since UDT is not fully implemented yet, nor is its schema finalized. The proposal here is to follow the same `valueFrom` syntax as the `Applications.Core/containers` resource type for referencing Radius Secrets in the `Applications.Core/udt` resource type, but this may change during tech design and implementation. ## Design Review Notes @@ -378,4 +422,4 @@ Add the ability for developers to reference values from their `Applications.Core - [x] The ability to specify secret managers per environment is a feature that is out of scope for this feature spec and should be addressed as a separate feature. Other environment-wide concerns may include other things like federated identity, VPC, firewall rules, diagnostics, etc. - [x] Revisit the mounting to volumes case to ensure it aligns with existing implementations of volumes in containers. - [x] Add ability to reference secrets in Dapr resources -- [ ] Add ability to reference secrets in custom UDT resources \ No newline at end of file +- [x] Add ability to reference secrets in custom UDT resources \ No newline at end of file From 799c6c2e5025adeaeee1822d953cf46e4568e2a5 Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Fri, 24 Jan 2025 15:36:48 -0800 Subject: [PATCH 18/19] add dapr and udt use cases Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index f97ce537..b42d30f2 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -5,7 +5,7 @@ ## Topic Summary -This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, and `Applications.Dapr/*` resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. +This feature spec outlines the desired user experience for extending the use-cases of `Applications.Core/secretStores` to allow for referencing secret stores in `Applications.Core/containers`, `Applications.Core/extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, `Applications.Dapr/*`, and custom user-defined type (UDT) resources. The goal is to enable developers to securely manage secrets for use in their applications by referencing `Applications.Core/secretStores` in their resources. ### Top level goals @@ -15,6 +15,7 @@ This feature spec outlines the desired user experience for extending the use-cas - The ability to [reference secret stores in a Recipe](https://github.com/radius-project/roadmap/issues/59) is out of scope for this feature spec, i.e. *As an operator, I can reference an `Applications.Core/secretStores` in my Recipes so that I no longer have to store secrets as plain text in the `secrets` field of my Recipe's `output` object for authentication, etc.* - Today the `type` property in the `Applications.Core/secretStores` is an enum -- this feature spec does not propose to change the existing [implementation](https://github.com/radius-project/radius/pull/7816) of the `type` property in the `Applications.Core/secretStores` resource type. +- User defined types (UDTs) are not yet fully implemented, nor is their schema finalized -- this feature spec does not assert any opinions on how UDTs should be implemented, but rather proposes that once UDTs are implemented, the ability to reference `Applications.Core/secretStores` in UDTs should be supported. ## User profile and challenges From 65fc0c48d645599479d4ac98e1370b2115b6804f Mon Sep 17 00:00:00 2001 From: Will Tsai <28876888+willtsai@users.noreply.github.com> Date: Wed, 5 Mar 2025 20:38:18 -0800 Subject: [PATCH 19/19] address feedback from 20250305 Signed-off-by: Will Tsai <28876888+willtsai@users.noreply.github.com> --- resources/2024-07-secretstore-feature-spec.md | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/resources/2024-07-secretstore-feature-spec.md b/resources/2024-07-secretstore-feature-spec.md index b42d30f2..9bc32a43 100644 --- a/resources/2024-07-secretstore-feature-spec.md +++ b/resources/2024-07-secretstore-feature-spec.md @@ -111,7 +111,7 @@ As an application developer using custom user-defined resources, I cannot specif [proposed feature] As a developer, I can reference an `Applications.Core/secretStores` in my `Applications.Dapr/*` resource definition so that Radius will use the Radius secret store to manage secrets for use in my Dapr components. I no longer have to create a Dapr secret store and manage the secrets in the Dapr secret store to be able to reference it in my `Applications.Dapr/*` resource. -[future feature] As a developer, I can specify a `Applications.Core/secretStores` in my custom user-defined resource once the [user-defined types](https://github.com/radius-project/design-notes/blob/main/architecture/2024-07-user-defined-types.md) feature is implemented. +[future feature] As a developer, I can specify a `Applications.Core/secretStores` in my custom user-defined resource once the [user-defined types](https://github.com/radius-project/design-notes/blob/main/architecture/2024-07-user-defined-types.md) feature is implemented. This is tracked in a separate [feature request](https://github.com/radius-project/radius/issues/8736). ### Detailed User Experience @@ -232,7 +232,7 @@ resource demo 'Applications.Core/containers@2023-10-01-preview' = { ``` > Note: the`secrets`, `filePath`, `fileName` properties and default values are just proposals and may be changed during tech design. They should also be optional for the `volumes` property in `Applications.Core/containers` to write the secret into a file on disk/memory with a specified file path and name, with the proposed defaults being `/var/run/secrets/` and `secretfile.txt` respectively. -(c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Dapr/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: +(c) Developer references the `Applications.Core/secretStores` resource in their `Applications.Extenders`, `Applications.Datastores/*`, `Applications.Messaging/*`, or `Applications.Dapr/*` resource definition to securely manage secrets for use in their application. Radius then uses the secret to authenticate into the resource at deploy time, e.g. by injecting the necessary environment variables using the secret values to allow an application container to connect to that resource. The secrets might be referenced in the resources within the `app.bicep` application definition as follows: **In an extender resource:** ```diff @@ -241,9 +241,8 @@ resource twilio 'Applications.Core/extenders@2023-10-01-preview' = { properties: { application: application environment: environment - recipe: { - name: 'twilio' - } + resourceProvisioning: 'manual' + fromNumber: '222-222-2222' secrets: { + password: { + valueFrom: { @@ -359,16 +358,7 @@ resource customtype 'Applications.Core/udt@2023-10-01-preview' = { properties: { application: application environment: environment - env:{ -+ URI: { -+ valueFrom: { -+ secretRef: { -+ source: authcreds.id -+ key: 'uri' -+ } -+ } -+ } - } + resourceProvisioning: 'manual' secrets: { + password: { + valueFrom: { @@ -384,7 +374,7 @@ resource customtype 'Applications.Core/udt@2023-10-01-preview' = { ``` > Note: This scenario is a future feature since UDT is not fully implemented yet, nor is its schema finalized. The proposal here is to follow the same `valueFrom` syntax as the `Applications.Core/containers` resource type for referencing Radius Secrets in the `Applications.Core/udt` resource type, but this may change during tech design and implementation. -Step 3: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables, written to a file on a volume and mounted to the container, used as credentials for authentication into the extender, datastore, messaging, or Dapr resource at deploy time, or used in the custom UDT resource at deploy time. +Step 3: Developer deploys the resources to Radius and the secrets required are either injected into the container as environment variables, written to a file on a volume and mounted to the container, used as credentials for authentication into the extender, datastore, messaging, or Dapr resource at deploy time (e.g. injected as env variables into the container), or used in the custom UDT resource at deploy time. ## Key investments