diff --git a/03-DESIGN/01-to-be/16-module-coverage.md b/03-DESIGN/01-to-be/16-module-coverage.md index 2db5f48..e2a2642 100644 --- a/03-DESIGN/01-to-be/16-module-coverage.md +++ b/03-DESIGN/01-to-be/16-module-coverage.md @@ -119,15 +119,16 @@ the consumer's side did not refuse, it just gave two of the three no credential. written to date had one consumer per node, which is the natural shape of a small test and not the shape of a machine. -**A consumer still cannot build a connection string** -([`023`](../../04-ISSUES/023-a-consumer-cannot-build-a-connection-string/00-report.md), open). It -is given its own password in whatever shape its configuration needs, and the host, port and user -name are still out of reach: the user name is invented by the provisioner and recorded nowhere, -and the bound values sit in a JSON document that an application reading `KEY=value` cannot use. +**A consumer could not build a connection string** +([`023`](../../04-ISSUES/023-a-consumer-cannot-build-a-connection-string/00-report.md), fixed). It +had its password in the right shape and the host, port and user name were out of reach: the user +name was invented by the provisioner and recorded nowhere, and the bound values sat in a JSON +document that an application reading `KEY=value` cannot use. -The asymmetry is worth stating, because it is backwards. **The secret is the hard case** — the -mesh must not be able to read it — and the secret is the part that now arrives. The host and port -are ordinary facts held in the clear, and they are the ones stuck. +The asymmetry was backwards, which is what made it worth stating. **The secret is the hard case** — +the mesh must not be able to read it — and the secret was the part that already arrived. The host +and port are ordinary facts held in the clear, and they were the ones stuck. Both halves came from +the same thing: the mesh knew something and did not say it. ## What the survey found that is not about coverage diff --git a/04-ISSUES/023-a-consumer-cannot-build-a-connection-string/00-report.md b/04-ISSUES/023-a-consumer-cannot-build-a-connection-string/00-report.md index 0bbb280..c9853f6 100644 --- a/04-ISSUES/023-a-consumer-cannot-build-a-connection-string/00-report.md +++ b/04-ISSUES/023-a-consumer-cannot-build-a-connection-string/00-report.md @@ -1,8 +1,8 @@ --- -status: located +status: fixed opened: 2026-09-01 located-in: [mesh-control] -fixed-by: +fixed-by: mesh-control 122680b amended-design: --- @@ -77,3 +77,35 @@ was fixed. Keycloak, Gitea, Mailu and MinIO all have manifests that parse and resolve, and none of them can start. This is what stands between the module set and a running one. + +## Fixed + +Both halves had the same cause: **the mesh knew something and did not say it.** + +**Who a consumer is, said once.** `ConsumerIdentity(node, module)` is one derivation, sent to the +provider in its grant and to the consumer in its binding — so the two agree by construction rather +than by two conventions that happened to match on the day they were written. The provisioners now +use the name they are given and **refuse to invent one** if the mesh says nothing: falling back to +a name of their own would create a login the consumer could never guess, and everything would +report success. They also refuse a name that does not carry the mesh's prefix, because that prefix +is how withdrawal finds what it made. + +**Bound values reach the file that needs them.** `${bound:provision:key}` is the symmetric twin of +the sealed placeholder and simpler: these values are not secret, so the control plane fills them +in before sending, and the host gains no field and learns no format. `at`, `as` and `from` are +true of any provision; every other key comes from what the provider said it *serves*, so the +control plane still learns nothing about what a `postgres-database` is. + +Keycloak and Gitea now produce complete connection strings — asserted from the manifests on disk, +checking that every part is filled, that no placeholder survives as a value, and that the password +is still a hole only the host can close. + +### Also found, and separate + +The lab run that was meant to prove this failed in a way that looked like the fix being wrong: a +rotation test could not authenticate against a real database. The cause was that the suite +rebuilt the control plane's image and not the provisioner's, so a run with an image built that +minute used a provisioner built the day before. Fixed in `mesh-lab`; it is +[`005`](../005-pipeline-test-harness-unbuildable/00-report.md)'s family — a rebuild covering +most of what a run uses is worse than one covering none, because the run that follows it is +believed.