DEV Community

Cover image for I built a tokenless secrets manager that runs entirely on Git and KMS (No Vault required)
James Spears
James Spears

Posted on

I built a tokenless secrets manager that runs entirely on Git and KMS (No Vault required)

If you've ever had to manage secrets for a production application, you know the pain of the "Secret Zero" problem: How do you securely deliver a secret to a workload without giving it a static .env file or password first?

Today, the industry standard way to solve this is to use HashiCorp Vault or Infisical tied to your cloud's machine identity (like AWS IAM Auth or Kubernetes Service Accounts).

That works beautifully, but the infrastructure cost is massive. You have to run an HA cluster, manage unseal keys, configure storage backends, and maintain a dedicated secrets server just to securely pass an API key.

The alternative is raw Mozilla SOPS + Git, which gives an amazing developer experience but leaves you writing messy custom KMS-decryption bash scripts in your CI pipelines to get those secrets into production.

I wanted the developer experience of Git, but the enterprise security of a tokenless, zero-trust architecture—without running a server. So, I built Clef.

What is Clef?

Clef (https://clef.sh) is an open-source secrets manager. It bridges the gap by treating your Git repository as the authoritative state and your cloud's native IAM as the authentication layer.

Here is how the architecture works from development to production:

1. Local Development (Secrets as Code)

Secrets are encrypted locally using SOPS and Age encryption. You define your service identities and namespaces in a simple clef.yaml manifest. No plaintext is ever written to disk.

# Initialize a new project
clef init

# Set a secret in development
clef set database/development DB_URL "postgres://localhost:5432/myapp"

# Inject secrets directly into your local Node process
clef exec database/development -- node server.js
Enter fullscreen mode Exit fullscreen mode

2. CI/CD (The Pack Phase)

When you merge your code, your CI pipeline runs clef pack. It decrypts only the SOPS files scoped to that specific service, merges them, and creates a lightweight JSON artifact.

3. Solving "Secret Zero" (KMS Envelope Encryption)

This is where the magic happens. To deliver that JSON artifact securely without static credentials, the CI pipeline generates an ephemeral, one-time-use Age key pair.

It encrypts the artifact with the ephemeral key, and then wraps the ephemeral private key using your cloud KMS (AWS or GCP).

4. Production Runtime (The Agent)

A lightweight Clef Agent sidecar runs next to your production app. It doesn't need a password or a .env file. Using the machine's native cloud IAM role (like an AWS EC2 or ECS Task Role), the agent simply asks KMS to unwrap the ephemeral key.

It then decrypts the artifact and serves the secrets to your app via a localhost API (127.0.0.1:7779).

// Your app code just fetches from localhost
const secrets = await fetch("http://127.0.0.1:7779/v1/secrets", {
  headers: { Authorization: "Bearer <local-token>" }
}).then(r => r.json());
Enter fullscreen mode Exit fullscreen mode

The Honest Trade-off

Security is always a trade-off. By eliminating the central server, your Git repository effectively becomes your access control list. You are trading infrastructure complexity for strict GitOps process discipline. If an insider can merge a PR that adds their personal public key to your clef.yaml manifest, they gain access to your secrets. To use Clef safely, you must enforce strict branch protection, require CODEOWNERS reviews on your security manifests, and run isolated CI pipelines.

Properly securing Git + CI is easier than securing Git + CI + Vault, but you have to treat your repo with the seriousness of a vault.

Try it out

Clef is fully open-source under the MIT license.

I wrote a detailed whitepaper breaking down the architecture, the KMS envelope math, and the threat model. I’d love for the DEV community to tear it apart, try out the CLI, and let me know what you think!

Let me know in the comments: For those of you running Vault today, is the operational overhead worth having a centralized policy engine, or would you trade it for a Git-native ACL like this?


Top comments (0)