<?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: Naveed Ahmed</title>
    <description>The latest articles on DEV Community by Naveed Ahmed (@naveedkumbhar).</description>
    <link>https://dev.to/naveedkumbhar</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%2F316298%2F0be009f8-20b4-41e7-9ef7-16a05f7314ab.png</url>
      <title>DEV Community: Naveed Ahmed</title>
      <link>https://dev.to/naveedkumbhar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/naveedkumbhar"/>
    <language>en</language>
    <item>
      <title>Apache Kafka Tutorial: KRaft, Docker &amp; Consumer Groups</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Wed, 04 Nov 2026 13:49:40 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/apache-kafka-tutorial-kraft-docker-consumer-groups-mih</link>
      <guid>https://dev.to/naveedkumbhar/apache-kafka-tutorial-kraft-docker-consumer-groups-mih</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/apache-kafka/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Apache Kafka is often described as a messaging system.&lt;/p&gt;

&lt;p&gt;That's partly true, but understanding it as a distributed event log gives you a much clearer picture of how it works.&lt;/p&gt;

&lt;p&gt;Producers write records to partitioned topics. Brokers store those records, and consumers read them at their own pace.&lt;/p&gt;

&lt;p&gt;Unlike a traditional work queue, Kafka can retain events after they've been consumed, allowing different applications to process or replay them independently.&lt;/p&gt;

&lt;p&gt;Let's walk through the key concepts and a small hands-on example.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. How Apache Kafka Works
&lt;/h2&gt;

&lt;p&gt;A simplified architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Producer
   |
   v
Kafka Topic
   |
   +-- Partition 0
   +-- Partition 1
   +-- Partition 2
   |
   v
Consumer Group
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each partition is an ordered sequence of records.&lt;/p&gt;

&lt;p&gt;Kafka uses offsets to identify record positions within a partition.&lt;/p&gt;

&lt;p&gt;If you have three partitions, you can have up to three actively assigned consumers within one consumer group for that topic.&lt;/p&gt;

&lt;p&gt;Adding more consumers than partitions doesn't create additional partition-processing parallelism.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What Is KRaft?
&lt;/h2&gt;

&lt;p&gt;Modern Apache Kafka uses KRaft to manage cluster metadata without an external ZooKeeper deployment.&lt;/p&gt;

&lt;p&gt;KRaft controllers form a quorum responsible for metadata decisions, while brokers handle client requests and partition storage.&lt;/p&gt;

&lt;p&gt;This separation matters when you're investigating broker failures, partition leadership changes, or controller health.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Start Kafka with Docker
&lt;/h2&gt;

&lt;p&gt;For a quick local test, you can start Kafka with the official Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; kafka-local &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:9092:9092 &lt;span class="se"&gt;\&lt;/span&gt;
  apache/kafka:4.4.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example uses the image's default single-node configuration for development.&lt;/p&gt;

&lt;p&gt;Create a topic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;kafka-local &lt;span class="se"&gt;\&lt;/span&gt;
  /opt/kafka/bin/kafka-topics.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--create&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topic&lt;/span&gt; orders.events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--partitions&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--replication-factor&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;kafka-local &lt;span class="se"&gt;\&lt;/span&gt;
  /opt/kafka/bin/kafka-topics.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--describe&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topic&lt;/span&gt; orders.events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you a simple environment for learning partitions and offsets.&lt;/p&gt;

&lt;p&gt;It isn't a highly available Kafka cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Produce and Consume Events
&lt;/h2&gt;

&lt;p&gt;Write a message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"orderId":101,"status":"created"}'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; kafka-local &lt;span class="se"&gt;\&lt;/span&gt;
  /opt/kafka/bin/kafka-console-producer.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topic&lt;/span&gt; orders.events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;kafka-local &lt;span class="se"&gt;\&lt;/span&gt;
  /opt/kafka/bin/kafka-console-consumer.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topic&lt;/span&gt; orders.events &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from-beginning&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeout-ms&lt;/span&gt; 10000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now have a local Kafka workflow using a producer, topic, and consumer.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Production Kafka Is a Different Problem
&lt;/h2&gt;

&lt;p&gt;Running one broker on a laptop is easy compared with managing a replicated cluster.&lt;/p&gt;

&lt;p&gt;In production, pay attention to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replication factor and minimum in-sync replicas&lt;/li&gt;
&lt;li&gt;Broker disk capacity and I/O&lt;/li&gt;
&lt;li&gt;Consumer group lag&lt;/li&gt;
&lt;li&gt;Partition leadership&lt;/li&gt;
&lt;li&gt;Authentication and authorization&lt;/li&gt;
&lt;li&gt;KRaft controller quorum health&lt;/li&gt;
&lt;li&gt;Recovery and upgrade procedures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Kubernetes, operators such as Strimzi can help manage cluster lifecycle, but they don't remove the need for careful storage and capacity planning.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Investigating Consumer Lag
&lt;/h2&gt;

&lt;p&gt;Consumer lag tells you how far a consumer group is behind the latest available partition offsets.&lt;/p&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;kafka-local &lt;span class="se"&gt;\&lt;/span&gt;
  /opt/kafka/bin/kafka-consumer-groups.sh &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bootstrap-server&lt;/span&gt; localhost:9092 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--describe&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--group&lt;/span&gt; inventory-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The group must exist and have committed offsets for meaningful output.&lt;/p&gt;

&lt;p&gt;If lag is increasing, check whether event production exceeds processing capacity.&lt;/p&gt;

&lt;p&gt;Also investigate slow downstream dependencies, consumer exceptions, frequent rebalances, and partition counts.&lt;/p&gt;

&lt;p&gt;Avoid resetting offsets without understanding the risk of skipping or replaying records.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Apache Kafka Guide
&lt;/h2&gt;

&lt;p&gt;The original article goes deeper into Kafka storage internals, KRaft, Docker Compose, Kafka vs RabbitMQ, Spring Boot, Strimzi, and production runbooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/apache-kafka/" rel="noopener noreferrer"&gt;Read Apache Kafka Architecture &amp;amp; Hands-On Production Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Kafka becomes much easier to operate once you understand how partitions, offsets, replication, and consumer groups work together.&lt;/p&gt;

&lt;p&gt;The challenge isn't just sending messages. It's making the streaming platform reliable when workloads grow and failures happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the most difficult Kafka problem you've investigated in production?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — DevOps &amp;amp; Platform Engineering&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>devops</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GitHub Actions OIDC AWS: Secure CI/CD Without Access Keys</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Tue, 03 Nov 2026 08:03:20 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/github-actions-oidc-aws-secure-cicd-without-access-keys-58a3</link>
      <guid>https://dev.to/naveedkumbhar/github-actions-oidc-aws-secure-cicd-without-access-keys-58a3</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/github-actions-oidc-aws-iam/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Still storing &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; and &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; in GitHub Actions secrets?&lt;/p&gt;

&lt;p&gt;It works, but it also means managing long-lived credentials, rotation, and the risk of those keys being exposed.&lt;/p&gt;

&lt;p&gt;For workflows deploying to AWS, there's a better option: OpenID Connect (OIDC).&lt;/p&gt;

&lt;p&gt;GitHub Actions can use OIDC federation to request temporary AWS credentials without storing permanent AWS access keys.&lt;/p&gt;

&lt;p&gt;Here's how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understanding GitHub Actions OIDC
&lt;/h2&gt;

&lt;p&gt;The authentication flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Actions
      |
      | Request signed OIDC JWT
      v
GitHub OIDC Provider
      |
      | JWT
      v
AWS STS
      |
      | Validate IAM role trust policy
      v
Temporary AWS Credentials
      |
      v
Deploy to AWS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS uses &lt;code&gt;AssumeRoleWithWebIdentity&lt;/code&gt; to exchange the signed token for temporary credentials after validating the issuer, audience, and allowed subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Register the GitHub OIDC Provider in AWS
&lt;/h2&gt;

&lt;p&gt;Configure an IAM OIDC identity provider with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provider URL:
https://token.actions.githubusercontent.com

Audience:
sts.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can configure it in the AWS IAM console, AWS CLI, or Terraform.&lt;/p&gt;

&lt;p&gt;For production, keeping identity infrastructure in Terraform helps make the configuration reviewable.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Configure a Restricted IAM Trust Policy
&lt;/h2&gt;

&lt;p&gt;This is the most important step.&lt;/p&gt;

&lt;p&gt;A trust policy should identify the GitHub repository and deployment context that may assume the role.&lt;/p&gt;

&lt;p&gt;For example, a branch-scoped policy condition can look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token.actions.githubusercontent.com:aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sts.amazonaws.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token.actions.githubusercontent.com:sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"repo:YOUR_ORG/YOUR_REPO:ref:refs/heads/main"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the condition portion of a trust policy, not the complete policy document.&lt;/p&gt;

&lt;p&gt;For repositories using GitHub's newer immutable OIDC subject format, adjust the value to match the actual token.&lt;/p&gt;

&lt;p&gt;Avoid broad wildcards that unintentionally authorize additional repositories or workflows.&lt;/p&gt;

&lt;p&gt;Also restrict the permissions attached to the role. A tightly scoped trust policy won't help much if the role has unnecessary administrator access.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Configure GitHub Actions
&lt;/h2&gt;

&lt;p&gt;The workflow needs permission to request an OIDC token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS OIDC Authentication&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;verify-aws&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::123456789012:role/github-oidc-role&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check caller identity&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws sts get-caller-identity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the example AWS account ID and IAM role.&lt;/p&gt;

&lt;p&gt;For production, pin third-party and security-sensitive actions to reviewed commit SHAs.&lt;/p&gt;

&lt;p&gt;The important point: &lt;code&gt;id-token: write&lt;/code&gt; authorizes requesting an OIDC token. It does not grant AWS permissions by itself.&lt;/p&gt;

&lt;p&gt;AWS evaluates the role trust policy before allowing role assumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Common OIDC Authentication Problems
&lt;/h2&gt;

&lt;p&gt;If you encounter &lt;code&gt;AccessDenied&lt;/code&gt; or a role-assumption failure, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The IAM identity provider exists in the correct AWS account.&lt;/li&gt;
&lt;li&gt;The token audience matches the trust policy.&lt;/li&gt;
&lt;li&gt;The subject claim matches the repository and deployment context.&lt;/li&gt;
&lt;li&gt;The job has &lt;code&gt;id-token: write&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The role ARN is correct.&lt;/li&gt;
&lt;li&gt;The workflow is running from an allowed branch or protected environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you use GitHub Environments, remember that the OIDC subject format differs from a branch-scoped subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Production Security Checklist
&lt;/h2&gt;

&lt;p&gt;For a safer setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restrict IAM trust to authorized repository identities.&lt;/li&gt;
&lt;li&gt;Use protected branches and deployment environments.&lt;/li&gt;
&lt;li&gt;Grant only necessary AWS permissions.&lt;/li&gt;
&lt;li&gt;Keep development and production roles separate.&lt;/li&gt;
&lt;li&gt;Review third-party GitHub Actions.&lt;/li&gt;
&lt;li&gt;Monitor role assumption and AWS API activity through CloudTrail.&lt;/li&gt;
&lt;li&gt;Avoid exposing temporary credentials in workflow logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OIDC removes the need to store permanent AWS keys for this authentication flow. It doesn't eliminate the need for secure workflow code and IAM design.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Tutorial
&lt;/h2&gt;

&lt;p&gt;My full guide includes detailed OIDC architecture, AWS CLI and Terraform configuration, trust policy examples, GitHub Actions YAML, and troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/github-actions-oidc-aws-iam/" rel="noopener noreferrer"&gt;GitHub Actions OIDC AWS: Full Secretless CI/CD Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Replacing static AWS keys with temporary credentials is a useful security improvement.&lt;/p&gt;

&lt;p&gt;But the real protection comes from combining OIDC with strict IAM trust policies, least privilege, and protected deployment workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you implemented GitHub Actions OIDC for your AWS deployments?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — DevOps &amp;amp; Platform Engineering&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>githubactions</category>
      <category>security</category>
    </item>
    <item>
      <title>Local LLM for DevOps: Ollama, vLLM &amp; Kubernetes Tutorial</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Tue, 03 Nov 2026 06:57:06 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/local-llm-for-devops-ollama-vllm-kubernetes-tutorial-5dn9</link>
      <guid>https://dev.to/naveedkumbhar/local-llm-for-devops-ollama-vllm-kubernetes-tutorial-5dn9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/local-llm-for-devops/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What if you could analyze Kubernetes failures and review Terraform configurations using an AI model running on your own hardware?&lt;/p&gt;

&lt;p&gt;That's one of the most useful applications of local LLMs for DevOps.&lt;/p&gt;

&lt;p&gt;Instead of sending every prompt to a hosted model API, you can run an open-weight model inside a controlled workstation or internal network.&lt;/p&gt;

&lt;p&gt;Two tools worth understanding are Ollama and vLLM.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Why Run an LLM Locally?
&lt;/h2&gt;

&lt;p&gt;Local inference can help teams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep more operational data within their own environment.&lt;/li&gt;
&lt;li&gt;Work without relying on an external inference service.&lt;/li&gt;
&lt;li&gt;Build internal tools for logs, infrastructure code, and runbooks.&lt;/li&gt;
&lt;li&gt;Control model selection, deployment, and inference infrastructure.&lt;/li&gt;
&lt;li&gt;Evaluate whether fixed infrastructure costs suit their workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, local deployment isn't automatically cheaper, faster, or more secure.&lt;/p&gt;

&lt;p&gt;You still need to account for compute resources, model quality, access controls, and operational maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Ollama vs vLLM
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Ollama&lt;/th&gt;
&lt;th&gt;vLLM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary use&lt;/td&gt;
&lt;td&gt;Local development and simple inference services&lt;/td&gt;
&lt;td&gt;Higher-throughput model serving&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Straightforward&lt;/td&gt;
&lt;td&gt;More infrastructure planning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common environment&lt;/td&gt;
&lt;td&gt;Laptop, workstation, private server&lt;/td&gt;
&lt;td&gt;GPU-backed servers and Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;td&gt;Local HTTP API&lt;/td&gt;
&lt;td&gt;OpenAI-compatible serving API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best starting point&lt;/td&gt;
&lt;td&gt;Individual DevOps workflows&lt;/td&gt;
&lt;td&gt;Shared team inference service&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both can be useful, depending on the workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Run Ollama with Docker
&lt;/h2&gt;

&lt;p&gt;For a CPU-based local test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; ollama &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:11434:11434 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; ollama_data:/root/.ollama &lt;span class="se"&gt;\&lt;/span&gt;
  ollama/ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pull a coding-focused model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;ollama ollama pull qwen2.5-coder:7b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then query the local API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://127.0.0.1:11434/api/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "qwen2.5-coder:7b",
    "prompt": "Explain Kubernetes CrashLoopBackOff and suggest diagnostic commands.",
    "stream": false
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model needs to be downloaded before offline use. The first pull requires network access unless the model files are already available locally.&lt;/p&gt;

&lt;p&gt;For GPU acceleration, follow the Docker and Ollama documentation for your hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Local Kubernetes Incident Triage
&lt;/h2&gt;

&lt;p&gt;A useful starting point is a read-only assistant that summarizes Pod failures.&lt;/p&gt;

&lt;p&gt;Collect the evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod my-app-123 &lt;span class="nt"&gt;-n&lt;/span&gt; staging

kubectl logs my-app-123 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; staging &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--previous&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After checking the output for credentials or sensitive information, send relevant excerpts to your local model.&lt;/p&gt;

&lt;p&gt;Ask it to identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Likely failure causes&lt;/li&gt;
&lt;li&gt;Relevant log lines&lt;/li&gt;
&lt;li&gt;Missing evidence&lt;/li&gt;
&lt;li&gt;Commands to verify the hypothesis&lt;/li&gt;
&lt;li&gt;Recommended next steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treat the result as a troubleshooting suggestion, not a verified root cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Review Terraform Changes Privately
&lt;/h2&gt;

&lt;p&gt;Another useful workflow is reviewing an infrastructure pull request.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform &lt;span class="nb"&gt;fmt&lt;/span&gt; &lt;span class="nt"&gt;-check&lt;/span&gt;
terraform validate
git diff &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s1"&gt;'*.tf'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A local LLM can help explain the changes or identify suspicious patterns.&lt;/p&gt;

&lt;p&gt;But don't rely on an LLM as your only validator.&lt;/p&gt;

&lt;p&gt;Use deterministic checks, infrastructure policies, security scanning, and human review before merging or applying changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. When to Use vLLM
&lt;/h2&gt;

&lt;p&gt;Ollama is a convenient starting point, but a platform team may need a centralized inference service for many applications.&lt;/p&gt;

&lt;p&gt;vLLM supports high-throughput model serving and an OpenAI-compatible API.&lt;/p&gt;

&lt;p&gt;For Kubernetes, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU node allocation and model memory&lt;/li&gt;
&lt;li&gt;Resource limits and scheduling&lt;/li&gt;
&lt;li&gt;Authenticated ingress or an internal API gateway&lt;/li&gt;
&lt;li&gt;Monitoring and request quotas&lt;/li&gt;
&lt;li&gt;Model versioning and persistence&lt;/li&gt;
&lt;li&gt;Network isolation and secrets handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not expose an inference endpoint publicly without an appropriate security boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Production Safeguards
&lt;/h2&gt;

&lt;p&gt;Local inference still needs security controls.&lt;/p&gt;

&lt;p&gt;Use read-only Kubernetes identities where practical, sanitize logs, authenticate model endpoints, and isolate inference workloads.&lt;/p&gt;

&lt;p&gt;Review AI-generated changes before deploying them.&lt;/p&gt;

&lt;p&gt;A useful first milestone is an assistant that explains failures and proposes checks, not one that autonomously modifies production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Local LLM for DevOps Guide
&lt;/h2&gt;

&lt;p&gt;My full article covers model selection, Ollama Docker setup, vLLM on Kubernetes, low-resource hardware, and practical SRE playbooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/local-llm-for-devops/" rel="noopener noreferrer"&gt;Read Local LLM for DevOps: Complete Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Local LLMs aren't a replacement for DevOps fundamentals.&lt;/p&gt;

&lt;p&gt;They're another tool that can make investigation, documentation, and infrastructure review more convenient when deployed with appropriate controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you tried Ollama or vLLM for DevOps work?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — DevOps &amp;amp; Platform Engineering&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>kubernetes</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Binance Hack 2026: 6 Zero Trust DevOps Security Lessons</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Sat, 31 Oct 2026 07:55:12 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/binance-hack-2026-6-zero-trust-devops-security-lessons-5323</link>
      <guid>https://dev.to/naveedkumbhar/binance-hack-2026-6-zero-trust-devops-security-lessons-5323</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/binance-hack-devops/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What would happen if an attacker gained access to a DevOps engineer's laptop in your organization?&lt;/p&gt;

&lt;p&gt;Would they find a few development tools?&lt;/p&gt;

&lt;p&gt;Or would they inherit cloud sessions, Kubernetes access, SSH credentials, and routes into sensitive production systems?&lt;/p&gt;

&lt;p&gt;That question became especially relevant following the October 2026 Binance security incident.&lt;/p&gt;

&lt;p&gt;Binance reported an estimated $6.3 billion impact. Its preliminary findings indicated that a compromised DevOps engineer's laptop may have provided access to a service container used to submit unauthorized withdrawal transactions.&lt;/p&gt;

&lt;p&gt;The company also said that the investigation was ongoing and that it had not found evidence of wallet private-key theft.&lt;/p&gt;

&lt;p&gt;The exact technical attack chain hasn't been fully established.&lt;/p&gt;

&lt;p&gt;Still, the incident offers an opportunity to review how developer endpoints interact with production infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Treat Developer Workstations as Part of Your Production Attack Surface
&lt;/h2&gt;

&lt;p&gt;DevOps engineers often use laptops to access:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud management APIs&lt;/li&gt;
&lt;li&gt;Kubernetes control planes&lt;/li&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Internal dashboards&lt;/li&gt;
&lt;li&gt;SSH and bastion systems&lt;/li&gt;
&lt;li&gt;Production troubleshooting tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A compromised endpoint may expose active sessions or allow misuse of already authenticated access.&lt;/p&gt;

&lt;p&gt;The goal shouldn't be to assume laptops will never be compromised.&lt;/p&gt;

&lt;p&gt;Instead, build systems that limit what a compromised endpoint can do.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Use Zero Trust Access
&lt;/h2&gt;

&lt;p&gt;Traditional VPN access can provide broad network connectivity.&lt;/p&gt;

&lt;p&gt;For sensitive production systems, consider identity-aware access with device posture checks and per-application authorization.&lt;/p&gt;

&lt;p&gt;A successful connection to the corporate network shouldn't automatically establish trust.&lt;/p&gt;

&lt;p&gt;Evaluate identity, device health, operation sensitivity, and session context before granting access.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Reduce Long-Lived Credentials
&lt;/h2&gt;

&lt;p&gt;Persistent cloud access keys and reusable administrative credentials increase the consequences of workstation compromise.&lt;/p&gt;

&lt;p&gt;Prefer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identity federation&lt;/li&gt;
&lt;li&gt;Short-lived cloud credentials&lt;/li&gt;
&lt;li&gt;Scoped Kubernetes access&lt;/li&gt;
&lt;li&gt;Strong MFA for privileged operations&lt;/li&gt;
&lt;li&gt;Timely session revocation and rotation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Temporary credentials reduce exposure, but active sessions and stolen tokens can still be misused during their validity period.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Review Kubernetes RBAC
&lt;/h2&gt;

&lt;p&gt;Production roles should not receive privileged capabilities by default.&lt;/p&gt;

&lt;p&gt;Pay particular attention to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pods/exec
pods/portforward
secrets
rolebindings
clusterrolebindings
deployments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A read-only monitoring identity generally shouldn't be able to launch shells in production Pods or modify workload permissions.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl auth can-i create pods/exec &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run these checks using the relevant identity or impersonation configuration.&lt;/p&gt;

&lt;p&gt;Also review inherited permissions and other roles bound to that identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Use Network Segmentation
&lt;/h2&gt;

&lt;p&gt;Even when an attacker gains access to one service, the rest of the environment shouldn't automatically become reachable.&lt;/p&gt;

&lt;p&gt;Kubernetes NetworkPolicies and compatible CNIs can help restrict traffic between workloads.&lt;/p&gt;

&lt;p&gt;For sensitive services, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default-deny policies&lt;/li&gt;
&lt;li&gt;Explicit ingress and egress rules&lt;/li&gt;
&lt;li&gt;Workload identity&lt;/li&gt;
&lt;li&gt;Mutual TLS where appropriate&lt;/li&gt;
&lt;li&gt;Controlled access to signing and transaction services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Network policies are useful, but they don't replace application-level authorization.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Require Independent Authorization for Sensitive Actions
&lt;/h2&gt;

&lt;p&gt;A single compromised identity should not have unlimited authority to execute high-impact transactions or infrastructure changes.&lt;/p&gt;

&lt;p&gt;Depending on the workload, use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separation of duties&lt;/li&gt;
&lt;li&gt;Independent approvals&lt;/li&gt;
&lt;li&gt;Transaction velocity limits&lt;/li&gt;
&lt;li&gt;Threshold authorization or signing controls&lt;/li&gt;
&lt;li&gt;Policy-enforced execution gateways&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multi-party approval must be enforced by separate trust boundaries, not simply by two steps within the same compromised process.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Monitor Runtime Behavior
&lt;/h2&gt;

&lt;p&gt;Security doesn't end after authentication.&lt;/p&gt;

&lt;p&gt;Monitor for unusual events such as unexpected shell processes, suspicious API usage, unauthorized workload changes, or abnormal network connections.&lt;/p&gt;

&lt;p&gt;Runtime tools such as Falco can help detect certain behaviors in containerized environments.&lt;/p&gt;

&lt;p&gt;Combine runtime telemetry with cloud audit logs, endpoint detection, and incident response processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Incident Response Starting Point
&lt;/h2&gt;

&lt;p&gt;If a privileged DevOps workstation is suspected of compromise:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Isolate the endpoint through the approved response process.&lt;/li&gt;
&lt;li&gt;Preserve relevant forensic evidence.&lt;/li&gt;
&lt;li&gt;Revoke or expire exposed sessions and credentials.&lt;/li&gt;
&lt;li&gt;Review cloud and Kubernetes audit activity.&lt;/li&gt;
&lt;li&gt;Investigate unauthorized changes and lateral movement.&lt;/li&gt;
&lt;li&gt;Restore access from a trusted device and validate recovery.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Avoid relying on credential rotation alone if the attacker may still control active sessions or workloads.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Binance Hack DevOps Analysis
&lt;/h2&gt;

&lt;p&gt;My full article explores the reported incident, workstation-to-cloud attack paths, Zero Trust access, Kubernetes hardening, runtime detection, and a practical incident response playbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/binance-hack-devops/" rel="noopener noreferrer"&gt;Read the Full Binance Hack DevOps Security Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The most useful security question isn't whether your company uses Kubernetes, a VPN, or MFA.&lt;/p&gt;

&lt;p&gt;It's whether a compromised identity or endpoint can cross too many trust boundaries without another independent control stopping it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If an engineer's workstation were compromised today, which production permissions would concern you most?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — DevOps &amp;amp; Platform Engineering&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt; | &lt;a href="https://interview.naveedkumbhar.com" rel="noopener noreferrer"&gt;DevOps Interview Scenarios&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>security</category>
      <category>kubernetes</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>AI Agent Guardrails: Cost Limits, Security &amp; Production Circuit Breakers</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Fri, 30 Oct 2026 07:00:17 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/ai-agent-guardrails-cost-limits-security-production-circuit-breakers-2f71</link>
      <guid>https://dev.to/naveedkumbhar/ai-agent-guardrails-cost-limits-security-production-circuit-breakers-2f71</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/ai-agent-guardrails/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AI agents can run commands, call cloud APIs, create infrastructure, and execute workflows with very little human intervention.&lt;/p&gt;

&lt;p&gt;That makes them useful for DevOps and platform engineering.&lt;/p&gt;

&lt;p&gt;But it also creates a serious question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when an agent keeps executing the wrong operation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A poorly controlled agent could repeatedly retry a failed command, create unnecessary resources, or attempt a production change outside its intended scope.&lt;/p&gt;

&lt;p&gt;System prompts alone aren't enough to prevent these problems.&lt;/p&gt;

&lt;p&gt;That's why production AI agents need enforceable guardrails.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Why Prompt-Based Rules Aren't Enough
&lt;/h2&gt;

&lt;p&gt;Imagine giving an agent the instruction:&lt;/p&gt;

&lt;p&gt;"Never make more than five API calls."&lt;/p&gt;

&lt;p&gt;That instruction communicates intent, but it doesn't create an actual execution limit.&lt;/p&gt;

&lt;p&gt;The agent may still request additional calls.&lt;/p&gt;

&lt;p&gt;A reliable control must be enforced by the application or tool-execution layer.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Agent
    |
    v
Tool Request
    |
    v
Policy Validation
    |
    +-- Allowed → Execute
    |
    +-- Denied → Reject &amp;amp; Log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same principle applies to spending limits, permissions, and destructive operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Four Layers of AI Agent Guardrails
&lt;/h2&gt;

&lt;p&gt;I prefer dividing agent controls into four layers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Execution bounds&lt;/td&gt;
&lt;td&gt;Limit iterations, retries, and runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token and API quotas&lt;/td&gt;
&lt;td&gt;Control requests, tokens, and concurrency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Financial controls&lt;/td&gt;
&lt;td&gt;Monitor and restrict cost-generating actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM and approval&lt;/td&gt;
&lt;td&gt;Restrict permissions and approve high-risk operations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These layers address different failure modes and work best together.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Implement a Simple Python Circuit Breaker
&lt;/h2&gt;

&lt;p&gt;A basic execution wrapper can reject requests when an agent exceeds its tool-call budget.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;monotonic&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentGuardrail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_calls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max_calls&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;monotonic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;monotonic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent deadline exceeded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_calls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tool-call limit exceeded&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;guardrail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentGuardrail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_calls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invoke_approved_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;guardrail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simplified demonstration, not a complete production implementation.&lt;/p&gt;

&lt;p&gt;For real deployments, use centralized quotas, atomic counters, concurrency controls, tool-level authorization, and durable audit records.&lt;/p&gt;

&lt;p&gt;The execution service must enforce those checks even when the model requests a different action.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. AI Agent Cost Controls
&lt;/h2&gt;

&lt;p&gt;When agents can create cloud resources or invoke paid APIs, cost management becomes an operational requirement.&lt;/p&gt;

&lt;p&gt;Useful controls include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per-task token budgets&lt;/li&gt;
&lt;li&gt;Maximum paid tool calls&lt;/li&gt;
&lt;li&gt;Request-rate and concurrency limits&lt;/li&gt;
&lt;li&gt;Cost estimates before resource creation&lt;/li&gt;
&lt;li&gt;Application-level spending ceilings&lt;/li&gt;
&lt;li&gt;Cloud billing alerts and automated remediation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cloud budget notifications are valuable, but they may arrive after charges have accumulated.&lt;/p&gt;

&lt;p&gt;They should not be treated as instantaneous hard caps.&lt;/p&gt;

&lt;p&gt;Enforce immediate limits at the tool gateway or application layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Least-Privilege IAM and Human Approval
&lt;/h2&gt;

&lt;p&gt;Avoid giving agents unrestricted shell access or administrative cloud credentials.&lt;/p&gt;

&lt;p&gt;Instead, expose narrowly scoped operations such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_pod_events
read_application_logs
query_cloud_metrics
get_deployment_history
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write operations should use separate identities and permissions.&lt;/p&gt;

&lt;p&gt;High-impact actions, such as deleting a database or changing IAM policies, should require explicit approval and independent authorization checks.&lt;/p&gt;

&lt;p&gt;A model's claim that an action is safe must not bypass your enforcement layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Production Checklist
&lt;/h2&gt;

&lt;p&gt;Before running autonomous agents in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit execution time and retry count.&lt;/li&gt;
&lt;li&gt;Restrict available tools.&lt;/li&gt;
&lt;li&gt;Validate all tool parameters.&lt;/li&gt;
&lt;li&gt;Enforce quotas and cost budgets.&lt;/li&gt;
&lt;li&gt;Use short-lived, scoped credentials.&lt;/li&gt;
&lt;li&gt;Require approval for sensitive changes.&lt;/li&gt;
&lt;li&gt;Record audit events without exposing secrets.&lt;/li&gt;
&lt;li&gt;Test failure and emergency-stop scenarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to contain mistakes before they become production incidents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Full AI Agent Guardrails Guide
&lt;/h2&gt;

&lt;p&gt;My complete article covers the four-tier architecture, Python circuit breakers, and AWS, Google Cloud, and Azure cost-management patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/ai-agent-guardrails/" rel="noopener noreferrer"&gt;Read AI Agent Guardrails: Framework, Cost Limits &amp;amp; Production Architecture&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AI agents can make operational workflows faster, but autonomous execution introduces risks that traditional chatbots don't have.&lt;/p&gt;

&lt;p&gt;The right approach is to enforce safety outside the model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which guardrail would you implement first: tool permissions, execution limits, cost controls, or human approval?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Share your thoughts in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>security</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Vibe Coding vs Spec-Driven Development: GitHub Spec Kit Guide</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Thu, 29 Oct 2026 13:47:02 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/vibe-coding-vs-spec-driven-development-github-spec-kit-guide-50c9</link>
      <guid>https://dev.to/naveedkumbhar/vibe-coding-vs-spec-driven-development-github-spec-kit-guide-50c9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/vibe-coding-vs-spec-driven-development/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AI coding assistants have changed how quickly developers can build applications.&lt;/p&gt;

&lt;p&gt;Describe a feature, generate code, run it, and ask the AI to fix whatever doesn't work.&lt;/p&gt;

&lt;p&gt;For a small prototype, that's often a great workflow.&lt;/p&gt;

&lt;p&gt;But what happens when the project grows, requirements change, and several engineers need to maintain the same codebase?&lt;/p&gt;

&lt;p&gt;That's where the difference between vibe coding and Spec-Driven Development becomes important.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What Is Vibe Coding?
&lt;/h2&gt;

&lt;p&gt;Vibe coding typically follows a conversational workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt
   ↓
Generate Code
   ↓
Run Application
   ↓
Fix With Another Prompt
   ↓
Repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be useful for prototypes, experiments, and quickly testing ideas.&lt;/p&gt;

&lt;p&gt;The challenge appears when important requirements remain unstated.&lt;/p&gt;

&lt;p&gt;An AI assistant might choose an unexpected architecture, overlook edge cases, or modify unrelated code during later iterations.&lt;/p&gt;

&lt;p&gt;These aren't inevitable outcomes, but they're risks worth managing.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What Is Spec-Driven Development?
&lt;/h2&gt;

&lt;p&gt;Spec-Driven Development (SDD) puts requirements and architecture ahead of code generation.&lt;/p&gt;

&lt;p&gt;Instead of starting with implementation, you establish a specification that developers and AI agents can use as a shared reference.&lt;/p&gt;

&lt;p&gt;A typical workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requirements
     ↓
Technical Design
     ↓
Implementation Tasks
     ↓
Code Generation
     ↓
Tests and Review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A good specification includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Functional requirements&lt;/li&gt;
&lt;li&gt;Acceptance criteria&lt;/li&gt;
&lt;li&gt;API and data contracts&lt;/li&gt;
&lt;li&gt;Security constraints&lt;/li&gt;
&lt;li&gt;Architecture decisions&lt;/li&gt;
&lt;li&gt;Testing expectations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't to write more documentation for its own sake.&lt;/p&gt;

&lt;p&gt;It's to make important decisions explicit before implementation begins.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. GitHub Spec Kit
&lt;/h2&gt;

&lt;p&gt;GitHub Spec Kit is an open-source toolkit for organizing specification-driven workflows with AI coding assistants.&lt;/p&gt;

&lt;p&gt;It provides a CLI and reusable templates for project rules, feature requirements, technical planning, and implementation tasks.&lt;/p&gt;

&lt;p&gt;You can install the Specify CLI using &lt;code&gt;uv&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv tool &lt;span class="nb"&gt;install &lt;/span&gt;specify-cli &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--from&lt;/span&gt; git+https://github.com/github/spec-kit.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize a project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;specify init auth-service &lt;span class="nt"&gt;--ai&lt;/span&gt; claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside your coding-agent workflow, you can then define requirements, create a plan, and break implementation into tasks.&lt;/p&gt;

&lt;p&gt;The exact supported commands depend on the installed Spec Kit version and agent integration.&lt;/p&gt;

&lt;p&gt;The important part is maintaining reviewable artifacts rather than depending entirely on chat history.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Why This Matters for DevOps
&lt;/h2&gt;

&lt;p&gt;The same problem appears when AI generates Kubernetes manifests or Terraform configurations.&lt;/p&gt;

&lt;p&gt;For example, asking:&lt;/p&gt;

&lt;p&gt;"Deploy my API to Kubernetes"&lt;/p&gt;

&lt;p&gt;doesn't specify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU and memory requests&lt;/li&gt;
&lt;li&gt;Security context&lt;/li&gt;
&lt;li&gt;Readiness probes&lt;/li&gt;
&lt;li&gt;Network access&lt;/li&gt;
&lt;li&gt;Secrets management&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Rollback requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A structured infrastructure specification makes these constraints visible before code is generated.&lt;/p&gt;

&lt;p&gt;You might define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;deployment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
  &lt;span class="na"&gt;resourceRequests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;250m&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;512Mi&lt;/span&gt;
  &lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runAsNonRoot&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;allowPrivilegeEscalation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an illustrative specification, not a Kubernetes Deployment manifest.&lt;/p&gt;

&lt;p&gt;Your tooling can use these requirements to generate and validate actual Kubernetes resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. When Should You Use Each Approach?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Suggested approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Quick prototype&lt;/td&gt;
&lt;td&gt;Vibe coding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exploring an idea&lt;/td&gt;
&lt;td&gt;Vibe coding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production API&lt;/td&gt;
&lt;td&gt;Spec-driven workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-developer project&lt;/td&gt;
&lt;td&gt;Spec-driven workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security-sensitive feature&lt;/td&gt;
&lt;td&gt;Specification and review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes infrastructure&lt;/td&gt;
&lt;td&gt;Specification, policy checks, and tests&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can also combine the two approaches.&lt;/p&gt;

&lt;p&gt;Prototype quickly, discover the requirements, then formalize them before building a maintainable production system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete GitHub Spec Kit Guide
&lt;/h2&gt;

&lt;p&gt;My full article explores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The limitations of unstructured AI coding&lt;/li&gt;
&lt;li&gt;Vibe coding vs Spec-Driven Development&lt;/li&gt;
&lt;li&gt;GitHub Spec Kit architecture&lt;/li&gt;
&lt;li&gt;Installing and using Specify CLI&lt;/li&gt;
&lt;li&gt;Project constitutions and technical plans&lt;/li&gt;
&lt;li&gt;AI-assisted Kubernetes and Terraform workflows&lt;/li&gt;
&lt;li&gt;Production validation and engineering guardrails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/vibe-coding-vs-spec-driven-development/" rel="noopener noreferrer"&gt;Read the Complete Vibe Coding vs Spec-Driven Development Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AI can help teams write code faster.&lt;/p&gt;

&lt;p&gt;But speed doesn't replace requirements, architecture, security, or verification.&lt;/p&gt;

&lt;p&gt;For prototypes, a conversational workflow may be enough.&lt;/p&gt;

&lt;p&gt;For systems people depend on, specifications make collaboration and review easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are you using vibe coding, GitHub Spec Kit, or another structured AI coding workflow?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Share your experience in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Scaling DevOps with AI: MCP, AI Agents &amp; Platform Engineering</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Thu, 29 Oct 2026 07:41:35 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/scaling-devops-with-ai-mcp-ai-agents-platform-engineering-410g</link>
      <guid>https://dev.to/naveedkumbhar/scaling-devops-with-ai-mcp-ai-agents-platform-engineering-410g</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/scaling-devops-in-the-age-of-ai/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;DevOps teams have been automating infrastructure for years.&lt;/p&gt;

&lt;p&gt;We have Terraform, Kubernetes, CI/CD pipelines, and dozens of monitoring tools.&lt;/p&gt;

&lt;p&gt;Yet engineers still spend a surprising amount of time investigating repetitive alerts, reviewing configuration changes, and collecting context during incidents.&lt;/p&gt;

&lt;p&gt;AI agents may help reduce that workload.&lt;/p&gt;

&lt;p&gt;But giving an AI agent access to production infrastructure introduces a different problem: how do you make sure it acts safely?&lt;/p&gt;

&lt;p&gt;I recently explored this question while writing about scaling DevOps in the age of AI.&lt;/p&gt;

&lt;p&gt;Here are the most important architectural lessons.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. From Manual Operations to AI-Assisted Engineering
&lt;/h2&gt;

&lt;p&gt;Traditional automation works well when the steps are known.&lt;/p&gt;

&lt;p&gt;AI can help with tasks where engineers first need to collect and interpret context.&lt;/p&gt;

&lt;p&gt;For example, an AI-assisted incident workflow might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collect Kubernetes Pod events&lt;/li&gt;
&lt;li&gt;Examine container restart reasons&lt;/li&gt;
&lt;li&gt;Query Prometheus metrics&lt;/li&gt;
&lt;li&gt;Compare recent deployments&lt;/li&gt;
&lt;li&gt;Summarize likely causes&lt;/li&gt;
&lt;li&gt;Recommend a relevant runbook&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That can reduce investigation effort, provided the output is checked against actual system evidence.&lt;/p&gt;

&lt;p&gt;The important distinction is that proposing a fix and safely executing a fix are separate responsibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. MCP Tools Instead of Unrestricted Shell Access
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol (MCP) provides a standardized way for AI applications to work with external tools.&lt;/p&gt;

&lt;p&gt;For DevOps teams, that might mean exposing narrowly scoped diagnostic operations instead of a general-purpose production terminal.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_pod_events(namespace, pod)
get_deployment_history(namespace, deployment)
query_prometheus(metric, time_range)
get_recent_application_errors(service)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, MCP doesn't automatically enforce security.&lt;/p&gt;

&lt;p&gt;The server implementing these tools must apply authentication, authorization, parameter validation, rate limits, and auditing.&lt;/p&gt;

&lt;p&gt;A read-only Kubernetes service account is a better starting point than cluster-admin credentials.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Use Three Levels of Production Guardrails
&lt;/h2&gt;

&lt;p&gt;Not every infrastructure action carries the same risk.&lt;/p&gt;

&lt;p&gt;I prefer separating automation into three levels.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Control&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read-only&lt;/td&gt;
&lt;td&gt;Fetch Pod logs and metrics&lt;/td&gt;
&lt;td&gt;Authenticated automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bounded change&lt;/td&gt;
&lt;td&gt;Adjust replicas within approved limits&lt;/td&gt;
&lt;td&gt;Deterministic policy and recovery checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-risk mutation&lt;/td&gt;
&lt;td&gt;Delete data or alter IAM permissions&lt;/td&gt;
&lt;td&gt;Explicit human approval&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These controls must be enforced outside the language model.&lt;/p&gt;

&lt;p&gt;You can use tools such as Open Policy Agent to evaluate structured requests, but a policy decision must still be enforced by the execution service.&lt;/p&gt;

&lt;p&gt;Even a Pod restart can cause problems, so production change automation needs workload-aware safeguards.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. AI-Assisted Kubernetes Incident Triage
&lt;/h2&gt;

&lt;p&gt;Imagine an application starts returning 5xx errors immediately after deployment.&lt;/p&gt;

&lt;p&gt;A diagnostic agent could gather:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl describe deployment api &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/api &lt;span class="nt"&gt;-n&lt;/span&gt; production

kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It could then correlate that information with application logs, traces, and recent code changes.&lt;/p&gt;

&lt;p&gt;The result might be a concise incident briefing containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What changed&lt;/li&gt;
&lt;li&gt;Which services are affected&lt;/li&gt;
&lt;li&gt;Relevant evidence&lt;/li&gt;
&lt;li&gt;Possible causes&lt;/li&gt;
&lt;li&gt;Suggested verification steps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's useful even if the agent never executes a production mutation.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Platform Engineering Makes AI More Reliable
&lt;/h2&gt;

&lt;p&gt;AI-generated infrastructure is only as useful as the standards around it.&lt;/p&gt;

&lt;p&gt;Without reusable patterns, different services can end up with inconsistent security settings, readiness probes, resource limits, and monitoring.&lt;/p&gt;

&lt;p&gt;An internal developer platform can provide approved templates, reusable modules, and controlled self-service workflows.&lt;/p&gt;

&lt;p&gt;AI agents can work within those boundaries instead of generating a completely new infrastructure design for every request.&lt;/p&gt;

&lt;p&gt;This is where platform engineering becomes important: it creates reliable building blocks for engineers and automation alike.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Guide
&lt;/h2&gt;

&lt;p&gt;My full article covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agentic platform engineering&lt;/li&gt;
&lt;li&gt;MCP-based DevOps tools&lt;/li&gt;
&lt;li&gt;Three-tier production guardrails&lt;/li&gt;
&lt;li&gt;Autonomous Kubernetes incident triage&lt;/li&gt;
&lt;li&gt;Self-healing workflow risks&lt;/li&gt;
&lt;li&gt;Internal developer platforms&lt;/li&gt;
&lt;li&gt;Practical career development for DevOps engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/scaling-devops-in-the-age-of-ai/" rel="noopener noreferrer"&gt;Read Scaling DevOps in the Age of AI: Full Architecture Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AI may change how DevOps work gets done, but it doesn't remove the need for engineering judgment.&lt;/p&gt;

&lt;p&gt;The opportunity is to automate repetitive investigation, create reliable self-service systems, and reserve human attention for decisions that truly need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Would you allow AI to execute production changes, or keep it restricted to diagnosis and recommendations?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>kubernetes</category>
      <category>architecture</category>
    </item>
    <item>
      <title>7 Kubernetes Deployment Strategies: Rolling, Canary, Blue/Green &amp; More</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Thu, 29 Oct 2026 06:57:14 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/7-kubernetes-deployment-strategies-rolling-canary-bluegreen-more-bho</link>
      <guid>https://dev.to/naveedkumbhar/7-kubernetes-deployment-strategies-rolling-canary-bluegreen-more-bho</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/kubernetes-deployment-strategies/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most Kubernetes teams start with RollingUpdate.&lt;/p&gt;

&lt;p&gt;It works well for many applications, but there are situations where you need more control over traffic, rollback behavior, or the number of users exposed to a new release.&lt;/p&gt;

&lt;p&gt;That's where different Kubernetes deployment strategies become useful.&lt;/p&gt;

&lt;p&gt;Let's look at seven approaches and when to use them.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Rolling Update
&lt;/h2&gt;

&lt;p&gt;RollingUpdate is the default Kubernetes Deployment strategy.&lt;/p&gt;

&lt;p&gt;It gradually replaces old Pods with new ones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RollingUpdate&lt;/span&gt;
  &lt;span class="na"&gt;rollingUpdate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;maxSurge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;25%&lt;/span&gt;
    &lt;span class="na"&gt;maxUnavailable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With enough available capacity and correctly configured readiness checks, this can help maintain application availability during a rollout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Stateless applications with backward-compatible changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Ramped Rollout
&lt;/h2&gt;

&lt;p&gt;A ramped rollout is a more controlled variation of RollingUpdate.&lt;/p&gt;

&lt;p&gt;Instead of updating several Pods at once, you replace them in smaller batches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RollingUpdate&lt;/span&gt;
  &lt;span class="na"&gt;rollingUpdate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;maxSurge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="na"&gt;maxUnavailable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="na"&gt;minReadySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This limits the pace of Pod replacement and requires newly ready Pods to remain ready for a minimum period.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Applications that need cautious rollouts or time for warm-up and observation.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Recreate
&lt;/h2&gt;

&lt;p&gt;Recreate terminates the old application Pods before creating the replacement Pods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Recreate&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's simple, but it normally creates an availability gap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Applications that cannot safely run old and new versions together, where downtime is acceptable.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Blue/Green Deployment
&lt;/h2&gt;

&lt;p&gt;Blue/Green keeps two application environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blue: Current production version&lt;/li&gt;
&lt;li&gt;Green: New application version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You validate Green before switching production traffic to it.&lt;/p&gt;

&lt;p&gt;If something goes wrong, traffic can be routed back to Blue, provided the old version remains compatible with shared dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Releases requiring controlled cutovers and fast traffic-based rollback.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Canary Deployment
&lt;/h2&gt;

&lt;p&gt;Canary deployment gradually exposes the new application version to real users.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stable Version: 95%
Canary Version: 5%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor error rates, latency, and application metrics before increasing the new version's traffic share.&lt;/p&gt;

&lt;p&gt;Argo Rollouts and compatible traffic-routing tools can automate progressive delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; High-traffic applications where limiting the initial blast radius matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. A/B Testing
&lt;/h2&gt;

&lt;p&gt;A/B testing routes different groups of users to different versions.&lt;/p&gt;

&lt;p&gt;Unlike Canary, the primary goal is often to compare user behavior or product outcomes rather than simply validate release stability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Feature experiments, beta releases, and user-segment testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Shadow Deployment
&lt;/h2&gt;

&lt;p&gt;Shadow deployment sends a copy of production requests to a new application version.&lt;/p&gt;

&lt;p&gt;Users still receive responses from the stable application.&lt;/p&gt;

&lt;p&gt;This allows teams to observe how the new version behaves under realistic traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Performance testing, infrastructure changes, and validating new services before cutover.&lt;/p&gt;

&lt;p&gt;Be careful with database writes and other side effects from mirrored requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  Which Kubernetes Deployment Strategy Should You Choose?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Main advantage&lt;/th&gt;
&lt;th&gt;Main trade-off&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rolling Update&lt;/td&gt;
&lt;td&gt;Simple gradual release&lt;/td&gt;
&lt;td&gt;Mixed application versions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ramped&lt;/td&gt;
&lt;td&gt;Slower, controlled replacement&lt;/td&gt;
&lt;td&gt;Longer rollout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recreate&lt;/td&gt;
&lt;td&gt;Avoids concurrent versions&lt;/td&gt;
&lt;td&gt;Downtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blue/Green&lt;/td&gt;
&lt;td&gt;Controlled traffic switching&lt;/td&gt;
&lt;td&gt;Duplicate capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canary&lt;/td&gt;
&lt;td&gt;Limits initial exposure&lt;/td&gt;
&lt;td&gt;Routing and monitoring complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A/B Testing&lt;/td&gt;
&lt;td&gt;User-segment experimentation&lt;/td&gt;
&lt;td&gt;More complex routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shadow&lt;/td&gt;
&lt;td&gt;Tests with mirrored requests&lt;/td&gt;
&lt;td&gt;Extra load and side-effect risks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The best choice depends on application architecture, downtime tolerance, available capacity, and rollback requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Production Checks That Matter
&lt;/h2&gt;

&lt;p&gt;Before using any deployment strategy, verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Readiness and startup behavior&lt;/li&gt;
&lt;li&gt;Available cluster resources&lt;/li&gt;
&lt;li&gt;Application and database compatibility&lt;/li&gt;
&lt;li&gt;Rollout monitoring&lt;/li&gt;
&lt;li&gt;Rollback procedures&lt;/li&gt;
&lt;li&gt;Error rates and latency&lt;/li&gt;
&lt;li&gt;Traffic-routing configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Useful Kubernetes commands include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deployment/my-app

kubectl describe deployment my-app

kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deployment/my-app

kubectl rollout undo deployment/my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful rollout status doesn't necessarily mean every user-facing feature is working correctly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Full Kubernetes Deployment Guide
&lt;/h2&gt;

&lt;p&gt;In my complete article, I compare all seven strategies with architecture diagrams, deployment manifests, production considerations, and troubleshooting examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/kubernetes-deployment-strategies/" rel="noopener noreferrer"&gt;Read the Complete Guide: 7 Kubernetes Deployment Strategies and When to Use Each&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;There's no single deployment strategy that works best for every application.&lt;/p&gt;

&lt;p&gt;RollingUpdate is a good default, but Blue/Green, Canary, and Shadow patterns can provide additional control when your requirements become more complex.&lt;/p&gt;

&lt;p&gt;The important part is understanding the trade-offs before deploying to production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which Kubernetes deployment strategy does your team use most often, and why?&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>cloudnative</category>
      <category>sre</category>
    </item>
    <item>
      <title>Ruby Deserialization Security: RCE Risks, Kubernetes Auditing &amp; Fixes</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Thu, 29 Oct 2026 05:20:39 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/ruby-deserialization-security-rce-risks-kubernetes-auditing-fixes-36ai</link>
      <guid>https://dev.to/naveedkumbhar/ruby-deserialization-security-rce-risks-kubernetes-auditing-fixes-36ai</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/ruby2shell/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🚨 Could a serialized object become a security problem in your Ruby application?&lt;/p&gt;

&lt;p&gt;Ruby provides powerful object serialization features, but accepting serialized data from untrusted sources can introduce serious security risks.&lt;/p&gt;

&lt;p&gt;For DevOps and SRE engineers, the challenge isn't just finding a vulnerable code path. It's identifying every service, container, and background worker that might process unsafe input.&lt;/p&gt;

&lt;p&gt;Here's a practical approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Why Ruby Deserialization Matters
&lt;/h2&gt;

&lt;p&gt;Ruby's Marshal module can serialize and reconstruct Ruby objects.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="s2"&gt;"demo"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is suitable only when the serialized data comes from a trusted source.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;Marshal.load&lt;/code&gt; with untrusted data can expose applications to dangerous object-loading behavior.&lt;/p&gt;

&lt;p&gt;The key question is whether an attacker can control the input passed to the deserializer.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Where Should You Look?
&lt;/h2&gt;

&lt;p&gt;Review applications and components that handle serialized objects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby on Rails services&lt;/li&gt;
&lt;li&gt;Background workers and job queues&lt;/li&gt;
&lt;li&gt;Cache and session integrations&lt;/li&gt;
&lt;li&gt;Internal APIs receiving binary data&lt;/li&gt;
&lt;li&gt;Third-party libraries that deserialize objects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't assume every Rails or Sidekiq deployment uses unsafe deserialization. Inspect your actual code paths and dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Audit Ruby Workloads in Kubernetes
&lt;/h2&gt;

&lt;p&gt;Start by identifying your running application images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; custom-columns&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'NAMESPACE:.metadata.namespace,POD:.metadata.name,IMAGES:.spec.containers[*].image'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check a candidate Ruby container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production deploy/rails-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; web &lt;span class="nt"&gt;--&lt;/span&gt; ruby &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you which runtime is running, but does not establish whether an application is exploitable.&lt;/p&gt;

&lt;p&gt;To inspect your codebase, search for deserialization calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-RInE&lt;/span&gt; &lt;span class="s1"&gt;'Marshal\.(load|restore)'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.rb'&lt;/span&gt; app lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review each match to determine where the data originates.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Scan Container Images
&lt;/h2&gt;

&lt;p&gt;Trivy can help identify known vulnerabilities in application images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;trivy image &lt;span class="nt"&gt;--scanners&lt;/span&gt; vuln &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--severity&lt;/span&gt; HIGH,CRITICAL &lt;span class="se"&gt;\&lt;/span&gt;
  registry.example.com/rails-api:production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For larger environments, use Software Bills of Materials (SBOMs) to track dependencies.&lt;/p&gt;

&lt;p&gt;Remember that automated scanners may not detect application-level insecure deserialization patterns.&lt;/p&gt;

&lt;p&gt;You need both dependency scanning and code review.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Production Hardening
&lt;/h2&gt;

&lt;p&gt;A safer approach includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Avoiding Marshal deserialization of untrusted input.&lt;/li&gt;
&lt;li&gt;Using JSON or another appropriate format for external data.&lt;/li&gt;
&lt;li&gt;Validating application inputs.&lt;/li&gt;
&lt;li&gt;Updating Ruby and application dependencies.&lt;/li&gt;
&lt;li&gt;Rebuilding and redeploying affected containers.&lt;/li&gt;
&lt;li&gt;Applying least-privilege security controls.&lt;/li&gt;
&lt;li&gt;Monitoring suspicious behavior and unexpected crashes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ingress and WAF rules may provide additional protection for specific paths, but they cannot guarantee safety if unsafe deserialization occurs inside application workers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Ruby Security Guide
&lt;/h2&gt;

&lt;p&gt;My full article discusses Ruby2Shell claims, Ruby object deserialization, Kubernetes auditing, container scanning, and production hardening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/ruby2shell/" rel="noopener noreferrer"&gt;Read the Ruby2Shell Technical Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note: The specific CVE-2026-113840 vulnerability details and claimed patch versions have not yet been independently confirmed through an official Ruby advisory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;A running container and a successful vulnerability scan don't necessarily mean your application is safe.&lt;/p&gt;

&lt;p&gt;Security also depends on how data enters your application and what happens when that data is processed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does your team identify unsafe deserialization in Ruby applications?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Share your approach in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | &lt;a href="https://pk.linkedin.com/in/naveedkumbhar" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>security</category>
      <category>devops</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>HTTP2Shell: Brotli Buffer Overflow Root Cause &amp; Production Fix</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Thu, 29 Oct 2026 03:53:45 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/http2shell-brotli-buffer-overflow-root-cause-production-fix-3l8k</link>
      <guid>https://dev.to/naveedkumbhar/http2shell-brotli-buffer-overflow-root-cause-production-fix-3l8k</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/http2shell/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🚨 A security vulnerability in a compression library might not sound like a major infrastructure problem. But when that library is used across applications, containers, and cloud runtimes, the impact can extend much further than expected.&lt;/p&gt;

&lt;p&gt;That's what makes &lt;strong&gt;HTTP2Shell (CVE-2026-111497)&lt;/strong&gt; important for DevOps, SRE, and security teams.&lt;/p&gt;

&lt;p&gt;The vulnerability affects Google's Brotli decompression library and can lead to memory corruption when vulnerable software processes specially crafted compressed data.&lt;/p&gt;

&lt;p&gt;Depending on the affected application and exploitability, consequences may include crashes, information disclosure, or remote code execution.&lt;/p&gt;

&lt;p&gt;Here's what engineering teams should understand and how to respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What Is HTTP2Shell?
&lt;/h2&gt;

&lt;p&gt;HTTP2Shell is an out-of-bounds write vulnerability in the native Brotli decoder.&lt;/p&gt;

&lt;p&gt;Brotli is widely used for data compression, including web traffic and application workloads.&lt;/p&gt;

&lt;p&gt;The vulnerability occurs when affected decoder versions process specially crafted compressed input, potentially writing beyond allocated memory boundaries.&lt;/p&gt;

&lt;p&gt;A simplified failure path looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Untrusted Brotli Input
         |
         v
Vulnerable Brotli Decoder
         |
         v
Out-of-Bounds Memory Write
         |
         v
Memory Corruption
         |
         v
Potential Crash / Data Exposure / RCE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite its name, HTTP2Shell isn't limited to HTTP/2. The underlying issue involves Brotli decompression, regardless of how attacker-controlled data reaches the decoder.&lt;/p&gt;

&lt;p&gt;An application is not necessarily exploitable simply because Brotli is installed. The relevant question is whether vulnerable decoding functionality processes untrusted input.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Which Applications Should You Check?
&lt;/h2&gt;

&lt;p&gt;The vulnerability can affect applications and services that bundle or dynamically load vulnerable Brotli implementations.&lt;/p&gt;

&lt;p&gt;Important environments to investigate include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js applications using vulnerable runtimes&lt;/li&gt;
&lt;li&gt;Python applications with affected Brotli packages&lt;/li&gt;
&lt;li&gt;.NET applications using affected decompression functionality&lt;/li&gt;
&lt;li&gt;Docker images containing vulnerable native libraries&lt;/li&gt;
&lt;li&gt;Kubernetes workloads running affected application images&lt;/li&gt;
&lt;li&gt;Other software with embedded Brotli decoders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Node.js, the October 2026 security updates include these fixed releases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Node.js release line&lt;/th&gt;
&lt;th&gt;Fixed version&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;22.x&lt;/td&gt;
&lt;td&gt;22.23.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24.x&lt;/td&gt;
&lt;td&gt;24.22.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26.x&lt;/td&gt;
&lt;td&gt;26.12.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Older, unsupported Node.js versions should be migrated to a maintained release.&lt;/p&gt;

&lt;p&gt;Also remember that Linux distributions may backport security fixes without changing the upstream version number. Check vendor advisories rather than relying only on raw version strings.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to Detect HTTP2Shell in Kubernetes
&lt;/h2&gt;

&lt;p&gt;For production environments, start by identifying the container images and runtimes actually deployed.&lt;/p&gt;

&lt;p&gt;List the images running in a namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; custom-columns&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'POD:.metadata.name,IMAGES:.spec.containers[*].image'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect a Node.js application's runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production deploy/api-gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; app &lt;span class="nt"&gt;--&lt;/span&gt; node &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"process.version"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the embedded Brotli version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; production deploy/api-gateway &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-c&lt;/span&gt; app &lt;span class="nt"&gt;--&lt;/span&gt; node &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"process.versions.brotli"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands help identify candidate workloads for further investigation.&lt;/p&gt;

&lt;p&gt;They don't prove exploitability on their own, and version checks should be interpreted alongside the relevant vendor advisories.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Scan Container Images with Trivy
&lt;/h2&gt;

&lt;p&gt;Container image scanning is another useful part of the investigation.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;trivy image &lt;span class="nt"&gt;--scanners&lt;/span&gt; vuln &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--severity&lt;/span&gt; HIGH,CRITICAL &lt;span class="se"&gt;\&lt;/span&gt;
  registry.example.com/api-service:production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the image reference with your actual production image.&lt;/p&gt;

&lt;p&gt;Review the findings for CVE-2026-111497 and affected Brotli-related packages.&lt;/p&gt;

&lt;p&gt;A clean scan doesn't necessarily mean every embedded runtime is safe. Some statically bundled libraries and application dependencies may require additional inspection.&lt;/p&gt;

&lt;p&gt;For larger environments, Software Bills of Materials (SBOMs) can help identify where affected dependencies are deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Immediate Production Mitigation
&lt;/h2&gt;

&lt;p&gt;If vulnerable workloads are identified, prioritize updating the affected runtime or library.&lt;/p&gt;

&lt;p&gt;A practical remediation workflow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify applications processing untrusted Brotli-compressed input.&lt;/li&gt;
&lt;li&gt;Review official vendor security advisories.&lt;/li&gt;
&lt;li&gt;Upgrade vulnerable runtimes and dependencies.&lt;/li&gt;
&lt;li&gt;Rebuild affected container images.&lt;/li&gt;
&lt;li&gt;Redeploy the updated workloads.&lt;/li&gt;
&lt;li&gt;Verify runtime versions and scan the rebuilt images.&lt;/li&gt;
&lt;li&gt;Monitor applications for abnormal crashes and unexpected errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For Kubernetes environments, rebuilding the container is particularly important.&lt;/p&gt;

&lt;p&gt;Updating a package on the host won't fix a vulnerable library already bundled inside an application image.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if patching can't happen immediately?
&lt;/h3&gt;

&lt;p&gt;Where feasible, temporarily disable Brotli decompression of untrusted input or block affected inbound compressed requests at the edge.&lt;/p&gt;

&lt;p&gt;However, a WAF or ingress rule isn't a complete solution.&lt;/p&gt;

&lt;p&gt;It may not protect applications decoding Brotli data from internal services, upstream responses, files, or other sources.&lt;/p&gt;

&lt;p&gt;Treat edge filtering as a temporary defense while completing the actual patching process.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What DevOps Teams Can Learn
&lt;/h2&gt;

&lt;p&gt;HTTP2Shell is another reminder that infrastructure security isn't limited to operating system packages.&lt;/p&gt;

&lt;p&gt;Modern applications depend on libraries embedded in language runtimes, containers, and other software components.&lt;/p&gt;

&lt;p&gt;A vulnerability deep inside one dependency can require changes across many services.&lt;/p&gt;

&lt;p&gt;That's why production teams need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regular container image scanning&lt;/li&gt;
&lt;li&gt;Dependency inventories and SBOMs&lt;/li&gt;
&lt;li&gt;Supported runtime versions&lt;/li&gt;
&lt;li&gt;Automated CI/CD security checks&lt;/li&gt;
&lt;li&gt;Reliable container rebuild procedures&lt;/li&gt;
&lt;li&gt;Clear emergency patching workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn't just to detect vulnerabilities. It's to know exactly which workloads are affected and how quickly they can be remediated.&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Read the Full HTTP2Shell Production Guide
&lt;/h2&gt;

&lt;p&gt;I wrote a detailed technical guide covering the vulnerability's root cause, affected runtimes, Kubernetes triage, container scanning, and production mitigation strategies.&lt;/p&gt;

&lt;p&gt;The complete article includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brotli buffer overflow architecture&lt;/li&gt;
&lt;li&gt;HTTP2Shell (CVE-2026-111497) root cause&lt;/li&gt;
&lt;li&gt;Node.js, Python, and .NET considerations&lt;/li&gt;
&lt;li&gt;Kubernetes workload auditing&lt;/li&gt;
&lt;li&gt;Trivy image scanning&lt;/li&gt;
&lt;li&gt;WAF and ingress mitigation approaches&lt;/li&gt;
&lt;li&gt;Container rebuilds and CI/CD security checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/http2shell/" rel="noopener noreferrer"&gt;Read the Complete HTTP2Shell: Brotli Buffer Overflow Root Cause &amp;amp; Production Fix&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;A library vulnerability can become an infrastructure-wide issue when the same component exists across dozens or hundreds of workloads.&lt;/p&gt;

&lt;p&gt;For DevOps and SRE teams, the priority is straightforward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identify exposure, patch affected dependencies, rebuild containers, and verify what's actually running in production.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;💬 How does your team handle emergency CVE patching across Kubernetes clusters?&lt;/p&gt;

&lt;p&gt;Do you use Trivy, SBOMs, automated dependency updates, or another approach?&lt;/p&gt;

&lt;p&gt;Share your experience in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🌐 &lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | 🐙 &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | 💼 &lt;a href="https://pk.linkedin.com/in/naveedkumbhar" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🛠️ &lt;a href="https://interview.naveedkumbhar.com" rel="noopener noreferrer"&gt;SRE Interview Practice&lt;/a&gt; | ☸️ &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>devops</category>
      <category>security</category>
      <category>node</category>
    </item>
    <item>
      <title>How a Kubernetes Database Migration Caused a 502 Production Outage</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Tue, 27 Oct 2026 05:33:05 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/how-a-kubernetes-database-migration-caused-a-502-production-outage-27co</link>
      <guid>https://dev.to/naveedkumbhar/how-a-kubernetes-database-migration-caused-a-502-production-outage-27co</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/database-migration-rolling-update-outage/" rel="noopener noreferrer"&gt;Naveed Ahmed's Engineering Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A routine Kubernetes rolling update. A breaking PostgreSQL schema migration. And suddenly, a production API starts returning &lt;strong&gt;502 Bad Gateway&lt;/strong&gt; errors.&lt;/p&gt;

&lt;p&gt;At 2:15 AM, an automated CI/CD deployment triggered what should have been a normal application update.&lt;/p&gt;

&lt;p&gt;Instead, database queries started blocking, API latency increased, and PostgreSQL connections became exhausted.&lt;/p&gt;

&lt;p&gt;The incident lasted around 24 minutes.&lt;/p&gt;

&lt;p&gt;The real problem wasn't Kubernetes itself. It was a database migration that wasn't compatible with the old and new application versions running simultaneously.&lt;/p&gt;

&lt;p&gt;Here's what happened and how to prevent it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What Went Wrong During the Kubernetes Rolling Update?
&lt;/h2&gt;

&lt;p&gt;Kubernetes rolling updates gradually replace old application pods with new ones.&lt;/p&gt;

&lt;p&gt;During deployment, both versions can run at the same time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kubernetes Rolling Update

Application v1 (Old Pods)
        +
Application v2 (New Pods)
        |
        v
 Shared PostgreSQL Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the deployment included a destructive database migration that removed a column still required by the older application pods.&lt;/p&gt;

&lt;p&gt;Those pods continued querying the deleted column, causing database errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key lesson:&lt;/strong&gt; A Kubernetes rolling update doesn't guarantee zero downtime if your database schema isn't backward-compatible.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. How PostgreSQL Lock Contention Caused 502 Errors
&lt;/h2&gt;

&lt;p&gt;The schema migration also introduced PostgreSQL lock contention.&lt;/p&gt;

&lt;p&gt;Operations such as dropping a column require an &lt;code&gt;ACCESS EXCLUSIVE&lt;/code&gt; lock.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If existing transactions hold conflicting locks, the migration must wait.&lt;/p&gt;

&lt;p&gt;New queries can then queue behind the waiting migration, causing a cascade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Schema Migration
       ↓
Exclusive Lock Wait
       ↓
Blocked Database Queries
       ↓
Connection Pool Exhaustion
       ↓
Application Timeouts
       ↓
HTTP 502 / 5xx Errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This explains why a database migration can disrupt API traffic even when Kubernetes pods appear to be running.&lt;/p&gt;

&lt;p&gt;To investigate blocked PostgreSQL sessions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;wait_event_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;wait_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;pg_blocking_pids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;blocking_pids&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pg_stat_activity&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;cardinality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pg_blocking_pids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps identify queries waiting on other database sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Why the Kubernetes Rollback Failed
&lt;/h2&gt;

&lt;p&gt;Rolling back the application doesn't automatically reverse database schema changes.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout undo deployment/api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This restores the previous Deployment revision, but it doesn't restore deleted PostgreSQL columns.&lt;/p&gt;

&lt;p&gt;If the older application still depends on the removed schema, errors can continue even after the rollback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key lesson:&lt;/strong&gt; Application rollback and database rollback are separate operations. Both need a compatible recovery strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Solution: Expand and Contract Database Migrations
&lt;/h2&gt;

&lt;p&gt;The safer approach is to introduce database schema changes gradually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Expand
&lt;/h3&gt;

&lt;p&gt;Add the new schema without removing existing columns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 2: Migrate
&lt;/h3&gt;

&lt;p&gt;Deploy compatible application code and backfill existing data.&lt;/p&gt;

&lt;p&gt;For large tables, use controlled batches rather than one massive transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Switch
&lt;/h3&gt;

&lt;p&gt;Update application reads and writes to use the new schema. Verify data consistency and wait until older application versions are no longer serving traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: Contract
&lt;/h3&gt;

&lt;p&gt;Remove the old column in a later deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach helps avoid breaking application compatibility during Kubernetes rolling updates. Destructive DDL can still require careful lock management.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Production Best Practices
&lt;/h2&gt;

&lt;p&gt;A few safeguards can reduce the risk of database migration outages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use backward-compatible schema changes.&lt;/li&gt;
&lt;li&gt;Run database migrations through a controlled CI/CD step or Kubernetes Job.&lt;/li&gt;
&lt;li&gt;Avoid running migrations independently from every application pod.&lt;/li&gt;
&lt;li&gt;Configure appropriate PostgreSQL &lt;code&gt;lock_timeout&lt;/code&gt; values.&lt;/li&gt;
&lt;li&gt;Monitor database connections, lock waits, API latency, and HTTP 5xx errors.&lt;/li&gt;
&lt;li&gt;Test rollback compatibility before production releases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a bounded lock wait can prevent migrations from waiting indefinitely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;lock_timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'5s'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose timeout values based on your workload and migration strategy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Complete Kubernetes Database Migration Postmortem
&lt;/h2&gt;

&lt;p&gt;In the full article, I break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The 24-minute production outage timeline&lt;/li&gt;
&lt;li&gt;Kubernetes rolling update failure&lt;/li&gt;
&lt;li&gt;PostgreSQL &lt;code&gt;AccessExclusiveLock&lt;/code&gt; contention&lt;/li&gt;
&lt;li&gt;Database connection pool exhaustion&lt;/li&gt;
&lt;li&gt;Why the rollback didn't restore service&lt;/li&gt;
&lt;li&gt;Expand and Contract migration strategies&lt;/li&gt;
&lt;li&gt;Production troubleshooting and prevention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/database-migration-rolling-update-outage/" rel="noopener noreferrer"&gt;Read the Full Kubernetes Database Migration 502 Outage Postmortem&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Kubernetes rolling updates can keep applications available during deployments, but they can't protect you from incompatible database changes.&lt;/p&gt;

&lt;p&gt;The biggest lesson from this incident is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your database schema must support both old and new application versions during a rolling deployment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you experienced database migration failures during Kubernetes deployments? How does your team handle zero-downtime schema changes?&lt;/p&gt;

&lt;p&gt;Share your experience in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by Naveed Ahmed — Lead DevOps &amp;amp; Platform Architect&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🌐 &lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Engineering Blog&lt;/a&gt; | 🐙 &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; | 💼 &lt;a href="https://pk.linkedin.com/in/naveedkumbhar" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🛠️ &lt;a href="https://interview.naveedkumbhar.com" rel="noopener noreferrer"&gt;SRE Interview Scenarios&lt;/a&gt; | ☸️ &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Mastery&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>postgres</category>
      <category>sre</category>
    </item>
    <item>
      <title>Caddy Web Server Tutorial: Architecture, Docker &amp; Production Guide</title>
      <dc:creator>Naveed Ahmed</dc:creator>
      <pubDate>Tue, 27 Oct 2026 03:53:32 +0000</pubDate>
      <link>https://dev.to/naveedkumbhar/caddy-web-server-tutorial-architecture-docker-production-guide-9nm</link>
      <guid>https://dev.to/naveedkumbhar/caddy-web-server-tutorial-architecture-docker-production-guide-9nm</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://blog.naveedkumbhar.com/caddy-web-server-tutorial/" rel="noopener noreferrer"&gt;Naveed Ahmed's Tech Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've worked with Nginx or Apache, you've probably spent some time configuring virtual hosts, setting up SSL certificates, troubleshooting reverse proxy rules, or fixing certificate renewal issues.&lt;/p&gt;

&lt;p&gt;These are normal parts of managing web infrastructure, but they can become repetitive, especially when you're responsible for multiple services.&lt;/p&gt;

&lt;p&gt;That's where Caddy caught my attention.&lt;/p&gt;

&lt;p&gt;Caddy is an open-source web server and reverse proxy written in Go. One of its biggest advantages is that it handles HTTPS automatically, including obtaining and renewing TLS certificates.&lt;/p&gt;

&lt;p&gt;You can also configure a reverse proxy with just a few lines.&lt;/p&gt;

&lt;p&gt;But how does Caddy actually work? Is it secure enough for production? And should you consider it instead of Nginx or Apache?&lt;/p&gt;

&lt;p&gt;I put together a detailed guide to explore these questions.&lt;/p&gt;

&lt;p&gt;Here's a practical overview of what I covered.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What Is Caddy, and Why Should DevOps Engineers Care?
&lt;/h2&gt;

&lt;p&gt;Caddy is a modern web server that can serve websites, handle HTTPS connections, and route incoming requests to backend applications.&lt;/p&gt;

&lt;p&gt;It supports many features you'd expect from a production web server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic HTTPS and TLS certificate renewal&lt;/li&gt;
&lt;li&gt;Reverse proxy and load balancing&lt;/li&gt;
&lt;li&gt;HTTP/2 and HTTP/3 support&lt;/li&gt;
&lt;li&gt;Simple Caddyfile configuration&lt;/li&gt;
&lt;li&gt;Dynamic configuration through a REST API&lt;/li&gt;
&lt;li&gt;Docker and container-based deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes Caddy interesting isn't that these features are impossible to implement with other web servers.&lt;/p&gt;

&lt;p&gt;It's that several of them work with very little configuration.&lt;/p&gt;

&lt;p&gt;For example, here's a basic reverse proxy configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;example.com {
    reverse_proxy localhost:3000
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's enough to tell Caddy to forward requests to an application listening on port 3000.&lt;/p&gt;

&lt;p&gt;With a public domain, correct DNS records, and the required network access, Caddy can also provision and manage HTTPS certificates automatically.&lt;/p&gt;

&lt;p&gt;For small applications and containerized services, this can save quite a bit of setup time.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Caddy vs. Nginx vs. Apache: Which One Makes Sense?
&lt;/h2&gt;

&lt;p&gt;Nginx and Apache have been around for years, and there's a reason they're still widely used.&lt;/p&gt;

&lt;p&gt;Both are mature, flexible, and proven in production environments.&lt;/p&gt;

&lt;p&gt;Caddy takes a slightly different approach, with more emphasis on sensible defaults and simplifying common configuration tasks.&lt;/p&gt;

&lt;p&gt;Here's how I look at the three:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Caddy&lt;/th&gt;
&lt;th&gt;Nginx&lt;/th&gt;
&lt;th&gt;Apache&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Automatic HTTPS&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;td&gt;Usually requires additional setup&lt;/td&gt;
&lt;td&gt;Usually requires additional setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuration&lt;/td&gt;
&lt;td&gt;Simple Caddyfile&lt;/td&gt;
&lt;td&gt;Directive-based&lt;/td&gt;
&lt;td&gt;Directive-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reverse proxy&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;td&gt;Available through modules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP/3&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Supported in compatible builds&lt;/td&gt;
&lt;td&gt;Depends on implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dynamic configuration&lt;/td&gt;
&lt;td&gt;REST API&lt;/td&gt;
&lt;td&gt;Depends on edition and tooling&lt;/td&gt;
&lt;td&gt;Typically file-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common use case&lt;/td&gt;
&lt;td&gt;Simple HTTPS and reverse proxy setups&lt;/td&gt;
&lt;td&gt;High-performance web serving and proxying&lt;/td&gt;
&lt;td&gt;Flexible web hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I wouldn't say Caddy is automatically better than Nginx or Apache.&lt;/p&gt;

&lt;p&gt;If you already have a well-managed Nginx environment, there's no reason to migrate just for the sake of using something newer.&lt;/p&gt;

&lt;p&gt;But if you're starting a new project and want HTTPS and reverse proxy configuration to be straightforward, Caddy is worth considering.&lt;/p&gt;

&lt;p&gt;The best choice still depends on your workload, operational requirements, and existing infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How Secure Is Caddy?
&lt;/h2&gt;

&lt;p&gt;Security is one of the more interesting parts of Caddy's architecture.&lt;/p&gt;

&lt;p&gt;Because it's written in Go, Caddy benefits from memory safety features that help prevent certain classes of memory-related vulnerabilities common in manually managed memory environments.&lt;/p&gt;

&lt;p&gt;However, that doesn't mean Caddy is free from vulnerabilities.&lt;/p&gt;

&lt;p&gt;Like any web server, it still needs proper configuration, timely security updates, and operational monitoring.&lt;/p&gt;

&lt;p&gt;For production environments, I'd pay particular attention to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running the service with minimal privileges&lt;/li&gt;
&lt;li&gt;Restricting access to the administration API&lt;/li&gt;
&lt;li&gt;Keeping Caddy and its modules updated&lt;/li&gt;
&lt;li&gt;Protecting TLS certificate storage&lt;/li&gt;
&lt;li&gt;Limiting unnecessary network exposure&lt;/li&gt;
&lt;li&gt;Monitoring logs and reverse proxy errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One important detail is Caddy's administration API, which normally listens on a local interface.&lt;/p&gt;

&lt;p&gt;It's useful for dynamic configuration, but you shouldn't expose it publicly without appropriate security controls.&lt;/p&gt;

&lt;p&gt;Automatic HTTPS is a helpful feature, but it doesn't replace good server security practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Installing Caddy on Ubuntu or Debian
&lt;/h2&gt;

&lt;p&gt;Getting started is relatively simple.&lt;/p&gt;

&lt;p&gt;For Ubuntu and Debian systems, Caddy provides an official package repository.&lt;/p&gt;

&lt;p&gt;First, install the required packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  debian-keyring &lt;span class="se"&gt;\&lt;/span&gt;
  debian-archive-keyring &lt;span class="se"&gt;\&lt;/span&gt;
  apt-transport-https &lt;span class="se"&gt;\&lt;/span&gt;
  curl &lt;span class="se"&gt;\&lt;/span&gt;
  gnupg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the official repository signing key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-1sLf&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'https://dl.cloudsmith.io/public/caddy/stable/gpg.key'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/caddy-stable-archive-keyring.gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-1sLf&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/caddy-stable.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the repository files readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg

&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;o+r /etc/apt/sources.list.d/caddy-stable.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Caddy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;caddy version
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status caddy &lt;span class="nt"&gt;--no-pager&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The official package installs Caddy as a systemd service, making it easier to manage on Linux servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Using Caddy as a Reverse Proxy
&lt;/h2&gt;

&lt;p&gt;Let's say you're running a Node.js application on port 3000.&lt;/p&gt;

&lt;p&gt;Instead of exposing that application directly to the internet, you can put Caddy in front of it.&lt;/p&gt;

&lt;p&gt;A simple Caddyfile looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.example.com {
    encode zstd gzip

    reverse_proxy 127.0.0.1:3000
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, Caddy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receives requests for &lt;code&gt;app.example.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Handles HTTPS automatically when the domain and network are configured correctly&lt;/li&gt;
&lt;li&gt;Enables response compression&lt;/li&gt;
&lt;li&gt;Forwards requests to the Node.js application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before applying changes, validate the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;caddy validate &lt;span class="nt"&gt;--config&lt;/span&gt; /etc/caddy/Caddyfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then reload Caddy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload caddy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is one of my favorite parts of Caddy.&lt;/p&gt;

&lt;p&gt;A common reverse proxy setup doesn't need a large configuration file, and you don't have to manage a separate certificate renewal workflow for typical publicly accessible domains.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Running Caddy with Docker
&lt;/h2&gt;

&lt;p&gt;If you use Docker regularly, Caddy can also run as a container.&lt;/p&gt;

&lt;p&gt;For example, you can start it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; caddy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 443:443 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 443:443/udp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;/Caddyfile:/etc/caddy/Caddyfile:ro"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; caddy_data:/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; caddy_config:/config &lt;span class="se"&gt;\&lt;/span&gt;
  caddy:2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This assumes you've created a Caddyfile in your current directory.&lt;/p&gt;

&lt;p&gt;The named volumes are important because Caddy needs persistent storage for certificate data and configuration state.&lt;/p&gt;

&lt;p&gt;For a real deployment, I'd recommend using Docker Compose and placing Caddy on the same Docker network as the backend services.&lt;/p&gt;

&lt;p&gt;That way, you can route requests using container service names rather than exposing every application's ports publicly.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.example.com {
    reverse_proxy app:3000
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;app&lt;/code&gt; would be the name of a backend service reachable through the shared Docker network.&lt;/p&gt;

&lt;p&gt;It's a clean approach for applications that need HTTPS without a complicated reverse proxy setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Would I Use Caddy in Production?
&lt;/h2&gt;

&lt;p&gt;Yes, I'd consider it, particularly for environments where keeping the web server simple is a priority.&lt;/p&gt;

&lt;p&gt;Some good use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small and medium-sized web applications&lt;/li&gt;
&lt;li&gt;Containerized services&lt;/li&gt;
&lt;li&gt;Internal applications and developer platforms&lt;/li&gt;
&lt;li&gt;Reverse proxies for APIs&lt;/li&gt;
&lt;li&gt;Self-hosted tools and dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But there are still things I'd check before deploying it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Certificate storage:&lt;/strong&gt; Make sure certificate data survives container restarts and redeployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Networking:&lt;/strong&gt; Confirm DNS records, firewall rules, and ports 80 and 443 are configured correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring:&lt;/strong&gt; Collect access logs, error logs, and relevant operational metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Keep the admin API restricted and run the service with appropriate permissions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration management:&lt;/strong&gt; Store the Caddyfile in version control and validate changes before deployment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And, as with any infrastructure component, I'd test it against the actual application's requirements rather than choosing it based on benchmark numbers alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Want to Go Deeper?
&lt;/h2&gt;

&lt;p&gt;This post covers the basics, but there's more to consider when running Caddy in production.&lt;/p&gt;

&lt;p&gt;I wrote a longer, hands-on guide that explores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caddy's architecture and request handling&lt;/li&gt;
&lt;li&gt;Caddy vs. Nginx vs. Apache&lt;/li&gt;
&lt;li&gt;Security considerations and hardening&lt;/li&gt;
&lt;li&gt;Installing Caddy across different environments&lt;/li&gt;
&lt;li&gt;Docker deployment and reverse proxy configuration&lt;/li&gt;
&lt;li&gt;Automatic HTTPS and certificate management&lt;/li&gt;
&lt;li&gt;Production configuration and troubleshooting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're evaluating Caddy for your next project, the complete tutorial should help you get started.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://blog.naveedkumbhar.com/caddy-web-server-tutorial/" rel="noopener noreferrer"&gt;Read the Complete Caddy Web Server Tutorial: Architecture, Docker &amp;amp; Production Guide&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;One thing I've learned while working with infrastructure is that more configuration doesn't necessarily mean a better setup.&lt;/p&gt;

&lt;p&gt;Sometimes, reducing the number of moving parts makes systems easier to maintain.&lt;/p&gt;

&lt;p&gt;That's what makes Caddy interesting to me.&lt;/p&gt;

&lt;p&gt;It doesn't replace every use case for Nginx or Apache, but it offers a practical alternative, especially when automated HTTPS and simple reverse proxy configurations are priorities.&lt;/p&gt;

&lt;p&gt;I'd be interested to hear how others are using it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you tried Caddy in production? Do you prefer it over Nginx, Apache, or Traefik?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Share your experience in the comments. I'd love to hear what worked, what didn't, and whether you'd recommend it.&lt;/p&gt;




&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;I'm Naveed Ahmed, a Lead DevOps &amp;amp; Platform Architect. I write about DevOps, Linux, cloud infrastructure, containers, Kubernetes, and production engineering.&lt;/p&gt;

&lt;p&gt;You can find more of my work here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;a href="https://naveedkumbhar.com" rel="noopener noreferrer"&gt;Personal Website&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✍️ &lt;a href="https://blog.naveedkumbhar.com" rel="noopener noreferrer"&gt;Technical Blog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 &lt;a href="https://pk.linkedin.com/in/naveedkumbhar" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 &lt;a href="https://github.com/naveedkumbhar" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🛠️ &lt;a href="https://interview.naveedkumbhar.com" rel="noopener noreferrer"&gt;970+ SRE Interview Scenarios&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;☸️ &lt;a href="https://k8s.naveedkumbhar.com" rel="noopener noreferrer"&gt;Kubernetes Learning Resources&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📬 &lt;a href="https://news.naveedkumbhar.com" rel="noopener noreferrer"&gt;DevOps Dispatch Newsletter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, and happy building!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>caddy</category>
      <category>docker</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
