docs(connections): cross-reference the identity model (identity vs. connections) (#9953)

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Integrations are governed through the Apps v2 "connections"
substrate documented in `doc/connections/`
> - Contributors adding connectors had no written boundary between
*signing a user in* (identity) and *connecting an external resource* (a
connection), so app-store work could drift into merging the two
> - Unwritten, that boundary risks a design where a sign-in provider's
token gets reused as a resource token, or the identity service grows a
connections hub — exactly the failure the separation exists to prevent
> - This pull request adds an "Identity vs. connections" section to the
public connections docs that names the three planes, states the standing
rule verbatim, and aligns naming across surfaces
> - The benefit is that connector implementers inherit the
identity/connection boundary from accessible repository documentation
instead of re-deriving it

## Linked Issues or Issue Description

Docs-only change. No public GitHub issue.

**Problem:** The `doc/connections/` docs describe how to add a connector
(the First-30 matrix and connector playbook) but never state where
identity ends and connections begin. Without an accessible statement of
that boundary, connector work can accidentally blur sign-in tokens and
resource tokens.

**Change:** Adds a public reference section fixing the boundary and
makes it self-contained for contributors without access to private
identity-service implementation documentation.

## What Changed

- `doc/connections/README.md`: adds an **Identity vs. connections**
section with the P1/P2/P3 model, D7 standing rule, rationale, naming
alignment, and canonical-doc cross-reference.
- `doc/connections/FIRST-30-MATRIX.md`: notes that every listed provider
is a plane-P2 connection and links the new section.
- `doc/connections/CONNECTOR-PLAYBOOK.md`: points connector authors to
the boundary and standing rule before implementation.
- Removes inaccessible private-repository documentation links so every
reference in the new public guidance is usable by contributors.

## Verification

- `git diff --check origin/master...HEAD`
- Verified Markdown table column consistency across the three changed
files.
- Verified no private `paperclip-id` URLs or new internal Paperclip
issue references remain in the diff.
- Current-head CI is fully green, including typecheck, build,
server/workspace tests, serialized suites, canary, and both e2e shards.
- Greptile reviewed commit `d964abab50b39a79fef394c0b1855dd1f2e4b92b` at
5/5 with no unresolved findings; its connections-doc validation returned
`RESULT: PASS`.

## Risks

Low risk — documentation only. No code, schema, migration, or runtime
behavior changes.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Anthropic Claude Opus 4.8 (`claude-opus-4-8`), 1M context, extended
thinking with tool use, authored the initial documentation change.
- OpenAI Codex CLI (runtime model identifier not exposed to this
session), agentic reasoning with shell and GitHub tooling, performed PR
preparation, rebase, review-loop diagnosis, and the public-link
correction.

## 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>
This commit is contained in:
Dotta 2026-07-27 19:12:57 -05:00 committed by GitHub
parent 1426494ab8
commit 3b0156238a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 62 additions and 0 deletions

View File

@ -4,6 +4,8 @@ This playbook is the repeatable template for adding a vendor to the Apps catalog
Use it when Paperclip acts on an external system through a governed connection: a stored credential, a capability catalog, access profiles and policy rules, and audit. Inbound integrations, such as an external client acting on Paperclip, use gateway or webhook guidance instead.
Every connector built with this playbook is a **plane P2** connection — a resource token in the instance vault, acquired via the connect broker, never a sign-in authenticator. Before writing a connector, read [Identity vs. connections](./README.md#identity-vs-connections) for the P1/P2/P3 boundary and the D7 standing rule (sign-in tokens are never reused as resource tokens; id.paperclip.ing never stores resource tokens; no connections hub on the ID service).
## Output
A complete connector proposal produces:

View File

@ -9,6 +9,11 @@ review gates for a provider before writing a connector ticket or playbook entry.
Source: harvested from [PAP-2432](/PAP/issues/PAP-2432) and made canonical for
the [PAP-13211](/PAP/issues/PAP-13211) Apps v2 unification program.
> Every provider here is a **plane P2** connection: a resource token in the
> instance vault, acquired via the connect broker — never a sign-in method. See
> [Identity vs. connections](./README.md#identity-vs-connections) for the P1/P2/P3
> boundary and the D7 standing rule.
## Batch Recommendation
First implementation batch after the proof providers:

View File

@ -69,6 +69,59 @@ The agent should not hold a durable provider credential. It should hold a
Paperclip run/session token; the server or broker resolves the connection,
checks governance, invokes the provider, and writes audit.
## Identity vs. connections
Signing a user *in* and connecting a *resource* are different planes with
different owners, different token profiles, and different homes. Do not merge
them. This section is the public, connections-side statement of the identity
model so connector implementers inherit the rule without depending on private
identity-service documentation or re-deriving it.
| Plane | Question | Lives where | Token profile |
| --- | --- | --- | --- |
| **P1. Sign-in methods** | *Who are you?* | `paperclip-id` (id.paperclip.ing → Account) | Minimal-scope provider tokens (`openid email profile`), used once to authenticate, encrypted at rest, never exported |
| **P2. Connections (Apps)** | *What may your agents touch?* | Paperclip App instances (`tool_connections`), acquired via the **connect broker** for hosted + self-hosted | Rich-scope, long-lived resource tokens in the **instance's** encrypted vault; per-agent grants; ask-first on writes |
| **P3. Login with Paperclip** | *Who may authenticate against us?* | `paperclip-id` OIDC provider + DB-backed client registry | Our ES256 ID/access tokens issued *by* us to registered RPs (instances, the broker, future third parties) |
Everything in `doc/connections/` — the [First-30 matrix](./FIRST-30-MATRIX.md),
the [connector playbook](./CONNECTOR-PLAYBOOK.md), and the connect-broker work —
lives on **plane P2**. It never acquires, stores, or brokers a P1 sign-in token.
### The standing rule (D7)
Adopted as a standing rule (decision D7) with the identity-model plan. State it
verbatim in any P2 design so the app-store work cannot drift into merging the
planes:
> Sign-in tokens are never reused as resource tokens; id.paperclip.ing never
> stores resource tokens; no connections hub on the ID service.
P2 tokens flow broker → instance vault as pass-through only; the id.paperclip.ing
Account page therefore must **not** grow a "Connections" hub. The reasons to
hold the planes apart (from the plan §3):
- **Scope discipline.** Sign-in wants the narrowest grant; connections want
deliberately broad ones. One button that does both is how you grant repo
access just to log in.
- **Blast radius.** id.paperclip.ing holding every customer's Vercel/Slack/GitHub
resource tokens would make it the single juiciest target in the fleet; the
broker is intentionally pass-through.
- **Self-hosted symmetry.** Instances own their vaults, so self-hosters don't
depend on our uptime to *use* their own connections.
- **Legibility.** Sign-in and connections answer different user questions, and
every product we benchmarked (Vercel, Railway, GitHub, Google) keeps them on
separate pages with separate names.
### Naming alignment
Use the surface-correct name for each plane; they intentionally differ:
| Surface | Plane | Name to use |
| --- | --- | --- |
| Paperclip App instances | P2 | **"Connections"** |
| id.paperclip.ing Account | P1 | **"Ways to sign in"** |
| id.paperclip.ing admin | P3 | **"OIDC clients"** (until the app store productizes it) |
## Packaging Rule
Default to a **catalog entry** when an integration can be described as metadata:
@ -85,6 +138,8 @@ not own durable tokens.
## Canonical Docs
- [Glossary](./GLOSSARY.md) defines product and internal terms.
- [Identity vs. connections](#identity-vs-connections) is the public statement
of the P1/P2/P3 boundary and the D7 standing rule for connections work.
- [Security threat model](./SECURITY-THREAT-MODEL.md) harvests the keeper from
[PAP-2359](/PAP/issues/PAP-2359) and maps it onto Apps v2.
- [First-30 matrix](./FIRST-30-MATRIX.md) harvests the keeper from