fix: resolve Claude OAuth token via secrets, remove non-functional settings page - #54
Open
lsimpsonsfdc wants to merge 1 commit into
Open
Conversation
…ttings page Adds a claudeOAuthTokenRef config field, resolved through ctx.secrets at call time. Paperclip's plugin worker processes deliberately don't inherit the host's environment (a real security boundary against leaking unrelated host secrets), so a token set on the Paperclip container/host itself is invisible to the plugin regardless of what env var it checks for. This reintroduces an operator-settable token (removed in LAC-1073, when credentials auto-detection from the local Claude install was believed to cover every deployment shape) specifically for the sandboxed-worker case LAC-1073 didn't have visibility into: the existing file/Keychain auto-detection still works fine when Paperclip and Claude Code run as the same unsandboxed user, but has no path to a token when they don't. Also removes the plugin's custom settings page. It was display-only (status text, no editable fields) since it was first written, and declaring a custom settingsPage slot suppresses Paperclip's own auto-generated config form entirely — which is the only thing that renders a working secret picker for claudeOAuthTokenRef. There was no way to edit any setting through this plugin's UI before this change, for any field. Status/account/source stay visible on the main Agent Usage page and dashboard widget, which already duplicated this info. Requires an @paperclipai/plugin-sdk version with EnvSecretRefBinding / object-shaped secrets.resolve() support (available in 2026.722.0, the version pinned by lacymorrow#52 — this repo's current committed lockfile resolves "latest" to 2026.517.0, which predates it and fails typecheck as a result).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related fixes found while running this plugin against a real, self-hosted Paperclip instance where Paperclip and the signed-in Claude Code user are not the same unsandboxed process.
Adds a
claudeOAuthTokenRefconfig field, resolved throughctx.secretsat call time, checked before theCLAUDE_CODE_OAUTH_TOKENenvironment variable and the local credentials file/Keychain. This reintroduces an operator-settable token — removed in #6 (LAC-1073) on the reasoning that "Paperclip agents run on the same machine as Claude — they share the same credentials... no reason to exist." That's true for the deployment shape LAC-1073 was written against, but doesn't hold for the one this plugin's own worker actually runs in by default: Paperclip's plugin worker processes deliberately don't inherit the host's environment (a real security boundary against leaking unrelated host secrets). ACLAUDE_CODE_OAUTH_TOKENset on the Paperclip host/container itself is invisible to the plugin worker regardless of what it checks for — confirmed live against a real deployment. File/Keychain auto-detection still works fine when Paperclip and Claude Code run as the same unsandboxed user (the case LAC-1073 addressed); this fix covers the sandboxed case it didn't have visibility into.secrets.read-refis the documented, supported path for a plugin to receive a value like this (PLUGIN_SPEC.md §22).Removes the plugin's custom settings page. It's been display-only (status text, no editable fields) since it was first written — and declaring a custom
settingsPageslot at all suppresses Paperclip's own auto-generated config form, which is the only thing that renders a working secret picker. There was no way to edit any setting through this plugin's UI before this change, for any field, only via direct API calls. Status/account/source stay visible on the main Agent Usage page and dashboard widget, which already duplicated this info.The
claudeOAuthTokenReffield declarestype: ["string", "object"]rather than a bare"string"— the secret picker's "bind to a secret" path sends a structured{ type: "secret_ref", secretId, version }object on save, which a"string"-only schema rejects with a validation error the moment an operator uses the picker instead of raw-pasting a token.Dependency note
This requires an
@paperclipai/plugin-sdkversion withEnvSecretRefBinding/ object-shapedsecrets.resolve()support (confirmed present in2026.722.0, the version pinned by #52). This repo's currently-committedpackage-lock.jsonresolves"latest"to a stale2026.517.0, which predates that support —npm run typecheckwill fail against it withModule '"@paperclipai/plugin-sdk"' has no exported member 'EnvSecretRefBinding'until #52 merges (that's the exact bug #52 fixes). Recommend merging #52 first and rebasing this PR, or merging in either order and re-running CI after both land.How to test
npm install npm run typecheck npm run build npm testManually: set
claudeOAuthTokenRefvia the picker on Paperclip's generated settings form (not this plugin's own — it no longer has one), confirm the dashboard/usage page/tools report real data even when the plugin worker has no ambient environment.Checklist
npm run typecheckpasses (against@paperclipai/plugin-sdk@2026.722.0; see dependency note above for the current lockfile)npm run buildproducesdist/manifest.js+dist/worker.jsclaudeOAuthTokenReffield, sandboxed-worker explanation, settings-page removal note