<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Microservice architecture</title>
        <description>A pattern language for microservices</description>
        <link>http://microservices.io</link>
        <atom:link href="http://microservices.io/feed.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>GenAI-based development platform - part 3: Announcing Isolarium, three flavors of secure sandboxes for GenAI-based coding agents</title>
            <description>&lt;p&gt;I’m pleased to announce that I’ve open-sourced &lt;a href=&quot;https://github.com/humansintheloop-dev/isolarium&quot;&gt;Isolarium&lt;/a&gt;, a companion project to &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools&quot;&gt;Idea to Code workflow&lt;/a&gt; that provides secure sandboxes for running GenAI-based coding agents like Claude Code.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://github.com/humansintheloop-dev/isolarium/raw/main/isolarium_logo.png&quot; alt=&quot;Isolarium logo consisting of an agent in a cicle representing the sandbox&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This article is part of a series about the GenAI-based development platform (a.k.a. harness) that I’ve been developing to make GenAI-based coding agents like Claude Code more productive, more secure and less frustrating.
The complete list of articles in the series is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/01/29/about-idea-to-code.html&quot;&gt;Part 0 - My GenAI development workflow: Idea to Code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/09/genai-development-platform-part-1-development-guardrails.html&quot;&gt;Part 1 - Guardrails for GenAI coding agents&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/17/overview-i2code-implement-agent-orchestrator.html&quot;&gt;Part 2 - How Idea to Code turns an idea into working, tested software&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/26/genai-development-platform-part-3-announcing-isolarium.html&quot;&gt;Part 3 - Announcing Isolarium, three flavors of secure sandboxes for GenAI-based coding agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I first describe the risks of running coding agents on a developer workstation and why secure sandboxes are necessary.
I then briefly describe Isolarium and the three flavors of sandboxes that it offers.
Let’s start by looking at the motivation for Isolarium.&lt;/p&gt;

&lt;h2 id=&quot;why-coding-agents-need-secure-sandboxes&quot;&gt;Why coding agents need secure sandboxes&lt;/h2&gt;

&lt;p&gt;There are three reasons why coding agents need secure sandboxes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Coding agents are vulnerable to attacks that can compromise the developer’s machine&lt;/li&gt;
  &lt;li&gt;Container-based testing libraries such as Testcontainers introduce additional risks&lt;/li&gt;
  &lt;li&gt;Even well-intentioned coding agents can cause damage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look at each one.&lt;/p&gt;

&lt;h3 id=&quot;coding-agent-security-risks&quot;&gt;Coding agent security risks&lt;/h3&gt;

&lt;p&gt;Coding agent security risks have been on my mind ever since I watched the excellent and deeply disturbing presentation &lt;a href=&quot;https://media.ccc.de/v/39c3-agentic-probllms-exploiting-ai-computer-use-and-coding-agents&quot;&gt;&lt;em&gt;Agentic ProbLLMs: Exploiting AI Computer-Use and Coding Agents&lt;/em&gt;&lt;/a&gt; by AI researcher &lt;a href=&quot;https://embracethered.com/blog/&quot;&gt;Johann Rehberger&lt;/a&gt;.
His &lt;em&gt;The Month of AI Bugs&lt;/em&gt; series - one post per day for the month of August 2025 - shows the risks that we face when we run coding agents.&lt;/p&gt;

&lt;p&gt;Coding agent security risks include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Exfiltration of developer credentials (SSH keys, GitHub tokens, cloud credentials)&lt;/li&gt;
  &lt;li&gt;Leakage of sensitive local files from the developer workstation&lt;/li&gt;
  &lt;li&gt;Unauthorized access to other repositories or organization resources&lt;/li&gt;
  &lt;li&gt;Execution of malicious commands on the developer’s machine&lt;/li&gt;
  &lt;li&gt;Malicious or unsafe dependency installation affecting the host environment&lt;/li&gt;
  &lt;li&gt;Persistence of compromise on the developer machine after an agent session ends&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;container-based-testing-libraries-introduce-additional-risks&quot;&gt;Container-based testing libraries introduce additional risks&lt;/h3&gt;

&lt;p&gt;Testing technologies such as the incredibly useful &lt;a href=&quot;https://testcontainers.com/&quot;&gt;Testcontainers library&lt;/a&gt; that allow tests to run arbitrary Docker containers introduce additional risks since they can be used to run malicious containers that attack the host machine.&lt;/p&gt;

&lt;h3 id=&quot;even-well-intentioned-coding-agents-can-cause-damage&quot;&gt;Even well-intentioned coding agents can cause damage&lt;/h3&gt;

&lt;p&gt;There’s also the risk of a well-intentioned coding agent causing damage by making unintended changes to the developer’s machine or code repository.
Coding agents, for example, attempt to run arbitrary Bash commands, or write code that runs Bash commands.&lt;/p&gt;

&lt;h2 id=&quot;secure-sandboxes-for-genai-based-coding-agents&quot;&gt;Secure sandboxes for GenAI-based coding agents&lt;/h2&gt;

&lt;p&gt;Isolarium is a command line tool intended to address these problems.
It runs coding agents in a secure, isolated and disposable environment.
For example, to run Claude Code:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;my-project
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;isolarium run &lt;span class=&quot;nt&quot;&gt;--create&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; claude &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This command creates an isolated environment for the coding agent to run in, and then runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;claude&lt;/code&gt; inside that environment.&lt;/p&gt;

&lt;h2 id=&quot;three-flavors-of-isolation&quot;&gt;Three flavors of isolation&lt;/h2&gt;

&lt;p&gt;Isolarium offers three flavors of isolation that make different trade-offs between security and overhead:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://nono.sh/&quot;&gt;Nono&lt;/a&gt; - the most lightweight yet least secure option since the agent has access to some of the host’s filesystem.&lt;/li&gt;
  &lt;li&gt;Container - more overhead due to image and container creation yet more secure since only the working tree is shared with the host.&lt;/li&gt;
  &lt;li&gt;Virtual machine - slow to provision but provides the strongest isolation since the agent has no access to the host’s filesystem. 
What’s more the coding agent has more freedom: e.g., run tests that use Testcontainers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;isolarium-works-with-i2code-implement&quot;&gt;Isolarium works with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;/post/architecture/2026/03/17/overview-i2code-implement-agent-orchestrator.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command&lt;/a&gt; described in the previous article implements the final step of the &lt;a href=&quot;/post/architecture/2026/01/29/about-idea-to-code.html&quot;&gt;Idea to Code workflow&lt;/a&gt;, which turns a plan derived from an idea into a pull request consisting of production code and tests.
It can now use Isolarium to run the coding agent in a secure, isolated environment:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;isolarium implement &lt;span class=&quot;nt&quot;&gt;--isolation-type&lt;/span&gt; &amp;lt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This command runs the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command inside an Isolarium environment with the specified isolation type.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;

&lt;p&gt;To learn more about Isolarium and to get started, check out the &lt;a href=&quot;https://github.com/humansintheloop-dev/isolarium&quot;&gt;GitHub repository&lt;/a&gt;.
I welcome your questions, feedback, and contributions.&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Thu, 26 Mar 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/03/26/genai-development-platform-part-3-announcing-isolarium.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/03/26/genai-development-platform-part-3-announcing-isolarium.html</guid>
        </item>
        
        <item>
            <title>Microservices Platforms - part 6: Build platform</title>
            <description>&lt;p&gt;This is the sixth article in a series based on my &lt;a href=&quot;/post/architecture/2025/11/23/qconsf-2025-microservices-platforms.html&quot;&gt;QCon San Francisco 2025 talk &lt;em&gt;Microservices Platforms: When Team Topologies Meets Microservices Patterns&lt;/em&gt;&lt;/a&gt;.
The articles in the series are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-when-team-topologies-meets-microservices-patterns-part-1/&quot;&gt;Microservices Platforms - part 1: Overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-2-service-foundation-platform/&quot;&gt;Microservices Platforms - part 2: Service foundation platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-3-security-platform/&quot;&gt;Microservices Platforms - part 3: Security platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-4-infrastructure-services-platform/&quot;&gt;Microservices Platforms - part 4: Infrastructure services platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-5-observability-platform/&quot;&gt;Microservices Platforms - part 5: Observability platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-6-build-platform/&quot;&gt;Microservices Platforms - part 6: Build platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article describes the &lt;strong&gt;Build platform&lt;/strong&gt;, which together with the Deployment platform, defines the path that changes take from laptop to production.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/qconsf-microservices-platforms-part-6/Microservices_Platforms_Build.png&quot; alt=&quot;Build platform&quot; style=&quot;float: left; width: 100%; margin-right: 1.5em; margin-bottom: 1em;&quot; /&gt;&lt;/p&gt;

&lt;p style=&quot;font-size: 1.25em; font-weight: bold;&quot;&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-6-build-platform/&quot;&gt;Read more (This post is for paying subscribers only)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Fri, 20 Mar 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/03/20/qconsf-microservices-platforms-part-6.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/03/20/qconsf-microservices-platforms-part-6.html</guid>
        </item>
        
        <item>
            <title>GenAI-based development platform - part 2: How Idea to Code turns an idea into working, tested software</title>
            <description>&lt;p&gt;This article is the third in a series about the GenAI-based development platform (aka. harness) that I’ve been developing to make GenAI-based coding agents like Claude Code more productive and less frustrating.
The platform is a set of tools, constraints and feedback loops that guide their behavior, catch mistakes and prevent them from generating large amounts of poor-quality code that is often incomplete and untested.&lt;/p&gt;

&lt;p&gt;The complete list of articles in the series is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/01/29/about-idea-to-code.html&quot;&gt;Part 0 - My GenAI development workflow: Idea to Code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/09/genai-development-platform-part-1-development-guardrails.html&quot;&gt;Part 1 - Guardrails for GenAI coding agents&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/17/overview-i2code-implement-agent-orchestrator.html&quot;&gt;Part 2 - How Idea to Code turns an idea into working, tested software&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/26/genai-development-platform-part-3-announcing-isolarium.html&quot;&gt;Part 3 - Announcing Isolarium, three flavors of secure sandboxes for GenAI-based coding agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article is about the last step in the &lt;a href=&quot;/post/architecture/2026/01/29/about-idea-to-code.html&quot;&gt;&lt;em&gt;Idea to Code&lt;/em&gt; workflow &lt;/a&gt; that turns a plan derived from the initial idea into a pull request consisting of production code and tests.
The actual development is performed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; subcommand.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ i2code implement docs/ideas/amazing-idea
...
PR marked ready for review
PR: https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools/pull/31
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docs/ideas/amazing-idea&lt;/code&gt; is a directory that contains the idea along with a specification and implementation plan that were derived from the idea.&lt;/p&gt;

&lt;p&gt;Let’s explore the implementation of this coding agent orchestrator.&lt;/p&gt;

&lt;h2 id=&quot;how-i2code-implement-orchestrates-claude-code-to-implement-a-plan&quot;&gt;How &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; orchestrates Claude Code to implement a plan&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command combines deterministic Python code and Claude Code invocations.&lt;/p&gt;

&lt;p&gt;The following diagram shows how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; works:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/worktree-mode-overview.png&quot; style=&quot;width: 100%&quot; alt=&quot;Diagram of the Idea to Code workflow in worktree mode&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The input to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; is a plan derived from the idea and consists of a series of small tasks.
The output is a GitHub pull request consisting of roughly one commit per task.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command uses TDD, so each commit contains both production code and tests.&lt;/p&gt;

&lt;p&gt;Let’s look at how this works in more detail.&lt;/p&gt;

&lt;h2 id=&quot;setup-phase&quot;&gt;Setup phase&lt;/h2&gt;

&lt;p&gt;The first phase is a one-time setup that, among other things, creates a Git working tree for the branch that will be used to implement the plan.
Subsequent runs of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; for the same plan will reuse the same working tree, so the setup phase is only needed once per branch.
This step is entirely deterministic, implemented in Python.&lt;/p&gt;

&lt;h2 id=&quot;recovery-phase&quot;&gt;Recovery phase&lt;/h2&gt;

&lt;p&gt;The second phase is the recovery phase, which attempts to recover incomplete work from previous runs of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; for the same plan.
If there are uncommitted changes that complete a task, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; invokes Claude Code to generate a commit message and commit the changes.
Next, if there are commits in the local repository that haven’t been pushed to the remote, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; pushes them.
It then enters the main implementation loop.&lt;/p&gt;

&lt;h2 id=&quot;main-implementation-loop&quot;&gt;Main implementation loop&lt;/h2&gt;

&lt;p&gt;The implement loop iteratively executes the tasks in the plan until all tasks are completed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/task-implementation-loop.png&quot; class=&quot;img-responsive&quot; alt=&quot;Diagram of the task implementation loop&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The loop consists of the following steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Fix any failed GitHub actions workflow for the current HEAD&lt;/strong&gt;, waiting for the build to complete if necessary.
If the build is broken, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; invokes Claude Code to diagnose the failure, and commit a fix.
It then pushes the fix and waits for the build to complete again.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Respond to comments and reviews of the pull request.&lt;/strong&gt;
If there are any comments or reviews requesting changes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; first invokes Claude Code to triage the feedback and determine what changes, if any, are needed to address it.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command invokes Claude Code one or more times to generate commits that address the feedback and pushes the changes.
It also responds to the comments and review with an explanation of the changes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Implement the next task in the plan.&lt;/strong&gt;
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; then takes the next task in the plan, and invokes Claude Code to implement it using TDD, creating a commit.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Push the commit and, if necessary, create a pull request.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Wait for the build to complete and repeat.&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Mark the pull request as ready for review.&lt;/strong&gt;
Once all the tasks in the plan have been implemented, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; marks the pull request as ready for review.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Wait for the comments or reviews.&lt;/strong&gt;
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command can wait for comments or reviews on the pull request, and respond to them as described in step 2.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;trunk-mode&quot;&gt;Trunk mode&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; command also supports a trunk-based development mode, where instead of creating a pull request, it commits directly to the current branch.&lt;/p&gt;

&lt;h2 id=&quot;to-learn-more&quot;&gt;To learn more&lt;/h2&gt;

&lt;p&gt;Take a look at the &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools/blob/master/docs/design/implement-steps.md&quot;&gt;design document for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt;&lt;/a&gt; in the &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools&quot;&gt;Humans in the Loop Dev repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;In the next post, I’ll describe how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i2code implement&lt;/code&gt; can execute Claude Code within a sandbox environment, which minimizes the security risks of using coding agents.&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Tue, 17 Mar 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/03/17/overview-i2code-implement-agent-orchestrator.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/03/17/overview-i2code-implement-agent-orchestrator.html</guid>
        </item>
        
        <item>
            <title>GenAI-based development platform - part 1: guardrails</title>
            <description>&lt;p&gt;This article is the second in a series about the GenAI-based development platform (aka. harness) that I’ve been developing to make GenAI-based coding agents like Claude Code more productive and less frustrating.
The platform is a set of tools, constraints and feedback loops that guide their behavior, catch mistakes and prevent them from generating large amounts of poor-quality code that is often incomplete and untested.&lt;/p&gt;

&lt;p&gt;The complete list of articles in the series is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/01/29/about-idea-to-code.html&quot;&gt;Part 0 - My GenAI development workflow: Idea to Code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/09/genai-development-platform-part-1-development-guardrails.html&quot;&gt;Part 1 - Guardrails for GenAI coding agents&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/17/overview-i2code-implement-agent-orchestrator.html&quot;&gt;Part 2 - How Idea to Code turns an idea into working, tested software&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/post/architecture/2026/03/26/genai-development-platform-part-3-announcing-isolarium.html&quot;&gt;Part 3 - Announcing Isolarium, three flavors of secure sandboxes for GenAI-based coding agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because coding agents cannot be relied on to consistently follow instructions, they must operate within deterministic guardrails that catch mistakes and enforce quality. 
Guardrails are therefore a central part of the platform.
This article describes some of these guardrails.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-guardrails.png&quot; alt=&quot;GenAI-based development platform guardrails&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Specifically, there are four guardrails that I want to cover:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Pre-commit checklist skill&lt;/li&gt;
  &lt;li&gt;Pre-commit Git hook&lt;/li&gt;
  &lt;li&gt;GitHub Actions workflow jobs&lt;/li&gt;
  &lt;li&gt;Automated pull request reviews&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first guardrail relies on the coding agent following instructions, while the others are deterministic mechanisms that enforce quality regardless of the agent’s behavior.
Together, they provide defense in depth: if one guardrail is bypassed or ignored, the others still catch problems.&lt;/p&gt;

&lt;p&gt;Let’s dive into each guardrail in turn, starting with the pre-commit checklist.&lt;/p&gt;

&lt;h2 id=&quot;pre-commit-checklist-skill&quot;&gt;Pre-commit checklist skill&lt;/h2&gt;

&lt;p&gt;The first guardrail is the pre-commit checklist provided by the &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools/blob/master/skills/commit-guidelines/SKILL.md#pre-commit-checklist&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;commit-guidelines&lt;/code&gt; skill&lt;/a&gt; that is part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;idea-to-code&lt;/code&gt; plugin in the &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools/&quot;&gt;Humans in the Loop workflow and tools repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This pre-commit checklist instructs the coding agent to run several quality and safety checks before creating a Git commit, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Dead code detection (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vulture&lt;/code&gt; for Python)&lt;/li&gt;
  &lt;li&gt;Linting with auto-fix (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ruff&lt;/code&gt;) to enforce coding standards&lt;/li&gt;
  &lt;li&gt;Static type checking for Python (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pyright&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Shell script linting for new or modified &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.sh&lt;/code&gt; files (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shellcheck&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Code health analysis using CodeScene, requiring a score of 10 for all modified files&lt;/li&gt;
  &lt;li&gt;Test coverage verification to ensure tests cover new or changed production code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any quality gates fail, the agent must stop and fix the issues before committing.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://codescene.io/&quot;&gt;CodeScene&lt;/a&gt; provides incredibly valuable feedback that has significantly improved the quality of the code generated by Claude Code. 
For example, requiring a CodeScene score of 10 for all modified files - in other words, the boy scout rule - has significantly improved the maintainability of the &lt;a href=&quot;https://codescene.io/projects/76822/jobs/5831141/results?scope=month&amp;amp;aspect=#code-health&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Idea To Code&lt;/code&gt; code base&lt;/a&gt;.
One challenge, however, is that Claude Code often tries to justify not addressing code smells identified by CodeScene, such as claiming they are “pre-existing” or otherwise “acceptable”.
This is one of the motivations for implementing the next guardrail.&lt;/p&gt;

&lt;h2 id=&quot;pre-commit-git-hook&quot;&gt;Pre-commit Git hook&lt;/h2&gt;

&lt;p&gt;The second guardrail is a &lt;a href=&quot;https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks&quot;&gt;pre-commit Git hook&lt;/a&gt; that automatically runs quality and security checks before allowing commits to be made.
It’s implemented using the &lt;a href=&quot;https://pre-commit.com/&quot;&gt;pre-commit framework&lt;/a&gt;, which is configured by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.pre-commit-config.yaml&lt;/code&gt; file.
See, for example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.pre-commit-config.yaml&lt;/code&gt; files for the &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools/blob/master/.pre-commit-config.yaml&quot;&gt;Idea to Code&lt;/a&gt;, and &lt;a href=&quot;https://github.com/eventuate-examples/eventuate-examples-realguardio/blob/development/.pre-commit-config.yaml&quot;&gt;Eventuate RealGuardIO&lt;/a&gt; repositories.&lt;/p&gt;

&lt;p&gt;In addition to running the tests, the pre-commit hook largely repeats the pre-commit checklist.
The pre-commit hook does not run the dead code detection tool since its output needs to be interpreted and acted upon by the coding agent, which is not something a pre-commit hook can do.
The hook also runs &lt;a href=&quot;https://github.com/gitleaks/gitleaks&quot;&gt;gitleaks&lt;/a&gt; to prevent secrets from being committed.&lt;/p&gt;

&lt;p&gt;The pre-commit hook is essential because, unlike a Claude Code skill, it is deterministic.
Its checks don’t rely on the GenAI-based coding agent following the checklist, which is often not the case.
Fortunately, Claude Code hasn’t tried to &lt;a href=&quot;/post/genaidevelopment/2025/09/10/allow-git-commit-considered-harmful.html&quot;&gt;bypass this pre-commit hook like I described previously&lt;/a&gt;.
And even if it did, there are two more guardrails.&lt;/p&gt;

&lt;h2 id=&quot;github-actions-workflow&quot;&gt;GitHub Actions workflow&lt;/h2&gt;

&lt;p&gt;The third guardrail is the set of checks performed by the GitHub Actions workflow that runs on every push or merge.
A GitHub Actions workflow runs the tests.
It also has one or more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lint&lt;/code&gt; jobs.&lt;/p&gt;

&lt;p&gt;For example, the Eventuate RealGuardIO repository’s workflow has a &lt;a href=&quot;https://github.com/eventuate-examples/eventuate-examples-realguardio/blob/development/.github/workflows/test.yml#L18&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lint&lt;/code&gt; job&lt;/a&gt; that performs various quality and security checks on the codebase, including shell script linting and secret scanning using gitleaks.
So does the &lt;a href=&quot;https://github.com/humansintheloop-dev/humansintheloop-dev-workflow-and-tools/blob/master/.github/workflows/ci.yml&quot;&gt;Idea To Code repository’s GitHub Action’s workflow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These checks will be performed even if the GenAI-based coding agent bypasses the pre-commit hook.
In a later post, I will describe how to block a GenAI-based coding agent from modifying the GitHub Actions workflow files, which provides an additional layer of protection.&lt;/p&gt;

&lt;h2 id=&quot;automated-github-status-checks-codescene-pull-request-review&quot;&gt;Automated GitHub status checks: CodeScene pull request review&lt;/h2&gt;

&lt;p&gt;The fourth and final guardrail is a set of automated checks that are performed when a pull request is created or a new commit is added.
The failure of one of these GitHub status checks can prevent the pull request from being merged until the issues are addressed.&lt;/p&gt;

&lt;p&gt;For example, I’ve configured CodeScene to automatically review all pull requests for the Eventuate RealGuardIO and Idea to Code repositories and provide feedback on code health.
The GitHub status check will fail if the CodeScene score is below 10.
It can also trigger a coding agent to respond to the CodeScene review and push a new commit that addresses the issues.
However, these days CodeScene issues are almost always detected earlier by the Git pre-commit hook, and so the pull request reviews rarely fail.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;In future articles, I’ll describe other elements of the GenAI-based development (aka. Harness) platform that I’m developing.&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Mon, 09 Mar 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/03/09/genai-development-platform-part-1-development-guardrails.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/03/09/genai-development-platform-part-1-development-guardrails.html</guid>
        </item>
        
        <item>
            <title>Why GenAI-based coding agents are a complex domain in Cynefin - and what that means for adoption</title>
            <description>&lt;p&gt;These days, tremendous energy is being poured into software delivery using GenAI-based coding agents.
A key part of using coding agents successfully is context engineering - carefully crafting prompts, skills, AGENT.md files, guardrails, etc. - to guide agent behavior.
This typically requires significant experimentation and iteration.
A prompt that works for one model version may fail with another.&lt;/p&gt;

&lt;p&gt;This difficulty is not accidental.
Using GenAI-based coding agents to reliably create high-quality software is fundamentally different from using traditional developer tools.
The relationship between prompt and outcome cannot be fully predicted in advance.
Effective practices evolve as teams experiment and learn.&lt;/p&gt;

&lt;p&gt;As a result, organizations cannot treat coding agents like conventional technologies that can be standardized through a single “one true way.”
Instead, they must adopt a mindset that prioritizes safe experimentation, rapid feedback, and continuous adaptation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-coding-agent-cynefin.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This article introduces the Cynefin framework - a model for understanding different types of problem domains - and explains why using GenAI-based coding agents belongs in the complex category and what that means for platform strategy and adoption.&lt;/p&gt;

&lt;h2 id=&quot;about-cynefin&quot;&gt;About Cynefin&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Cynefin_framework&quot;&gt;Cynefin&lt;/a&gt; is a framework that helps us understand the nature of the problem we’re facing and how we should respond to it. 
It characterizes problems as either clear, complicated, complex, or chaotic, and for each category, it prescribes a different approach to problem-solving.
Cynefin distinguishes between situations where cause and effect are obvious, where they require expert analysis, where they can only be understood in retrospect, and where no perceivable order exists.&lt;/p&gt;

&lt;p&gt;The framework is typically visualized as follows:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/a/ab/Cynefin_framework_2022.jpg&quot; class=&quot;img-responsive&quot; style=&quot;max-width: 450px&quot; /&gt;
&lt;figcaption&gt;The Cynefin framework — image from &lt;a href=&quot;https://en.wikipedia.org/wiki/Cynefin_framework&quot;&gt;Wikipedia&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at the clear, complicated, and complex domains in more detail and then see how they relate to software development in general and GenAI-based coding agents in particular.&lt;/p&gt;

&lt;h2 id=&quot;about-clear-domains&quot;&gt;About Clear domains&lt;/h2&gt;

&lt;p&gt;In clear domains, the relationship between cause and effect is obvious.
You simply need to recognize the situation and apply the established rule or best practice.&lt;/p&gt;

&lt;p&gt;In a clear domain, effective problem-solving requires:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Sense - observe and establish facts&lt;/li&gt;
  &lt;li&gt;Categorize - match it to a known pattern&lt;/li&gt;
  &lt;li&gt;Respond - apply the established best practice&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A simple CRUD-style &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;User Profile Management&lt;/code&gt; subdomain can be considered a clear domain.&lt;/p&gt;

&lt;h3 id=&quot;about-complicated-domains&quot;&gt;About complicated domains&lt;/h3&gt;

&lt;p&gt;In complicated domains, the relationship between cause and effect is knowable but not obvious.
Determining the correct response requires analysis and expertise.&lt;/p&gt;

&lt;p&gt;In a complicated domain, effective problem-solving requires:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Sense - gather data&lt;/li&gt;
  &lt;li&gt;Analyze - use expertise to determine cause&lt;/li&gt;
  &lt;li&gt;Respond - apply a good practice&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Income tax calculation&lt;/code&gt; is an example of a complicated domain: the rules are deterministic, but applying them correctly requires careful analysis and expert knowledge, due to the large number of interdependent rules, exceptions, and conditional thresholds.&lt;/p&gt;

&lt;h3 id=&quot;about-cynefin-complex-domains&quot;&gt;About Cynefin complex domains&lt;/h3&gt;

&lt;p&gt;In a complex domain, the relationship between cause and effect can only be understood in retrospect and may not be repeated reliably.
Progress requires safe-to-fail experiments rather than upfront analysis.
There may not be a single optimal solution - only solutions that work better or worse in a given context.&lt;/p&gt;

&lt;p&gt;In a complex domain, effective problem solving requires:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Probe - run safe experiments&lt;/li&gt;
  &lt;li&gt;Sense - observe what happens&lt;/li&gt;
  &lt;li&gt;Respond - amplify what works, dampen what doesn’t&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Urban delivery routing and scheduling is an example of a complex domain. 
Traffic patterns, demand fluctuations, and human behavior create emergent outcomes that cannot be fully predicted in advance, which means effective solutions require experimentation and adaptation.&lt;/p&gt;

&lt;h2 id=&quot;why-software-development-is-complex&quot;&gt;Why software development is complex&lt;/h2&gt;

&lt;p&gt;Software development - the activity of building and evolving non-trivial software systems - is complex in Cynefin terms.
Some individual development tasks are clear or complicated - for example, applying a framework API, configuring infrastructure, or implementing a well-understood algorithm.
But architectural and design decisions must be made under uncertainty before their full consequences can be known.
Defining service boundaries, choosing abstractions, and modeling the domain are therefore complex activities in their own right, since the “right” decision cannot be determined through analysis alone.
Quite often the consequences of these decisions only become visible through testing, deployment, and real-world use rather than through upfront analysis.
As a result, effective software development requires iterative experimentation, rapid feedback, and continuous adaptation.
Except when building trivial applications, it also requires expert architectural judgment - in other words, experienced developers.&lt;/p&gt;

&lt;h2 id=&quot;developer-tools-are-clear-or-complicated&quot;&gt;Developer tools are clear or complicated&lt;/h2&gt;

&lt;p&gt;Although software development as a whole is complex, typical developer technologies - programming languages, frameworks, build tools, databases - are usually clear or complicated domains.
The relationship between cause and effect is stable and knowable.
You learn the rules, the APIs, and the configuration options, and then apply them.&lt;/p&gt;

&lt;p&gt;When problems arise, they can usually be resolved through analysis, debugging, or consulting documentation.
Even when experimentation is required, the underlying behavior is governed by defined rules and produces consistent results.
And, while systems built with these tools can exhibit complex behavior, the tools themselves operate according to stable and analyzable rules.
What’s more, when the tools themselves are changing rapidly, they might feel even chaotic, but that’s an emotional response to change rather than an inherent property of the domain.
In other words, most developer tools require expertise and analysis rather than safe-to-fail experimentation.&lt;/p&gt;

&lt;h2 id=&quot;using-an-llm-based-coding-agent-is-a-complex-domain&quot;&gt;Using an LLM-based coding agent is a complex domain&lt;/h2&gt;

&lt;p&gt;What makes LLMs so powerful is that they can tackle tasks within complex domains - including software development.
Yet this power comes with important differences.
LLM-based coding agents are fundamentally different from traditional developer tools.
Using such agents to reliably create high-quality software is a complex domain because the relationship between prompt and outcome cannot be fully predicted in advance.
A prompt that works in one context may fail in another.
Small changes in wording, context, or model version can produce disproportionately different results.&lt;/p&gt;

&lt;h3 id=&quot;cause-and-effect-can-only-be-understood-in-retrospect&quot;&gt;Cause and effect can only be understood in retrospect&lt;/h3&gt;

&lt;p&gt;The system does not expose a stable, fully understandable set of rules that can be exhaustively learned and applied.
Because outcomes depend on the interaction between prompt wording, model configuration, tool calls, retrieved context, and the surrounding codebase, behavior arises from the system as a whole rather than from a single predictable rule set.
Instead, progress requires iterative prompting, experimentation, and rapid feedback.
Effective use of a coding agent therefore resembles safe-to-fail experimentation more than traditional tool usage driven by analysis and expertise.&lt;/p&gt;

&lt;h3 id=&quot;probabilistic-nature-of-llms&quot;&gt;Probabilistic nature of LLMs&lt;/h3&gt;

&lt;p&gt;This unpredictability stems from the nature of LLMs themselves.
LLMs are probabilistic models that generate tokens by sampling from a probability distribution conditioned on the context.
Depending on the sampling strategy and model configuration, the same prompt can yield different outputs.
This probabilistic behavior helps explain why using an LLM-based coding agent is a complex domain, where cause and effect cannot be reduced to fixed, analyzable rules.&lt;/p&gt;

&lt;p&gt;Organizations must manage the complexity of the software system and the complexity of using coding agents at the same time.
Adoption therefore requires a thoughtful and deliberate approach.&lt;/p&gt;

&lt;h2 id=&quot;organizations-must-adopt-a-complex-domain-mindset-for-coding-agents&quot;&gt;Organizations must adopt a complex-domain mindset for coding agents&lt;/h2&gt;

&lt;p&gt;When an organization adopts GenAI-based coding agents, it cannot treat them like traditional developer tools.
First, it must shift engineering practices toward fast feedback and disciplined experimentation.
Second, the organization must define a GenAI-based development platform - the platform that supports the use of coding agents - as a learning amplifier, not as a vehicle for enforcing a rigid “one true way.” 
Let’s first look at the implications for engineering practices and then explore how this complexity shapes platform strategy and governance.&lt;/p&gt;

&lt;h3 id=&quot;engineering-practices-must-shift&quot;&gt;Engineering practices must shift&lt;/h3&gt;

&lt;p&gt;First, if coding agents are treated instead as a merely complicated domain - essentially as more advanced automation - organizations are likely to overtrust their outputs and underinvest in feedback loops, guardrails, and human-in-the-loop checkpoints. 
In such a complex environment, automated testing and real-time observability must explicitly replace manual policy as the primary mechanism for governance. 
This, in turn, requires a &lt;a href=&quot;/post/architecture/2026/02/08/architecting-for-genai-based-software-delivery.html&quot;&gt;fast-flow development model&lt;/a&gt; designed for experimentation and rapid feedback - without it, large-scale adoption of coding agents will stall.&lt;/p&gt;

&lt;h3 id=&quot;managing-the-unpredictability-of-outcomes&quot;&gt;Managing the unpredictability of outcomes&lt;/h3&gt;

&lt;p&gt;Second, the inherent unpredictability of GenAI-based coding agents requires a profound leadership mindset shift: moving away from the illusion of top-down control and toward a culture of continuous discovery. 
Because adoption is non-linear and success emerges through iteration rather than upfront analysis, leaders cannot rely on traditional rollout schedules or standardized mandates. 
Instead of attempting to eliminate variance, leaders must embrace an agile mindset that prioritizes enablement and evolutionary progress.&lt;/p&gt;

&lt;h3 id=&quot;the-platform-must-not-act-as-a-policy-factory&quot;&gt;The platform must not act as a policy factory&lt;/h3&gt;

&lt;p&gt;Third, this complexity also shapes platform strategy and governance.
In clear or complicated domains, a platform group that’s responsible for an internal development platform can act as a policy factory.
It defines standards, publishes the one true way, and measures success through consistency and compliance.
That approach works when cause and effect are stable and the best practices are knowable.&lt;/p&gt;

&lt;p&gt;Because developing software with GenAI-based coding agents is a complex domain, practices do not converge on a single, fixed best practice.
Prompting strategies, context engineering patterns, guardrails, and workflows evolve as teams experiment and learn.
What works today may need refinement tomorrow as models, tooling, and organizational context change.
The “one true way” is neither fully knowable nor stable.
Although certain patterns may stabilize over time, model evolution, changing tooling, and shifting organizational context ensure that practices remain sensitive to change.&lt;/p&gt;

&lt;h3 id=&quot;the-genai-based-development-platform-must-amplify-learning&quot;&gt;The GenAI-based development platform must amplify learning&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-development-platform.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Because reliably using coding agents operates in the Cynefin complex domain, a policy factory approach freezes learning too early.
Instead, the GenAI-based development platform - the platform that supports the use of coding agents - must function as a learning amplifier.
It should enable safe-to-fail experimentation, share emerging patterns, and provide guardrails.
The goal of the platform and its team shifts from prescribing correctness to accelerating collective learning.&lt;/p&gt;

&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;https://domainanalysis.io/&quot;&gt;Indu Alagarsamy&lt;/a&gt; for reviewing this article and providing valuable feedback.&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Sun, 01 Mar 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/03/01/using-genai-based-coding-agents-cynefin-complex-domain.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/03/01/using-genai-based-coding-agents-cynefin-complex-domain.html</guid>
        </item>
        
        <item>
            <title>Microservices Platforms - part 5: Observability platform</title>
            <description>&lt;p&gt;This is the fifth article in a series based on my &lt;a href=&quot;/post/architecture/2025/11/23/qconsf-2025-microservices-platforms.html&quot;&gt;QCon San Francisco 2025 talk &lt;em&gt;Microservices Platforms: When Team Topologies Meets Microservices Patterns&lt;/em&gt;&lt;/a&gt;.
The articles in the series are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-when-team-topologies-meets-microservices-patterns-part-1/&quot;&gt;Microservices Platforms - part 1: Overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-2-service-foundation-platform/&quot;&gt;Microservices Platforms - part 2: Service foundation platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-3-security-platform/&quot;&gt;Microservices Platforms - part 3: Security platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-4-infrastructure-services-platform/&quot;&gt;Microservices Platforms - part 4: Infrastructure services platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-5-observability-platform/&quot;&gt;Microservices Platforms - part 5: Observability platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-6-build-platform/&quot;&gt;Microservices Platforms - part 6: Build platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article describes the &lt;strong&gt;Observability platform&lt;/strong&gt;, which simplifies the development of &lt;a href=&quot;https://premium.microservices.io/microservices-rules-9-develop-observable-services/&quot;&gt;observable microservices&lt;/a&gt; - services whose behavior and usage can be understood by their teams.
It explains how a platform group provides shared observability capabilities that enable service teams to focus on their core domain responsibilities.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/qconsf-microservices-platforms-part-5/Microservices_Platforms_Observability.png&quot; alt=&quot;Microservices platform architecture diagram with the Observability component highlighted, showing its relationship to the Service, Service Foundation, Build, Security, Deployment, and Infrastructure Services components&quot; style=&quot;float: left; width: 100%; margin-right: 1.5em; margin-bottom: 1em;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-5-observability-platform/&quot;&gt;Read more (This post is for paying subscribers only)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Tue, 24 Feb 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/02/24/qconsf-microservices-platforms-part-5.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/02/24/qconsf-microservices-platforms-part-5.html</guid>
        </item>
        
        <item>
            <title>Authentication and authorization in a microservice architecture: Part 6 - implementing complex authorization using Oso Cloud local authorization</title>
            <description>&lt;p&gt;This article is the sixth in a series of articles about authentication and authorization in a microservice architecture.
The complete series is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://microservices.io/post/architecture/2025/04/25/microservices-authn-authz-part-1-introduction.html&quot;&gt;Overview of authentication and authorization in a microservice architecture&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://microservices.io/post/architecture/2025/05/28/microservices-authn-authz-part-2-authentication.html&quot;&gt;Implementing authentication&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://microservices.io/post/architecture/2025/07/22/microservices-authn-authz-part-3-jwt-authorization.html&quot;&gt;Implementing JWT-based authorization&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://microservices.io/post/architecture/2025/09/16/microservices-authn-authz-part-4-authorization-using-fetch-and-replicate.html&quot;&gt;Implementing authorization using fetch and replicate&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://microservices.io/post/architecture/2025/12/09/microservices-authn-authz-part-5-using-an-authorization-service.html&quot;&gt;Implementing complex authorization using Oso Cloud&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://microservices.io/post/architecture/2026/02/13/microservices-authn-authz-part-6-oso-local-authorization.html&quot;&gt;Implementing complex authorization using Oso Cloud local authorization&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the &lt;a href=&quot;https://microservices.io/post/architecture/2025/12/09/microservices-authn-authz-part-5-using-an-authorization-service.html&quot;&gt;previous article&lt;/a&gt;, I described how a microservices-based application can use an authorization service, such as Oso Cloud, to make authorization decisions.
Once the application’s authorization policy is defined declaratively in Oso, the application populates Oso with facts which correspond to relationships between entities.
Then, when handling a request, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;disarmSecuritySystem()&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security System Service&lt;/code&gt; invokes Oso passing the user’s identity, the operation to authorize (“disarm”), and the security system ID.
Oso decides whether the operation is authorized by evaluating the authorization policy using its stored facts and the authorization request’s parameters.&lt;/p&gt;

&lt;p&gt;This approach works well for operations that act on a single entity.
Potentially complicated authorization logic is replaced by much simpler calls to Oso Cloud.
But invoking Oso repeatedly for bulk operations that act on large collections of entities is likely to be inefficient due to the communication overhead.
This article starts by exploring a more efficient way to authorize bulk query operations using a combination of local facts and facts stored in Oso Cloud.
After that, it revisits how to authorize single-entity operations using locally stored facts.
Let’s begin by looking at a simple example of a bulk query operation.&lt;/p&gt;

&lt;h2 id=&quot;problem-implementing-findsecuritysystems&quot;&gt;Problem: Implementing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; system operation returns a list of the security systems that the user is authorized to access.
This data is used to populate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View Security Systems&lt;/code&gt; page of the RealGuardIO application’s UI.
Let’s first look at why such a bulk query is challenging to implement.&lt;/p&gt;

&lt;h3 id=&quot;inefficient-approach-one-by-one-authorization-using-oso&quot;&gt;Inefficient approach: One-by-one authorization using Oso&lt;/h3&gt;

&lt;p&gt;One way to implement authorization for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; to do the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Query the database for all security systems - the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security System Service&lt;/code&gt; doesn’t maintain any other authorization-related data&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For each security system, query Oso to check whether the user is authorized to view that security system&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach is straightforward to implement.
The problem is that unless there are just a few &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt;, it’s likely to be inefficient.&lt;/p&gt;

&lt;p&gt;A better approach, which was described in &lt;a href=&quot;https://microservices.io/post/architecture/2025/04/25/microservices-authn-authz-part-1-introduction.html#database-access-logic&quot;&gt;part 1&lt;/a&gt;, is to integrate the authorization check into the data access logic, i.e. the SQL query.
In &lt;a href=&quot;https://microservices.io/post/architecture/2025/09/16/microservices-authn-authz-part-4-authorization-using-fetch-and-replicate.html#the-replicate-strategy-is-faster-and-less-coupled&quot;&gt;part 4&lt;/a&gt; I described this approach with an example that efficiently retrieved &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt; by executing SQL SELECT that joined the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;security_systems&lt;/code&gt; table with data replicated from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Customer Service&lt;/code&gt;.
Let’s look at how to do that when using Oso Cloud.&lt;/p&gt;

&lt;h3 id=&quot;integrating-oso-into-the-database-access-logic-using-local-authorization&quot;&gt;Integrating Oso into the database access logic using local authorization&lt;/h3&gt;

&lt;p&gt;Oso Cloud has a feature called &lt;a href=&quot;https://www.osohq.com/docs/develop/facts/local-authorization&quot;&gt;local authorization&lt;/a&gt;, which makes authorization decisions using a combination of facts stored in Oso Cloud and the service’s database.
Two key local authorization methods are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorizeLocal()&lt;/code&gt;.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorizeLocal()&lt;/code&gt; method is the local authorization equivalent of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorize()&lt;/code&gt;.
It returns a SQL SELECT statement that, when executed by the service, returns either true (authorized) or false (not authorized).
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt; method returns a SQL WHERE clause fragment that can be used to implement bulk queries such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt;.
I’ll describe how to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorizeLocal()&lt;/code&gt; later in this article.
Let’s first look at how to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;configuring-local-authorization&quot;&gt;Configuring local authorization&lt;/h4&gt;

&lt;p&gt;To use local authorization, you must specify a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_authorization_config.yaml&lt;/code&gt; when creating the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Oso&lt;/code&gt; client:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OsoServiceConfiguration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configurationFilePath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...;&lt;/span&gt;

  &lt;span class=&quot;nd&quot;&gt;@Bean&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Oso&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;oso&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;${oso.url}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;osoUrl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                 &lt;span class=&quot;nd&quot;&gt;@Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;${oso.auth}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;osoAuth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optionsBuilder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OsoClientOptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configurationFilePath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;optionsBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withDataBindingsPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configurationFilePath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Oso&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;osoAuth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;URI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;osoUrl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optionsBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The path to the configuration file is passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;optionsBuilder.withDataBindingsPath()&lt;/code&gt;.
One interesting challenge in a Spring Boot application is that the configuration file is typically in a JAR file nested within the Spring Boot JAR file.
The RealGuardIO example application contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClasspathLocalAuthorizationConfigFileSupplier&lt;/code&gt; that maps a classpath resource to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.nio.file.Path&lt;/code&gt; using a Virtual FileSystem - a Java feature that I was previously unaware of.&lt;/p&gt;

&lt;p&gt;The local authorization configuration file contains two sections.
First, the first section maps Polar predicates, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_relation(…​)&lt;/code&gt;, which are named logical rules or facts in Oso Cloud’s policy language, to SQL SELECT queries.
This mapping enables Oso Cloud to generate SQL that uses facts stored locally.
Second, the second section maps resource types to database column types.
This section is optional but recommended in order to improve performance.&lt;/p&gt;

&lt;p&gt;Interestingly, in this particular example, all required authorization data is replicated to Oso, so no fact mappings are required.
Strictly speaking, this example can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Oso.list()&lt;/code&gt; instead of local authorization.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Oso.list(user, permission, resourceType)&lt;/code&gt; returns a list of resourceIDs that the user has permission to perform an action on.
A service can then use that list to construct an SQL SELECT.
However, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt; is not only more convenient, since it returns a SQL fragment, but it also supports scenarios, such as the one described later in this article, that require local data.&lt;/p&gt;

&lt;p&gt;Here’s the configuration file that configures local authorization:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;facts:

sql_types:
  Location: integer
  SecuritySystem: integer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This configuration file specifies that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Locations&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt; have an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Integer&lt;/code&gt; primary key.
Later in this article, we will revisit this configuration file for a scenario where some facts are stored locally.&lt;/p&gt;

&lt;h4 id=&quot;implementing-findsecuritysystems-with-osolistlocal&quot;&gt;Implementing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;Let’s now look at how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt;.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;listLocal()&lt;/code&gt; method has four parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user&lt;/code&gt; - the ID of the user attempting to access the resources&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;permission&lt;/code&gt; - the permission, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resourceType&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystem&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ID column&lt;/code&gt; - the primary key column of the table containing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This method makes it straightforward to integrate authorization checks into SQL queries.
The SQL SELECT for retrieving &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt; looks something like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var sql = &quot;SELECT * FROM ss security_systems WHERE &quot; + oso.listLocal(...);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The SELECT’s WHERE clause is simply the fragment returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;listLocal()&lt;/code&gt;.
The following diagram shows how this works:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;/i/microservices-auth/part-6/oso-list-local.png&quot; alt=&quot;oso list local&quot; class=&quot;img-responsive&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;In this example scenario, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;listLocal()&lt;/code&gt; returns a SQL fragment that’s equivalent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ss.id IN (202, 203)&lt;/code&gt;.
In other words, Oso Cloud returns an SQL WHERE-clause predicate containing inline values that constrain the IDs of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt; that the user is allowed to view.
Later, you will see that the SQL predicate can join with other tables when authorization uses local data.
Let’s now look at an example of using local fact data for authorization.&lt;/p&gt;

&lt;h2 id=&quot;making-authorization-decisions-with-locally-stored-facts&quot;&gt;Making authorization decisions with locally stored facts&lt;/h2&gt;

&lt;p&gt;Currently, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Customer Service&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security Service&lt;/code&gt; populate Oso with all the facts needed for authorization.
As a result, the SQL fragment returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Oso.listLocal()&lt;/code&gt; does not reference any database tables.
However, while the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Customer Service&lt;/code&gt; needs to publish its data to Oso so that it is available to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security Service&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security Service&lt;/code&gt; does not.
Instead, it can use local authorization to combine the facts in its database with those in Oso.&lt;/p&gt;

&lt;p&gt;Specifically, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security Service&lt;/code&gt; does not need to publish the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystemAssignedToLocation&lt;/code&gt; event to maintain the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Location-SecuritySystem&lt;/code&gt; relationship in Oso.
Instead, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_relation(SecuritySystem{…​}, &quot;location&quot;, Location{…​)&lt;/code&gt; fact can be mapped to the SQL &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SELECT&lt;/code&gt; that queries the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;security_system&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Let’s first look at the configuration file that defines the mapping.
After that, we’ll revisit the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; query.
Finally, we’ll explore how to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorizeLocal()&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-configuration-file&quot;&gt;The configuration file&lt;/h3&gt;

&lt;p&gt;Here’s the Oso configuration file that maps the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_relation(SecuritySystem{SECURITY_SYSTEM}, &quot;location&quot;, Location{LOCATION})&lt;/code&gt; relation to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;security_system&lt;/code&gt; table:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;facts:
  &quot;has_relation(SecuritySystem:_, String:location, Location:_)&quot;:
    query: &apos;SELECT id, location_id FROM security_system WHERE location_id IS NOT NULL&apos;

sql_types:
  Location: integer
  SecuritySystem: integer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s now look at how this affects the SQL fragment returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-findsecuritysystems-query-with-local-facts&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; query with local facts&lt;/h3&gt;

&lt;p&gt;While the code that implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;findSecuritySystems()&lt;/code&gt; is unaffected by this change, the SQL fragment now references the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;security_system&lt;/code&gt; table.
Oso Cloud determines the locations that the user is authorized to access and returns an SQL fragment that queries the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;security_system&lt;/code&gt; table to determine the IDs of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystems&lt;/code&gt; at those locations.
Here’s an example fragment:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ss.id IN (WITH RECURSIVE
c0(arg0, arg2) AS NOT MATERIALIZED (
SELECT id, location_id FROM security_system WHERE location_id IS NOT NULL
)
 SELECT f1.arg0
FROM c0 AS f1, (
VALUES (1769998271122), (17699982711222)
) as cs( arg0 )
WHERE f1.arg2 = cs.arg0
)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This generated fragment uses common table expressions that are essentially named subqueries.
It’s equivalent to:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  ss.id IN (SELECT id  FROM security_system  WHERE location_id IN (1769998271122, 17699982711222))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that we’ve seen how to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.listLocal()&lt;/code&gt; to implement bulk queries, let’s look at local authorization for single-entity operations.&lt;/p&gt;

&lt;h3 id=&quot;using-authorizelocal&quot;&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authorizeLocal()&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Since some facts are only available locally, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security System Service&lt;/code&gt; cannot use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorize()&lt;/code&gt; (described previously in &lt;a href=&quot;https://microservices.io/post/architecture/2025/12/09/microservices-authn-authz-part-5-using-an-authorization-service.html&quot;&gt;part 4&lt;/a&gt;) to authorize operations such as ‘arm’ and ‘disarm’.
Instead, it must use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oso.authorizeLocal()&lt;/code&gt;.
This method has three parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user&lt;/code&gt; - the user attempting to perform the operation&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;permission&lt;/code&gt; - the operation, such as “disarm”&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resourceID&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystem&lt;/code&gt; with ID 101&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It returns a SQL query that determines whether the user is authorized to access that resource.
The query returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;.
The following diagram shows how it works:&lt;/p&gt;

&lt;figure&gt;
&lt;img src=&quot;/i/microservices-auth/part-6/oso-authorize-local.png&quot; alt=&quot;oso authorize local&quot; class=&quot;img-responsive&quot; /&gt;
&lt;/figure&gt;

&lt;p&gt;Here, for example, is how the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Security System Service&lt;/code&gt; can check whether a user is authorized to disarm a security system:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oso&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;authorizeLocal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;CustomerEmployee&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;&quot;disarm&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SecuritySystem&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;securitySystemId&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jdbcTemplate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;queryForObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here’s the SQL query returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authorizeLocal()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;WITH&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;RECURSIVE&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MATERIALIZED&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;location_id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;security_system&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;location_id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IS&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;EXISTS&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1767657091967&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17676570919672&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arg0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arg0&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This query is equivalent to:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  SELECT EXISTS (
    SELECT 1 FROM security_system
    WHERE id = 1 AND location_id IN (1767657091967, 17676570919672)
  ) AS allowed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In other words, Oso generates a SQL query that determines whether the specified &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SecuritySystem&lt;/code&gt; is at a location that the user is allowed to disarm.&lt;/p&gt;

&lt;h2 id=&quot;show-me-the-code&quot;&gt;Show me the code&lt;/h2&gt;

&lt;p&gt;The RealGuardIO application (work-in-progress) can be found in the following &lt;a href=&quot;https://github.com/eventuate-examples/eventuate-examples-realguardio&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;https://www.linkedin.com/in/hazalmestci/&quot;&gt;Hazal Mestci&lt;/a&gt; for reviewing this article and providing valuable feedback.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Oso local authorization enables a service to make authorization decisions using a combination of facts stored in Oso and the service’s local database&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;listLocal(user, permission, resourceType, ID column)&lt;/code&gt; - returns a SQL WHERE clause fragment that filters results based on permissions&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authorizeLocal(user, permission, resource)&lt;/code&gt; - returns a SQL SELECT that makes authorization decisions using local data&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Local authorization requires a configuration file that maps Polar predicates facts, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_relation&lt;/code&gt;, which are named logical rules or facts in Oso Cloud’s policy language, to SQL queries&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The generated SQL fragments and SELECT statements can include Oso facts, such as resource IDs&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If local tables and Oso-stored data overlap, the generated SQL can contain a union of local and Oso-stored data&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Fri, 13 Feb 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/02/13/microservices-authn-authz-part-6-oso-local-authorization.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/02/13/microservices-authn-authz-part-6-oso-local-authorization.html</guid>
        </item>
        
        <item>
            <title>QCONSF Microservices Platforms - part 4: Infrastructure services platform</title>
            <description>&lt;p&gt;This is the fourth in a series of articles based on my &lt;a href=&quot;/post/architecture/2025/11/23/qconsf-2025-microservices-platforms.html&quot;&gt;QCon San Francisco 2025 talk &lt;em&gt;Microservices Platforms: When Team Topologies Meets Microservices Patterns&lt;/em&gt;&lt;/a&gt;.
The articles in the series are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-when-team-topologies-meets-microservices-patterns-part-1/&quot;&gt;Microservices Platforms - part 1: Overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-2-service-foundation-platform/&quot;&gt;Microservices Platforms - part 2: Service foundation platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-3-security-platform/&quot;&gt;Microservices Platforms - part 3: Security platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-4-infrastructure-services-platform/&quot;&gt;Microservices Platforms - part 4: Infrastructure services platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-5-observability-platform/&quot;&gt;Microservices Platforms - part 5: Observability platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-6-build-platform/&quot;&gt;Microservices Platforms - part 6: Build platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article discusses the &lt;strong&gt;Infrastructure Services Platform&lt;/strong&gt;, which enables stream-aligned service teams to deliver quickly without becoming infrastructure experts.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/qconsf-microservices-platforms-part-4/Microservices_Platforms_Infrastructure_Services.png&quot; alt=&quot;Slide 27&quot; style=&quot;float: left; width: 100%; margin-right: 1.5em; margin-bottom: 1em;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-4-infrastructure-services-platform/&quot;&gt;Read more (This post is for paying subscribers only)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Thu, 12 Feb 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/02/12/qconsf-microservices-platforms-part-4.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/02/12/qconsf-microservices-platforms-part-4.html</guid>
        </item>
        
        <item>
            <title>GenAI-based software delivery needs a fast flow architecture</title>
            <description>&lt;p&gt;GenAI doesn’t change the fundamentals of software architecture.
In fact, GenAI-based software development is an amplifier of organizational capabilities, not a replacement for sound architectural principles.
It can make high-performing organizations even better and make low-performing organizations worse.
For organizations adopting GenAI-based software delivery, fast flow is therefore not optional, but essential.&lt;/p&gt;

&lt;p&gt;This article explores what GenAI-based software delivery means for architecture and organizations.
It begins by revisiting the need for fast flow and why it remains the defining characteristic of high-performing software delivery, regardless of tooling. 
It then introduces the concept of a fast-flow socio-technical architecture and the architectural characteristics that enable it. 
From there, the article examines how these same characteristics support GenAI-based software delivery. 
It looks specifically at the role of the microservice architecture in providing the boundaries and fast feedback that GenAI-based coding agents need.
Finally, it poses a practical question for engineering leaders: whether their current socio-technical architecture is ready for GenAI-based software delivery.&lt;/p&gt;

&lt;p&gt;Let’s start by looking at fast flow.&lt;/p&gt;

&lt;h2 id=&quot;the-need-for-fast-flow&quot;&gt;The need for fast flow&lt;/h2&gt;

&lt;p&gt;High-performing software development organizations are ones that practice fast flow: the continuous delivery of value to customers combined with continuous learning and improvement.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-fast-flow/fast-flow.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at how to achieve fast flow.&lt;/p&gt;

&lt;h2 id=&quot;fast-flow-requires-a-socio-technical-architecture-that-supports-it&quot;&gt;Fast flow requires a socio-technical architecture that supports it&lt;/h2&gt;

&lt;p&gt;Fast flow in turn requires a particular kind of &lt;a href=&quot;/post/architecture/2025/11/29/sag-2025-growing-sociotechical-architecture.html&quot;&gt;socio-technical architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-fast-flow/socio-technical-architecture-for-fast-flow.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s a socio-technical architecture consisting of two parts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An organization structured using &lt;a href=&quot;https://premium.microservices.io/microservices-rules-3-apply-team-topologies/&quot;&gt;Team Topologies&lt;/a&gt; that practices &lt;a href=&quot;https://premium.microservices.io/microservices-rules-1-practice-continuous-delivery/&quot;&gt;DevOps&lt;/a&gt; (as defined by the DevOps Handbook)&lt;/li&gt;
  &lt;li&gt;A fast flow architecture that enables Team Topologies and DevOps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s focus on the second part: the fast flow architecture.&lt;/p&gt;

&lt;h2 id=&quot;the-characteristics-of-a-fast-flow-architecture&quot;&gt;The characteristics of a fast flow architecture&lt;/h2&gt;

&lt;p&gt;As I describe in &lt;a href=&quot;https://www.manning.com/books/microservices-patterns-second-edition?utm_source=microservices-patterns-chris&amp;amp;utm_medium=affiliate&amp;amp;utm_campaign=book_richardson4&amp;amp;a_aid=microservices-patterns-chris&amp;amp;a_bid=c4d8dec5&amp;amp;chan=mm_microservicesio&quot;&gt;Chapter 5 of Microservices Patterns, 2nd Edition&lt;/a&gt;, a fast flow architecture is an architecture that promotes team autonomy and optimizes the two inner and outer developer loops.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-fast-flow/fast-workflow.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The outer loop is the &lt;strong&gt;change-deploy-analyze&lt;/strong&gt; loop, which is the application’s delivery workflow.
The change step consists of design decision-making phase followed by the inner &lt;strong&gt;edit-test-analyze&lt;/strong&gt; loop - the developer’s implementation workflow.&lt;/p&gt;

&lt;p&gt;An architecture enables fast flow by satisfying these five quality attributes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Modifiability&lt;/strong&gt; - reflects how easily changes can be made to the application.
It is achieved through designing an architecture that is &lt;a href=&quot;https://premium.microservices.io/microservices-rules-7-design-loosely-design-time-coupled-services-part-1/&quot;&gt;loosely design-time coupled&lt;/a&gt; and cohesive.
Loose design-time coupling increases the likelihood that changes are localized to a small part of the application, reducing cognitive load and enabling team autonomy by reducing the need for coordination between teams.
See &lt;a href=&quot;/post/architecture/2025/03/23/andrew-harmel-law-architecture-advice-process.html&quot;&gt;Andrew Harmel-Law’s architecture advice process and fast flow&lt;/a&gt; for more on decision-making and team autonomy.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Evolvability&lt;/strong&gt; - describes how easy it is to upgrade the application’s technology stack.
For large applications, it is achieved by using a multi-component (microservice) architecture which allows for most architectural decisions to be made separately for each component - often within a team - and for upgrades to be done incrementally.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Testability&lt;/strong&gt; - reflects how easy and fast it is to verify that a change is releasable.
&lt;a href=&quot;https://premium.microservices.io/microservices-rules-8-design-independently-deployable-services-3/&quot;&gt;Testability&lt;/a&gt; is achieved through designing an architecture that is loosely design-time coupled, loosely build-time coupled, and is verifiable using fast-running automated tests that run locally on a developer’s laptop.
Loose coupling reduces both the scope and impact of a change, which reduces the number of tests that need to be run.
Fast-running tests accelerate both the inner and outer development loops, resulting in faster feedback.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Deployability&lt;/strong&gt; - reflects how easy and fast it is to deploy a change into production.
&lt;a href=&quot;https://premium.microservices.io/microservices-rules-8-design-independently-deployable-services/&quot;&gt;Deployability&lt;/a&gt; is achieved through designing an architecture that supports deployments that are automated, fast, reliable, can be done without affecting SLAs, and can be automatically rolled back when there’s a problem.
High deployability accelerates the outer development loop by reducing the time it takes to get feedback from production and from users.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Observability&lt;/strong&gt; - reflects how easy it is to understand the behavior of the application and its users.
&lt;a href=&quot;https://premium.microservices.io/microservices-rules-9-develop-observable-services/&quot;&gt;Observability&lt;/a&gt; is achieved through designing an architecture that implements the &lt;a href=&quot;/patterns/index.html#observability&quot;&gt;observability patterns&lt;/a&gt;.
Observability enables teams to understand how their code is behaving in production and how users are using it.
It’s essential for fast feedback in the outer development loop and supports deployability by providing the telemetry that determines whether a deployment is successful or not, and whether a rollback is needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together these five quality attributes enable fast flow by optimizing the inner and outer development loops and by promoting team autonomy.
They are essential for high-performance software delivery organizations.
Let’s now see how they are also required for GenAI-based software delivery.&lt;/p&gt;

&lt;h2 id=&quot;why-fast-flow-architecture-is-essential-for-genai-based-software-delivery&quot;&gt;Why fast flow architecture is essential for GenAI-based software delivery&lt;/h2&gt;

&lt;p&gt;The quality attributes that enable fast flow by humans also support GenAI-based software delivery.
Moreover, there are characteristics of GenAI-based development that actually require these quality attributes even more strongly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-fast-flow/genai-fast-flow-architecture.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s explore each one in turn.&lt;/p&gt;

&lt;h3 id=&quot;modifiability-reduces-the-scope-of-changes&quot;&gt;Modifiability reduces the scope of changes&lt;/h3&gt;

&lt;p&gt;Modifiability makes it easier for GenAI coding agents to make changes to the application.
Because changes are localized, the coding agent can focus on a small part of the application.
What’s more, cohesion means that once the code for the change has been located, there is less extraneous code to consider.
There’s less code that needs to go in the context window and fewer tokens to process.&lt;/p&gt;

&lt;p&gt;Conversely, without modifiability, GenAI coding agents struggle to localize changes and are forced to reason about large, tightly coupled parts of the system.
As a result, the agent’s context window fills with unrelated code, increasing token usage, reducing accuracy, and raising the likelihood of unintended side effects.
Instead of accelerating delivery, agents amplify architectural coupling and increase the risk of widespread regressions.&lt;/p&gt;

&lt;h3 id=&quot;evolvability-reduces-the-impact-of-changes&quot;&gt;Evolvability reduces the impact of changes&lt;/h3&gt;

&lt;p&gt;Evolvability makes it easier for GenAI coding agents to upgrade the application’s technology stack.
The impact of a change is localized to a small part of the application - i.e., a single component/service - there’s less work for the agent to do.
Once again, there’s less code that needs to go in the context window and fewer tokens to process.&lt;/p&gt;

&lt;p&gt;In an architecture that lacks evolvability, even small technology upgrades have a system-wide impact.
When GenAI coding agents attempt such changes, the blast radius quickly expands beyond a single component, requiring broad coordination and extensive validation.
This negates the benefits of automation and often forces changes to be batched, slowing delivery and increasing risk.&lt;/p&gt;

&lt;h3 id=&quot;testability-provides-fast-feedback-and-guardrails&quot;&gt;Testability provides fast feedback and guardrails&lt;/h3&gt;

&lt;p&gt;Testability is critically important for GenAI-based software delivery.
There are two reasons why: guardrails and fast feedback.&lt;/p&gt;

&lt;h4 id=&quot;testability-enables-automated-testing-the-guardrails-for-coding-agents&quot;&gt;Testability enables automated testing: the guardrails for coding agents.&lt;/h4&gt;

&lt;p&gt;Testability enables GenAI coding agents to use TDD.
The tests provide essential guardrails for coding agents.
They constrain agent behavior by defining what correctness means, forcing agents to make progress through verifiable steps rather than speculative code generation.
The &lt;a href=&quot;https://premium.microservices.io/microservices-rules-2-implement-fast-automated-deployment-pipelines/&quot;&gt;deployment pipeline&lt;/a&gt; further constrains agent behavior by enforcing quality gates that must be satisfied before a change can be deployed to production.&lt;/p&gt;

&lt;p&gt;Without strong testability, GenAI coding agents lack fast, reliable feedback on whether a change is correct.
Errors propagate further through the delivery pipeline before being detected, if they are detected at all.
In this situation, agents can generate changes faster than the organization can verify them, turning CI into a bottleneck and production into the first meaningful feedback loop.&lt;/p&gt;

&lt;p&gt;Not only does testability enable automated tests as guardrails, but it also provides coding agents with fast feedback.&lt;/p&gt;

&lt;h4 id=&quot;testability-provides-fast-feedback-in-the-inner-and-outer-development-loops&quot;&gt;Testability provides fast feedback in the inner and outer development loops&lt;/h4&gt;

&lt;p&gt;Testability enables the tests written using TDD to execute quickly.
It provides fast feedback in the inner development loop when the coding agent is implementing a change.
It also reduces the number of tests that need to be run to verify a change, which, like modifiability, reduces the amount of code and test results that need to go in the context window and the number of tokens to process.&lt;/p&gt;

&lt;p&gt;Testability also accelerates the outer development loop, which means the coding agent can get feedback faster from production.
What’s more, testability means that the deployment pipeline can handle the volume of changes being made by multiple coding agents.
Without testability, the deployment pipeline becomes a bottleneck.
Either feedback is delayed, or changes are batched, which complicates troubleshooting test failures and production outages.&lt;/p&gt;

&lt;h3 id=&quot;deployability-provides-fast-feedback-and-safe-deployments&quot;&gt;Deployability provides fast feedback and safe deployments&lt;/h3&gt;

&lt;p&gt;Deployability is critically important for GenAI-based software delivery because it provides fast feedback in the outer development loop.
It also ensures that deployments are safe.
If the agent makes a mistake that’s not caught by a code review, deployability ensures that the deployment can be automatically rolled back when there’s a problem.
Deployability acts as a guardrail that prevents coding agents from causing production outages.&lt;/p&gt;

&lt;p&gt;In architectures with low deployability, deployments are slow, risky, or require manual coordination.
When GenAI coding agents increase the rate of change, these constraints force changes to be queued or bundled together.
This delays feedback, complicates rollback, and increases the likelihood that a single agent-generated error results in a production incident.&lt;/p&gt;

&lt;h3 id=&quot;observability-provides-fast-feedback-and-understanding-of-behavior&quot;&gt;Observability provides fast feedback and understanding of behavior&lt;/h3&gt;

&lt;p&gt;Observability is essential for GenAI-based software delivery because it provides fast feedback in the outer development loop.
It ensures that deployments are safe by providing the telemetry that determines whether a deployment is successful or not, and whether a rollback is needed.
It’s yet another guardrail that prevents coding agents from causing production outages.
Observability also provides the coding agent with an understanding of how the code is behaving in production and quickly identifies issues that need to be addressed.&lt;/p&gt;

&lt;p&gt;Without effective observability, the impact of agent-generated changes in production is difficult to assess.
Failures take longer to detect, root causes are harder to identify, and corrective actions are delayed.
In such environments, GenAI coding agents can inadvertently repeat or compound mistakes because the system provides no clear signal about what is actually happening in production.&lt;/p&gt;

&lt;h3 id=&quot;fast-flow-architecture-as-the-foundation-for-genai-based-software-delivery&quot;&gt;Fast flow architecture as the foundation for GenAI-based software delivery&lt;/h3&gt;

&lt;p&gt;Taken together, these architectural characteristics are how a fast-flow architecture supports GenAI-based software delivery.
Architectural boundaries and loose coupling constrain the scope and impact of agent-generated changes, while fast, automated feedback loops provide control and correction.
In such environments, GenAI coding agents can increase the rate of change without overwhelming teams, pipelines, or production systems.
By contrast, introducing GenAI agents into a slow-flow architecture - one that lacks these qualities - increases change velocity without increasing the system’s ability to absorb it.
Feedback is delayed, changes are batched, blast radii expand, and risk accumulates faster than it can be managed.
This contrast sets the context for understanding the role that architectural structure plays in enabling GenAI-based software delivery at scale.&lt;/p&gt;

&lt;h2 id=&quot;why-the-microservice-architecture-matters-for-genai-based-software-delivery&quot;&gt;Why the microservice architecture matters for GenAI-based software delivery&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;/patterns/monolithic.html&quot;&gt;monolithic architecture&lt;/a&gt; supports fast flow for small applications developed by a small organization consisting of a few teams.
However, fast flow at scale - a large application developed by large organizations consisting of many teams - often requires the &lt;a href=&quot;/patterns/microservices.html&quot;&gt;microservice architecture&lt;/a&gt;.
There are two reasons why:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Greater team autonomy - teams can work autonomously on different parts of the system simultaneously without stepping on each other’s toes&lt;/li&gt;
  &lt;li&gt;High-capacity deployment pipelines - by using per-service deployment pipelines, the architecture can handle the volume of changes being made by multiple teams
It avoids a key limitation of a monolithic architecture, which has a single deployment pipeline that is likely to become a bottleneck as the organization and application scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s now look at how GenAI-based software delivery amplifies the need for the microservice architecture.&lt;/p&gt;

&lt;h2 id=&quot;how-genai-based-coding-agents-scale-software-development&quot;&gt;How GenAI-based coding agents scale software development&lt;/h2&gt;

&lt;p&gt;GenAI-based coding agents effectively scale software development.
The rate of change is significantly higher than if humans were doing the work.
A single developer might even use multiple coding agents to help them with their work.
As a result, GenAI-based software delivery creates some of the scaling challenges that the microservice architecture is intended to address.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/posts/genai/genai-fast-flow/genai-microservices.png&quot; class=&quot;img-responsive&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s look at how the microservice architecture supports GenAI-based software delivery.&lt;/p&gt;

&lt;h3 id=&quot;service-boundaries-act-as-guardrails-for-coding-agents&quot;&gt;Service boundaries act as guardrails for coding agents&lt;/h3&gt;

&lt;p&gt;For GenAI-based software delivery, the microservice architecture provides an important guardrail.
By constraining a coding agent to work within a single service, it enforces clear ownership boundaries and limits the scope of change by default.
This aligns service boundaries with Conway’s Law and prevents agents from making system-wide changes that ignore ownership boundaries and/or require cross-team coordination.&lt;/p&gt;

&lt;p&gt;Of course, an agent can still make changes that affect other services - for example, by changing an API contract or adding collaborators.
But such changes are explicit and therefore visible, reviewable, and governable.
As a result, architectural boundaries replace informal social cues as the primary mechanism for governing agent behavior at scale.&lt;/p&gt;

&lt;h3 id=&quot;small-codebases-reduce-agent-working-set-size&quot;&gt;Small codebases reduce agent working set size&lt;/h3&gt;

&lt;p&gt;The microservice architecture breaks down a large application into a set of smaller, loosely design-time coupled, independently deployable services.
As a result, the coding agent can focus on a single service when making a change.
Since a service has a small code base, it’s easier for a GenAI coding agent to work with.
There’s simply less code to comprehend, less code to go in the context window, and fewer tokens to process.&lt;/p&gt;

&lt;h3 id=&quot;faster-feedback-from-local-test-execution&quot;&gt;Faster feedback from local test execution&lt;/h3&gt;

&lt;p&gt;The small code base of a microservice also means that the service’s tests execute quickly.
This provides fast feedback in the inner development loop when the coding agent is implementing a change.&lt;/p&gt;

&lt;h3 id=&quot;faster-feedback-from-independent-deployments&quot;&gt;Faster feedback from independent deployments&lt;/h3&gt;

&lt;p&gt;Since each service has its own deployment pipeline, the deployment pipeline has less work to do due to the smaller code base.
It’s also handling a smaller volume of changes - most likely from one small team and their coding agents.
As a result, deployments are fast and provide fast feedback in the outer development loop.
Other teams and their coding agents can independently deploy their services without affecting each other.&lt;/p&gt;

&lt;p&gt;Taken together, service boundaries, automated tests, deployment pipelines, and observability form a control system for GenAI-based software delivery.
They continuously sense the effects of changes, compare observed behavior to intended outcomes, and apply corrective action by rejecting, rolling back, or guiding subsequent changes.
Without these fast, automated feedback loops, coding agents can amplify errors faster than the organization can detect and correct them.&lt;/p&gt;

&lt;h2 id=&quot;fast-flow-architecture-microservices-and-the-genai-coding-agent-experience&quot;&gt;Fast flow architecture, microservices, and the GenAI coding agent experience&lt;/h2&gt;

&lt;p&gt;A microservice architecture with these characteristics - modifiability, evolvability, testability, deployability, and observability - provides the foundation for GenAI-based software delivery at scale.
The architecture constrains the scope and impact of agent-generated changes while providing fast, automated feedback that enables correction at speed.
By offering clear service boundaries, independent deployment pipelines, and localized feedback loops, it allows GenAI coding agents to operate in parallel without overwhelming teams, delivery pipelines, or production systems.&lt;/p&gt;

&lt;p&gt;Just as fast-flow architecture improves &lt;a href=&quot;https://premium.microservices.io/microservices-rules-4-provide-a-great-developer-experience/&quot;&gt;developer experience&lt;/a&gt; by reducing cognitive load and accelerating feedback, it also defines the &lt;strong&gt;GenAI coding agent experience&lt;/strong&gt;.
Small codebases, explicit boundaries, fast tests, and reliable deployments determine how effectively agents can reason about changes, validate correctness, and make progress.
In contrast, introducing GenAI coding agents into a slow-flow architecture degrades both developer experience and agent experience, increasing friction, batching, and risk rather than sustainable throughput.&lt;/p&gt;

&lt;h2 id=&quot;are-you-ready-for-genai-based-software-delivery&quot;&gt;Are you ready for GenAI-based software delivery?&lt;/h2&gt;

&lt;p&gt;A key question every engineering leader should be asking themselves is: “Is our socio-technical architecture ready for GenAI-based software delivery?”
Answering this question requires more than evaluating individual tools or experimenting with coding agents.
It means examining whether the organization’s team structure, architectural boundaries, and delivery mechanisms can safely absorb a much higher rate of change.
If the answer is “no”, then the challenge is not adopting GenAI, but transforming the socio-technical architecture so that it supports fast flow through clear boundaries, fast feedback, and effective guardrails.
Only then can GenAI-based software delivery be used to accelerate outcomes rather than amplify existing bottlenecks and risks.&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;
</description>
            <pubDate>Sun, 08 Feb 2026 08:03:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/02/08/architecting-for-genai-based-software-delivery.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/02/08/architecting-for-genai-based-software-delivery.html</guid>
        </item>
        
        <item>
            <title>QCONSF Microservices Platforms part 3: Security platform</title>
            <description>&lt;p&gt;This is the third in a series of articles based on my &lt;a href=&quot;/post/architecture/2025/11/23/qconsf-2025-microservices-platforms.html&quot;&gt;QCon San Francisco 2025 talk &lt;em&gt;Microservices Platforms: When Team Topologies Meets Microservices Patterns&lt;/em&gt;&lt;/a&gt;.
The articles in the series are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-when-team-topologies-meets-microservices-patterns-part-1/&quot;&gt;Microservices Platforms - part 1: Overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-2-service-foundation-platform/&quot;&gt;Microservices Platforms - part 2: Service foundation platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-3-security-platform/&quot;&gt;Microservices Platforms - part 3: Security platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-4-infrastructure-services-platform/&quot;&gt;Microservices Platforms - part 4: Infrastructure services platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-5-observability-platform/&quot;&gt;Microservices Platforms - part 5: Observability platform&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-6-build-platform/&quot;&gt;Microservices Platforms - part 6: Build platform&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article discusses the &lt;strong&gt;Security platform&lt;/strong&gt;, which simplifies the development of secure microservices.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/i/qconsf-2025-microservices-platforms-part-3/Microservices_Platforms_Security_Platform.png&quot; alt=&quot;Slide 27&quot; style=&quot;float: left; width: 100%; margin-right: 1.5em; margin-bottom: 1em;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://premium.microservices.io/microservices-platforms-part-3-security-platform/&quot;&gt;Read more (This post is for paying subscribers only)&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;need-help-with-modernizing-your-architecture&quot;&gt;Need help with modernizing your architecture?&lt;/h2&gt;

&lt;p&gt;I help organizations modernize safely and avoid creating a modern legacy system — a new architecture with the same old problems. If you’re planning or struggling with a modernization effort, I can help.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://chrisrichardson.net&quot;&gt;Learn more about my modernization and architecture advisory work →&lt;/a&gt;&lt;/p&gt;

</description>
            <pubDate>Fri, 30 Jan 2026 08:01:00 +0000</pubDate>
            <link>http://microservices.io//post/architecture/2026/01/30/qconsf-microservices-platforms-part-3.html</link>
            <guid isPermaLink="true">http://microservices.io//post/architecture/2026/01/30/qconsf-microservices-platforms-part-3.html</guid>
        </item>
        
    </channel>
</rss>
