Show HN: kiln – Git-native, decentralized secret management using age
by pacmansyyu | 2025-07-17 15:23:24+00:00
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