Files
PaperClipAI/doc/connections/1PASSWORD.md
T
DottaandPaperclip 4d90634f74 feat(connections): add 1Password service-account connector (#17249)
## 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>
2026-10-23 13:27:33 -07:00

155 lines
9.1 KiB
Markdown

# 1Password
Connect from **Connectors → 1Password**, choose who can use the connection, and
fill **Paste your 1Password Service Account token**. Setup links directly to
[Create a service account](https://www.1password.dev/service-accounts/get-started#create-a-service-account).
No desktop sign-in, CLI installation, Connect server, or OAuth application is
required. Change agent access and action policies on **Permissions** after setup.
## Provider contract
Reviewed on 2026-10-22 against the official
[service-account guide](https://www.1password.dev/service-accounts/get-started),
[SDK documentation](https://www.1password.dev/sdks), and
[item-management guide](https://www.1password.dev/sdks/manage-items).
The implementation pins the official `@1password/sdk` to **0.5.0**. 1Password's
documentation MCP server searches documentation; it is not an authenticated vault
integration. This connector uses a provider-owned SDK bridge through the existing
`rest_api` connection path, rather than advertising an unsupported remote MCP URL.
Create a service account with access only to the vaults the selected agents need.
Grant **Read Items** and **Write Items** for reading and managing items. An existing
read-only token can connect; provider permissions still deny its writes. Vault
access and permissions are immutable: create a replacement service account and
reconnect in Paperclip to change them. Built-in Personal, Private, Employee, and
default Shared vaults cannot be selected. Creating a service account requires a
1Password subscription and the appropriate account permissions.
The method is `1password/service-account`. Its configured URL
`https://my.1password.com/` is a routing identity, not a public REST or MCP endpoint.
The SDK uses the account address in the token and handles regional API access.
Paperclip accepts only HTTPS account addresses under `1password.com`,
`1password.ca`, or `1password.eu`, without custom ports, paths, or URL credentials.
There are no OAuth metadata, registration, callback, refresh, or revocation
endpoints in this method. Reconnect replaces the token through the normal vault
credential writer; provider revocation is managed in 1Password.
## Actions and governance
| Action | Risk | Result |
| --- | --- | --- |
| `onepassword_list_vaults` | Read | Vaults authorized by the service account |
| `onepassword_list_items` | Read | Item summaries in one vault |
| `onepassword_get_item` | Read | An item including its secret fields |
| `onepassword_resolve_secret` | Read | The value of one `op://vault/item/field` reference |
| `onepassword_create_item` | Write | A new Login, Password, API Credentials, or Secure Note item |
| `onepassword_update_item` | Write | An item with specified properties updated |
| `onepassword_archive_item` | Destructive | An archived item |
| `onepassword_delete_item` | Destructive | A deleted item |
Updates preserve the SDK's item version and omitted properties. Supplied `fields`
and `tags` arrays replace their previous arrays. Supported editable field types
are Text, Concealed, Totp, Url, and Email. Vault and item operations require IDs;
secret references support the provider's ordinary `op://` format. Vault
administration, sharing, document/file exports, and arbitrary commands are not
exposed. 1Password enforces the service account's vault boundary on every call.
All actions use existing company, agent, responsible-user, connection-grant,
profile, Allowed / Ask first / Off, quarantine, and audit checks. Setup uses the
existing default of all discovered actions Allowed for the chosen agents. The
credential field explicitly describes required vault permissions. Select trusted
agents: item reads and secret-reference resolution intentionally return secret
values to the agent and ordinary tool-result history. The service-account token
itself is always redacted, including if it is stored in an item being read.
Personal setup creates user-owned secrets and declarations; shared setup creates
company-owned secrets. Credentials never enter connection configuration or agent
environment variables. The worker receives only the selected invocation token
and validated arguments. It has no inherited environment or desktop identity.
Each invocation starts a disposable worker to isolate SDK initialization and
cryptography from the API event loop. There is no background polling or retained
SDK client. The worker is terminated on completion or deadline (15 seconds for
discovery, at most 30 seconds for calls). Termination stops local work; an already
accepted provider mutation can finish remotely. Writes are never retried
automatically. Provider errors use fixed actionable messages, and worker output
is bounded to 1 MiB; raw SDK errors and stdout/stderr never enter server logs.
## Verification
`server/src/services/connectors/onepassword/onepassword.test.ts` exercises strict
arguments, patch preservation, forged endpoint rejection, and actual worker
deadline termination with unrelated event-loop progress.
`server/src/services/connectors/onepassword/worker.test.ts` executes the worker
entry point with synthetic SDK results to verify nested token redaction and
oversized-result rejection before posting a result to the gateway.
`server/src/__tests__/onepassword-connection.test.ts` exercises encrypted
credential ownership, personal declarations, reads and writes through a running
agent's gateway session, classification, refresh, reconnect, action policy,
cross-company denial, and revocation of a retained session. The ordinary suite
uses provider fixtures. `PAPERCLIP_ONEPASSWORD_LIVE=1` plus an environment-supplied
`OP_SERVICE_ACCOUNT_TOKEN` enables the account-bound variant, which creates and
deletes only synthetic test items. Never put a token in a command argument.
Setup and management use the production components; the 1Password Storybook
stories provide catalog, token, rejection, inline task setup, narrow-screen, and
Permissions/Test simulations. These fixtures do not establish provider access.
Live qualification status is recorded in
[`tool-method-permission-reviews.json`](./tool-method-permission-reviews.json).
On 2026-10-22, the supplied account passed live connect, eight-action discovery,
vault listing through a running agent's gateway, catalog refresh, token
replacement/reconnect preserving the connection ID, another gateway read,
removal, and denial through the retained gateway session. Audit and connection
responses did not contain the credential. The account could list one vault but
1Password denied a minimal synthetic item creation for lack of permission; no
item was created.
On 2026-10-23, a replacement token with Write Items permission passed the live
governed lifecycle for both personal and shared credentials. All eight actions
ran through an actual run-scoped gateway: list vaults, create and list a
synthetic item, read it, update it and verify the update, resolve its secret
reference, archive it, and delete it. Catalog refresh, reconnect, another read,
connection removal, and retained-session denial also passed. Both synthetic
items were deleted, and their absence from item listings was verified. Audit,
responses, and the captured log did not contain the credential.
The first 2026-10-23 attempt stopped before any provider call because the host
had exhausted PostgreSQL semaphores. The passing run used a temporary test-only
PostgreSQL profile with ten connections and fewer workers; no shared service or
host limit was changed. The deterministic provider suite covers mutations and
the ordinary policy boundaries separately.
The browser walkthrough used a fresh local test instance, a personal credential,
and one explicitly selected disposable agent. It reached the normal Permissions
screen with all eight actions. Initial setup failures during development (a
canonical URL mismatch and a rewritten token label) were corrected before the
passing walkthrough. An inherited Node `--input-type` flag also broke the first
compiled-worker smoke; workers now start with an explicit empty Node argument
list, and packaging is verified separately from source execution.
## Branding provenance
Official source: 1Password's product site, retrieved 2026-10-22:
- Light theme: `https://1password.com/favicon/icon-v2.svg`
- Dark theme: `https://1password.com/favicon/icon-v2-light.svg`
The native icon shapes and colors are preserved. Each SVG adds only an explicit
matching `viewBox` so the official icon scales inside Paperclip's standard gray
frame. The browser-served manifest contains asset paths only.
## Shared changes
1Password owns its schemas, SDK mapping, account-address validation, errors,
worker lifecycle, and result sanitization under
`server/src/services/connectors/onepassword/`. The existing native-provider
catalog registry registers its probe, tools, classification, contract hashes,
and executor. Shared setup, health, discovery, and gateway code dispatch that
existing contract; existing providers retain their behavior. No schema or database migration is needed.
The shared credential-label formatter preserves explicit "Paste your" prompts
from the manifest, so setup shows **Paste your 1Password Service Account token**
without a provider-specific UI branch. Ordinary key labels keep their existing
presentation.