Adding governance to an AI agent, things like change management, approval records, and audit trails, doesn’t have to mean rebuilding it. If an agent’s tools are explicitly scoped at build time and wrapped in decorators that correct for vendor API quirks, adding a governed step is a matter of a sentence or two of instruction, not new integration work. This walks through exactly what has to be true first for that to hold.
On a recent Itential webinar, I built a FlowAgent from a blank project using tools we already had, then added a full change management process to it with two sentences of prompt guidance. No rebuild. What follows is what actually happened, tool by tool, so you can see exactly where the reasoning stopped and the execution started.
Inside the Itential Platform‘s agent projects section, we created a new project for application infrastructure provisioning. A project is a container for FlowAgents. Most teams organize projects around a use case, sometimes with several FlowAgents inside one project handling related actions. Itential’s own F5 project, for example, splits creation, modification, and deletion of load balancer VIPs into separate FlowAgents rather than one FlowAgent trying to do all three.
For this build, one FlowAgent was enough. And by default, a project a builder creates is private to them; nobody else on the team sees it until the builder chooses to share it, the same instinct as not pushing code to a shared branch until it’s ready.
A FlowAgent needs the same two things you would hand a colleague if you delegated the task: instructions and tools.
Instructions came first, as a prompt, written in Markdown, covering the inputs the FlowAgent needs (app name, region, template, requester), the naming standard to enforce, the network allocation to request from Infoblox, and the exact steps to follow: confirm the region is supported, get human approval before creating anything, allocate the subnet, create the VPC, launch the instance, confirm deployment, report back.
You provision a new AWS VPC and an EC2 instance inside it, pre-allocating the VPC's subnet from Infoblox first.
## Inputs
- {{ app_name }} — the requested app_name name
- {{ region }} — the target AWS region
- {{ template }} — the requested EC2 instance size/template
- {{ requestor }} — who is asking
## Policy
Name pattern for both VPC and instance: {{ app_name }}
Fixed facts:
- Infoblox network container: the lab's test container `10.99.0.0/16`.
- Allocate a `/28` for the VPC.
- Never reuse a block already assigned to another VPC in the container — always take the next available one from Infoblox, never hand-pick a CIDR.
## Steps
1. **Validate.** Confirm that {{ region }} is supported, {{ template }} is non-empty. Note any corrections.
2. **Approval #1.** Present the request (VPC name, instance name, region, template) and your validation result (pass/fail + corrections). Ask for approval to proceed. On rejection: stop, report rejected.
2a. **Create a ServiceNow Change request** Create CR record and add all the parameters for the request and approver information.
3. **Allocate a subnet.** Ask Infoblox for the next available `/28` under the fixed container above. Record the returned CIDR exactly as given — never recompute or guess it by hand.
4. **Create the VPC.** Provision a new VPC named {{ app_name }} in {{ region }}, using the shared prefix and the CIDR block just allocated. Capture whatever identifiers come back (VPC ID, subnet ID, etc.).
5. **Launch the EC2 instance.** Provision the instance named {{ app_name }} in {{ region }}, using the shared prefix, the requested template, and placing it in the VPC just created. Capture the returned instance ID and any IP address.
6. **Confirm deployment.** Look the instance back up to verify it's actually running inside the new VPC before declaring success. If it isn't visible yet, state that plainly rather than assuming success.
6a. **Update ServiceNow Change request** Update CR record with all provisioning results and assets.
7. **Final report.** One HTML message, Itential-branded (light background, navy text, bright-blue CTAs, pink used sparingly for exceptions, inline-styled tables, Arial fonts). Cover: the request, validation result, subnet allocation, VPC details, instance details, confirmation check result, approval log, and overall status.
Tools came next: an existing script already used for VPC and EC2 instance creation, and a native Infoblox API. Both were tools the team already had. Nothing was rebuilt to make this FlowAgent work.
This is the part worth sitting with. The FlowAgent didn’t get new infrastructure access. It got the same APIs and scripts a person would use to do this by hand, wired up through explicit tool association rather than letting the model guess at what’s available.
Every tool a FlowAgent can call gets chosen at build time, by the person building it. Nothing gets added by default.
That’s a deliberate contrast to giving an assistant broad access to dozens of MCP servers and thousands of tools at once and trusting it to pick the right one. In infrastructure and networking, where teams are rightly risk-averse, that approach raises an obvious question: what stops it from deciding, mid-task, that it needs to do something nobody scoped it to do?
The build for this FlowAgent only included what the task required: view data for human-in-the-loop steps, the Infoblox network-assignment tool, and the specific EC2 calls needed to list and create instances. Notably, it did not include an EC2 delete call. If the goal had only been to demonstrate service creation, the destructive tool simply wouldn’t have been on the list.
That distinction matters even after the FlowAgent is shared. Someone else on the team can open the prompt and rewrite the FlowAgent’s intent entirely, asking it to also open tickets or send emails. None of that takes effect unless the FlowAgent also has the tool to do it. Changing the words doesn’t change what it’s authorized to touch. That separation between intent and capability is the same model teams already use for engineers: a tier one engineer might be limited to creating access ports, while shutting down BGP peering is escalated to someone with a different level of access. FlowAgents can be scoped the same way, restricted to read and recommend, without the ability to act.
With instructions and tools in place, the FlowAgent ran end-to-end: allocate an IP through Infoblox, then provision the EC2 instance in AWS. No human wrote the API payload. No human mapped which field went where.
That part surprised even the person who built it: “It formulated the payload by itself, which I always struggle doing in my own script. Every time a vendor changes their API I have to go touch that script again.”
That quote is the whole argument for reasoning over hardcoding in one sentence. A static script breaks the moment a vendor changes their API contract. A FlowAgent reasoning over that same API adapts, because it’s interpreting the tool in context instead of executing a fixed sequence someone wrote six months ago.
Midway through the run, a step failed. The subnet allocation call had been given a value in slash notation (a CIDR-style prefix) when the underlying API actually needed a plain integer for network size, a mismatch the vendor’s own API spec didn’t make explicit. The FlowAgent recognized the failure, corrected the value, and retried the call itself. No human intervened.
That kind of self-correction is exactly what makes teams nervous the first time they see it, and exactly why retry behavior isn’t left open-ended. The builder sets the ceiling: retry a tool call up to a defined number of times, and on the final failure, stop and take a specific fallback action, such as exiting and opening an incident ticket rather than continuing to guess. Self-healing and unbounded improvisation are not the same thing, and the platform is built to keep them separate.
Nobody wrote a Jinja template. Nobody specified HTML formatting or a color scheme for the human-in-the-loop approval screen. The only instruction given was to present the request in a way an approver could act on, and, separately, a note to use Itential-branded colors. From that, the FlowAgent generated a formatted, styled approval view on its own, pulling in the fields that mattered for a decision-maker to see.
That is the same category of work as the payload formatting: data transformation, presentation, and formatting logic that used to require a script, a workflow step, or a Jinja template someone maintained by hand. None of it touches infrastructure. All of it used to be tactical busywork somebody had to build and keep updated every time a new service came online.
Here’s the part that actually matters for anyone deciding whether FlowAgents are safe to run against real infrastructure. With the FlowAgent already working, we added governance to it without touching the original build.
Two new steps went into the existing FlowAgent, live:
Both steps used native ServiceNow tools already available in the platform, the same create-change-request and update-change-request calls documented straight from ServiceNow’s API spec. Because ServiceNow’s generic API needed sharper instructions to behave the way this workflow required, in the same way the Infoblox subnet field needed a decorator earlier, both tools were wrapped in a decorator: a layer that teaches the FlowAgent exactly what a tool expects, correcting for a vendor spec that’s ambiguous or generic, without touching the vendor’s underlying API.
Total prompt guidance required for both steps: two sentences.
As Karan put it, watching it happen: “It only took two sentences and tool association, and it started doing more than what I do today.”
This is the detail that separates a good demo from a production-credible one: nothing changed for whoever requests the FlowAgent’s work. Same inputs. Same request. The only thing that changed sits entirely on the back end, where every run now lands a ServiceNow change record alongside the infrastructure change itself.
Nobody told the FlowAgent what to name that change record either. Left to its own judgment, it produced a self-documenting title and description straight from the job’s context: what was provisioned, for what purpose, in which region. Open the ticket and the provisioning details, validation results, and plan steps are already there, without a human writing a change summary after the fact.
That’s an audit trail that builds itself while the work happens, not one bolted on afterward.
None of this worked because the FlowAgent is unusually clever. It worked because of what was already true before the two sentences were typed:
Change the org tomorrow, swap ServiceNow for Freshworks, and the same pattern holds: swap the API calls the decorator points to, and the FlowAgent keeps running the same way.
It’s tempting to read this as a story about how fast you can build a FlowAgent. That’s not the interesting part. The interesting part is that governance was the easy addition, not the hard one.
Most teams treat compliance and audit as something you architect for up front, before you’re confident the use case is even right, because retrofitting it later feels like it should mean a rebuild. This build is evidence against that assumption. The FlowAgent was proven first, on tools the team already trusted. The change management layer went in after, in two sentences, because the scoping, the decorators, and the guardrails were already doing their job.
That’s the actual argument here: you don’t have to get governance perfect before you prove the use case. Prove the use case on tools you already trust, then make it accountable. If your integrations are wired up cleanly, that second step should never be the hard one.
None of this required exotic tooling, just tools that were already integrated and scoped correctly. If yours aren’t there yet, that’s the gap worth closing first.
▶️ Watch the full build on-demand →
🔌 Connect with me on LinkedIn to talk through what this looks like on your stack.
In this build, adding a ServiceNow change request step and a follow-up update step took two sentences of prompt guidance, using native ServiceNow tools already available in the platform. No rebuild was required.
Explicit tool association is a deliberate governance decision. Every tool a FlowAgent can call is chosen at build time by the person building it, rather than left open to hundreds of MCP tools the model picks from on its own. That keeps a FlowAgent from deciding, mid-task, to do something nobody scoped it to do, and it means rewriting a FlowAgent’s prompt doesn’t expand what it’s authorized to touch.
A decorator is a layer that teaches a FlowAgent exactly what a native vendor API expects, correcting for a spec that’s ambiguous or generic, without modifying the vendor’s underlying API. In this build, a decorator corrected an Infoblox field that needed a plain integer instead of CIDR notation, and separately made ServiceNow’s generic change-request API behave the way the workflow required.
Yes, within limits the builder defines. During this build, a subnet allocation call failed due to a formatting mismatch, and the FlowAgent corrected the value and retried automatically. Builders set a retry ceiling and a defined fallback action, such as exiting and opening an incident ticket, so self-correction never becomes open-ended improvisation.
See how Itential connects AI reasoning to governed execution across your entire infrastructure.