Files
hq/04-ISSUES/124-a-consumer-cannot-be-told-what-its-provider-derived/00-report.md
jochen 146fd6b3a8 Issue 124: a consumer cannot be told a value its provider derived for it
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.
2026-09-26 16:47:06 +02:00

3.9 KiB

status, opened, located-in, fixed-by, amended-design
status opened located-in fixed-by amended-design
located 2026-09-26
mesh-controller internal/catalogue/declaration.go
mesh-sdk src/provisioner
mesh-catalog modules/minio

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 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.