Commit Graph

5 Commits

Author SHA1 Message Date
Stéphane Tailland 613de34bd2 Stop caching reads on a read-write API
The proxy cache held every GET on the whole service for 60 seconds, and these
APIs accept writes. Kong's proxy cache has no invalidation on write: a POST
that changes a product passes through the same gateway, and the gateway goes on
serving the value it captured before it, for up to a minute, with nothing in the
response saying so.

It produced a real wrong answer. An agent woken by a stock event read the figure
from before that event and reported, in one sentence, "68 in stock, above the
threshold" and "it crossed the threshold, from 68".

The manifest is kept, unreferenced, carrying the reason — so reinstating it is a
decision rather than a rediscovery.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 08:26:25 +02:00
Stéphane Tailland e9997c360e feat(mcp): authorise tool-call parameters, not just the tool name
The ACL answers 'may this identity call create-product'. Nothing answered 'may
it call it with these arguments' — write authorises writing, not this
particular record. And the read cap counts calls, so one call asking for a
hundred thousand rows cost the same as one asking for ten.

The OPA plugin sends the decoded JSON-RPC body, so the decision point sees the
tool name and its arguments. The policy lives once in k8s-platform/opa and every
domain asks the same server.

Enforced at the gateway rather than in an agent, because an agent that has been
talked into something is the case this exists for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 18:09:16 +02:00
Stéphane Tailland cc3dc35c0e feat(mcp): cap read volume per caller identity
A scope authorises a read and says nothing about volume. An agent reads a
thousand records in seconds where a person clicks ten, and until now nothing
noticed: the token is valid, the tool is permitted, the ACL passes. That gap
stopped being theoretical the day an autonomous run started reading the whole
catalog on a schedule.

identifier: credential keys the counter on the sub claim — the end user,
whoever is asking on their behalf — so an agent looping under one person's
identity spends that person's budget and cannot spend everyone's. Verified on
catalog: pm-user and ro-user hold separate counters.

Per-route namespace, so a busy domain cannot exhaust another's.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 18:05:48 +02:00
Stéphane Tailland a4967d13ee Addition of MCP server 2026-08-23 15:00:57 +02:00
Stéphane Tailland 66565367f1 Build customers-api REST layer (Layer 3), mirroring catalog-api
8 routes over Customer + orders/payments sub-resources, proxying to
classic-models-api. openid-connect with RFC 8693 token exchange to
classic-models-api audience, rate-limiting, proxy-cache, audit-log —
same plugin set and structure as catalog-api's REST surface.

Not deployed: dev/gitrepository.yaml points at a gitea repo that
doesn't exist yet (kong-customers-api.git, 404). No MCP layer yet
either, unlike catalog-api.
2026-08-23 14:34:47 +02:00