Repository navigation
docs: configure verified PostgreSQL TLS in the getting-started tutorial - #2054
nellshamrell wants to merge 3 commits into
Conversation
Document operator-owned server and CA Secrets, certificate lifecycle, and rollout readiness. Refresh the generated TLS reference and embedded demo configuration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Nell Shamrell-Harrington <nells@microsoft.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Static Web App Preview
Deployed from commit |
|
The sample-sync check is failing because this PR includes the updated PostgreSQL template from radius-project/samples#2700, while CI compares against the published The only differing file is Once the samples companion merges into |
Approver assessment1. OrientationThe implementation is coherent, but this PR is not ready to merge independently. It teaches the client side of the PostgreSQL TLS change and depends on the recipe and samples companions becoming available. Review of #2054, head
2. What the code changesThe diff contains three files, with 52 additions and five deletions. It matches the stated scope.
There are no application-code, dependency, generator, or workflow changes. The removal of highlighted sample line numbers avoids leaving incorrect highlights after inserting the TLS configuration. 3. Data and control flowThe intended path is:
The names agree across the tutorial and application: the database is I also checked the companion server Recipes: both expect 4. Key implementation decisionsDoes this configure verified TLS, or merely encrypted traffic?Code's answer: it sets Why it matters: encryption alone does not establish which server the client reached. Certificate-chain validation establishes trust in the issuer; hostname verification checks that the certificate identifies the requested server. The existing demo constructs a PostgreSQL URL without an explicit TLS override and passes it to Alternative: modify the application to construct an explicit TLS configuration object. That would require application tests and image publication. For this bounded sample change, configuration is simpler. Reported live tests include rejection of the wrong CA and hostname, which is stronger evidence than a successful connection alone. Who owns the certificates?Code's answer: the operator owns both certificate Secrets; the application owns its separate password Secret. The client never receives the server private key. See tutorial, lines 42–48 and cleanup, lines 87–90. Why it matters: deleting the application must not silently delete externally managed certificates. Conversely, users need explicit cleanup instructions because those Secrets survive application deletion. This boundary is sound. Generating a CA inside the sample would add private-key management and obscure the distinction between a demonstration certificate and an organization's trusted issuer. What proves deployment success?Code's answer: Why it matters: successful submission through It still does not prove the demo client trusts the certificate. The server probe uses its own connection settings, not the application's mounted CA and hostname verification. A successful todo operation remains the stronger end-to-end check. 5. Failure handling and operationsMissing or invalid server certificate material prevents the companion server from serving successfully; it does not silently fall back to plaintext. Missing client CA material prevents the intended verified connection. The tutorial correctly rejects Rotation is manual. The operator updates the server Secret and restarts the database Deployment; clients must restart when their startup-loaded CA changes. The tutorial states this at line 52. The same paragraph warns that replacement Pods start with empty databases because these Recipes do not provision durable storage. This is important: reverting the documentation or template cannot recover lost data. Recovery requires a backup. 6. Security and compatibilityThe new client mount contains public trust material, not a private key. The application's password flow remains unchanged, including the existing warning that the demo displays injected connection variables. The template deliberately becomes incompatible with plaintext-only PostgreSQL Recipes. The tutorial makes that explicit at line 50. It also preserves TLS on an The preceding installation page selects edge CLI installers for the script-based paths. That supports the intended unreleased scope, but it does not prove that an existing environment has refreshed its Recipe Pack. Recipe publication and environment configuration remain deployment prerequisites. No Azure Recipe implementation changes appear in this PR. The Kubernetes-specific CA mount should not be interpreted as a portable Azure deployment example. 7. Test evidence and gapsVerified during this review:
Reported evidence, not independently rerun here: local integration checks exercised both recipe drivers, required/optional policies, actual database operations, wrong-CA and wrong-hostname rejection, and password precedence. Limits: build and compiler checks cannot prove the published Recipe Pack or current demo image behaves correctly. This review checked the generated text against its source but did not rerun the full generation pipeline or deploy a cluster. The sole failing CI check is sample synchronization. It compares against published 8. Risk register
9. FindingsBlocking findings: no code defect established. There is a concrete merge dependency: radius-project/samples#2700 must reach Non-blocking concern: tutorial lines 58–65 stop at database readiness and visible connection entries. Add an explicit create/list/delete todo step so readers verify the newly introduced client-trust configuration, rather than only resource discovery. Strengths: private-key separation, accurate Secret ownership, explicit data-loss warnings, and configuration-only reuse of the existing client. Residual risks: mutable published artifacts and previously initialized environments can diverge from the tested combination. 10. Approval recommendationComment. The implementation is suitable for the intended Kubernetes tutorial, but I would hold approval until the samples dependency clears and the compatible recipe publication path is confirmed. Once those gates are satisfied, the remaining tutorial verification improvement is non-blocking. 11. Coverage and confidenceRead all three changed files and the merge-base diff; inspected the issue, PR discussion, checks, sample client path, companion certificate/readiness contracts, Container Recipe mappings, and publication/sync behavior. Covered ownership, trust, failure behavior, cleanup, compatibility, and generated-output consistency. Performance, concurrency, and database-schema migration review were not applicable to this configuration/documentation diff. No files were changed and no approval was submitted. Confidence: medium. Source consistency is strong; live integration evidence is reported rather than independently reproduced, and publication dependencies remain unresolved. |
Restore sample highlights, add self-contained development certificate setup and cleanup, and verify the demo connection with todo operations. Defer the generated reference update to the authoritative bot pipeline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Nell Shamrell-Harrington <nells@microsoft.com>
|
Added a create/refresh/delete todo step after opening the demo. This checks the client's database connection rather than treating connection metadata or database readiness as proof that client TLS trust works. |
| Deploy the updated definition from its published URL. The `--parameters` argument sets the database password, and `$(openssl rand -hex 16)` generates a random value on each deploy. This works in Bash and Zsh; in PowerShell, generate the value separately and pass it in: | ||
| ### Prepare PostgreSQL TLS | ||
|
|
||
| Before deploying this edge sample, use a PostgreSQL Kubernetes Recipe with TLS support and prepare the operator-owned certificates. The default `required` policy rejects plaintext TCP connections. `optional` permits plaintext but still requires a server certificate; it is not a workaround for missing TLS configuration. |
There was a problem hiding this comment.
nit (non-blocking): after radius-project/resource-types-contrib#419 (0e9d2f7), the Recipes generate a self-signed certificate when <name>-tls is absent, so optional no longer requires an operator certificate. The tutorial still needs one because the demo uses verify-full and needs a CA it trusts. Could we give that reason here instead? radius-project/samples#2700 now words it this way.
Summary
Update the PostgreSQL getting-started tutorial for TLS-enforcing Kubernetes Recipes. Add development certificate commands, a server TLS Secret, public-only client CA trust, and verified TLS. Restore sample highlighting, make cleanup work in a new terminal, and verify the connection with todo operations.
The embedded sample matches the samples companion. Leave the generated schema reference to the existing bot pipeline.
Reason for change
Related to radius-project/resource-types-contrib#337.
Merge after radius-project/resource-types-contrib#419 and radius-project/samples#2700. Confirm compatible recipe artifacts and default-pack references are available before publishing the tutorial.
Sample-sync remains blocked until the samples companion lands on
edge. Older-version docs and Azure behavior are unchanged.How to test
With Node.js and Go installed:
Expect a successful build and highlighted sample. Compare the embedded template with the samples companion. Follow the tutorial with TLS-capable Recipes, wait for rollout readiness, then create, refresh, and delete a todo.
Local
npm --prefix docs run build, focused spelling, certificate/hostname checks, offline Secret-shape checks, and cleanup-command checks passed. Earlier integration verified database operations; it was not rerun for these documentation edits.Only rerun
download-sample-app.shafter the samples companion lands onedge; expect no drift. Remote sync is not yet passing.File change summary
docs/content/getting-started/add-connection/_index.mddocs/static/samples/demo/app-postgresql.bicep