# Secrets live in six places and one of them is a DM

> Source: <https://anthony.dev.profullstack.com/blog/009-post.html>
> Published: 2026-08-16 10:03:24+00:00

# Your secrets live in six places and one of them is a DM

*2026-08-16, by Anthony “chovy” Ettinger.*

**How this was written:** drafted with an AI assistant from my own notes,
then edited by me. I work on the tool described below, so read it as what it is — me
telling you about a thing I build.

## The actual problem

Count where a secret for one of your projects currently lives. There is a `.env`

on
your laptop. There is a copy in Doppler, or in Railway's variables tab, because that's what the
deploy reads. There is a third copy in GitHub Secrets so CI can run. There is a Slack DM from
eight months ago containing a fourth copy, sent to whoever joined that week. And there is an SSH
key on exactly one machine, which is why you can't work from the other one.

None of those four copies agree with each other. You find out which one is stale during an outage. Meanwhile the honest onboarding instruction for a new teammate is “ask me and I'll paste it to you,” which is a credential-sharing workflow the same way a shoebox is an accounting system.

The paid tools solve one slice of this and then own you. Doppler is good at Doppler. Railway
is good at Railway. Neither is good at “here is my `.env`

, put it in both, tell
me what changed first, and let me undo it.” And none of them will hold an SSH key.

## What we built instead

[LogicSRC Credential Sharing](https://logicsrc.com/credential-sharing) is an open
spec plus an MIT-licensed CLI for exactly that gap: provider-neutral secret sync, plus
end-to-end-encrypted team vaults, with an audit trail and an undo button. It's part of
[LogicSRC](https://logicsrc.com/), the Profullstack open-spec project — open
schemas and conventions for coordination between humans, agents and hosted services. The code is
at [github.com/profullstack/logicsrc](https://github.com/profullstack/logicsrc).

Install is a shell line and Node 18+, macOS or Linux:

```
curl -fsSL https://logicsrc.com/install.sh | sh
logicsrc login
```

## The loop I actually run

Ninety percent of my use is three commands. Link a directory to a team project and environment
once, then push and pull the `.env`

like it's a branch:

```
logicsrc secrets teams link      # interactive: team → project → env
logicsrc secrets up              # push .env to the linked environment
logicsrc secrets down            # pull it back
logicsrc secrets down staging    # pull a different env of the same project
```

The link lives in `~/.config/logicsrc/secrets-links.json`

, keyed by the directory's
real path — deliberately outside the project, so nothing about your secret storage lands in
the repo. There's no config file to gitignore because there's no config file.

Onboarding a teammate is four commands and no DMs:

```
logicsrc teams create acme --name "Acme Inc"
logicsrc teams push acme web prod --env .env
logicsrc teams invite acme teammate@example.com
logicsrc teams grant acme web prod teammate@example.com
```

They run `logicsrc teams pull acme web prod --env .env`

and they're working. When
they leave, you rotate rather than hoping:

```
logicsrc credentials rotate acme web prod --approve
```

I run north of 170 vaults on one team this way, named `<project>--<env>`

.
It scales past the point where a shared password manager entry stops being funny.

## The part that matters: the server can't read your secrets

The vaults are end-to-end encrypted and the server is a zero-knowledge relay. It stores three
things: each member's X25519 public key, the vault's data-encryption key sealed once per member,
and ciphertext. Adding a member re-seals the vault key *to* them; it never unwraps the key
anywhere but on a member's machine. Removing a member is a rotation, not a permission flag flip.

This is the property that makes me comfortable putting SSH keys in it, which the CLI does as a first-class thing:

```
logicsrc secrets ssh push profullstack    # back up ~/.ssh to vault ssh--<you>
logicsrc secrets ssh list profullstack    # paths, kinds, modes — never key bodies
logicsrc secrets ssh pull profullstack    # restore, permission bits intact
logicsrc secrets ssh agent profullstack   # load into ssh-agent, never onto disk
```

That last one is the one I like. New machine, new container, someone else's box — keys into the running agent, nothing written to disk to forget about later.

## Anywhere to anywhere, with a dry run and an undo

The sync side is provider-neutral. Adapters exist for `.env`

files, Doppler
(project/config-scoped), Railway service variables, GitHub Secrets (repo, org and environment),
sh1pt tokens for App Store Connect / Play / npm / Docker / Cloudflare, and SSH keys. Run
`logicsrc credentials providers`

for the live list and what each one can do.

Every move is a plan you can look at before it happens:

```
logicsrc credentials diff --from env --from-path .env --to railway \
  --to-project <projectId> --to-config <environmentId>

logicsrc credentials plan --from env --from-path .env --to doppler \
  --to-project <project> --to-config <config>

logicsrc credentials sync --plan <planId>             # dry run by default
logicsrc credentials sync --plan <planId> --approve   # actually writes
logicsrc credentials audit --run <runId> --format markdown
logicsrc credentials rollback --run <runId>
```

Three design decisions in there that I'd defend to anyone:

**Dry run is the default.**`sync`

without`--approve`

writes nothing. You have to say the word.**Plans, diffs and audits are redacted.** They show key names, targets, fingerprints and timestamps — never values. You can paste an audit into a ticket.**Rollback captures a pre-image.** Undo is a new plan that restores what was there, not a prayer that someone kept a copy.

## Where it's rough

I'm not going to oversell an 0.1.x. The CLI reports `0.1.2`

as I write this. Two
things will bite you early:

`teams pull`

writes the decrypted`.env`

into the*current directory*unless you pass`--env <path>`

. Cd into the project first.`push`

auto-creates a vault when`<project>--<env>`

doesn't exist, which means a typo silently makes a new vault instead of erroring. Check`logicsrc teams vaults <team>`

before pushing somewhere new.

Also: `logicsrc --help`

only lists the top-level groups. The interesting
subcommands live under `logicsrc teams --help`

and
`logicsrc credentials --help`

. Don't conclude something is missing from the top-level
help alone — I have done exactly that to myself.

## Why open spec

Credential management is the last place you want a black box, and the second-to-last place you want a lock-in. The spec is public and the client is MIT, which means you can read what gets sent to the relay, verify that the sealing happens on your machine, and fork the thing if we disappear. That's not a marketing position, it's the only arrangement that makes sense for software whose entire job is holding the keys.

Spec, adapter list and full command reference:
[logicsrc.com/credential-sharing](https://logicsrc.com/credential-sharing). If you try
it and something's wrong, the issues are open.
