Skip to content

fix: accept OAuth DCR metadata in vault set - #288

Merged
steipete merged 11 commits into
openclaw:mainfrom
feniix:fix/286-vault-dcr-client-info
Aug 8, 2026
Merged

fix: accept OAuth DCR metadata in vault set#288
steipete merged 11 commits into
openclaw:mainfrom
feniix:fix/286-vault-dcr-client-info

Conversation

@feniix

@feniix feniix commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • validate OAuth client information according to each known field's shape instead of requiring every value to be a string
  • preserve standard DCR arrays and timestamps, unrestricted JWK/provider metadata, existing null-compatible imports, and the string-only workaround
  • add command-level persistence and malformed-payload regression coverage

Type of change

  • Feature
  • Bug fix
  • Hotfix
  • Spike / exploration
  • Documentation
  • Refactor

Real CLI behavior proof

Ran the built CLI with an isolated MCPORTER_CONFIG and XDG_DATA_HOME, the fake token from #286, DCR arrays and a registration timestamp. No server was contacted.

$ printf '%s\n' "$PAYLOAD" | node dist/cli.js vault set demo --stdin
Saved OAuth credentials for 'demo' to <temp>/data/mcporter/credentials.json

$ jq '.entries[] | {tokens, clientInfo}
      | del(.tokens.__mcporter_generation, .clientInfo.__mcporter_client_generation)' \
    <temp>/data/mcporter/credentials.json
{
  "tokens": {
    "access_token": "fake",
    "token_type": "Bearer"
  },
  "clientInfo": {
    "client_id": "abc",
    "redirect_uris": [
      "https://example.test/cb"
    ],
    "grant_types": [
      "authorization_code"
    ],
    "response_types": [
      "code"
    ],
    "token_endpoint_auth_method": "none",
    "client_id_issued_at": 1754600000,
    "client_name": null
  }
}

This proves both the reported DCR shape and the previously accepted null value persist through the real CLI.

Test plan

  • pnpm exec vitest run tests/vault-validation.test.ts tests/vault-command.test.ts
  • pnpm check
  • pnpm test

Closes #286

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 Urgent regression or broken agent/channel workflow affecting real users now. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. labels Aug 8, 2026
@clawsweeper

clawsweeper Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed August 8, 2026, 4:48 PM ET / 20:48 UTC.

ClawSweeper review

What this changes

Updates vault set to validate known OAuth client-registration fields by their actual string, string-array, or numeric shapes, with persistence and malformed-input tests.

Regression provenance

Possible regression — probable (reproduction; reviewed change). No predecessor PR is attributed.

Merge readiness

⚠️ Ready for maintainer review - 3 items remain

Keep open. Current main and v0.13.0 still reject standard DCR arrays; this PR supplies a focused fix with real CLI persistence proof. A maintainer should select this implementation or the overlapping #287 before either lands.

Priority: P1
Reviewed head: b91b1853cfcc5d6b6417c7b4ec6cecc8fd5f4f7a
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused patch with direct CLI proof and regression coverage; its merge readiness depends on resolving the overlapping open implementation.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (terminal): A redacted built-CLI transcript shows the after-fix stdin import and resulting persisted DCR client metadata with a fake token.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): A redacted built-CLI transcript shows the after-fix stdin import and resulting persisted DCR client metadata with a fake token.
Evidence reviewed 5 items Released and current defect: The v0.13.0 source and current main both require every non-null clientInfo value to be a string, which rejects DCR arrays such as redirect_uris.
Proposed compatibility repair: The PR head separately validates standard string arrays and numeric registration timestamps while retaining null compatibility and pass-through metadata.
Persistence boundary: The vault read path keeps client information when its issuer is valid, so the accepted DCR arrays and timestamps survive the write/read flow exercised by the PR test.
Findings None None.
Security None None.

How this fits together

The vault command imports OAuth tokens and dynamic client-registration metadata from stdin or files into MCPorter’s local credential store. OAuth refresh and registration later consume the stored client information to authenticate MCP server access.

flowchart LR
  A[OAuth registration payload] --> B[Vault set command]
  B --> C[Client metadata validation]
  C --> D[Local credentials vault]
  D --> E[OAuth refresh and registration]
  E --> F[Authenticated MCP server access]
Loading

Decision needed

Question Recommendation
Should this PR be the canonical DCR vault-import fix, or should its focused compatibility behavior be consolidated into #287 instead? Use this focused PR as canonical: Merge this narrow field-shape validator and close the overlapping PR after preserving any independently needed coverage.

Why: Both open PRs repair the same user-visible failure but differ in validation scope and adjacent behavior, so a mechanical merge decision cannot choose the intended long-term credential contract.

Before merge

  • Resolve merge risk (P1) - fix(vault): accept dynamic client registration clientInfo in vault set #287 changes the same vault-validation boundary with a broader contract; merging both without selection or consolidation could create incompatible or duplicate validation behavior.
  • Complete next step (P2) - A maintainer must select or consolidate the two viable, overlapping OAuth vault fixes; there is no remaining narrow automated repair to make on this branch.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production versus test delta production +40/-2, tests +62/-1 The field-shape validator is accompanied by more regression coverage than production logic; the separate release-note addition is +4 lines.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #286
Summary: This PR is a candidate repair for the canonical DCR vault-import regression, while another open PR addresses the same validator boundary.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Select one canonical validation contract (recommended)
    Use this focused implementation as the landing path and preserve only independently necessary coverage from the overlapping PR.
  2. Consolidate before landing
    Adopt the broader implementation only after explicitly retaining this PR’s null-compatible and provider-metadata behavior.

Technical review

Best possible solution:

Land one narrow, schema-aware DCR import validator with persistence coverage for accepted arrays/timestamps and malformed field values, while preserving null-compatible and provider-specific metadata.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main’s string-only loop proves the rejection path, and the PR provides an after-fix built-CLI persistence transcript using the reported DCR shape.

Is this the best way to solve the issue?

Yes for the reported regression: per-field validation accepts standard DCR shapes without discarding provider metadata. The remaining choice is which overlapping PR should own that contract.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against ba80d985c867.

Labels

Label justifications:

  • P1: Standard OAuth dynamic-client-registration data cannot currently be seeded through the vault command.
  • merge-risk: 🚨 compatibility: The patch changes which existing and provider-specific client-information payloads are accepted and persisted.
  • merge-risk: 🚨 auth-provider: The changed vault data feeds OAuth client registration and token-refresh flows.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): A redacted built-CLI transcript shows the after-fix stdin import and resulting persisted DCR client metadata with a fake token.
  • proof: sufficient: Contributor real behavior proof is sufficient. A redacted built-CLI transcript shows the after-fix stdin import and resulting persisted DCR client metadata with a fake token.

Evidence

What I checked:

  • Released and current defect: The v0.13.0 source and current main both require every non-null clientInfo value to be a string, which rejects DCR arrays such as redirect_uris. (src/cli/vault-command.ts:154, 49dcd3e7fffd)
  • Proposed compatibility repair: The PR head separately validates standard string arrays and numeric registration timestamps while retaining null compatibility and pass-through metadata. (src/cli/vault-command.ts:172, b91b1853cfcc)
  • Persistence boundary: The vault read path keeps client information when its issuer is valid, so the accepted DCR arrays and timestamps survive the write/read flow exercised by the PR test. (src/oauth-vault.ts:224, ba80d985c867)
  • Feature provenance: Blame attributes the string-only validator on the v0.13.0 release commit; the current PR head also has a recent release-note commit by the same area contributor. (src/cli/vault-command.ts:154, b91b1853cfcc)
  • Real behavior proof: The PR body includes a redacted built-CLI transcript showing a fake-token DCR payload persisted with arrays, a timestamp, and a null client field. (b91b1853cfcc)

Likely related people:

  • steipete: Git blame ties the current string-only validator to Peter Steinberger’s v0.13.0 release commit, and the current PR head includes a follow-up commit authored by steipete. (role: introduced the current validation and recent area contributor; confidence: high; commits: 49dcd3e7fffd, b91b1853cfcc; files: src/cli/vault-command.ts, CHANGELOG.md)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (5 earlier review cycles)
  • reviewed 2026-08-08T12:25:28.574Z sha 060ddd1 :: needs real behavior proof before merge. :: [P1] Preserve null-compatible client-info input | [P3] Remove the release-owned changelog entry
  • reviewed 2026-08-08T12:34:13.114Z sha 912fe61 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-08T14:05:39.498Z sha 912fe61 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-08T16:54:40.956Z sha 912fe61 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-08T20:14:53.402Z sha 912fe61 :: needs maintainer review before merge. :: none

@feniix

feniix commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review findings:

  • restored null-compatible client-info imports with persistence regression coverage
  • removed the release-owned changelog entry
  • added a redacted real vault set --stdin persistence transcript to the PR body

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 8, 2026
@feniix

feniix commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

It looks like #287 and this PR were developed concurrently and both address #286. Linking #287 here for visibility; happy for maintainers to choose or consolidate the preferred approach.

@steipete
steipete force-pushed the fix/286-vault-dcr-client-info branch from 912fe61 to b91b185 Compare August 8, 2026 20:44
@steipete

steipete commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Exact-head maintainer proof for b91b1853cfcc5d6b6417c7b4ec6cecc8fd5f4f7a:

  • Rebased onto current main and retained Sebastian Otaegui / @feniix as author of all ten contributor commits. Added the maintainer-owned 0.13.1 changelog credit.
  • Diff: 4 files, +106/-3 (CHANGELOG.md, src/cli/vault-command.ts, tests/vault-command.test.ts, tests/vault-validation.test.ts).
  • Focused regression proof: pnpm exec vitest run tests/vault-validation.test.ts tests/vault-command.test.ts — 2 files, 26 tests passed.
  • Repository gates: pnpm docs:list, pnpm check, pnpm docs:site, pnpm test, and git diff --check — all clean. Full suite: 183 files passed / 4 skipped; 1,389 tests passed / 26 skipped.
  • Built CLI behavior proof: an isolated node dist/cli.js vault set demo --stdin run exited 0 and persisted fake RFC 7591 arrays, numeric issuance/secret-expiry timestamps, client_name: null, numeric token expires_at, and nested provider metadata with their original JSON values. A second fresh invocation with partial clientInfo and no client_id also exited 0. A malformed numeric application_type exited 1 with a field-specific error and did not replace the prior entry. The example.test server was not contacted.
  • Structured Codex-backed autoreview: final integrated autoreview --mode branch --base origin/main run was clean with no accepted/actionable findings; secret scan clean. No review-driven changes were required.
  • Exact diff/public-proof model-identifier audit: PASS; no model-bearing change or non-public identifier is present.
  • Exact-head CI: run 31277639023 completed successfully for Ubuntu, macOS, and Windows. PR state is mergeable/CLEAN.

Scope is intentionally limited to #286. Two useful findings from concurrent PR #287 remain separate follow-ups: sanitizing malformed-JSON errors and validating token expires_at / expiresAt. No live provider proof was needed because vault set only validates and persists the supplied local payload.

Thanks @feniix for the precise report, compatibility analysis, implementation, and real-CLI proof.

@steipete
steipete merged commit 4e8e37d into openclaw:main Aug 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P1 Urgent regression or broken agent/channel workflow affecting real users now. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vault set rejects clientInfo from OAuth dynamic client registration

2 participants