Skip to content

connector-mcp: an mcp instance with a stdio transport accepts a static auth, resolves its credentialRef, and then drops the value silently, so the declared credential reaches nothing #29607

Closed

Description

@objectstack-fleet

domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

Filing gate: ① an out-of-scope finding of the #29434 card thread (measurement 3 in project file server-seat3/29434-route-options.md, on origin/main 2420778c), which the seat ruled out of #29434's scope (Q2 = A). Filed by domain:server seat 3. ⛔ Not a claim. Suggested-grade: p3 (the author's credential silently does nothing; nothing leaks).

What happens (source reading, not reproduced through a public door)

  • A declarative mcp connector instance with providerConfig.transport.kind: 'stdio' and auth: { type: 'bearer', credentialRef } is accepted.
  • The materializer in service-automation resolves the reference, lists it in Setup, and degrades the instance if the reference is missing.
  • The provider (connector-mcp/src/mcp-provider.ts, the stdio arm of normalizeTransport) then ignores ctx.auth. The resolved credential never reaches the server, and nothing tells the author.

#29434 adds providerConfig.transport.credentialEnv, the route that lets a static auth reach a stdio server. After it lands, an auth on stdio without credentialEnv is still dropped silently.

Wanted (measure, then choose)

  • A. Advisory only. A lint warning says the stdio auth reaches nothing and names credentialEnv. No accept set moves.
  • B. Refuse at the provider. The instance is refused with a sentence that names credentialEnv. This is Clause-②: no (narrowing) and BREAKING for apps that declare auth beside a literal env. It needs a migration note and the full dogfood battery.
  • Measure how many shipped templates and examples declare auth on a stdio mcp instance, and recommend one option.

Serial: after #29434's PR merges (same provider file and the advisory it rewords).

Dedupe: searched stdio auth ignored mcp, credentialEnv; nearest #29434, #29341. New.

Links back: #29434, #29341, #29424.

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · domain:server · pm:queue · 2026-11-02T21:55Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Filing addendum · #29607 · 2026-11-02T22:26Z

    Carried from the hardening note in ① of the contract review on PR #29621 (#29434, head f3ff3349), as item 2 of this card. This is source reading, non-blocking.

    The #29341 advisory (connector-credential-literal) does not judge the transport.credentialEnv string itself. Suppose a secret is typed into it by mistake, in a form that passes the env-var-name check (underscore and alphanumerics). It would then be served on a metadata read and echoed by two configuration refusals.

    Wanted: the advisory runs its credential-literal predicate on credentialEnv too, and warns when the value looks like a secret rather than a name. That is a warning only, so no accept set moves.

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

    Claim: PM loop round 8 · 2026-11-02T23:37Z
    Session: session_01JQwxbacSXJQqAztgt4UMrS (seat); dev = card thread session_01JQwxbaSFr2XhX4m1qEAiXy
    Account: os-warren
    Branch: claude/project-thread-iltz47 (a project card thread pushes only its assigned branch; measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-29607
    Domain: domain:server
    Seat: domain:server#4
    File surface: the connector-credential-literal advisory (the #29341 lint rule and its explanation entry) and, where the advisory needs it, a read-only look at packages/connectors/connector-mcp/src/mcp-provider.ts; tests, changesets (stop on breach; explain in the report). ⛔ No refusal in the provider (option B needs a ruling); no packages/spec/**; no packages/metadata-protocol/src/protocol.ts (seat 5 freeze until 2026-11-03 06:00Z).
    Container & model: M, mode:thread (the os-dev agent type is not loaded in seat sessions), model: TIER_DEFAULT, effort: project default (the maintainer sets effort)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — follow-up of #29434 (PR #29621)
    Thread-read: 6590066946
    Premise: source reading (card); dev reproduces the dropped ctx.auth on a stdio instance first and counts shipped declarations
    Serial constraints cleared: #29434 landed as PR #29621

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbaSFr2XhX4m1qEAiXy
    os-dev-report

    {
      "issue": 29607,
      "status": "done",
      "branch": "claude/project-thread-iltz47",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29664",
      "session": "session_01JQwxbaSFr2XhX4m1qEAiXy",
      "premise_still_valid": true,
      "summary": "Route A plus item 2, both as warnings on the existing connector-credential-literal advisory (no accept set moves, mcp-provider.ts and packages/spec untouched). Item 1: a provider mcp entry on a stdio transport with a bearer, api-key or basic auth and no transport.credentialEnv draws one warning at connectors[N].auth naming credentialEnv. Item 2: credentialEnv is judged by a new sibling predicate isCredentialShapedName in credential-literal.ts (the existing predicate's R1 reads the key, so it is true for every value under credentialEnv); it draws on an auth-scheme value or a 16+ letters-and-digits run with 4+ letter/digit switches, never on a conventional or long capital name (the seat's pins). Reproduced first on origin/main 3482f3d8 through the automation service: the ref was resolved, the instance came up ready, the child reported unset:0, nothing said so. Count of shipped templates/examples declaring static auth on a stdio mcp instance: 0 (objectstack examples, create-objectstack templates, content/docs, skills; hotcrm; docs.objectos.ai).",
      "tests": "On 9bb1b840 under the lock: pnpm --filter @objectstack/lint test && typecheck, Test Files 192 passed (192), Tests 7924 passed (7924), tsc --noEmit and check:test-typecheck clean, VERDICT command-exit 0. Ablations via scripts/ablation-replace.mjs (tests import src, no build leg), each restored to the HEAD blob with git diff HEAD empty: item 1 guard deleted, 8 failed / 23 passed; item 1 condition forced false, 6 failed / 25 passed; item 2 condition forced false, 4 failed / 27 passed; alternation floor set to 0, 7 failed / 86 passed. The first item 1 attempt was a refused no-op (anchor contained in its replacement) and was redone.",
      "gates": "dispatch-gates --commands on 9bb1b840: 57 families; 56 exit 0 (check-plugin-teardown-shape --self-test exit 3 until git fetch origin 621a4876, then exit 0); check:dual-build-cjs-loads exit 3, NOT MEASURED (workspace not fully built), left to CI. --ran: 57 derived, 56 run, 1 NOT-MEASURED, 0 UNRUN. pnpm lint exit 0. Branch is 4 commits behind origin/main e0187d0f, none touching packages/lint, packages/connectors or a derivation input; not merged. PR check-runs: in_progress at report time.",
      "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2: pr_create through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, read-back 10509 bytes sent and stored, identical), and this os-dev-report comment through post-stamped.mjs. git push is not a REST write.",
      "open_questions": [],
      "security_findings": "withheld",
      "out_of_scope_findings": [
        "carrier: none · noted, not filed: skills/objectstack-automation/references/integration-recipes.md recipe 6 says a stdio server's credentials ride transport.env, which predates credentialEnv and steers to the literal the advisory warns on; skills/** is Tier H, so the PR leaves it",
        "carrier: none · noted, not filed: content/docs/automation/connectors.mdx could add that the advisory now reports a stdio auth with no credentialEnv; the authoring-rules.ts row comment for lintConnectorCredentialLiterals still names only the four maps (incomplete, not false)"
      ]
    }
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

    Landing record · #29607 · PR #29664 · 2026-11-03T01:36Z

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29664-*' 0 refs (released)
    Ancestry git merge-base --is-ancestor ece5faac origin/main yes
    Content git grep -c isCredentialShapedName origin/main -- packages/lint/src/credential-literal.ts 6

    Release: claim 6591288051 (session_01JQwxbacSXJQqAztgt4UMrS, card thread session_01JQwxbaSFr2XhX4m1qEAiXy, branch claude/project-thread-iltz47) · full landing
    Produce: PR #29664 merged as ece5faac at 2026-11-03T01:36Z. The connector-credential-literal advisory now warns when a stdio MCP server's auth reaches nothing (no transport.credentialEnv), and when a credential is typed into transport.credentialEnv. It is route A, a warning, so nothing is refused. ACCEPT on the PR. Fixes #29607 closed this card as completed.

    • Noted, not filed: the skills recipe (integration-recipes.md recipe 6) still says stdio credentials ride transport.env; connectors.mdx could name the new findings.
    • State: pm:dispatched removed; the card is closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions