Paperclip
Paperclip is a control plane for the AI agents you run at work: it hires them, assigns them issues, and holds their budgets and approvals. It also has its own secret store — and that is where seekrit fits, because the two answer different questions. Paperclip decides which agent may do what; seekrit decides what a credential is worth if the agent leaks it.
npx paperclipai plugin install @seekrit/paperclip-plugin
One install adds four agent tools, the three seekrit skills, and a secrets panel under the company. The rest of this page is what to configure and why the design is shaped the way it is.
Why a seekrit secret is not a Paperclip secret_ref
Start here, because it is the thing people look for and do not find.
Paperclip resolves an adapter's secret_ref through its own provider system,
and that provider list is closed: local_encrypted, aws_secrets_manager,
gcp_secret_manager, vault. There is no seekrit provider to select, so there
is no honest way to express a seekrit secret as a Paperclip secret.
The dishonest way — copying a value out of seekrit into Paperclip's store — is worse than it looks. It creates a second plaintext copy under a different lifecycle, so a rotation in seekrit silently leaves Paperclip serving the old value, and a revocation in seekrit revokes nothing. The plugin does not do it, and neither should you.
Instead, values reach a run at the moment of use, two ways.
Paperclip's execution policy governs review and approval stages. It does not cover network egress or sandboxing — that gap is exactly what the egress proxy fills.
The two paths
| Path | Use it when | What the run holds |
|---|---|---|
Inject and exec — seekrit:run_command | The run is your own tooling: a build, a test suite, a migration, a dev server | The real value, in one child process's environment |
Egress proxy — {{seekrit:NAME}} placeholders | The credential is going to a model, a sandbox, generated code, or a subagent whose output you cannot predict | Never a value — only a placeholder |
Default to the first for tooling you wrote and the second for anything an agent is about to hand onward. When both would work, the proxy is stronger: it also bounds where the credential can go.
Configure the plugin
One field is required: a seekrit service token, chosen with Paperclip's own
secret picker in Settings → Plugins → seekrit. This is the one credential that
should live in Paperclip's store — it is Paperclip's token, and it is the
ceiling on everything its agents can reach, so scope it narrowly with
seekrit access grant.
The rest are defaults so a tool call needs no arguments:
| Field | Default | What it does |
|---|---|---|
app / env / group | The target tools use when a call names none. | |
allowRunCommand | on | Turn off execution, leaving the read-only and write-only tools. |
cliPath | seekrit | Where the CLI is, if not on the host's PATH. |
timeoutSeconds | 300 | Hard cap on one tool invocation. |
The seekrit CLI must be installed on the Paperclip host: the plugin shells out to it rather than reimplementing the crypto, which is also how it avoids ever holding a plaintext itself.
What the agent gets
| Tool | Does |
|---|---|
seekrit:list_secrets | Names, versions, and when each last changed. Never a value. |
seekrit:run_command | Runs a command with secrets injected into that child only; returns exit code and output. |
seekrit:store_secret | Encrypts and stores a value. Write-only — nothing reads one back. |
seekrit:proxy_config | Generates a seekrit-proxy.toml for the upstreams a workload calls. |
There is deliberately no get_secret. Reading a value is the local MCP
server's job, next to your key; a Paperclip tool that returned one would put
plaintext into a run transcript by design. A test in the package enforces the
absence.
The plugin also installs the three seekrit skills into the company's library, so
an agent knows when to reach for those tools — including
seekrit-paperclip, which covers the Paperclip-specific traps: never put a
value in an adapter env map, a project env map, an approval payload, or an issue
comment.
MCP servers, per adapter
Paperclip is the control plane; the adapter's runtime speaks MCP. So MCP
config is per-runtime and lives next to the agent's working directory, not in
Paperclip's database. For the Claude Code adapter — and the Codex, Cursor,
Gemini CLI, and OpenCode adapters, which inherit their CLI's own MCP support the
same way — that is a project-scoped .mcp.json:
seekrit paperclip init --dir /srv/paperclip/workspaces/storefront
An existing file is merged, not replaced. See
seekrit paperclip init for the
flags.
Wiring the proxy
For runs you do not trust, generate a config and run the proxy beside Paperclip:
seekrit proxy init --mode forward \
--preset anthropic --preset openai --preset gemini
SEEKRIT_TOKEN=skt_… seekrit proxy run
Then paste the placeholder environment into the agent's Configuration →
Environment variables. seekrit paperclip init --preset … prints exactly this
table for the presets you name:
| Variable | Value |
|---|---|
ANTHROPIC_API_KEY | {{seekrit:ANTHROPIC_API_KEY}} |
OPENAI_API_KEY | {{seekrit:OPENAI_API_KEY}} |
GEMINI_API_KEY | {{seekrit:GEMINI_API_KEY}} |
HTTPS_PROXY | http://127.0.0.1:8081 |
NODE_EXTRA_CA_CERTS | absolute path to seekrit-proxy-ca.pem |
Every value is a plain string. A placeholder is not a secret, so none of it needs
a secret_ref and none of it trips PAPERCLIP_SECRETS_STRICT_MODE — which is
the practical reason this path is the one to reach for. Use SSL_CERT_FILE or
REQUESTS_CA_BUNDLE instead of NODE_EXTRA_CA_CERTS for a non-Node runtime.
A run wired this way holds no key. The proxy refuses any host not in its config, and that config is not something the run can edit.
The secrets panel
The plugin adds a page at /:company/seekrit listing what the configured
environment holds — names, versions, last changed. It reads live and falls back
to its last snapshot when seekrit is unreachable, saying which it is showing: an
empty table would read as "no secrets", which is a different and wrong answer to
"we could not ask".
Skills without the plugin
Paperclip installs skills straight from a GitHub repository, pinned to a commit. If you want the instructions but not the plugin, paste this into the source field on the Skills page:
https://github.com/seekritdev/agent-plugin
That is the same agent plugin package every other coding agent installs, so the guidance your Paperclip agents follow matches the guidance your local ones do.
Where the boundary sits
Paperclip is self-hosted, so its server is a process you run. A plugin that
decrypts there is in the same position as seekrit run or
the SDKs — the customer's own side of the line — and
seekrit's API still never sees a plaintext, a private key, or a data key.
What the plugin adds on top of that is narrower than it needs to be, on purpose: it holds no network capability of its own (the CLI subprocess makes the calls), posts no issue comments, caches no resolved value, and writes the service token to no log, no activity row, and no error message.
One honest caveat: because the plugin never sees the values run_command
injects, it cannot redact them from that command's output. A program that prints
its own credential has leaked it — the tool description tells the agent so
before it pipes stdout into a comment.