Skip to content

Commit 679774a

Browse files
committed
Align Kubernetes postgreSQL recipe secret handling with Azure
The Kubernetes recipe returned `secrets: { password, connectionString }`, but the postgreSqlDatabases type declares no `secrets` property, so neither value was reachable from an application. The Azure recipe in recipe-packs/azure/aks-recipepack.bicep maps only `host`, and deliberately does not use the `outputs.secrets` mechanism it uses one entry away for redisCaches. That distinction is intentional. PostgreSQL administrator credentials flow into the recipe as user-supplied properties, so there is nothing to hand back; Redis access keys are generated by the infrastructure and must flow out. Drop the unreachable secrets output so both platforms agree, and document the reasoning. Also emit `port` as a string to match `type: string` on the resource type, and update test/app.bicep to show the supported pattern: the application authors its own Radius.Security/secrets resource and binds it into the container with valueFrom.secretKeyRef. A connection cannot carry the password (sensitive properties redact to null and are skipped by the containers recipe), so this is the only way to deliver it, and it keeps the value out of the pod spec and off the container resource, where env values are stored unencrypted. Signed-off-by: Will Smith <willdavsmith@gmail.com>
1 parent 65d8ba8 commit 679774a

2 files changed

Lines changed: 46 additions & 8 deletions

File tree

Data/postgreSqlDatabases/recipes/kubernetes/bicep/kubernetes-postgresql.bicep

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,16 @@ resource svc 'core/Service@v1' = {
188188
}
189189

190190
//////////////////////////////////////////
191-
// Output Radius result
191+
// Output Radius result
192+
//
193+
// No `secrets` output: the administrator credentials flow *into* this Recipe as
194+
// user-supplied properties, so there is nothing for the Recipe to hand back. An
195+
// application that needs the password for a consuming container already holds it
196+
// and should author its own Radius.Security/secrets resource, binding it with
197+
// `valueFrom.secretKeyRef` (see test/app.bicep). This matches the Azure recipe in
198+
// recipe-packs/azure/aks-recipepack.bicep, which maps only `host`. Contrast with
199+
// redisCaches, where the access key is generated by the infrastructure and so is
200+
// returned via `outputs.secrets`.
192201
//////////////////////////////////////////
193202

194203
output result object = {
@@ -204,11 +213,8 @@ output result object = {
204213
)
205214
values: {
206215
host: '${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local'
207-
port: port
216+
// `port` is declared `type: string` on the Resource Type, so emit a string.
217+
port: string(port)
208218
database: database
209219
}
210-
secrets: {
211-
password: password
212-
connectionString: 'postgresql://${username}:${password}@${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local:${port}/${database}'
213-
}
214220
}

Data/postgreSqlDatabases/test/app.bicep

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,35 @@ extension radius
33
@description('The ID of your Radius Environment. Set automatically by the rad CLI.')
44
param environment string
55

6-
@description('Database admin password. Set on the resource `password` property (x-radius-sensitive), so Radius encrypts it at rest and injects it decrypted into the Recipe as the flexible server administrator password.')
6+
@description('Database admin password. Set on the `password` property of the database (x-radius-sensitive, so Radius encrypts it at rest and injects it decrypted into the Recipe) and stored in a Radius.Security/secrets resource for the consuming container to bind by reference.')
77
@secure()
88
param password string
99

1010
resource app 'Radius.Core/applications@2025-08-01-preview' = {
11-
name: 'postgresql-azure-test'
11+
name: 'postgresql-test'
1212
properties: {
1313
environment: environment
1414
}
1515
}
1616

17+
// The password is also needed by the consuming container. Store it in a
18+
// Radius.Security/secrets resource rather than passing it to the container as a
19+
// plain `env` value: `data.value` is x-radius-sensitive (encrypted at rest,
20+
// redacted on reads), whereas a container `env.value` is stored unencrypted on
21+
// the container resource and rendered literally into the Pod spec.
22+
resource dbCreds 'Radius.Security/secrets@2025-08-01-preview' = {
23+
name: 'postgresql-credentials'
24+
properties: {
25+
environment: environment
26+
application: app.id
27+
data: {
28+
password: {
29+
value: password
30+
}
31+
}
32+
}
33+
}
34+
1735
resource postgresql 'Radius.Data/postgreSqlDatabases@2025-08-01-preview' = {
1836
name: 'postgresql'
1937
properties: {
@@ -34,6 +52,20 @@ resource democontainer 'Radius.Compute/containers@2025-08-01-preview' = {
3452
containers: {
3553
demo: {
3654
image: 'ghcr.io/radius-project/samples/demo:latest'
55+
// Host, port, and database arrive automatically as
56+
// CONNECTION_POSTGRES_* env vars from the connection below. Only the
57+
// password needs wiring, and it is bound by reference so the value
58+
// never lands in the Pod spec or on this container's state.
59+
env: {
60+
POSTGRES_PASSWORD: {
61+
valueFrom: {
62+
secretKeyRef: {
63+
secretName: dbCreds.name
64+
key: 'password'
65+
}
66+
}
67+
}
68+
}
3769
ports: {
3870
web: {
3971
containerPort: 3000

0 commit comments

Comments
 (0)