Skip to content

fix(auth): support OpenAI OAuth vision in Peekaboo - #293

Open
scotthuang wants to merge 3 commits into
openclaw:mainfrom
scotthuang:fix/openai-oauth-vision
Open

fix(auth): support OpenAI OAuth vision in Peekaboo#293
scotthuang wants to merge 3 commits into
openclaw:mainfrom
scotthuang:fix/openai-oauth-vision

Conversation

@scotthuang

@scotthuang scotthuang commented Jul 23, 2026

Copy link
Copy Markdown

What problem this solves

Peekaboo already converts captures into provider-neutral image messages, but its OpenAI availability gate only accepted a currently valid OAuth access token. Once that token expired, Peekaboo reported OpenAI as unavailable and stopped before Tachikoma had a chance to use the refresh token.

Previous call chain

expired OpenAI access token + valid refresh token
  -> ConfigurationManager.hasOpenAIAuth()
  -> validOAuthAccessToken() == nil
  -> OpenAI reported unavailable
  -> Tachikoma refresh/vision path never reached

New call chain

expired OpenAI access token + valid refresh token
  -> ConfigurationManager.hasOpenAIAuth() == true
  -> Tachikoma refreshes the OAuth session
     - stored login: atomically persists the rotated chain
     - environment source: caches the rotated chain only in this process
  -> Codex Responses receives text + image
  -> visual answer returned

Implementation

  • treat a refreshable OpenAI OAuth session as available when the current access token has expired
  • keep OAuth access tokens and expiry timestamps paired by credential source, rather than mixing environment and stored values
  • bump Tachikoma to the Codex OAuth Responses vision implementation and its environment-credential boundary fix
  • document OpenAI OAuth support for see --analyze, image --analyze, and agent vision
  • document that environment OAuth refreshes stay process-local while peekaboo config login persists refresh rotation

Evidence

Red-green availability proof

The deterministic setup stores:

OPENAI_ACCESS_TOKEN=<expired token>
OPENAI_ACCESS_EXPIRES=<one hour in the past>
OPENAI_REFRESH_TOKEN=<present>

Red step: the PR test was run with only the new refresh-token clause temporarily removed, reproducing the previous implementation.

return self.validOAuthAccessToken(prefix: "OPENAI") != nil

Observed result:

Expectation failed: manager.hasOpenAIAuth()
Test failed after 0.008 seconds

Green step: restore the PR implementation:

return self.validOAuthAccessToken(prefix: "OPENAI") != nil ||
    self.hasOAuthRefreshToken(prefix: "OPENAI")

Observed result:

Test passed after 0.007 seconds

Only that availability condition changed between the red and green runs. Both repositories were restored to clean state afterward.

Reproduction command:

/usr/bin/arch -arm64 swift test \
  --package-path Core/PeekabooCore \
  -Xswiftc -DPEEKABOO_SKIP_AUTOMATION \
  --filter "OpenAI availability accepts an expired access token with a refresh token"

Real OAuth vision proof from the pinned Tachikoma dependency

openclaw/Tachikoma#40 includes protocol-level red/green evidence using the same valid ChatGPT OAuth token:

Old public endpoint -> HTTP 401, missing api.responses.write scope
New Codex endpoint  -> deterministic 16x16 red PNG -> GPT-5.6 Sol returned "red"
Elapsed             -> 6.252 seconds
SSE completion      -> status=completed, total_tokens=55

The image is embedded in the live integration test; no host desktop was captured.

Environment credential-boundary proof

The pinned Tachikoma commit d4cd49f adds direct tests proving that an environment-supplied OAuth refresh does not write to ~/.peekaboo/credentials:

cache refreshed environment credentials without persisting      passed
continue an environment refresh chain in memory                 passed
environment value changes invalidate the in-memory chain         passed
ignore-environment changes invalidate the in-memory chain        passed
refresh environment account without overwriting stored account  passed

The tests assert an empty credential store for environment-only sessions, unchanged stored values when a separate stored account exists, correct use of rotated refresh tokens, and cache invalidation when the source changes. Stored-login refreshes retain their separate atomic-persistence test.

Dependency

Important

Depends on openclaw/Tachikoma#40. This PR must merge only after that dependency lands; then the Tachikoma gitlink must be repinned to the final upstream merge commit before Peekaboo merges.

User impact

After the Tachikoma dependency lands, users authenticated through peekaboo config login openai can use OpenAI OAuth for image analysis and agent vision without configuring a separate OpenAI API key. Existing explicit API-key configurations retain priority. Hosts that inject OAuth through environment variables keep those credentials ephemeral and must provide fresh values after a process restart.

Validation

  • deterministic availability red/green: failed in 0.008 seconds before the clause, passed in 0.007 seconds with the fix
  • ConfigurationAccessorsOAuthTests — 14 tests passed
  • pinned Tachikoma AuthManagerTests — 19 tests passed
  • pinned Tachikoma OpenAIResponsesProviderTests — 30 tests passed
  • pinned Tachikoma full suite — 842 of 843 tests passed; the only failure is an unrelated existing real-network OpenAI audio test that timed out after 60 seconds
  • previous Peekaboo head passed all five macOS CI jobs; the new submodule-pointer/docs head is tracked in the current CI run
  • pnpm run lint:docs — passed
  • git diff --check

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal priority bug or improvement with limited blast radius. 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. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. labels Jul 27, 2026
@clawsweeper

clawsweeper Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codex review: found issues before merge. Reviewed July 31, 2026, 7:51 PM ET / 23:51 UTC.

ClawSweeper review

What this changes

This PR lets Peekaboo accept a refreshable OpenAI OAuth session for vision, keeps access-token expiry paired with its credential source, updates the Tachikoma submodule, and documents stored versus environment refresh behavior.

Merge readiness

⚠️ Needs maintainer review before merge - 5 items remain

This PR remains necessary: current main still rejects an expired OpenAI OAuth access token before Tachikoma can refresh it. The implementation is focused and proof-rich, but it must not merge while its Tachikoma gitlink remains the explicitly temporary upstream review revision rather than the final merged dependency commit.

Priority: P2
Reviewed head: 99254685f7d9b765bb1beca4be5b181f3b62d425

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The patch has strong focused proof and a narrow scope, but the unresolved temporary dependency pin prevents merge readiness.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (live_output): The PR body provides deterministic red/green availability output and describes live protocol-level OAuth vision and environment-boundary evidence from the pinned dependency; any additional live-token evidence should remain redacted.
Patch quality 🦐 gold shrimp (3/6) Security review found an item that needs attention.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The PR body provides deterministic red/green availability output and describes live protocol-level OAuth vision and environment-boundary evidence from the pinned dependency; any additional live-token evidence should remain redacted.
Evidence reviewed 6 items Current main still has the reported gate: hasOpenAIAuth() returns true only for a non-empty API key or a currently valid OAuth access token; an expired access token with a usable refresh token still returns false on current main.
The PR adds a narrow source-pairing implementation: The branch separately validates environment access token plus environment expiry and stored access token plus stored expiry, then recognizes a refresh token for the availability gate.
Focused regression coverage accompanies the code change: The branch adds tests for an expired stored access token with a refresh token and for preventing a stale stored expiry from invalidating a valid environment access token.
Findings 1 actionable finding [P1] Repin Tachikoma to the final merged OAuth revision
Security Needs attention Temporary provider revision controls credential persistence: The updated Tachikoma gitlink supplies the environment-versus-stored OAuth refresh boundary, but the PR identifies the selected revision as a review commit rather than the final upstream merge revision.

How this fits together

Peekaboo’s configuration manager gates image-analysis and agent-vision requests before they reach Tachikoma, which resolves OpenAI API-key or OAuth credentials. Tachikoma refreshes an eligible OAuth session and sends the resulting text-and-image request to the OpenAI Responses service.

flowchart LR
  A[Image or agent vision request] --> B[Peekaboo configuration]
  B --> C{OpenAI credentials available?}
  C -->|no| D[Provider unavailable]
  C -->|yes| E[Tachikoma credential resolver]
  E --> F[Use API key or refresh OAuth]
  F --> G[OpenAI Responses vision]
  G --> H[Visual answer]
Loading

Before merge

  • Repin Tachikoma to the final merged OAuth revision (P1) - The gitlink selects d4cd49f, while the PR description identifies it as an upstream review revision and says Peekaboo must use the final Tachikoma merge commit. Landing this pin would ship an unfinalized provider and credential-boundary dependency; repin after upstream merges and rerun the focused OAuth checks.
  • Resolve security concern: Temporary provider revision controls credential persistence - The updated Tachikoma gitlink supplies the environment-versus-stored OAuth refresh boundary, but the PR identifies the selected revision as a review commit rather than the final upstream merge revision.
  • Resolve merge risk (P1) - Merging the current gitlink would bind Peekaboo to an OAuth provider and environment-credential persistence implementation that the PR itself identifies as an upstream review revision, rather than the final merged dependency.
  • Resolve merge risk (P1) - The change crosses OAuth refresh, provider routing, and secret persistence boundaries; the exact final Tachikoma commit needs focused validation for both stored-login rotation and environment-only refresh behavior.
  • Complete next step (P2) - The remaining blocker is dependency-finalization sequencing and exact-provider validation, not a safe standalone repair on the current branch.

Findings

  • [P1] Repin Tachikoma to the final merged OAuth revision — Tachikoma:1
  • [medium] Temporary provider revision controls credential persistence — Tachikoma:1
Agent review details

Security

Needs attention: No separate application-code security defect is evident, but the unfinalized dependency pin governs a sensitive OAuth credential-persistence boundary and must be finalized before merge.

Review metrics

Metric Value Why it matters
Patch surface 5 files changed; 75 added, 16 removed The diff stays focused on the OAuth availability gate, credential lookup, regression tests, documentation, and one dependency pointer.
Dependency surface 1 Tachikoma gitlink changed The exact dependency revision controls the OAuth vision protocol and environment credential persistence boundary.

Merge-risk options

Maintainer options:

  1. Repin the final Tachikoma OAuth merge (recommended)
    After the upstream OAuth vision work merges, replace the review gitlink with its final merge commit and rerun focused provider and credential-boundary validation.
  2. Pause pending upstream finalization
    Keep this branch open without merging the temporary dependency pin until the upstream OAuth provider contract is finalized.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
After the upstream OAuth vision work merges, repin the Tachikoma submodule to its final merge commit and run focused Peekaboo OAuth availability plus Tachikoma credential-boundary validation.

Technical review

Best possible solution:

Once the Tachikoma OAuth vision work is merged upstream, repin this PR to its final merge commit and validate the focused Peekaboo availability cases plus Tachikoma’s stored and environment credential-boundary behavior against that exact revision.

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

Yes. Current main has a clear source-level path: an expired OpenAI OAuth access token makes hasOpenAIAuth() return false even when a refresh token is available, so the provider refresh path is never reached. The branch includes a focused deterministic regression test, though this read-only review did not execute it.

Is this the best way to solve the issue?

Yes, conditionally. Admitting a refreshable OAuth session and pairing access-token expiry by source is the narrow maintainable fix, but the provider dependency must be repinned to its final merged upstream revision before this implementation is safe to land.

Full review comments:

  • [P1] Repin Tachikoma to the final merged OAuth revision — Tachikoma:1
    The gitlink selects d4cd49f, while the PR description identifies it as an upstream review revision and says Peekaboo must use the final Tachikoma merge commit. Landing this pin would ship an unfinalized provider and credential-boundary dependency; repin after upstream merges and rerun the focused OAuth checks.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.99

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P2: This is a bounded user-facing OpenAI authentication improvement with no demonstrated current outage beyond the affected refreshable-session path.
  • merge-risk: 🚨 compatibility: The patch changes stored-versus-environment credential precedence and expiry interpretation for existing OAuth setups.
  • merge-risk: 🚨 auth-provider: The patch changes when OpenAI OAuth is considered available and relies on provider-side token refresh behavior.
  • merge-risk: 🚨 security-boundary: The changed dependency is responsible for ensuring environment-supplied OAuth refresh credentials are not persisted to the local credential store.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR body provides deterministic red/green availability output and describes live protocol-level OAuth vision and environment-boundary evidence from the pinned dependency; any additional live-token evidence should remain redacted.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides deterministic red/green availability output and describes live protocol-level OAuth vision and environment-boundary evidence from the pinned dependency; any additional live-token evidence should remain redacted.

Evidence

Security concerns:

  • [medium] Temporary provider revision controls credential persistence — Tachikoma:1
    The updated Tachikoma gitlink supplies the environment-versus-stored OAuth refresh boundary, but the PR identifies the selected revision as a review commit rather than the final upstream merge revision.
    Confidence: 0.98

What I checked:

Likely related people:

  • Peter Steinberger: Auth accessors and credential helpers were established in the configuration-manager split, and current-line blame attributes the relevant current-main surface to the v3.9.8 release commit. (role: configuration subsystem author; confidence: high; commits: aeba4739af74, 416247a4e080; files: Core/PeekabooCore/Sources/PeekabooAutomation/Configuration/ConfigurationManager+Accessors.swift, Core/PeekabooCore/Sources/PeekabooAutomation/Configuration/ConfigurationManager+Credentials.swift)
  • Sebastien Tardif: Recent current-main work serialized configuration persistence transactions, which is adjacent to the OAuth credential storage behavior this PR relies on. (role: recent credential-persistence contributor; confidence: medium; commits: 17b614864c3c; files: Core/PeekabooCore/Sources/PeekabooAutomation/Configuration/ConfigurationManager+Credentials.swift)

Rank-up moves

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

  • Repin Tachikoma to the final merged OAuth revision after upstream lands.
  • Publish redacted focused validation for stored-login refresh rotation and environment-only refresh against that exact pin.

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 (11 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-29T20:23:31.354Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma after its OAuth change merges upstream
  • reviewed 2026-07-29T21:46:07.917Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to its final merged OAuth revision
  • reviewed 2026-07-29T22:18:27.471Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to its final merged OAuth revision
  • reviewed 2026-07-30T07:38:43.510Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to the final merged OAuth revision
  • reviewed 2026-07-30T23:36:13.653Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to the final merged OAuth revision
  • reviewed 2026-07-31T10:31:17.006Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to the final merged OAuth revision
  • reviewed 2026-07-31T16:02:08.029Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to the final merged OAuth revision
  • reviewed 2026-07-31T19:20:07.357Z sha 9925468 :: found issues before merge. :: [P1] Repin Tachikoma to the final merged OAuth revision

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. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant