Skip to content

Add authentication to the datastore MCP server (recommend user_oidc / Keycloak) #45

@ausbru87

Description

@ausbru87

Summary

The datastore MCP server (deploy/datastore-mcp/) is currently registered in Coder with auth_type: none and, by its own design comment (server/main.go lines 8-11), deliberately does not validate the inbound Authorization header. It is reachable only in-cluster (datastore-mcp.coder-demo-mcp.svc.cluster.local:8000, ClusterIP, no ingress), so today's exposure is limited to cluster-internal callers, but it has no authentication of its own.

This issue tracks adding authentication, ideally identity-aware auth tied to Keycloak now that all Coder logins are Keycloak-only.

Options considered

Option What Difficulty
A. Shared secret (custom_headers / api_key) coderd sends a static header; server compares to an env secret Low (~1-2 hrs). Transport auth only, no per-user identity
B. Per-user Keycloak identity (user_oidc) coderd forwards the calling user's Keycloak OIDC access token as Bearer (coderd/mcp.go oidcMCPTokenSource); server validates the JWT against Keycloak JWKS Medium (~0.5-1 day). Recommended
C. Per-user identity + row-level data scoping Option B plus mapping Keycloak group claims (/alpha, /bravo) to allowed tables/rows (Postgres RLS) High (days). Data-authorization project

Recommended approach: B (user_oidc)

Reuses the existing Keycloak login with no separate Connect step, matching the Keycloak-only posture.

Tasks

  • Add JWT validation middleware to the datastore MCP server: fetch Keycloak JWKS from https://auth.usgov.coderdemo.io/realms/coder, verify signature, issuer, and expiry; reject otherwise with 401.
  • Optionally surface the verified username in the server's governance logging.
  • Rebuild and push the usgov/datastore-mcp image; bump the tag in deploy/datastore-mcp/k8s/mcp-server.yaml.
  • PATCH /api/experimental/mcp/servers/{id} to set auth_type: user_oidc.
  • Verify end-to-end from a Coder Agents chat (authorized user succeeds, missing/invalid token returns 401).

Known caveat

The forwarded token is issued for the coder OIDC client, so its aud/azp is coder. The validator must validate issuer + signature + expiry and accept azp=coder rather than requiring its own audience. Confirm the token shape before implementing.


Generated by Coder Agents, on behalf of @ausbru87.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions