Skip to content

v0.28.6 OAuth /token always returns "Invalid client_secret" with --enable-dcr (DCR completely broken) #720

@gorlitskygroup-png

Description

@gorlitskygroup-png

Summary

When gbrain serve --http --enable-dcr is used, every OAuth authorization_code token exchange fails with invalid_client / Invalid client_secret, including for clients that just successfully registered via /register and immediately used the returned secret. Same affects refresh_token grant. This makes DCR-based MCP clients (Claude.ai, etc.) completely unable to connect.

Root cause

Two interacting code paths:

  1. src/core/oauth-provider.ts:145GBrainClientsStore.getClient() returns the SHA-256 hash in the client_secret field:

    client_secret: r.client_secret_hash as string | undefined,
  2. @modelcontextprotocol/sdk/././middleware/clientAuth.js:23 does plain string compare.

The plaintext secret from the request can never === the SHA-256 hex digest returned by getClient().

Workaround (one-line middleware patch)

app.post('/token', express.urlencoded({ extended: false }), (req, _res, next) => {
  const grant = req.body?.grant_type;
  if ((grant === 'authorization_code' || grant === 'refresh_token') && typeof req.body?.client_secret === 'string') {
    req.body.client_secret = createHash('sha256').update(req.body.client_secret).digest('hex');
  }
  next();
});

Verified against Claude.ai's connector flow. Happy to send a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions