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>
317 lines
14 KiB
Markdown
317 lines
14 KiB
Markdown
# Connection setup — agent access
|
|
|
|
Product map: [Connection setup](../feature-map/connection-setup.md).
|
|
|
|
Feature ID: `connection-setup`.
|
|
|
|
Review date: 2026-10-12. Source commit: `f981fa3cc10cb8663a87dec60345fbff46d54d0a`.
|
|
|
|
This is a source-reviewed baseline of representative operations and known gaps.
|
|
Each capability needs operation-level review before its entire scope can be
|
|
qualified. No live agent execution is claimed. Follow the [map contract](../README.md)
|
|
for format, permission checks, evidence and maintenance.
|
|
|
|
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 adds a service-account catalog method. Agents request access through
|
|
the existing connection tools and invoke its reviewed item actions through the
|
|
run-scoped gateway. The service-account token stays in the selected user/company
|
|
vault; vault boundaries are enforced by 1Password. Setup remains board-owned.
|
|
Evidence and limits: [1Password connector](../../doc/connections/1PASSWORD.md).
|
|
|
|
## `catalog`
|
|
|
|
Capability ID: `connection-setup/catalog`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /runtime-tools/connections/search`.
|
|
|
|
Agent access: `available` — Native connections_search / run-bound runtime-tools MCP.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — exercise a listed permitted operation with actual agent
|
|
credentials/run context; inspect its result and applicable persistence/attribution.
|
|
Assert the relevant denied actor, owner, company or mode from Policy. Review the
|
|
remaining operations before qualifying the whole capability.
|
|
|
|
Gaps: Runtime tool broker searches available services without granting connection
|
|
administration.
|
|
|
|
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.
|
|
|
|
The connector catalog declares the feature key. Shared availability checks use
|
|
the saved application identity. Notebook owns publication and file uploads;
|
|
Paperclip uses its existing MCP tools and OAuth flow.
|
|
|
|
Notebook source addition: `paperclip-notebook` is discoverable through
|
|
`connections_search` and requestable through `connection_request`. Its standard
|
|
personal authorization requests read, write, share, and delete scopes. Notebook
|
|
page ownership remains enforced by the remote service; a client-supplied agent
|
|
label grants no authority. The direct MCP connection requires no Cloud instance
|
|
enrollment. Notebook fixture evidence: `verified` against disposable PostgreSQL 18
|
|
with controlled MCP responses — [Notebook integration](../../doc/connections/PAPERCLIP-NOTEBOOK.md)
|
|
and [generic OAuth fixture](../../server/src/__tests__/generic-mcp-connection.test.ts).
|
|
Ordinary MCP calls retain assignment and Allowed / Ask first / Off policy.
|
|
Live deployed publication and hosted/self-hosted OAuth remain release checks.
|
|
|
|
|
|
## `identity-and-access`
|
|
|
|
Capability ID: `connection-setup/identity-and-access`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /api/companies/{companyId}/tools/connections`.
|
|
|
|
Agent access: `restricted` — Board setup API plus agent connection_request.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — assert the documented agent denial with an owned test fixture;
|
|
verify any listed agent request/result path separately. A delegated operation needs its
|
|
own policy and access review.
|
|
|
|
Gaps: Selecting account ownership/eligible agents is management; an agent can request
|
|
the intended connection.
|
|
|
|
## `credentials`
|
|
|
|
Capability ID: `connection-setup/credentials`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /api/agents/me/connections/{connectionId}/start-authorization`.
|
|
|
|
Agent access: `partial` — Scoped start-authorization/request flow; human provider login.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — exercise a listed permitted operation with actual agent
|
|
credentials/run context; inspect its result and applicable persistence/attribution.
|
|
Assert the relevant denied actor, owner, company or mode from Policy. Review the
|
|
remaining operations before qualifying the whole capability.
|
|
|
|
Gaps: An initiation endpoint exists; it is not authorization to complete the person's
|
|
credential flow.
|
|
|
|
Braintrust uses the existing setup/request path for US and EU OAuth and API-key
|
|
methods. OAuth requests only `mcp`; provider authorization follows the selected
|
|
account's permissions. Personal invocation credentials must belong to their
|
|
user, while shared identities use company credentials. Region and explicit
|
|
method survive resume and reconnect. Agents use assigned tools through the
|
|
run-scoped gateway and receive no Braintrust token. See
|
|
[Braintrust](../../doc/connections/BRAINTRUST.md) for method keys and the
|
|
qualification matrix. Separate live US OAuth proof passed browser authorization,
|
|
49-tool discovery, bounded read, synthetic dataset insert/readback through actual
|
|
process-agent runs and gateway sessions, catalog refresh, OAuth reconnect, local
|
|
removal, post-removal denial, and structural API/log redaction. US API-key and
|
|
both EU methods remain `not-run` against real accounts. Live token expiry/refresh,
|
|
remote OAuth revocation, and native CLI automatic capability delivery remain
|
|
unqualified. Public metadata probes performed no registration or account
|
|
authorization; fixtures do not establish live proof for the remaining methods.
|
|
|
|
Daytona native setup uses an organization API key in the selected personal or
|
|
company vault grant. It does not borrow sandbox-provider credentials or CLI
|
|
login tokens. Agents use assigned provider tools through the normal run-bound
|
|
gateway; they cannot export the key. [Database-backed fixtures](../../server/src/__tests__/daytona-connection.test.ts)
|
|
cover selected vault ownership and gateway reads/writes with provider responses
|
|
replaced by fixtures. Real provider authentication remains unqualified.
|
|
|
|
Unikraft native setup uses an organization API token in the selected personal or
|
|
company vault grant. It does not borrow `unikraft login` state or `UKC_TOKEN`.
|
|
Agents use assigned provider tools through the run-bound gateway, limited to the
|
|
published metro hosts, and cannot export the token. [Database-backed fixtures](../../server/src/__tests__/unikraft-connection.test.ts)
|
|
cover vault ownership and gateway reads, writes and sandbox commands with
|
|
fixture provider responses. Real provider authentication remains unqualified.
|
|
|
|
## `handoff`
|
|
|
|
Capability ID: `connection-setup/handoff`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /api/connection-intents/{interactionId}/complete`.
|
|
|
|
Agent access: `restricted` — Addressed-user completion; server wakes the agent with
|
|
updated access.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — assert the documented agent denial with an owned test fixture;
|
|
verify any listed agent request/result path separately. A delegated operation needs its
|
|
own policy and access review.
|
|
|
|
Gaps: OAuth/callback and addressed-user checks are deliberate separate boundaries.
|
|
|
|
## `draft-recovery`
|
|
|
|
Capability ID: `connection-setup/draft-recovery`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /api/connection-intents/{interactionId}/phase`.
|
|
- `POST /api/tool-connections/{connectionId}/reconnect`.
|
|
|
|
Agent access: `restricted` — Human setup/resume APIs; agent request state and
|
|
continuation.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — assert the documented agent denial with an owned test fixture;
|
|
verify any listed agent request/result path separately. A delegated operation needs its
|
|
own policy and access review.
|
|
|
|
Gaps: Board setup recovery exists. Browser-only navigation state is not automatically an
|
|
agent API gap.
|
|
|
|
## `task-request`
|
|
|
|
Capability ID: `connection-setup/task-request`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /runtime-tools/connections/request`.
|
|
|
|
Agent access: `available` — Native connection_request / run-bound runtime-tools MCP.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — exercise a listed permitted operation with actual agent
|
|
credentials/run context; inspect its result and applicable persistence/attribution.
|
|
Assert the relevant denied actor, owner, company or mode from Policy. Review the
|
|
remaining operations before qualifying the whole capability.
|
|
|
|
Gaps: This is the existing agent bridge for human-required setup; do not invent a second
|
|
approval system.
|
|
|
|
## `channel-setup`
|
|
|
|
Capability ID: `connection-setup/channel-setup`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /api/companies/{companyId}/chat-endpoints`.
|
|
|
|
Agent access: `restricted` — Board channel management; agent requests required setup.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — assert the documented agent denial with an owned test fixture;
|
|
verify any listed agent request/result path separately. A delegated operation needs its
|
|
own policy and access review.
|
|
|
|
Gaps: Provider endpoint, represented agent and linked sender are operator choices today.
|
|
|
|
Internal recovery: Telegram discovery walks bounded pages at startup. Configuration
|
|
commits only queue the changed connection; durable maintenance rows supply retry deadlines. Inactive subscription
|
|
repair is parked until an endpoint or connection change. This creates no agent
|
|
management permission or new API. Local database-backed provider-fixture tests in
|
|
[channel integration](../../server/src/__tests__/chat-channels.integration.test.ts)
|
|
cover recovery, rollback, retries and idle query silence; they do not establish
|
|
live provider or agent access.
|
|
|
|
## `failure`
|
|
|
|
Capability ID: `connection-setup/failure`.
|
|
|
|
Review: `baseline`.
|
|
|
|
API: `present` — representative operation IDs:
|
|
|
|
- `POST /api/tool-connections/{connectionId}/health-check`.
|
|
|
|
Agent access: `partial` — Agent observes connection tool errors; board repair APIs.
|
|
|
|
Policy: Setup and credentials belong to the addressed authorized human; active-run tools
|
|
can search/request access.
|
|
|
|
Evidence: `source-only` —
|
|
[implementation](../../server/src/routes/connection-intents.ts#L130) at the reviewed
|
|
commit above.
|
|
|
|
Verification: `not-run` — exercise a listed permitted operation with actual agent
|
|
credentials/run context; inspect its result and applicable persistence/attribution.
|
|
Assert the relevant denied actor, owner, company or mode from Policy. Review the
|
|
remaining operations before qualifying the whole capability.
|
|
|
|
Gaps: Error reporting and human repair exist; no generic agent permission to reconnect
|
|
accounts.
|
|
|
|
Supabase and Vercel deployment methods (2026-10-22) reuse human-authorized setup
|
|
and assigned run-scoped tools. Native Supabase calls use the saved project;
|
|
native Vercel calls use the saved team and validate project ownership. Tokens
|
|
remain in the selected personal/company vault grant and cannot be exported by
|
|
`mintConnectionTokenForAgent`. Action policies, changed-schema quarantine,
|
|
responsible-user access and immediate removal apply to deployment/configuration
|
|
calls. Database/provider-fixture evidence lives in
|
|
[deployment connector governance](../../server/src/__tests__/deployment-connections.test.ts).
|
|
It does not establish authenticated provider deployment, OAuth consent or remote
|
|
revocation. See [Supabase](../../doc/connections/SUPABASE.md) and
|
|
[Vercel](../../doc/connections/vercel.md) for the remaining live-proof matrix.
|
|
|
|
Native delivery (2026-10-23): reviewed REST connections are admitted in connection
|
|
readiness, native runtime snapshots, and runtime gateway preparation. The real
|
|
Codex walkthrough initially failed at all three despite a successful board test;
|
|
the database-backed lifecycle regression now covers ready search/request,
|
|
existing-card completion, assigned-tool search/call, and inactive/unrecognized
|
|
connection denial for both providers. After repair, a real Codex agent deployed
|
|
and configured both services. Supabase's Dashboard invocation returned the marker,
|
|
and Vercel's signed-in browser served the preview. The Vercel first-deployment
|
|
production exception remains recorded as a separate failed outcome; default
|
|
preview now requires an existing deployment and reports target mismatches for
|
|
reconciliation. See the provider documents for the external-deletion race limit.
|