mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-24 18:19:05 +02:00
## Thinking Path > - Paperclip lets people manage AI agents and govern their access to outside services. > - Apps connections keep provider credentials in the instance vault and mediate every action through grants, policies, and audit. > - Agents currently have no Apps connection for reading or managing 1Password items with an operator-supplied service-account token. > - 1Password supports this through its official SDK; its documentation MCP server does not expose vault operations. > - This pull request adds a one-field service-account connection and registers eight reviewed SDK actions through the existing native-provider catalog. > - Operators can select vault permissions in 1Password and agent/action access in Paperclip without installing a CLI or handing durable credentials to agents. ## Linked Issues or Issue Description Related: #16144 adds 1Password as Paperclip's secret-storage backend. This PR adds the separate Apps/tool-access flow with a per-connection credential; it does not change secret providers or use a server-wide ambient token. **Subsystem affected** Apps catalog, native tool-provider registry, and shared connection setup. **Problem or motivation** People need to paste their own `OP_SERVICE_ACCOUNT_TOKEN`, find official service-account setup instructions, and authorize agents to use the selected vaults through ordinary Paperclip governance. **Proposed solution** Add `1password/service-account`, with a password field labeled **Paste your 1Password Service Account token** and a link to [1Password's creation instructions](https://www.1password.dev/service-accounts/get-started#create-a-service-account). Use the pinned official `@1password/sdk` 0.5.0 for vault/item listing, item and secret-reference reads, and item create/update/archive/delete. **Alternatives considered** A remote MCP card would not provide vault access. A local CLI or a third-party MCP package adds installation and credential surfaces that the official SDK avoids. ## What Changed - Added the source and generated catalog definition, permission review, official light/dark artwork, documentation, and capability-map references. - Added a provider-owned SDK bridge with strict schemas, account-domain validation, contract hashes, fixed errors, bounded output, and disposable workers with cancellation/deadlines. - Registered the provider through master's native-provider catalog; existing setup, health, discovery, gateway, policy, and audit owners remain in place. - Labeled the single password field **Paste your 1Password Service Account token**. The shared formatter preserves explicit credential prompts; ordinary key labels retain their existing presentation. - Added credential-ownership, gateway read/write, policy/revocation, worker, setup UI, and interactive Storybook coverage. ## Verification - Final review follow-up: added two deterministic worker-entry tests for nested exact-token redaction and oversized-output rejection. Removing each guard caused exactly its regression test to fail. The focused provider suite passed **15 tests**, and the official server typecheck passed after rebuilding stale workspace SDK artifacts. Current head `569cb7f9bd57db791fb13a6034ce69bf50878cb1` passed the full [CI run](https://github.com/paperclipai/paperclip/actions/runs/40016166260), including typecheck, build, unit/integration tests, and all eight browser shards. The required `ci / verify` and `ci / e2e` gates passed. [Greptile](https://github.com/paperclipai/paperclip/pull/17249#issuecomment-6353731805) and [Paperclip Review](https://github.com/paperclipai/paperclip/pull/17249#issuecomment-6372165895) each rated this exact head **5/5**, with no open findings. Paperclip Review completed with a neutral check because its scoped reviewer could not inspect CI; the full CI result was verified separately. Other neutral checks and intentionally skipped Storybook jobs contain no actionable findings. - CI recovery on the same commit: the first attempt lost six jobs. Five logged simultaneous runner shutdowns at 18:49 UTC on 2026-10-23; the sixth stopped logging before a test result and its root cause was not established. No assertion failure appeared in the retrieved logs. All six jobs and the aggregate gates passed one failed-job retry. [CI run](https://github.com/paperclipai/paperclip/actions/runs/40005754936). - Copy follow-up: the catalog, provider, and setup UI suites passed **275 tests**. The governed gateway lifecycle passed **3 tests** (one live-only test skipped), including create, update, archive, and delete. UI token gates and map checks passed. The branch was rebased onto `9c442cf48e` to resolve additive catalog conflicts while retaining the Vercel and Supabase entries. The existing live write proof below remains applicable; this follow-up changes presentation only. - Five affected suites, including the existing Daytona consumer, passed **290 tests** (one opt-in live test skipped in fixture mode). Full `pnpm -r typecheck` and `pnpm build` passed. The local broad-suite attempt could not complete because PostgreSQL semaphore exhaustion prevented a competing integration suite from starting; the complete affected-file retry passed after disposable-process cleanup. The prior commit `f208a8aff6dc28859cc3f343497e18d85f124579` passed the complete CI matrix. All CI build, typecheck, test, and browser gates also passed on the earlier commit `9e2f3d3140368a08da43b004b2e8d3a0f4c0fa4d`. The separate Paperclip Review reported a worker-result regression-test gap on that head; the follow-up above addresses it. Its review thread is resolved, and both fresh current-head reviews are clean as recorded above. - Token gates, module boundaries, brand validation, map checks, and Storybook catalog checks passed. - Direct SDK create/archive/delete and rejected-call coverage passed (13 provider tests); the Storybook Permissions/Test play completed successfully in Chromium. Server and UI typechecks passed after those fixes. Greptile passed prior commit `9e2f3d3140368a08da43b004b2e8d3a0f4c0fa4d` at **5/5**. Both reviewers also passed the worker-test follow-up at **5/5** as recorded above. - Live 1Password proof on 2026-10-22: connect, eight-action discovery, vault listing through an actual run-scoped gateway, refresh, reconnect preserving identity, another read, removal, and denial through the retained session passed. Credential absence was asserted in responses/audit; an exact-token scan of inspected logs and changed files passed. - Real browser: Connectors → 1Password → token entry → personal access limited to one disposable agent → completion → Permissions → Test `onepassword_list_vaults` succeeded. The disposable connection was removed afterward. - Compiled-worker smoke initially exposed inherited Node launch flags. Workers now use explicit empty `execArgv`; the compiled worker then authenticated successfully and listed one vault. - Live write proof on **2026-10-23**: the replacement Keychain token passed all eight actions through the actual run-scoped gateway for both personal and shared credentials. The test created, listed, read, updated, resolved a secret from, archived, and deleted two synthetic items. Both were absent from subsequent item lists. Refresh/reconnect, identity preservation, removal, retained-session denial, and credential absence passed. The live suite passed **3 tests** (one fixture-only test skipped) in 116.65 seconds. The expanded fixture suite passed **3 tests** (one live-only test skipped); the 13 provider tests and server typecheck passed. An exact-token scan passed over 64 source/log files. - Failure history: the original token denied creation on 2026-10-22 and created no item. The first 2026-10-23 attempt stopped before provider calls because host PostgreSQL semaphore limits prevented test-database startup. A temporary ten-connection test profile allowed the complete retry to pass without changing shared services or host limits. A new delete-result assertion also exposed an outdated fixture response (`success` instead of `deleted`); the fixture was corrected and the complete fixture suite passed. Official contract sources: [service accounts](https://www.1password.dev/service-accounts/get-started), [SDKs](https://www.1password.dev/sdks), [item management](https://www.1password.dev/sdks/manage-items), [official JavaScript SDK](https://github.com/1Password/onepassword-sdk-js). ## Risks - Authorized item/secret reads intentionally return secret values to the agent and ordinary tool-result history. Select trusted agents and use restricted service-account vaults; the connection token itself is redacted. - New connections retain existing Paperclip action defaults, including Allowed writes/destructive actions for selected agents. 1Password still enforces the token's permissions. - Service-account access cannot be changed in place. Create a replacement account and reconnect to change vault permissions; read-only keys can connect but cannot write. - SDK authentication happens per action in a disposable worker. Calls have a 30-second maximum; cancellation stops local work, while a mutation already accepted by 1Password can still finish. Writes are never automatically retried. - Additive dependency and catalog change; no database migration. Disable/remove the connection to withdraw access, or remove the provider from catalog visibility for rollback. ## Model Used OpenAI Codex, based on GPT-6, with code editing, shell/browser tools, and live provider verification. A more specific runtime model ID and context-window limit were not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
254 lines
15 KiB
Markdown
254 lines
15 KiB
Markdown
---
|
|
navigation: {"section":"Apps, channels, and extensions","sectionOrder":50,"order":10}
|
|
---
|
|
|
|
# Connection setup
|
|
|
|
People connect an app or account, choose who may use it, and recover incomplete
|
|
setup from either Apps or a task that needs access. A saved draft, a completed
|
|
provider login, a usable connection, and a resumed task are separate checkpoints.
|
|
Chat channels additionally require an endpoint and linked sender identity.
|
|
|
|
Feature ID: `connection-setup`.
|
|
|
|
Agent access: [companion](../agent-access-map/connection-setup.md).
|
|
|
|
Prompt Injection Prevention reuses shared OpenRouter API-key setup directly from
|
|
Settings → Connections. It adds no Apps provider or transport. Credential ownership
|
|
and audience rules are the existing connection rules; saving a connection alone
|
|
does not activate the service. See [service configuration](../../doc/prompt-injection-prevention.md).
|
|
|
|
1Password is available from Apps with a service-account token and an official
|
|
service-account creation link. Its vault access is chosen in 1Password; action
|
|
policies use the ordinary Permissions screen. See [connector notes](../../doc/connections/1PASSWORD.md).
|
|
|
|
## Sub-features
|
|
|
|
- `catalog`: `connection-setup/catalog` — find a provider, inspect its available methods, and open setup;
|
|
unavailable methods explain their prerequisite rather than silently switching.
|
|
- `identity-and-access`: `connection-setup/identity-and-access` — select personal/shared identity and eligible agents;
|
|
an empty explicit selection and company-wide access must not be confused.
|
|
- `credentials`: `connection-setup/credentials` — provider sign-in, key, or generic MCP URL follows its supported
|
|
setup method; credentials are not retained in browser draft storage.
|
|
- `handoff`: `connection-setup/handoff` — provider popup/full-page callback returns to the correct setup
|
|
host with the original task intent and identity choice intact.
|
|
- `draft-recovery`: `connection-setup/draft-recovery` — cancel, Back, Save & exit, reload, Finish setup, and reconnect
|
|
preserve the exact draft rather than creating duplicate connections.
|
|
- `task-request`: `connection-setup/task-request` — only the addressed person resolves the requested connection;
|
|
usable access releases the pending task request through normal continuation.
|
|
- `channel-setup`: `connection-setup/channel-setup` — provider endpoint, represented agent, linked sender, and
|
|
communication instructions are configured before an external message is used.
|
|
- `failure`: `connection-setup/failure` — denied login, unreachable/private URL, expired credentials, and
|
|
permission errors leave an actionable state rather than a false success.
|
|
|
|
## How to get to it (user POV)
|
|
|
|
### `apps-catalog`
|
|
|
|
Open Apps (`/apps`), choose an app, and connect from its landing page. Select an
|
|
available method and access, then complete setup. Existing connections open
|
|
their details; unfinished ones offer a way to finish setup.
|
|
|
|
### `mcp-link`
|
|
|
|
Use **Connect with a link** or `/apps/byo` for a generic MCP server. Paste its
|
|
URL, select access, and follow the probe's sign-in/key guidance. Provider-specific
|
|
catalog setup and a generic endpoint may use different flows.
|
|
|
|
### `task-request`
|
|
|
|
Open the task's pending connection request and its setup action as the named
|
|
user. Setup can open in a task dialog and may use an OAuth popup. Follow the
|
|
request's original link if setup falls back to a standalone page.
|
|
|
|
### `resume-connection`
|
|
|
|
From Apps or connection details, use Finish setup, reconnect, or the offered
|
|
authentication recovery action. Reload or return from the provider before
|
|
checking whether the same saved connection became usable.
|
|
|
|
### `chat-channel`
|
|
|
|
With chat connectors enabled, select a supported chat/email provider in Apps
|
|
or open `/apps/chat/connect`. Complete that provider's endpoint setup, then
|
|
open its settings (`/apps/chat/:endpointId/settings`). Follow identity linking
|
|
as the intended sender before messaging the agent externally.
|
|
|
|
## Driving it with Playwright and the Paperclip CLI
|
|
|
|
Preconditions: follow the [baseline](./README.md#before-driving-a-journey).
|
|
Choose a disposable provider account/resource and record its auth method,
|
|
deployment mode, account ownership, and access selection. For live setup, use
|
|
the provider's documented prerequisites in the
|
|
[connector playbook](../../doc/connections/CONNECTOR-PLAYBOOK.md). Automated fixtures
|
|
do not establish OAuth registration, public callbacks, or production provider access.
|
|
|
|
### `apps-catalog`
|
|
|
|
Automated: [Browse](../../ui/src/pages/apps/Browse.test.tsx),
|
|
[unconnected app](../../ui/src/pages/apps/AppNotConnected.test.tsx), and
|
|
[AppsConnect](../../ui/src/pages/apps/AppsConnect.test.tsx) cover catalog entry,
|
|
access selection, provider-specific method choices, and setup failures with
|
|
mocked APIs. [Connection intents](../../tests/e2e/connection-intents.spec.ts)
|
|
drives store and task setup against one fake provider through a useful continuation:
|
|
|
|
```sh
|
|
pnpm exec vitest run ui/src/pages/apps/Browse.test.tsx ui/src/pages/apps/AppsConnect.test.tsx
|
|
pnpm exec playwright test -c tests/e2e/playwright.config.ts tests/e2e/connection-intents.spec.ts
|
|
```
|
|
|
|
Manual: connect from an unconnected provider landing. Select the intended
|
|
identity and agent access, complete authentication, reload, and inspect the
|
|
saved connection. Run a permitted read-only action with an eligible agent and
|
|
verify its useful result. Try an ineligible agent and confirm denial. Repeat
|
|
with a user who cannot install company-wide; the UI must not imply broad access.
|
|
|
|
Notebook is internally gated by `enablePaperclipNotebook` (default off, no settings toggle). Disabled instances hide setup/discovery and deny curated Notebook dispatch and publishing; local removal and grant revocation remain available.
|
|
|
|
Availability is catalog metadata evaluated by shared connector checks. Notebook
|
|
publication and file uploads stay in the Notebook service.
|
|
|
|
Paperclip Notebook uses the existing personal-account MCP OAuth setup at
|
|
`https://notebook.paperclip.app/mcp`. Sign in through Cloud, assign agents, and
|
|
verify tool discovery. The connection keeps its default catalog name.
|
|
Reconnect must preserve agent assignments and Allowed / Ask first / Off choices.
|
|
Removal disables local use and clears saved credentials. Remote authorization
|
|
can be revoked separately in Notebook's Connected apps screen; automatic remote
|
|
cleanup and custom keyed refresh recovery are deferred. A lost rotating-token
|
|
response may require reconnecting. Notebook tools use the selected connection's
|
|
ordinary action gateway. See [Notebook](../../doc/connections/PAPERCLIP-NOTEBOOK.md)
|
|
for the Notebook-owned uploader and fixture coverage. Live Notebook qualification
|
|
still requires the deployed service and both hosted and self-hosted clients.
|
|
|
|
Daytona follows this same key/access wizard. Its native method exposes the
|
|
published platform and Toolbox HTTP actions using provider sandbox IDs, without
|
|
a Paperclip task or lease requirement. [Daytona browser setup](../../tests/e2e/daytona-connector.spec.ts)
|
|
checks the catalog, password field, access controls, and optional organization
|
|
pin. It does not submit a key or qualify a real provider account. See
|
|
[Daytona](../../doc/connections/DAYTONA.md) for API-key authority and OAuth limits.
|
|
|
|
For Braintrust, verify US OAuth (default), US API key, EU OAuth, and EU API key
|
|
from both Apps and `/apps/connect?source=braintrust`. Inspect the exact regional
|
|
endpoint and method after Save & exit, cancellation/resume, and reconnect;
|
|
these operations must retain the saved connection and its access choices.
|
|
Verify the key stays out of browser draft storage and public responses, then
|
|
perform a bounded read and disposable write through an actual eligible run.
|
|
The [Braintrust qualification matrix](../../doc/connections/BRAINTRUST.md#qualification-record)
|
|
records completed US OAuth connect/discovery, bounded read, synthetic write
|
|
through actual process-agent gateway calls, catalog refresh, reconnect, local
|
|
removal, and structural redaction. US API-key and both EU methods still need
|
|
account-bound proof. Live token expiry/refresh, remote OAuth revocation, and
|
|
native CLI automatic capability delivery remain unqualified; public metadata
|
|
and fixtures do not establish those results.
|
|
|
|
Unikraft follows the same key/access wizard. Setup asks only for the API token;
|
|
the default metro is an optional select under Advanced, and each action can name
|
|
another published metro. [Unikraft browser setup](../../tests/e2e/unikraft-connector.spec.ts)
|
|
checks the catalog, password field, access controls and the advanced metro. It
|
|
does not submit a token or qualify a real provider account. See
|
|
[Unikraft](../../doc/connections/UNIKRAFT.md) for token authority and metros.
|
|
|
|
### `mcp-link`
|
|
|
|
Automated: AppsConnect's generic MCP cases cover probe-driven auth, private or
|
|
unreachable endpoints, preregistered clients, secret-backed headers, and unsafe
|
|
authorization URLs. These are component/API mocks, not remote provider proof.
|
|
|
|
[Catalog publication](../../server/src/__tests__/tool-catalog-publication.test.ts)
|
|
uses PostgreSQL and a controlled MCP response to check bounded writes, repeated
|
|
page entries, preserved action choices, rollback, and concurrent publication.
|
|
It does not verify a live provider's discovery contract.
|
|
|
|
Manual: connect a known test MCP URL through the link flow, verify its saved
|
|
endpoint and a read-only action, then repeat with a bad URL and wrong credential.
|
|
The error should explain the next action and preserve non-secret setup context.
|
|
Test no-auth and authenticated endpoints separately; never infer one from the other.
|
|
|
|
### `task-request`
|
|
|
|
Automated: [interaction card](../../ui/src/components/IssueThreadInteractionCard.test.tsx)
|
|
checks addressed-user controls. AppsConnect tests cover page/dialog parity,
|
|
task-bound OAuth, popup handoff, and verifying a saved connection before closing.
|
|
Withdrawn requests render a terminal acknowledgement with no setup action; the
|
|
interaction-body test and narrow Storybook journey cover this recovery state.
|
|
The connection-intents browser suite above exercises fixture-backed continuation.
|
|
|
|
Manual: ask an agent to use an unavailable app, open its request as the named
|
|
user, and complete setup in the dialog. Verify the card settles, the exact task
|
|
resumes, and the agent returns a useful provider result. Repeat the page-host
|
|
fallback and denied OAuth path. As another user, confirm that merely seeing the
|
|
task does not grant the right to resolve the request.
|
|
|
|
### `resume-connection`
|
|
|
|
Automated: AppsConnect tests cover exact-draft resume, declined OAuth, reconnect
|
|
lookup failure/retry, response-lost creation, archived connection revival, and
|
|
saved account reuse. [App detail](../../ui/src/pages/apps/AppDetail.test.tsx) covers
|
|
the connection host. These tests do not complete a real provider login.
|
|
|
|
Manual: leave setup through its footer, reload Apps, choose Finish setup, and
|
|
confirm the same connection is resumed. Decline provider login and recover from
|
|
that checkpoint. Reconnect an expired disposable account and verify a permitted
|
|
action afterwards. Count connections before/after to catch accidental duplicates.
|
|
|
|
### `chat-channel`
|
|
|
|
Automated: [setup routing](../../ui/src/pages/apps/chat/ChatEndpointSetup.routing.test.tsx),
|
|
[saved setup state](../../ui/src/pages/apps/chat/ChatEndpointSetup.state.test.ts),
|
|
[email setup](../../ui/src/pages/apps/chat/EmailEndpointSetup.test.tsx), and
|
|
[identity confirmation](../../ui/src/pages/apps/chat/ChatIdentityConfirm.test.tsx)
|
|
cover shared UI logic with fixtures. Provider-specific live setup is not implied.
|
|
|
|
[Channel integration](../../server/src/__tests__/chat-channels.integration.test.ts)
|
|
also covers bounded Telegram subscription recovery at startup and after committed
|
|
configuration changes, saved retry deadlines, rollback, and parking pending
|
|
repair while an endpoint or connection is inactive. The provider responses are
|
|
fixtures. Settled maintenance leaves no discovery timer or database scans.
|
|
|
|
Manual: complete setup for one named provider, reload endpoint settings, link
|
|
the intended sender, and send a disposable message. Verify one task and a useful
|
|
reply in the originating conversation. Inspect an unlinked sender's denial and
|
|
the endpoint's pause behavior. Repeat independently for each provider at issue;
|
|
Slack setup does not qualify Discord, Telegram, GitHub, email, or iMessage.
|
|
|
|
## Gotchas
|
|
|
|
- For connecting an assistant to Paperclip itself, use [Assistant connections (MCP)](./assistant-connections.md). This recipe's MCP-link journey connects Paperclip to an external app server.
|
|
- Private endpoint rejection depends on deployment: owned loopback MCP servers
|
|
are supported in local-trusted/private instances. Public authenticated
|
|
deployments apply the private-network restriction.
|
|
|
|
- A successful OAuth callback is not proof of saved connection access or task
|
|
continuation. Verify all three checkpoints.
|
|
- Personal identity, shared account access, and per-agent access are distinct.
|
|
Connecting an account does not waive an Off action or Ask first review.
|
|
- A tool app connection is not a chat endpoint. The same provider can offer both.
|
|
- Old Apps/Connections URLs can redirect to Apps. Use the current navigation and
|
|
record the actual destination rather than documenting an obsolete screen.
|
|
- Full provider matrix, AI-account selection, gateway/profile administration,
|
|
and account revocation lifecycles remain outside this seed recipe.
|
|
- For governed actions after setup, use [questions and approvals](./questions-and-approvals.md).
|
|
|
|
### Documentation scope: App catalog and connection setup
|
|
|
|
Provider-specific authentication/revocation, credential-only accounts, and aggregator administrative variants still need their own detailed matrices.
|
|
|
|
Supabase and Vercel deployment connections (2026-10-22): Apps offers Supabase
|
|
browser sign-in, hosted MCP personal access token, and project-scoped Management
|
|
API methods, plus Vercel's team-scoped access token method. Supabase's optional
|
|
MCP project pin leaves project creation available when unset; the native method
|
|
requires a project and offers Edge Function deployment and selected configuration.
|
|
Vercel supports preview/production deployment, build settings, environment
|
|
variables and existing domain attachment. Personal/shared credential ownership,
|
|
action permissions, reconnect and removal use the regular setup flow. See
|
|
[Supabase](../../doc/connections/SUPABASE.md) and
|
|
[Vercel](../../doc/connections/vercel.md) for method boundaries and qualification.
|
|
|
|
For these native methods, continue past a successful connection test into an
|
|
actual native agent task: readiness, assigned-tool delivery, and task-card reuse
|
|
must all work. The 2026-10-23 walkthrough exposed and repaired omitted REST
|
|
admission at those boundaries. Verify a served deployment and provider settings,
|
|
not only the catalog action count. Vercel preview requires an existing deployment;
|
|
its provider makes the first deployment production, so an empty-project preview
|
|
must fail before submission and explain the explicit production prerequisite.
|