<?xml version="1.0" encoding="UTF-8"?>
<urlset
  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">

  <url>
    <loc>https://omarbadran.dev/</loc>
    <lastmod>2026-07-29</lastmod>
    <changefreq>monthly</changefreq>
    <priority>1.0</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/"/>
    <image:image>
      <image:loc>https://omarbadran.dev/profile-sticker.webp</image:loc>
      <image:title>Omar Badran — عمر بدران — Full Stack Developer and AppSec Specialist, Alexandria Egypt</image:title>
      <image:caption>Omar Badran (عمر بدران), Full Stack Developer and Application Security Specialist based in Alexandria, Egypt. Available for hire.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/cv</loc>
    <lastmod>2026-07-29</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/cv"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/cv"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/cv"/>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog</loc>
    <lastmod>2026-07-28</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog"/>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/ollama-local-models</loc>
    <lastmod>2026-07-28</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/ollama-local-models"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/ollama-local-models"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/ollama-local-models"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/ollama-local-models.webp</image:loc>
      <image:title>Ollama: Run Real Models on Your Own Machine</image:title>
      <image:caption>One command pulls a model and serves it on localhost. For prototyping, private data, and never paying per token again.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/claude-code-skills</loc>
    <lastmod>2026-07-24</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/claude-code-skills"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/claude-code-skills"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/claude-code-skills"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/claude-code-skills.webp</image:loc>
      <image:title>Turn Your Workflow Into a Claude Skill</image:title>
      <image:caption>Prompting the same instructions every session is a waste. A skill is a folder that teaches the model how you work — once — and it pays back on every project after that.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/llama-cpp-quantization</loc>
    <lastmod>2026-07-21</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/llama-cpp-quantization"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/llama-cpp-quantization"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/llama-cpp-quantization"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/llama-cpp-quantization.webp</image:loc>
      <image:title>llama.cpp and the Quantization You Actually Need</image:title>
      <image:caption>Q4, Q5, Q8 — the difference between a model that fits your GPU and one that does not, explained without the maths.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/subagent-team</loc>
    <lastmod>2026-07-17</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/subagent-team"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/subagent-team"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/subagent-team"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/subagent-team.webp</image:loc>
      <image:title>Building a Subagent Team That Reviews Its Own Work</image:title>
      <image:caption>One agent writing code is autocomplete. Several specialists who critique and correct each other is a process — and the difference shows up in the diff.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/vllm-serving-throughput</loc>
    <lastmod>2026-07-14</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/vllm-serving-throughput"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/vllm-serving-throughput"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/vllm-serving-throughput"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/vllm-serving-throughput.webp</image:loc>
      <image:title>vLLM: When You Outgrow One Request at a Time</image:title>
      <image:caption>Continuous batching and paged attention are why a serving stack handles fifty concurrent users on hardware that choked on five.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/claude-md-that-works</loc>
    <lastmod>2026-07-09</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/claude-md-that-works"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/claude-md-that-works"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/claude-md-that-works"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/claude-md-that-works.webp</image:loc>
      <image:title>Writing a CLAUDE.md the Model Actually Follows</image:title>
      <image:caption>Most project instruction files are wish lists. The ones that work read like a senior engineer briefing a new hire on day one — specific, ordered, and short.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/open-webui-chat-ui</loc>
    <lastmod>2026-07-07</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/open-webui-chat-ui"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/open-webui-chat-ui"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/open-webui-chat-ui"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/open-webui-chat-ui.webp</image:loc>
      <image:title>Open WebUI: A Chat Front-End Your Client Can Actually Use</image:title>
      <image:caption>Local models are useless to a business until someone non-technical can talk to them. This is the missing half.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/portfolio-that-converts</loc>
    <lastmod>2026-06-30</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/portfolio-that-converts"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/portfolio-that-converts"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/portfolio-that-converts"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/portfolio-that-converts.webp</image:loc>
      <image:title>Your Portfolio Is a Product, Not a Gallery</image:title>
      <image:caption>A grid of screenshots tells a client what you touched. A case study tells them what you decided — and decisions are the only thing they are actually buying.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/whisper-speech-to-text</loc>
    <lastmod>2026-06-30</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/whisper-speech-to-text"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/whisper-speech-to-text"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/whisper-speech-to-text"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/whisper-speech-to-text.webp</image:loc>
      <image:title>Whisper: Transcription That Handles Arabic</image:title>
      <image:caption>Most speech-to-text falls apart on Arabic dialects. Here is what actually works, and where it still struggles.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/comfyui-node-pipelines</loc>
    <lastmod>2026-06-23</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/comfyui-node-pipelines"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/comfyui-node-pipelines"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/comfyui-node-pipelines"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/comfyui-node-pipelines.webp</image:loc>
      <image:title>ComfyUI: Image Generation as a Pipeline, Not a Prompt Box</image:title>
      <image:caption>Nodes and graphs look intimidating until you need the same result twice. Then they are the only sane option.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/rtl-first-arabic</loc>
    <lastmod>2026-06-21</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/rtl-first-arabic"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/rtl-first-arabic"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/rtl-first-arabic"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/rtl-first-arabic.webp</image:loc>
      <image:title>Arabic-First, Not Arabic-Translated</image:title>
      <image:caption>Flipping a layout to RTL is twenty minutes of CSS. Making an Arabic interface feel native is a different job entirely — and users notice the gap immediately.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/aider-terminal-pair</loc>
    <lastmod>2026-06-16</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/aider-terminal-pair"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/aider-terminal-pair"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/aider-terminal-pair"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/aider-terminal-pair.webp</image:loc>
      <image:title>Aider: AI Pair Programming That Commits</image:title>
      <image:caption>It edits your repo and writes the commit message. Which is either exactly what you want or a very good reason to work on a branch.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/own-your-name-seo</loc>
    <lastmod>2026-06-12</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/own-your-name-seo"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/own-your-name-seo"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/own-your-name-seo"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/own-your-name-seo.webp</image:loc>
      <image:title>Owning Your Own Name in Search</image:title>
      <image:caption>If someone searches your name after a meeting, whatever they find becomes your reference check. Here is the exact stack I used to make sure they find me.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/continue-dev-assistant</loc>
    <lastmod>2026-06-09</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/continue-dev-assistant"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/continue-dev-assistant"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/continue-dev-assistant"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/continue-dev-assistant.webp</image:loc>
      <image:title>Continue: An Open-Source Coding Assistant You Control</image:title>
      <image:caption>Point it at a local model, a cloud model, or both. The value is choosing where your code goes.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/llms-txt-geo</loc>
    <lastmod>2026-06-03</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/llms-txt-geo"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/llms-txt-geo"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/llms-txt-geo"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/llms-txt-geo.webp</image:loc>
      <image:title>Getting Cited by AI Answer Engines</image:title>
      <image:caption>People ask a model about you before they open a search engine. Generative engine optimisation is mostly just being unambiguous in machine-readable ways.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/mcp-servers</loc>
    <lastmod>2026-06-02</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/mcp-servers"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/mcp-servers"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/mcp-servers"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/mcp-servers.webp</image:loc>
      <image:title>Model Context Protocol: Stop Writing Bespoke Tool Glue</image:title>
      <image:caption>One protocol so any assistant can talk to your database, your files, your ticketing system. Write the server once.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/whatsapp-checkout</loc>
    <lastmod>2026-05-26</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/whatsapp-checkout"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/whatsapp-checkout"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/whatsapp-checkout"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/whatsapp-checkout.webp</image:loc>
      <image:title>When the Best Checkout Is No Checkout</image:title>
      <image:caption>I built a storefront with no payment gateway on purpose. In the right market, a well-formed WhatsApp message converts better than any card form you can design.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/langchain-when-to-use</loc>
    <lastmod>2026-05-26</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/langchain-when-to-use"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/langchain-when-to-use"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/langchain-when-to-use"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/langchain-when-to-use.webp</image:loc>
      <image:title>LangChain: When the Framework Helps and When It Hurts</image:title>
      <image:caption>For a three-step chain, the raw SDK is shorter and clearer. For an agent with twelve tools and retries, it is not.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/llamaindex-rag</loc>
    <lastmod>2026-05-19</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/llamaindex-rag"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/llamaindex-rag"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/llamaindex-rag"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/llamaindex-rag.webp</image:loc>
      <image:title>LlamaIndex: RAG Beyond the Toy Example</image:title>
      <image:caption>Chunking strategy decides whether your retrieval works. Everything else is a distant second.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/security-by-design-small-teams</loc>
    <lastmod>2026-05-18</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/security-by-design-small-teams"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/security-by-design-small-teams"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/security-by-design-small-teams"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/security-by-design-small-teams.webp</image:loc>
      <image:title>Security by Design When You Are the Whole Team</image:title>
      <image:caption>You do not get a security review, a pentest budget, or a second pair of eyes. What you get is the ability to make the cheap decisions early — before they become expensive.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/qdrant-vector-search</loc>
    <lastmod>2026-05-12</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/qdrant-vector-search"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/qdrant-vector-search"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/qdrant-vector-search"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/qdrant-vector-search.webp</image:loc>
      <image:title>Qdrant: Picking a Vector Database Without the Hype</image:title>
      <image:caption>Filtered search is the feature that decides this, not raw benchmark numbers nobody reproduces.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/llm-proxy-pii</loc>
    <lastmod>2026-05-08</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/llm-proxy-pii"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/llm-proxy-pii"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/llm-proxy-pii"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/llm-proxy-pii.webp</image:loc>
      <image:title>Never Put Your API Key in the Browser</image:title>
      <image:caption>Every AI feature I ship sits behind a server proxy that redacts personal data before it leaves the building. Here is the shape of that proxy, and why each part exists.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/n8n-ai-automation</loc>
    <lastmod>2026-05-05</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/n8n-ai-automation"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/n8n-ai-automation"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/n8n-ai-automation"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/n8n-ai-automation.webp</image:loc>
      <image:title>n8n: Automation That Survives the Client Handover</image:title>
      <image:caption>A workflow the client can see and edit beats a cron job only you understand.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/email-otp-2fa</loc>
    <lastmod>2026-04-28</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/email-otp-2fa"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/email-otp-2fa"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/email-otp-2fa"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/email-otp-2fa.webp</image:loc>
      <image:title>Email OTP That Is Not Security Theatre</image:title>
      <image:caption>One-time codes are easy to add and easy to get wrong. Six digits with no rate limit, no expiry, and a leaky error message is worse than no second factor at all.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/dify-llmops</loc>
    <lastmod>2026-04-28</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/dify-llmops"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/dify-llmops"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/dify-llmops"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/dify-llmops.webp</image:loc>
      <image:title>Dify: Giving Non-Developers a Safe AI Playground</image:title>
      <image:caption>Prompt versioning, logs, and spend limits — the boring parts that make an AI feature survive contact with a real team.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/ragas-eval</loc>
    <lastmod>2026-04-21</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/ragas-eval"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/ragas-eval"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/ragas-eval"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/ragas-eval.webp</image:loc>
      <image:title>Ragas: You Cannot Improve a RAG You Do Not Measure</image:title>
      <image:caption>Faithfulness, relevance, context precision. Three numbers that turn "it feels better" into a decision.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/image-heavy-cwv</loc>
    <lastmod>2026-04-16</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/image-heavy-cwv"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/image-heavy-cwv"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/image-heavy-cwv"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/image-heavy-cwv.webp</image:loc>
      <image:title>Core Web Vitals on an Image-Heavy Site</image:title>
      <image:caption>Photography studios, interior designers, florists — my clients sell with pictures. Making those sites fast is a constraint problem, not a plugin you install.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/unsloth-finetuning</loc>
    <lastmod>2026-04-14</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/unsloth-finetuning"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/unsloth-finetuning"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/unsloth-finetuning"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/unsloth-finetuning.webp</image:loc>
      <image:title>Unsloth: Fine-Tuning on Hardware You Already Have</image:title>
      <image:caption>Before you fine-tune anything, read the part about why your problem is probably a retrieval problem.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/openai-agents-patterns</loc>
    <lastmod>2026-04-07</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/openai-agents-patterns"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/openai-agents-patterns"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/openai-agents-patterns"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/openai-agents-patterns.webp</image:loc>
      <image:title>Agent Patterns That Survive Production</image:title>
      <image:caption>Loop limits, tool timeouts, and a hard budget. An agent without these is an outage with a personality.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/self-host-fonts</loc>
    <lastmod>2026-04-05</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/self-host-fonts"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/self-host-fonts"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/self-host-fonts"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/self-host-fonts.webp</image:loc>
      <image:title>Self-Host Your Fonts. All of Them.</image:title>
      <image:caption>Two link tags to a font CDN cost you a DNS lookup, a connection, a redirect chain, and a layout shift — on the most visible text on the page.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/owasp-llm-top-10</loc>
    <lastmod>2026-03-31</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/owasp-llm-top-10"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/owasp-llm-top-10"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/owasp-llm-top-10"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/owasp-llm-top-10.webp</image:loc>
      <image:title>The OWASP LLM Top 10, Translated Into Actual Fixes</image:title>
      <image:caption>Prompt injection, insecure output handling, excessive agency. Each one with the line of code that prevents it.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/client-monorepo</loc>
    <lastmod>2026-03-24</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/client-monorepo"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/client-monorepo"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/client-monorepo"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/client-monorepo.webp</image:loc>
      <image:title>One Monorepo Per Client</image:title>
      <image:caption>Public site, admin dashboard, API. Three apps that must agree on types and ship together. Splitting them across three repos is how small teams create integration bugs.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/prompt-injection-defense</loc>
    <lastmod>2026-03-24</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/prompt-injection-defense"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/prompt-injection-defense"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/prompt-injection-defense"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/prompt-injection-defense.webp</image:loc>
      <image:title>Prompt Injection Is Not a Prompt Problem</image:title>
      <image:caption>You cannot instruct your way out of it. The fix is architectural: assume the model will be turned against you.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/garak-llm-scanner</loc>
    <lastmod>2026-03-17</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/garak-llm-scanner"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/garak-llm-scanner"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/garak-llm-scanner"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/garak-llm-scanner.webp</image:loc>
      <image:title>Garak: Scan Your LLM App Before Someone Else Does</image:title>
      <image:caption>A vulnerability scanner aimed at model behaviour — jailbreaks, leakage, toxicity — run in CI like any other test.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/case-studies-not-screenshots</loc>
    <lastmod>2026-03-11</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/case-studies-not-screenshots"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/case-studies-not-screenshots"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/case-studies-not-screenshots"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/case-studies-not-screenshots.webp</image:loc>
      <image:title>Write Case Studies, Not Screenshots</image:title>
      <image:caption>The five-part structure I use for every project write-up, and the one question that decides whether a paragraph stays in or gets cut.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/pyrit-red-teaming</loc>
    <lastmod>2026-03-10</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/pyrit-red-teaming"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/pyrit-red-teaming"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/pyrit-red-teaming"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/pyrit-red-teaming.webp</image:loc>
      <image:title>Red-Teaming Your Own AI Feature</image:title>
      <image:caption>An hour of structured attack attempts before launch is worth more than any amount of post-incident analysis.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/presidio-pii-redaction</loc>
    <lastmod>2026-03-03</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/presidio-pii-redaction"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/presidio-pii-redaction"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/presidio-pii-redaction"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/presidio-pii-redaction.webp</image:loc>
      <image:title>Presidio: Redaction That Beats Your Regex</image:title>
      <image:caption>My hand-rolled patterns caught emails and phones. They missed everything shaped slightly differently.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/llm-guard-output</loc>
    <lastmod>2026-02-24</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/llm-guard-output"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/llm-guard-output"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/llm-guard-output"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/llm-guard-output.webp</image:loc>
      <image:title>Treat Model Output Like User Input</image:title>
      <image:caption>Rendering generated text as HTML is XSS where the payload is written by a stranger through your own feature.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/model-supply-chain</loc>
    <lastmod>2026-02-17</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/model-supply-chain"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/model-supply-chain"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/model-supply-chain"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/model-supply-chain.webp</image:loc>
      <image:title>That Model File Is Executable Code</image:title>
      <image:caption>Pickle-based checkpoints can run arbitrary code on load. Downloading weights from a random mirror is not neutral.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/agentic-ai-risk</loc>
    <lastmod>2026-02-10</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/agentic-ai-risk"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/agentic-ai-risk"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/agentic-ai-risk"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/agentic-ai-risk.webp</image:loc>
      <image:title>The Blast Radius of an Autonomous Agent</image:title>
      <image:caption>Give an agent shell access and a budget, and you have built an insider threat that never sleeps.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/nuclei-templates</loc>
    <lastmod>2026-02-03</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/nuclei-templates"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/nuclei-templates"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/nuclei-templates"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/nuclei-templates.webp</image:loc>
      <image:title>Nuclei: Vulnerability Scanning You Can Read</image:title>
      <image:caption>Templates are YAML. You can audit exactly what a check does before you run it against a client.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/semgrep-custom-rules</loc>
    <lastmod>2026-01-27</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/semgrep-custom-rules"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/semgrep-custom-rules"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/semgrep-custom-rules"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/semgrep-custom-rules.webp</image:loc>
      <image:title>Writing a Semgrep Rule for Your Own Codebase</image:title>
      <image:caption>The generic ruleset finds generic bugs. The rule you write for your own mistake finds it forever.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/trivy-container-scanning</loc>
    <lastmod>2026-01-20</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/trivy-container-scanning"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/trivy-container-scanning"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/trivy-container-scanning"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/trivy-container-scanning.webp</image:loc>
      <image:title>Trivy: One Scanner for Images, IaC and Dependencies</image:title>
      <image:caption>Add it to CI in ten minutes. Then spend a week deciding which findings you are actually going to fix.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/osv-scanner-deps</loc>
    <lastmod>2026-01-13</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/osv-scanner-deps"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/osv-scanner-deps"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/osv-scanner-deps"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/osv-scanner-deps.webp</image:loc>
      <image:title>Your Dependency Tree Is Your Attack Surface</image:title>
      <image:caption>A twelve-line utility can pull in ninety packages. Every one of them runs with your privileges.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/gitleaks-secret-scanning</loc>
    <lastmod>2026-01-06</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/gitleaks-secret-scanning"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/gitleaks-secret-scanning"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/gitleaks-secret-scanning"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/gitleaks-secret-scanning.webp</image:loc>
      <image:title>The Secret You Committed Is Still in the History</image:title>
      <image:caption>Deleting the line does nothing. Rotating the credential is the only fix, and a pre-commit hook is the only prevention.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/trufflehog-verified-secrets</loc>
    <lastmod>2025-12-30</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/trufflehog-verified-secrets"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/trufflehog-verified-secrets"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/trufflehog-verified-secrets"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/trufflehog-verified-secrets.webp</image:loc>
      <image:title>Secret Scanning That Verifies Before It Alarms</image:title>
      <image:caption>A scanner that tests whether a found key is live turns a thousand false positives into three real emergencies.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/zap-dast-ci</loc>
    <lastmod>2025-12-23</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/zap-dast-ci"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/zap-dast-ci"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/zap-dast-ci"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/zap-dast-ci.webp</image:loc>
      <image:title>OWASP ZAP in CI Without Wrecking Your Pipeline</image:title>
      <image:caption>A baseline scan on every pull request, a full scan nightly. Getting that split wrong is why teams turn DAST off.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/wazuh-siem-small</loc>
    <lastmod>2025-12-16</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/wazuh-siem-small"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/wazuh-siem-small"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/wazuh-siem-small"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/wazuh-siem-small.webp</image:loc>
      <image:title>A SIEM for Teams Who Cannot Afford a SOC</image:title>
      <image:caption>Log collection you never read is theatre. Three alerts you actually respond to is a security programme.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/sigma-detection-rules</loc>
    <lastmod>2025-12-09</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/sigma-detection-rules"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/sigma-detection-rules"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/sigma-detection-rules"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/sigma-detection-rules.webp</image:loc>
      <image:title>Detection as Code with Sigma Rules</image:title>
      <image:caption>Write the detection once in a vendor-neutral format, convert it to whatever your SIEM speaks.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/atomic-red-team</loc>
    <lastmod>2025-12-02</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/atomic-red-team"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/atomic-red-team"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/atomic-red-team"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/atomic-red-team.webp</image:loc>
      <image:title>Testing Whether Your Alerts Actually Fire</image:title>
      <image:caption>Everyone deploys detection. Almost nobody verifies it triggers. Small, safe, mapped test cases fix that.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/falco-runtime-security</loc>
    <lastmod>2025-11-25</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/falco-runtime-security"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/falco-runtime-security"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/falco-runtime-security"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/falco-runtime-security.webp</image:loc>
      <image:title>Runtime Security: Catching What the Scanner Missed</image:title>
      <image:caption>A clean image can still spawn a shell at 3am. Build-time scanning cannot see that; runtime rules can.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/projectdiscovery-recon</loc>
    <lastmod>2025-11-18</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/projectdiscovery-recon"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/projectdiscovery-recon"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/projectdiscovery-recon"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/projectdiscovery-recon.webp</image:loc>
      <image:title>Building a Recon Workflow With ProjectDiscovery Tools</image:title>
      <image:caption>Subfinder into httpx into nuclei. Three tools, one pipe, and the whole external surface of an authorised target.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/sigstore-signing</loc>
    <lastmod>2025-11-11</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/sigstore-signing"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/sigstore-signing"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/sigstore-signing"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/sigstore-signing.webp</image:loc>
      <image:title>Signing Your Artifacts Without Managing Keys</image:title>
      <image:caption>Keyless signing tied to your CI identity. The barrier to supply-chain integrity dropped to almost nothing.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/sbom-syft-grype</loc>
    <lastmod>2025-11-04</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/sbom-syft-grype"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/sbom-syft-grype"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/sbom-syft-grype"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/sbom-syft-grype.webp</image:loc>
      <image:title>An SBOM Is Just an Honest Inventory</image:title>
      <image:caption>When the next Log4j lands, the only question that matters is "are we affected". An SBOM answers it in seconds.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/renovate-dependency-updates</loc>
    <lastmod>2025-10-28</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/renovate-dependency-updates"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/renovate-dependency-updates"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/renovate-dependency-updates"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/renovate-dependency-updates.webp</image:loc>
      <image:title>Automating Dependency Updates Without Drowning</image:title>
      <image:caption>Grouping, scheduling and auto-merge for patches. Otherwise you get forty pull requests and ignore all of them.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/github-actions-hardening</loc>
    <lastmod>2025-10-21</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/github-actions-hardening"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/github-actions-hardening"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/github-actions-hardening"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/github-actions-hardening.webp</image:loc>
      <image:title>Your CI Has More Secrets Than Your Production Server</image:title>
      <image:caption>Pin actions to a commit SHA, scope permissions per job, never run untrusted code on a privileged trigger.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/infisical-secrets</loc>
    <lastmod>2025-10-14</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/infisical-secrets"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/infisical-secrets"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/infisical-secrets"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/infisical-secrets.webp</image:loc>
      <image:title>Where Client Project Secrets Should Actually Live</image:title>
      <image:caption>Not in the repo, not in a WhatsApp message, not in a .env you emailed. Here is the small-team answer.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/pre-commit-hooks</loc>
    <lastmod>2025-10-07</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/pre-commit-hooks"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/pre-commit-hooks"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/pre-commit-hooks"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/pre-commit-hooks.webp</image:loc>
      <image:title>The Pre-Commit Hooks Worth Installing Today</image:title>
      <image:caption>Secret scan, formatter, linter, large-file guard. Four hooks that prevent the four most common self-inflicted wounds.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/docker-image-slimming</loc>
    <lastmod>2025-09-30</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/docker-image-slimming"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/docker-image-slimming"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/docker-image-slimming"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/docker-image-slimming.webp</image:loc>
      <image:title>A Smaller Image Is a Smaller Attack Surface</image:title>
      <image:caption>No shell, no package manager, no curl. Most of your CVE count comes from tools your app never uses.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/biome-toolchain</loc>
    <lastmod>2025-09-23</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/biome-toolchain"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/biome-toolchain"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/biome-toolchain"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/biome-toolchain.webp</image:loc>
      <image:title>Biome: Replacing Two Tools With One Fast One</image:title>
      <image:caption>Linting and formatting in a single binary. On a mid-size project the difference is seconds versus instant.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/bun-runtime</loc>
    <lastmod>2025-09-16</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/bun-runtime"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/bun-runtime"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/bun-runtime"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/bun-runtime.webp</image:loc>
      <image:title>Bun: Where It Wins and Where I Still Use Node</image:title>
      <image:caption>Install speed and the test runner are genuinely great. Production deployment is where I stay conservative.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/astro-islands</loc>
    <lastmod>2025-09-09</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/astro-islands"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/astro-islands"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/astro-islands"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/astro-islands.webp</image:loc>
      <image:title>Astro: Ship Less JavaScript on Content Sites</image:title>
      <image:caption>A marketing site does not need a hydrated framework on every page. Islands make that an architecture, not a compromise.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/shadcn-copy-paste-ui</loc>
    <lastmod>2025-09-02</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/shadcn-copy-paste-ui"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/shadcn-copy-paste-ui"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/shadcn-copy-paste-ui"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/shadcn-copy-paste-ui.webp</image:loc>
      <image:title>The Copy-Paste Component Model</image:title>
      <image:caption>You own the file, so you can restyle it into a brutalist theme without fighting a library you cannot edit.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/playwright-e2e</loc>
    <lastmod>2025-08-26</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/playwright-e2e"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/playwright-e2e"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/playwright-e2e"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/playwright-e2e.webp</image:loc>
      <image:title>Playwright: The Only Tests Clients Ever Notice</image:title>
      <image:caption>Unit tests protect you. End-to-end tests protect the checkout. Guess which one the client cares about.</image:caption>
    </image:image>
  </url>

  <url>
    <loc>https://omarbadran.dev/blog/zod-runtime-validation</loc>
    <lastmod>2025-08-19</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="https://omarbadran.dev/blog/zod-runtime-validation"/>
    <xhtml:link rel="alternate" hreflang="ar" href="https://omarbadran.dev/blog/zod-runtime-validation"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://omarbadran.dev/blog/zod-runtime-validation"/>
    <image:image>
      <image:loc>https://omarbadran.dev/img/blog/zod-runtime-validation.webp</image:loc>
      <image:title>TypeScript Types Vanish at Runtime</image:title>
      <image:caption>Your compile-time safety does nothing to a malformed request body. One schema per route closes the gap.</image:caption>
    </image:image>
  </url>

</urlset>
