AI-era secrets

Secrets — encrypted in git, safe from AI agents

`sc secrets` encrypts your secrets with your SSH key (RSA or Ed25519) and commits ciphertext to git. Authorized teammates decrypt with their private key. AI agents reading repo files see ciphertext, never values.

Any file, encrypted in git
Add any file — .env, *.pem, secrets.yaml — and the ciphertext lives in a single committed registry at .sc/secrets.yaml. Encrypted against every authorized SSH public key (RSA or Ed25519).
Team-based access via SSH keys
Standard SSH keys are the access policy. Add a teammate’s public key and the registry re-encrypts; remove the key and they’re locked out. No KMS or broker service.
AI-agent–safe by construction
Plaintext files are gitignored. An AI agent (Claude Code, Cursor, Codex) reading the repo sees encrypted blobs, not values. Leakage into chat completions or auto-commits drops to ~zero.
CI/CD reveal flow
Decryption happens at the deploy boundary using a CI-scoped private key carried in SC_CONFIG. Local dev: reveal once, then standard docker-compose.

Why this is a 2026 feature, not a 2018 one

The first generation of secrets managers (HashiCorp Vault, AWS Secrets Manager, 1Password Connect) solved one problem: keep secrets out of source code. They worked.

What changed in 2025–2026: AI agents read your repo files. Claude Code, Cursor, Codex, Devin, GitHub Copilot Workspace — they all open files, follow paths, and feed contents into LLM context. If your secrets.yaml sits in plaintext (even gitignored), any agent run against the repo has at least a chance to read it, summarize it, paste it into a chat completion, or commit it back.

The 2026 secrets-sprawl report logged 1.27M leaked AI-service credentials in 2025, an 81% YoY jump (GitGuardian). Many of those leaks went through AI agents, not despite them.

SC’s secrets workflow inverts the threat model:

  1. The plaintext files are gitignored, never committed. The only thing in git is .sc/secrets.yaml — a registry of encrypted blobs.
  2. Decryption requires a private SSH key that lives in ~/.ssh/, never the repo.
  3. Re-encryption to add or remove a teammate is one command — no rotating keys, no Vault auth tokens, no IAM-policy archeology.

The mechanism, briefly

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Bootstrap a new repo (generates an SSH keypair, writes .sc/cfg.default.yaml).
# Or bring your own existing key (RSA or Ed25519) by editing cfg.default.yaml.
sc secrets init --generate

# Add any file to the encrypted registry
sc secrets add .sc/stacks/my-svc/secrets.yaml
sc secrets add config/production.env
sc secrets add infra/github-app-private-key.pem

# Add a teammate (re-encrypts every entry with Alice's key)
sc secrets allow "$(cat alice.pub)"

# Hide all plaintexts again before a commit (leaves only .sc/secrets.yaml in tree)
sc secrets hide

# Use locally — writes plaintext copies back to original paths (.gitignored)
sc secrets reveal

# Use in CI — decrypts via SC_CONFIG carried as a GH Actions secret
sc secrets reveal --force

The repo’s encrypted registry .sc/secrets.yaml carries, for every authorized public key, the list of files and the ciphertext encrypted under that key. To decrypt, SC matches the user’s private key against the right block. To revoke, sc secrets disallow <key> removes that key’s blocks and re-encrypts the registry without it.

There’s no central server. No KMS subscription. The cryptography is the access policy.

Reference syntax in your client.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
stacks:
  prod:
    type: single-image
    template: lambda
    parent: my-org/my-infra
    config:
      domain: api.my-org.com
      env:
        OPENAI_API_KEY: "${secret:openai-api-key}"
        DATABASE_URL:    "${resource:postgres.uri}"
        STRIPE_KEY:      "${secret:stripe-live}"

sc deploy decrypts, injects the values into the deployment target’s environment, and zeros them from memory.

What this enables

  • Multi-agent workflows on real infra. Forge — our flagship — runs Claude Code agents that touch real deployments. Forge sits on top of SC’s encrypted-in-git foundation, layered with a per-invocation secret manifest, JIT-vs-proxy credential transport, and outbound DLP, so agents never hold plaintext credentials in their address space.
  • Compliance by construction. SOC 2 evidence for “secrets at rest” reduces to “we never have plaintext at rest.” Audit log is git log.
  • No vendor lock-in. Standard SSH keys work everywhere. Self-host SC, take your secrets with you.

Compared to alternatives

ToolMechanismAI-agent surface
Plain env file (.env, .env.local)Plaintext on filesystemAny agent reading files leaks
Vault / AWS Secrets ManagerNetwork-fetched, with brokerAgent that calls broker still holds plaintext briefly
Doppler / 1Password ConnectNetwork-fetched, broker patternSame — broker call materializes plaintext into the agent’s process
GitHub Encrypted SecretsEncrypted, GitHub-onlyInside GH Actions, becomes env vars an agent in CI can read
SC sc secretsCiphertext at rest in git, SSH-key decrypt at useRepo contents leak ciphertext only; decrypt happens at deploy boundary

The pattern doesn’t replace KMS-backed brokers everywhere — they still have a role for runtime-rotated credentials and dynamic auth. But for secrets that need to exist in source control (config schema, integration keys for design partners, CI bootstrap creds, deploy keys), SC’s encrypted-in-git approach is the one that matches the post-AI threat model.

Ship your infrastructure on autopilot.

Try the SC parent stack in your own repo, or see what we built on top of it — Forge, our flagship AI workflow engine for teams.