From 146fd6b3a802a03b92054e410cfca01690eafc14 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 26 Sep 2026 16:47:06 +0200 Subject: [PATCH] Issue 124: a consumer cannot be told a value its provider derived for it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The object store derives each consumer's bucket from the login the mesh minted, and never reads the one a definition named. The consumer still has to tell its own software which bucket to use, and has no way to be told: bound values come from the provider's serves, which is a literal block identical for every consumer, and a provisioner returns nothing. So all three consumers wrote the answer down by hand and one of them wrote the predecessor's bucket — a key scoped to one bucket and software asking for another, which reads like a credential fault and is not one. Records the general shape: any interface where the provider names the resource forces the consumer to reproduce the provider's rule, kept in agreement by hand and checked by nothing. --- .../00-report.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 04-ISSUES/124-a-consumer-cannot-be-told-what-its-provider-derived/00-report.md diff --git a/04-ISSUES/124-a-consumer-cannot-be-told-what-its-provider-derived/00-report.md b/04-ISSUES/124-a-consumer-cannot-be-told-what-its-provider-derived/00-report.md new file mode 100644 index 0000000..2df48fb --- /dev/null +++ b/04-ISSUES/124-a-consumer-cannot-be-told-what-its-provider-derived/00-report.md @@ -0,0 +1,65 @@ +--- +status: located +opened: 2026-09-26 +located-in: [mesh-controller internal/catalogue/declaration.go, mesh-sdk src/provisioner, mesh-catalog modules/minio] +fixed-by: +amended-design: +--- + +# 124 — A consumer cannot be told a value its provider derived for it, so it transcribes one + +## What was observed + +The object-store interface gives each consumer a bucket. The provider **derives** which one: it +takes the login the mesh minted for that consumer and normalises it into a bucket name, then creates, +checks and removes exactly that. Its own comment states the reasoning — derived from the login, so +teardown recomputes it with nothing to persist — and it never reads the bucket a consumer's +definition named. + +The consumer still has to tell its own software which bucket to use. It has no way to be told, so +all three consumers wrote the answer down by hand. Two transcribed it correctly. The third named the +predecessor's bucket, while the key the mesh scopes for it admits only the derived one: it would have +authenticated successfully and been refused on every object, which reads like a credential fault and +is not one. That was found by reading, not by running, and it was filed as part of the fix. + +## Why the value cannot arrive + +A definition may interpolate five things: a secret, a seat, a port, a machine fact, and a **bound** +value — what a provider said a consumer must know. Everything about the arrangement is already +delivered that way: the endpoint, the port, the region, the login itself. + +The bound values come from what the provider `serves`, and **`serves` is a literal block in the +provider's definition**: the same values for every consumer. A value derived *per consumer* has no +way into it. Nothing else can carry it either — a provisioner's contract takes the provision and +returns nothing, so what it derived stays inside it. + +So the mesh has a value it computed, a consumer that needs exactly that value, and no channel +between them. The gap is not that the answer is unknown; it is that the answer cannot be passed. + +## Why it matters beyond this instance + +Every interface where the provider names the resource has this shape. A database provisioner that +prefixed database names, a queue provider that scoped vhosts, an object store that derives buckets — +each would force the consumer to reproduce the provider's rule in its own definition. That is a copy +of somebody else's logic, kept in agreement by hand, which is the failure +[issue 119](../119-a-module-definition-decides-where-its-files-live/00-report.md) records for paths +and this one records for names. + +It also shifts a rule out of the place that can enforce it. The provider knows its own naming rule +and can refuse a bad one; a transcription in a consumer's definition is a string, and no check +compares it to what the provider will actually create. The one wrong instance was well-formed. + +## Open questions + +- Should a provider be able to return consumer-visible values from provisioning — the natural + channel, since the provider is what derived them, but it means a grant carries data the provider + wrote rather than only data the mesh minted. +- Or should `serves` be able to say a value is derived from the consumer's identity, with the + mesh performing the derivation — which keeps the provider declarative, and requires the mesh to + know normalisation rules belonging to somebody else's protocol. It already knows one: the identity + limit is 20 characters *because* of what an object store's access key accepts. +- Either way: should a consumer that names a resource its provider will not use be **refused** rather + than ignored? The contributed bucket was read by nothing, and looked authoritative for months. +- What would have caught the wrong instance? A test that resolves a consumer's grant and compares the + bucket in its own configuration against the one the provider would create is a check that could + exist today, for any interface, without the mechanism above.