mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
The least-privilege half of the criterion could not hold as built. provision_mcp.py creates the endpoint owner's workspace through CoreHandler().create_workspace, which makes that account its ADMIN, and 2.3.3 knows only ADMIN and MEMBER - both write table data. There is no read-only workspace role to demote to, so mutating_tools_enabled: false bounded nothing while create_rows, update_rows and delete_rows sat in the served allowlist. The adapter's contract simply omits them: a client calling one is refused with DENY_UNKNOWN_TOOL. Omission is the mechanism, since passthrough.py refuses to load a contract that lists a mutating tool while mutations are off. The other ten stay recorded under upstream_serves so a version bump enabling one shows up as drift rather than as a silently wider surface. The transport was what reverted this twice. Baserow speaks classic HTTP+SSE, where a GET opens the response stream and the stream names a second URL for requests, while the adapter only ever spoke Streamable HTTP. adapter.upstream_transport selects sse.py and defaults to streamable_http, so no existing provider changes. The endpoint key stops being a client credential. Clients present credentials.mcp_bearer to the sidecar; the key reaches the sidecar as ADAPTER_UPSTREAM_PATH_KEY and is spliced in percent-encoded, so it never enters the rendered contract and a key carrying a separator cannot open a path of its own. Deploy is green: the probe reached list_databases over SSE, the served surface matched the contract, and the sidecar proved it reaches only its provider.
18 lines
627 B
YAML
18 lines
627 B
YAML
---
|
|
credentials:
|
|
secret_key:
|
|
description: Django SECRET_KEY for Baserow
|
|
algorithm: alphanumeric
|
|
validation:
|
|
min_length: 50
|
|
mcp_bearer:
|
|
description: Bearer an MCP client presents to the Baserow adapter sidecar. Distinct from the endpoint key the sidecar presents upstream, because reaching
|
|
Baserow says nothing about who called the adapter.
|
|
algorithm: alphanumeric
|
|
validation: "^[A-Za-z0-9]{32,}$"
|
|
length: 48
|
|
mcp_endpoint_key:
|
|
description: URL-path secret of the MCP endpoint, stored in MCPEndpoint.key (varchar 32)
|
|
algorithm: random_hex_16
|
|
validation: "^[a-f0-9]{32}$"
|