<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Prajna</title>
    <description>The latest articles on DEV Community by Prajna (@prasols).</description>
    <link>https://dev.to/prasols</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4094880%2F3049174a-136a-4915-99c9-fb4a381334a8.gif</url>
      <title>DEV Community: Prajna</title>
      <link>https://dev.to/prasols</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prasols"/>
    <language>en</language>
    <item>
      <title>Why We Built a Config and Secrets Manager That Never Phones Home</title>
      <dc:creator>Prajna</dc:creator>
      <pubDate>Wed, 26 Aug 2026 01:14:41 +0000</pubDate>
      <link>https://dev.to/prasols/why-we-built-a-config-and-secrets-manager-that-never-phones-home-5hm9</link>
      <guid>https://dev.to/prasols/why-we-built-a-config-and-secrets-manager-that-never-phones-home-5hm9</guid>
      <description>&lt;p&gt;&lt;em&gt;How we built KeyKosh(K2): offline Ed25519 licensing, Docker-only delivery, and one-time pricing — for people who self-host on purpose.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Most config management tools assume two things: that your infrastructure can reach the internet, and that you're fine with a vendor's cloud sitting in your critical path. Not all of them — a couple self-host cleanly, one has no server at all — but enough that it shaped the market.&lt;/p&gt;

&lt;p&gt;The pattern was consistent. The governance features a team actually needs — RBAC, SSO, audit logging — sat behind per-identity pricing or an enterprise tier. Self-hosted builds still wanted to call home. The alternatives that avoided both took real operational muscle to run well.&lt;/p&gt;

&lt;p&gt;What we wanted was unglamorous and apparently hard to buy: install it, own it, govern it, and have it call nobody.&lt;/p&gt;

&lt;h2&gt;
  
  
  What KeyKosh does
&lt;/h2&gt;

&lt;p&gt;One Docker image and a Postgres. An organization → application → environment tree holding config and secrets, per-org roles, an audit log, and Java/Node/Python SDKs that read over scoped tokens. The &lt;a href="https://keykosh.com" rel="noopener noreferrer"&gt;feature list is on the site&lt;/a&gt;; what's worth writing about is the reasoning behind three decisions that shaped it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6r4gvmh3ula9y6o4qvri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6r4gvmh3ula9y6o4qvri.png" alt=" " width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three decisions worth explaining
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Licensing is offline.&lt;/strong&gt; Activation is an Ed25519 signature verified against a public key bundled in the image. No license server, no callback, no outbound call ever. The interesting part was accepting the constraint honestly: if validation is offline, revocation has to be designed for it — signed key IDs, an operator-supplied denylist — rather than pretending a callback exists.&lt;/p&gt;

&lt;p&gt;It also answers the question every closed-source self-hosted tool gets asked. If this project disappears, nothing changes for you: there is no server of ours to die, your license is a perpetual signed artifact, and your data is in your Postgres.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enforcement degrades instead of bricking.&lt;/strong&gt; Paid keys are domain-bound to prevent resale. But a key on the wrong host, an expired trial, a revoked key — the install drops to the free tier's limits and keeps serving config. Nothing is deleted, and the caps apply only to &lt;em&gt;creating&lt;/em&gt; new resources. A licensing mistake should be an inconvenience, not an outage.&lt;/p&gt;

&lt;p&gt;That's the kind of claim a vendor shouldn't be believed on, so it's pinned by twelve assertions run against the published image with a real purchased key, including "the degraded install still serves config to an SDK token" and "the encrypted-at-rest secret still decrypts while degraded." Results at &lt;a href="https://keykosh.com/proof.txt" rel="noopener noreferrer"&gt;keykosh.com/proof.txt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We shipped an encrypted offline cache, then deleted it.&lt;/strong&gt; This is the decision we'd defend hardest, and it started as a mistake.&lt;/p&gt;

&lt;p&gt;The SDKs keep a local copy of your config so your app boots when the server is unreachable. The first version was a binary format, encrypted and keyed to the token that fetched it. It looked responsible, and it survived review because "we encrypt the cache" is the sentence everyone wants to say.&lt;/p&gt;

&lt;p&gt;Then we tried to write the threat model down. The file exists so the SDK can start when there is no server to ask — so the key has to be derivable by the SDK, alone, on a machine that can't reach us. Which means the key travels with the file. A lock whose key is taped to it is not a lock, and calling it encryption tells operators to relax about a file that deserves the same care as a &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So the format is now plaintext JSON, and the docs say plainly that it holds whatever the token could read, secrets included: gitignore it, mount it with secret file modes, turn it off per client if you'd rather fail closed than boot stale.&lt;/p&gt;

&lt;p&gt;Two things fell out that we didn't plan. Python's SDK lost its last dependency and is now genuinely zero-dep. And workload-identity clients — authenticating with signed AWS STS envelopes rather than a static token — could suddenly use the file at all, because there was no longer a token to key it to. The encrypted design had quietly excluded the credential type with the best security story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing, and why it isn't per-seat
&lt;/h2&gt;

&lt;p&gt;The license is one-time and perpetual, and nothing is metered per seat. That second part matters less as a discount than as a decoupling.&lt;/p&gt;

&lt;p&gt;Per-identity pricing means the tool gets more expensive precisely as the team grows — which is the same moment governance starts mattering, because roles and an audit trail are things you need &lt;em&gt;because&lt;/em&gt; there are now enough people to need them. You end up paying most for the controls at the point you can least treat them as optional. Attaching the license to a domain instead of a headcount breaks that link, and it's structural rather than generous: with no recurring meter there's no metering to build, so per-seat billing was never an option.&lt;/p&gt;

&lt;p&gt;It isn't unbounded — each tier has a user ceiling, so cost moves in a step rather than a slope. &lt;a href="https://keykosh.com/pricing" rel="noopener noreferrer"&gt;The numbers are on the pricing page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is today
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhufzi7mid7z3vxz57cau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhufzi7mid7z3vxz57cau.png" alt=" " width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The platform and the three SDKs (Maven Central, npm, PyPI — MIT and readable on GitHub) are built and tested end to end.&lt;/p&gt;

&lt;p&gt;What has &lt;em&gt;not&lt;/em&gt; been proven, stated so you don't have to find it in a comment thread: there has been no third-party security audit. The admin UI is an MVP. Password resets are admin-issued rather than self-service, because a self-hosted install has no guaranteed outbound mail. The approval flow is unit-tested rather than black-box tested. That list, and the full assertion results, are on the proof page.&lt;/p&gt;

&lt;p&gt;Two disclosures worth making up front. KeyKosh is built and maintained by a one-person team — which is exactly why the architecture is designed so that our survival isn't your dependency. And it was built with heavy AI assistance; we'd rather say so than have someone find it. Judge it on the proof page and the bare-VM install rather than on how it was written.&lt;/p&gt;

&lt;p&gt;Free tier and a 14-day trial, no card: &lt;a href="https://keykosh.com" rel="noopener noreferrer"&gt;keykosh.com&lt;/a&gt;. The quickstart is one &lt;code&gt;curl&lt;/code&gt; and one &lt;code&gt;docker compose up&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We'd genuinely value feedback — especially on where offline, domain-bound licensing would break in your environment.&lt;/p&gt;

</description>
      <category>selfhosted</category>
      <category>devops</category>
      <category>docker</category>
      <category>security</category>
    </item>
  </channel>
</rss>
