Skip to content

fix: resolve Claude OAuth token via secrets, remove non-functional settings page - #54

Open
lsimpsonsfdc wants to merge 1 commit into
lacymorrow:mainfrom
s4solutionsllc:upstream/fix-settings-oauth-secret
Open

fix: resolve Claude OAuth token via secrets, remove non-functional settings page#54
lsimpsonsfdc wants to merge 1 commit into
lacymorrow:mainfrom
s4solutionsllc:upstream/fix-settings-oauth-secret

Conversation

@lsimpsonsfdc

Copy link
Copy Markdown

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 claudeOAuthTokenRef config field, resolved through ctx.secrets at call time, checked before the CLAUDE_CODE_OAUTH_TOKEN environment 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). A CLAUDE_CODE_OAUTH_TOKEN set 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-ref is 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 settingsPage slot 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 claudeOAuthTokenRef field declares type: ["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-sdk version with EnvSecretRefBinding / object-shaped secrets.resolve() support (confirmed present in 2026.722.0, the version pinned by #52). This repo's currently-committed package-lock.json resolves "latest" to a stale 2026.517.0, which predates that support — npm run typecheck will fail against it with Module '"@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 test

Manually: set claudeOAuthTokenRef via 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 typecheck passes (against @paperclipai/plugin-sdk@2026.722.0; see dependency note above for the current lockfile)
  • npm run build produces dist/manifest.js + dist/worker.js
  • Updated the README — new claudeOAuthTokenRef field, sandboxed-worker explanation, settings-page removal note
  • PR is focused (one logical change — the token secret and the settings-page removal are the same root fix, since the settings page was blocking the secret picker)

…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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant