For teams running coding agents

Transcripts are a credential sink.

Every secret your agent touches gets written down somewhere you don't control and can't purge. Not in a log you rotate — in a conversation that is stored, replayed, summarised, and shared.

What usually happens
session transcript
you
use this token to publish: npm_8Fq2xKd0sLpQm4vX1nRb…
agent
✓ published @acme/widget@1.4.2
# the token is now a permanent part of
# this record, and every copy of it

The task succeeded. A live publish credential is now sitting in a document that will outlive the task by years.

What should happen
session transcript
you
publish using sec://aws/npm/ci#token
agent
✓ published @acme/widget@1.4.2
# the transcript holds a pointer.
# resolving it requires authorization
# that lives outside this document.

Same outcome. The agent got a working credential; the record got a reference that is inert without access you control separately.

This isn't the leak you already know how to handle.

Every other place a secret escapes to has a remedy. This one has four properties that break all of them.

You can't rewrite it

A secret committed to Git can be purged and force-pushed. A secret in a transcript is in a record you don't own the storage for, with no equivalent of git filter-repo.

It gets replayed

Transcripts are re-read on every turn, restored when a session resumes, and summarised into new contexts. One paste is read back hundreds of times across places you never sent it.

It gets shared

Sessions end up in screenshots, bug reports, support threads, and pasted into other chats to ask what went wrong. Each hop is a copy you can't recall.

Nothing tells you it leaked

There is no scanner for this, no push protection, no alert. A credential in a transcript looks exactly like a credential doing its job, right up until it isn't.

Why the usual advice fails

“Don't paste secrets into the chat” is not a policy. It's a wish.

Agents deploy things, publish packages, query production, and call APIs. Those tasks need credentials. Telling someone not to supply one is telling them not to use the tool for the work they bought it for — so they paste it anyway, at the moment they are most focused on something else.

The mistake is treating this as a discipline problem. It's an interface problem: the agent needs the capability, not the value. Handing over the value is just the only way we've offered.

what the agent actually needs
# not this
NPM_TOKEN=npm_8Fq2xKd0sLpQm4vX1nRb…
# this
NPM_TOKEN=sec://aws/npm/ci#token
secrefs run -- npm publish
secrefs: resolved 1 secret reference(s): NPM_TOKEN
+ @acme/widget@1.4.2

What this does not do

It moves the credential, it doesn't remove it

Something still has to authorize the fetch — usually the machine's own cloud credentials. SecRefs converts one long-lived token in a permanent document into a short-lived credential scoped by your existing identity provider. Strictly better, not zero.

An agent that prints it, leaks it

Resolution puts a real value in the process. If the agent then echoes it, it's in the transcript again. This closes the path secrets normally escape through — config, environment, pasted setup — not deliberate output.

Local compromise still wins

Anything with code execution on the machine can read the resolved value out of memory, exactly as it could read a token from .env. The threat this addresses is the record, not the host.

Your agent gets the value. Your transcript gets the reference.

Works with the vault you already run — AWS Secrets Manager, HashiCorp Vault, Bitwarden. SecRefs stores nothing and never holds a copy of your secrets.

npm install @secrefs/node · pip install secrefs