Skip to content

feat(mcp-oauth): confidential pre-registered clients (client_secret_env) — REQ-044 Phase 2#323

Merged
Shooksie merged 1 commit into
release/0.7from
agent/v0.7.0/mcp-oauth-client-secret
Jul 12, 2026
Merged

feat(mcp-oauth): confidential pre-registered clients (client_secret_env) — REQ-044 Phase 2#323
Shooksie merged 1 commit into
release/0.7from
agent/v0.7.0/mcp-oauth-client-secret

Conversation

@Shooksie

Copy link
Copy Markdown
Contributor

Implements Phase 2 of REQUIREMENT-044 (portal task TASK-339 covered Phase 1). Lets an authorization_code MCP server pin a confidential pre-registered app — client_id + client_secret_env — unlocking providers that reject Dynamic Client Registration and require a client_secret at token exchange (HubSpot, Dropbox).

Changes (single repo — OauthConfig.client_secret_env already exists in animus-protocol)

  • validation (orchestrator-config): permit client_secret_env for flow=authorization_code, but only alongside a pinned client_id (reject blank; reject secret-without-id). Still reject the other m2m *_env/token_url pointers.
  • resolution (animus-mcp-oauth/config.rs): ServerResolution gains client_secret, resolved from client_secret_env via process env first, then the project keychain (animus secret set).
  • flow (animus-mcp-oauth/flow.rs): both pinned-client branches (run_auth loopback + begin_auth portal) attach the secret via OAuthClientConfig::with_client_secret; begin_auth persists it into PendingAuth so complete_auth authenticates the exchange as the same app (that consumer already existed — only the producer was missing).
  • docs + 3 validation tests.

Verification

  • cargo check -p orchestrator-config -p animus-mcp-oauth
  • cargo test -p orchestrator-config authorization_code → 7 passed (3 new) ✅
  • cargo test -p animus-mcp-oauth → 4 passed ✅
  • cargo fmt --check + cargo clippy clean on both crates ✅

Shipping note

This lands on the release/0.7 line; getting it into the portal requires a new ao-cli release + portal repin (Dockerfile ANIMUS_VERSION / .animus/plugins.lock) + the workflow-runner match per the deploy runbook — a separate, gated step.

…secret_env)

REQUIREMENT-044 Phase 2. Allow an authorization_code MCP server to pin a
CONFIDENTIAL pre-registered app: client_id + client_secret_env. Unlocks
providers that reject DCR and require a client_secret at token exchange
(HubSpot, Dropbox).

- validation: permit client_secret_env for flow=authorization_code (only
  alongside a pinned client_id; reject blank); keep rejecting the other
  m2m *_env pointers.
- config resolution: ServerResolution gains client_secret, resolved from
  client_secret_env via process env then the project keychain the
  'animus secret' surface writes to.
- flow: both pinned-client branches (run_auth loopback + begin_auth portal)
  attach the resolved secret via OAuthClientConfig::with_client_secret;
  begin_auth persists it into PendingAuth so complete_auth authenticates
  the exchange as the same app (that consumer already existed).
- docs + validation tests (accept with client_id; reject without; reject blank).

No new CLI flags; the secret is config-driven and keychain-resolved.
@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
animus-docs Ready Ready Preview, Comment Jul 12, 2026 6:07pm

Request Review

@Shooksie Shooksie merged commit 56dbaad into release/0.7 Jul 12, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant