@penstock/paperclip-plugin
v0.1.5
Published
Paperclip connector that routes Anthropic-compatible agent traffic through api.penstock.run.
Readme
@penstock/paperclip-plugin
Reusable Paperclip connector plugin for routing Anthropic-compatible Paperclip agent traffic through managed Penstock.
Contract
- Source contract: PEN-245
- Implementation issue: PEN-248
- Default API base:
https://api.penstock.run - Anthropic proxy base:
https://api.penstock.run/anthropic
Security Model
- Org keys are represented by host secret references such as
PENSTOCK_ORG_KEY. - Secret values are resolved at runtime through
ctx.secrets.resolveand are never written into plugin config, agent adapter config, logs, UI, or test fixtures. - The plugin refuses activation when the host SDK does not expose agent adapter writes; it does not call private APIs or guess config shapes.
- Full-fleet
enabledmode is not the default and should only follow the external cutover runbook and founder go/no-go.
ccrotate Migration Compatibility
The plugin exposes a conservative ccrotate-compatible facade under its normal Paperclip plugin API namespace:
GET /api/plugins/penstock.paperclip-plugin/api/snapshotGET /api/plugins/penstock.paperclip-plugin/api/statusPOST /api/plugins/penstock.paperclip-plugin/api/refreshGET /api/plugins/penstock.paperclip-plugin/api/state
These routes read Penstock core's compatibility endpoints first:
GET /v1/serve-pool/compat/snapshotGET /v1/serve-pool/compat/status
During rollout skew, the plugin falls back to translating /v1/pools/default
and /v1/pools/default/health locally. Both paths intentionally use
placeholder account identities such as [email protected] rather
than provider account emails.
Per-account ccrotate mutation routes are also declared so callers fail closed with an explicit migration error instead of a 404:
/switch/set-session/import/statePOST/clear-stale-tiers/refresh-one/claude-relogin/codex-relogin
Paperclip plugins cannot own top-level paths such as
$PAPERCLIP_BASE_URL/ccrotate/*; plugin API routes are always mounted under
/api/plugins/:pluginId/api/*. During BLO migration, keep the existing
/ccrotate/* auth-proxy route in place until a deployment-level proxy is
repointed to Penstock and the Anthropic route has a healthy BYOS node.
Development
pnpm install
pnpm typecheck
pnpm lint
pnpm test
pnpm build
npx paperclipai plugin install /absolute/path/to/paperclip-plugin
npx paperclipai plugin inspect @penstock/paperclip-pluginHost Capability Status
The consumed SDK (@paperclipai/plugin-sdk → @penstock/[email protected]) exposes
ctx.agents.updateAdapterOverrides (capability agents.adapter.write) and
ctx.secrets.create / ctx.secrets.rotate (capability secrets.manage), in addition to
ctx.agents.list and ctx.secrets.resolve (secrets.read-ref). Live canary / enabled /
rollback activation is implemented: applyRepoint (src/worker.ts) calls
updateAdapterOverrides for each targeted agent and clears the override on rollback (the
host restores the pre-override adapter snapshot it captured in the config revision).
Activation fails closed — if the host lacks the capability or does not implement the method,
the SDK dispatch throws rather than silently no-op'ing.
Remaining, by design:
- Org-key secret provisioning is operator-driven. The plugin declares
secrets.read-refand resolvesactiveOrgKeySecretRef; it does not declaresecrets.manageand does not create or rotate the org key itself. Provision the Penstock org key as a host secret and setactiveOrgKeySecretRefin plugin config. To let the plugin create/rotate the org key in-band, addsecrets.manageto the manifest plus a rotation action — not enabled by default. - Cutover sequencing. Repointing real agents at managed
api.penstock.runis gated on the native managed serve being live (retiring legacyccrotate-serve, tracked in Penstock as PEN-1039 / PEN-1017). Until then, usepreview/canaryagainst the ccrotate-compat facade.
