From 1887d90821d52c66ca4d357679852cd48159ae76 Mon Sep 17 00:00:00 2001 From: Michal Date: Fri, 17 Apr 2026 23:54:46 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20scrub=20MCPLOCAL=5FMCPD=5FTOKEN=20?= =?UTF-8?q?=E2=80=94=20pod=20has=20no=20persistent=20mcpd=20identity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The earlier plan recommended an MCPLOCAL_MCPD_TOKEN env var so the pod would have a ServiceAccount session into mcpd. It's unnecessary: the pod forwards every inbound client bearer (mcpctl_pat_...) verbatim to mcpd for all downstream calls — both introspect and project discovery. mcpd's auth middleware dispatches on the prefix and resolves the McpToken principal directly. No pod secret, no rotation story. Updates: - serve.ts header: explicit "identity model" section calling this out so future readers don't restore the env var thinking it's missing. - docs/mcptoken-implementation.md: drop the "mount MCPLOCAL_MCPD_TOKEN" Pulumi guidance and the "dedicated ServiceAccount" follow-up item; state the correct image URL (internal 10.0.0.194 registry) and the gated-vs-ungated rule for LLM config mounts. No runtime code changes — serve.ts never actually required the token; this just fixes the documentation and the header comment. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/mcptoken-implementation.md | 5 +++-- src/mcplocal/src/serve.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/mcptoken-implementation.md b/docs/mcptoken-implementation.md index 9b08847..f2f24f1 100644 --- a/docs/mcptoken-implementation.md +++ b/docs/mcptoken-implementation.md @@ -126,8 +126,9 @@ The extracted `parseRoleBinding` helper is what PR 3's `mcpctl create mcptoken - ### Deploy-time steps still owed (outside this repo) -- **Pulumi (`../kubernetes-deployment`, stack `homelab`)** — add a `Deployment` named `mcplocal` in ns `mcpctl` pointing at the new image, a `Service` named `mcp` (port 3200→80), an `Ingress` for `mcp.ad.itaz.eu` with TLS via the existing cluster-issuer, a PVC `mcplocal-cache` (10Gi RWO), a Secret `mcplocal-env` with `MCPLOCAL_MCPD_URL` + `MCPLOCAL_MCPD_TOKEN`, and a NetworkPolicy mirroring mcpd's. `fulldeploy.sh` already runs `pulumi preview` first and halts on drift. -- **mcplocal's own identity** — recommend minting a dedicated `ServiceAccount:mcplocal-http` subject in mcpd with a non-expiring session token and putting it in `MCPLOCAL_MCPD_TOKEN`. The current session-minting path expires after 30d. +- **Pulumi (`../kubernetes-deployment`, stack `homelab`)** — add a `Deployment` named `mcplocal` in ns `mcpctl` pointing at `10.0.0.194:3012/michal/mcplocal:latest` (internal registry), a `Service` named `mcp` (port 3200→80, ClusterIP), an `Ingress` for `mcp.ad.itaz.eu` with TLS via the existing cluster-issuer, a PVC `mcplocal-cache` (10Gi RWO, mounted `/var/lib/mcplocal/cache`), and a NetworkPolicy mirroring mcpd's. Required env: **just `MCPLOCAL_MCPD_URL`** (point at `http://mcpd.mcpctl.svc.cluster.local:3100`). Optionally `MCPLOCAL_TOKEN_POSITIVE_TTL_MS` / `MCPLOCAL_TOKEN_NEGATIVE_TTL_MS` for stricter revocation. `fulldeploy.sh` already runs `pulumi preview` first and halts on drift. +- **No pod-level secret required** (revised from earlier draft) — the pod has no persistent identity to mcpd. Every inbound `Authorization: Bearer mcpctl_pat_…` is forwarded verbatim to mcpd, and mcpd's auth middleware resolves the McpToken principal. This eliminates the original `MCPLOCAL_MCPD_TOKEN` secret and its rotation story. Trade-off: a token with `--rbac=empty` can't read `/api/v1/projects/:name/servers`, but it also can't meaningfully serve MCP, so this is the right failure mode. See `src/mcplocal/src/serve.ts` header comment. +- **LLM provider config** — if any project served by this pod is `gated: true`, mount your `~/.mcpctl/config.json` as a ConfigMap at `/root/.mcpctl/config.json`. Ungated projects (proxyModel `content-pipeline` or no LLM-driven stages) need nothing. ### Test stats diff --git a/src/mcplocal/src/serve.ts b/src/mcplocal/src/serve.ts index 8b16314..9aad665 100644 --- a/src/mcplocal/src/serve.ts +++ b/src/mcplocal/src/serve.ts @@ -9,6 +9,14 @@ * - Requires MCPLOCAL_MCPD_URL to point at mcpd inside the cluster. * - Registers a token-auth preHandler on `/projects/*` and `/mcp`. * - FileCache directory honours MCPLOCAL_CACHE_DIR (wired via project-mcp-endpoint). + * + * Identity model: **the pod has no persistent identity to mcpd.** Every + * inbound request's `Authorization: Bearer mcpctl_pat_…` is forwarded + * verbatim for all downstream mcpd calls (introspect + project + * discovery). mcpd's auth middleware dispatches on the `mcpctl_pat_` + * prefix and resolves the McpToken principal. As a result there is + * deliberately no MCPLOCAL_MCPD_TOKEN env var — adding one would only + * create a rotation problem for a state we don't need. */ import { McpRouter } from './router.js'; import { createHttpServer } from './http/server.js';