<?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: Coddy</title>
    <description>The latest articles on DEV Community by Coddy (@iris_line_).</description>
    <link>https://dev.to/iris_line_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3913750%2Fe870fa0b-5238-4a50-8451-04a874ee2c3f.jpg</url>
      <title>DEV Community: Coddy</title>
      <link>https://dev.to/iris_line_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iris_line_"/>
    <language>en</language>
    <item>
      <title>We audited every SSH connection to production for a month. Here's what we found.</title>
      <dc:creator>Coddy</dc:creator>
      <pubDate>Fri, 24 Jul 2026 14:21:47 +0000</pubDate>
      <link>https://dev.to/iris_line_/we-audited-every-ssh-connection-to-production-for-a-month-heres-what-we-found-2770</link>
      <guid>https://dev.to/iris_line_/we-audited-every-ssh-connection-to-production-for-a-month-heres-what-we-found-2770</guid>
      <description>&lt;p&gt;After the ex-employee key incident, I stopped trusting my own assumptions about who was actually connecting to what. So for one month, I logged every SSH session across three environments: a 6-person startup, a 40-person mid-size company, and my own infrastructure.&lt;/p&gt;

&lt;p&gt;The numbers were worse than I expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;23% of connections came from credentials nobody could immediately identify.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not malicious, mostly. Old CI/CD service keys still hanging around. A contractor's access that IT thought was revoked. One senior engineer connecting through a personal laptop key he'd generated two jobs ago and never removed from the authorized_keys file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The average time between "this person left the team" and "their SSH access was actually cut" was 11 days.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the 40-person company, offboarding meant filing a ticket, waiting for infra to manually SSH into each box, and removing the key by hand. Eleven days is eleven days of a former employee, or worse, whoever now controls their laptop or email, having standing access to production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nobody could answer "who connected to the payments database last week" without grepping raw auth logs across a dozen hosts.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not because they didn't care. Because the tooling made it genuinely hard. Bash history is local and unreliable. Centralized logging existed but nobody had built the query for "SSH sessions grouped by host and user" because nobody had needed it until they suddenly did, mid-incident.&lt;/p&gt;

&lt;p&gt;Here's what actually fixed it, in order of impact:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. One source of truth for who has access to what.&lt;/strong&gt; Not a spreadsheet. Not "ask in the #infra channel." A system where access is a first-class object you can list, not a side effect of someone having a key file somewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Revocation as a single action, not a per-host chore.&lt;/strong&gt; If cutting access takes more than one click, it will eventually take more than one day. Every day past zero is risk you're carrying for no reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. An audit log that answers the question before someone asks it.&lt;/strong&gt; Not "technically the data exists in syslog somewhere." A log you'd actually query during an incident, at 2am, without needing to remember which host has which retention policy.&lt;/p&gt;

&lt;p&gt;None of this is exotic. It's the same access-control discipline every team already applies to production databases and cloud consoles. SSH just tends to be the one thing that's still running on trust and tribal memory, because it's the layer underneath everything else and nobody wants to touch it.&lt;/p&gt;

&lt;p&gt;I ended up building this into SecurSSH after hitting the same wall repeatedly, team vaults instead of shared keys, role-based access that revokes instantly, and an audit log that's actually queryable. Not the point of this post though, the audit itself is worth doing regardless of what tool you use afterward.&lt;/p&gt;

&lt;p&gt;If you run the same kind of audit on your own infra, even informally for a week, I'd genuinely like to know what you find. My guess is the offboarding gap is universal.&lt;/p&gt;

</description>
      <category>infrastructure</category>
      <category>devops</category>
      <category>security</category>
      <category>ssh</category>
    </item>
    <item>
      <title>The day I found an ex-employee's SSH key still active in production — 18 months later</title>
      <dc:creator>Coddy</dc:creator>
      <pubDate>Fri, 03 Jul 2026 10:39:56 +0000</pubDate>
      <link>https://dev.to/iris_line_/the-day-i-found-an-ex-employees-ssh-key-still-active-in-production-18-months-later-published-5721</link>
      <guid>https://dev.to/iris_line_/the-day-i-found-an-ex-employees-ssh-key-still-active-in-production-18-months-later-published-5721</guid>
      <description>&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%2Fpo5sth6rk6nvsyjq2nds.jpg" 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%2Fpo5sth6rk6nvsyjq2nds.jpg" alt=" " width="800" height="479"&gt;&lt;/a&gt;It was a routine audit.&lt;/p&gt;

&lt;p&gt;I was going through our authorized_keys files across production servers — something I do every few months, mostly out of paranoia.&lt;/p&gt;

&lt;p&gt;Then I saw it.&lt;/p&gt;

&lt;p&gt;A key belonging to a developer who had left the company a year and a half ago.&lt;/p&gt;

&lt;p&gt;Not a contractor. Not a freelancer.A full-time engineer who had access to everything.Database servers. API endpoints. The works.&lt;/p&gt;

&lt;p&gt;He had probably forgotten about it.We had definitely forgotten about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not a rare story
&lt;/h2&gt;

&lt;p&gt;Ask any sysadmin and they will tell you a version of this. The details change. &lt;br&gt;
The outcome doesn't.&lt;/p&gt;

&lt;p&gt;The problem is structural.&lt;/p&gt;

&lt;p&gt;SSH was built for individual access.&lt;br&gt;
There is no native concept of a team,a role, or an expiration date.&lt;/p&gt;

&lt;p&gt;authorized_keys files multiply silently&lt;br&gt;
across servers. Keys get copied without anyone noticing. Offboarding is manual —and manual means missed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What went wrong — and why it keeps happening
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. No single source of truth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every developer manages their own ~/.ssh config.Nobody has a complete picture of who has access to what across the entire infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Key sprawl is invisible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is no standard way to audit SSH access.&lt;br&gt;
Keys get copied. Servers get cloned.&lt;br&gt;
The surface area grows quietly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Offboarding is an afterthought&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Removing someone from Slack, email, and GitHub takes 10 minutes. SSH? That's on someone's to-do list. It stays there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Rotation is too painful to do&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rotating SSH keys properly means updating every authorized_keys on every server.&lt;br&gt;
In practice, most teams never rotate.&lt;br&gt;
The key that was "temporary" in 2023 is still there in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I changed after that day
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Centralized every SSH credential in one encrypted place&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assigned access per role — not per individual&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up an audit trail for every connection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Made offboarding a one-click operation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tools to do this properly exist now.We just don't talk about them enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question nobody asks until it's too late
&lt;/h2&gt;

&lt;p&gt;How many active SSH keys does your team have right now across all servers?&lt;/p&gt;

&lt;p&gt;Not the ones you know about.&lt;br&gt;
All of them.&lt;/p&gt;

&lt;p&gt;If you can't answer that question instantly,you have the same problem we had.&lt;/p&gt;

&lt;p&gt;Has this ever happened to your team?&lt;br&gt;
How do you handle SSH access management?&lt;/p&gt;

&lt;p&gt;Drop your approach in the comments —&lt;br&gt;
I'm genuinely curious how other teams solve this in practice.&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>programming</category>
      <category>ssh</category>
    </item>
  </channel>
</rss>
