Show HN: kiln – Git-native, decentralized secret management using age

kiln.sh

12 points by pacmansyyu 7 hours ago

Hi HN, I've been building this tool for the past couple of weeks to solve a problem that seems universal across development teams: sharing environment variables securely.

You know the drill - someone needs the staging database URL, so it gets shared over chat. Production API keys end up in plaintext files. Or you set up some complex secret management system that becomes a single point of failure during critical deployments.

At Zerodha, we're a stock broker with strict regulatory requirements. Our infrastructure needs to be auditable, and our data must stay with us for instant recovery. But the deeper issue was that every solution we tried made deployments dependent on external services.

We tried GitLab CI's built-in secrets, but they're stored unencrypted and only repository maintainers can access them. HashiCorp Vault was too complex to manage with painful ACL setup, plus it's now crippled by their BSL license change. AWS Secrets Manager would create the vendor lock-in we wanted to avoid.

The breaking point came when we wanted to manage secrets through Terraform for idempotency and better infrastructure-as-code practices. But Terraform has no built-in way to encrypt secrets without relying on external providers. We could either store secrets in plaintext in our Terraform configs or add yet another external dependency to our deployment pipeline.

That's when I had the idea: what if we could inject encrypted environment variables directly into Terraform, so anyone with the right key could deploy without hunting down secrets from different systems? As I iterated through this idea, I realized the same pattern would work for any application - from personal projects to team deployments.

So I built kiln. It encrypts environment variables using age encryption into files that live alongside your code. No servers, no network calls, no external dependencies. Each team member gets their own key, and you control access per environment.

Here's how it works:

  # Generate a new age key, or use your existing SSH keys
  kiln init key
  
  # Initialize with your team's public keys
  kiln init config --recipients "alice=$(curl https://gitlab.company/alice.keys)" --recipients "me=$(cat ~/.ssh/id_ed25519.pub)"
  
  # Set secrets (prompts securely, never shows in terminal)
  kiln set DATABASE_URL
  kiln set API_KEY
  
  # Run your app with decrypted environment
  kiln run npm start
  

  # These encrypted files are safe to commit
  git add .kiln.env kiln.toml

Why not SOPS? SOPS is great for general file encryption, but kiln is built specifically for the environment variable workflow. It has commands like "run", "export", and built-in team management. Think "SOPS for .env files" with a focus on developer UX.

Why not raw age encryption? Age is perfect for the crypto layer, but terrible for day-to-day team workflows. Try managing 20 team members across 5 environments with raw age commands - you'll go insane. kiln handles the orchestration.

As for technical details, kiln:

- Uses age encryption (modern, audited, simple)

- Works with existing SSH keys or generates new age keys

- Role-based access via TOML configuration

- Single, cross-platform Go binary

- Zero network dependencies - everything works offline

- MIT licensed

The game-changer: secrets travel with code. No more "can someone send me the staging secrets?" in chat. No more broken deploys because the secret service is down. No more hoping your vendor doesn't change their pricing or licensing.

Try it out - I'm confident it'll help improve your team's deployment workflows. Feel free to ask me any questions!

GitHub: https://github.com/thunderbottom/kiln

Docs: https://kiln.sh

Or install now: go install github.com/thunderbottom/kiln@latest

goku12 6 hours ago

> Why not SOPS? SOPS is great for general file encryption, but kiln is built specifically for the environment variable workflow. It has commands like "run", "export", and built-in team management. Think "SOPS for .env files" with a focus on developer UX.

As far as I know, SOPS supports the same workflow with the 'exec-env' subcommand. What would be the difference here?

  • pacmansyyu 6 hours ago

    Yes, SOPS does have `exec-env` which does the same thing, kind of. From one of the issues, it currently lacks support for the POSIX-semantic way to run commands: https://github.com/getsops/sops/issues/1469, where you cannot add a `--` to tell sops that everything after it is supposed to be a command, so you end up having to quote everything. Other things that I found lacking were that with SOPS, adding a new team member means manually updating .sops.yaml, re-encrypting all files, and managing PGP/age keys. With kiln, you just add their SSH key to kiln.toml and run `kiln rekey`.

    kiln also lets you have different access controls per environment file (devs get staging, only ops get production) without separate .sops.yaml configs, automatically discovers keys from SSH agent/~/.kiln/, and has built-in template rendering and export formats for different tools. You could definitely build similar workflows with SOPS + scripts, or any other tool, but kiln packages these common patterns into a single tool with better UX for teams.

    Think of kiln as "opinionated SOPS", focused specifically on environment variables rather than general file encryption.