# An agent for apps without APIs

By Derik Callahan · 2026-09-12 · https://derikcallahan.com/writing/an-agent-for-apps-without-apis

> Every identity program has a list of disconnected applications that someone provisions by hand. I built a proof of concept where a model drives the browser instead — with a human approving every write and a hashed screenshot behind every step.

Every identity governance program has the same embarrassing appendix: the disconnected applications. These are systems with no SCIM, no API, and no connector, where provisioning and deprovisioning happen because someone works through a ticket by hand. They're usually the accounts that outlive the employee.

Browser agents looked like a real answer, so I built a proof of concept to see whether one could hold up to audit.

## How it works

A Python orchestrator gives a model (Claude, served through Azure AI Foundry) control of a browser through Playwright. The model sees a screenshot, works out what's on the page, and decides what to click, type, or open next. The task is plain identity work: create the account, assign the role, disable the user.

Three things make it more than a demo:

- **A YAML agent factory.** Each application's workflow is a template, not code. "Deprovision a user in app X" is a short YAML file with inputs and a goal. Adding a new disconnected app means writing a template, not shipping a release.
- **Human approval before any write.** Read steps run freely. Before a write that changes access, the orchestrator posts an adaptive card to Microsoft Teams with what it plans to do and the current screenshot. An approver confirms or denies it, and the task waits until they do.
- **An evidence pipeline.** Every step's screenshot goes to blob storage with its SHA-256 hash, alongside a JSON audit log of every model decision. When an auditor asks "how do you know this user was removed," the answer is a sequence of hashed images showing that it happened.

It runs as a small HTTP service: start a task, check its status, receive the approve or deny callback.

## What I learned

**The model is the easy part.** Modern models are good at reading a screenshot of an admin console. The engineering effort goes into everything around the model: timeouts, retries, knowing when a page has actually finished loading, and refusing to continue when the screen doesn't match what was expected.

**Evidence changes the conversation.** Security and audit teams don't trust "the bot did it." They do trust a tamper-evident record of what the bot saw and did at each step. The screenshots matter more to the business case than the automation does.

**The agent is an identity too.** The browser agent signs into the target app with a real account that has real privileges. That account needs the same treatment as any privileged identity: scoped to the minimum, credentials in a vault, sessions recorded, access reviewed. I wrote more about that in [the agent is an identity](/writing/the-agent-is-an-identity).

**Approval fatigue is the real risk.** If every step needs a click, approvers stop reading. Gating only the writes that change access, and showing a screenshot instead of a JSON blob, is what keeps the human actually reviewing.

This is still a proof of concept, not a product. But it changed my view on disconnected apps. Their real problem was never the missing API. It was the missing evidence.
