AI Agent Action Catalog: Find Access You Do Not Need
Build an AI agent action catalog that exposes excess permissions by recording each operation, impact, owner, identity, and approval decision.

An AI agent action catalog is the fastest way to find permissions nobody consciously chose. It lists the operations an agent can perform outside its own workspace, then forces a decision about each one: who owns it, what happens if it goes wrong, and whether a human must approve it.
Most teams start in the wrong place. They inventory API keys, integrations, or software accounts, then conclude they understand access. They do not. A credential is a container. The security decision lives at the operation level: “create a draft invoice” differs sharply from “issue a refund,” even when both calls use the same token.
I have watched permission reviews fail because a team asked, “Does the agent need access to the billing system?” That question is too broad to answer honestly. Ask whether it needs to read a single invoice, create a draft, submit a refund, update payout details, or export the customer list. The answers are usually different. The unnecessary access appears in those differences.
An integration list hides the permissions that matter
A system inventory tells you where an agent connects. An action catalog tells you what it can cause. Keep both, but do not mistake one for the other.
Consider an agent connected to a source control service. “Repository access” may include reading code, opening a pull request, changing branch protection, creating a deployment key, publishing a release, or deleting a repository. Treating that collection as one permission turns a set of separate risk decisions into a lazy yes or no.
The same mistake appears with SSH. “The agent can SSH to staging” says nearly nothing. A constrained command that fetches service status has a different consequence from shell access under an account that can restart services, read deployment secrets, or alter firewall rules. Catalog the command family or endpoint, not the transport alone.
The distinction matters because exposure has two dimensions that teams regularly blend together:
- Reachability is whether the agent can contact a system.
- Authority is what the system will allow after contact.
- Consequence is what can happen if the agent makes a mistaken or manipulated request.
An internal endpoint can have low reachability and very high authority. A public API can have broad reachability but limited authority. Approval design based only on whether a service is “internal” will miss both cases.
NIST Special Publication 800-53, control AC-6, describes least privilege as granting only the access needed to accomplish assigned tasks. That language sounds obvious until you apply it to an agent. “Assigned task” cannot mean “help with engineering.” It needs to mean an operation with a target, method, boundary, and expected result. If you cannot write that down, you cannot claim least privilege.
Start with action names that a reviewer can understand without opening a code repository. “POST /v1/issues” is useful evidence, but “create issue in the engineering tracker” tells the owner what they are approving. Keep both in the record.
Build one row for one externally visible operation
Each catalog row should represent the narrowest action that can receive a distinct access or approval decision. If two operations could sensibly have different owners, impacts, or approval requirements, they need separate rows.
A practical row has enough detail for an engineer to implement control and enough plain language for the system owner to reject it. Use the following fields:
| Field | What to record | Why it exists |
|---|---|---|
| Action ID | Stable identifier, such as deploy.production.restart-service | Preserves a decision when names change |
| System | Destination system and environment | Separates production from test access |
| Operation | Human-readable verb and object | Makes the permission reviewable |
| Technical route | API method and path, command pattern, or tool call | Lets engineers enforce the boundary |
| Identity | Credential type, account, scopes, and delegation model | Reveals shared or oversized authority |
| Data handled | Inputs sent and outputs returned | Exposes data leakage risk |
| Impact | Consequence category and reversibility | Drives the approval choice |
| Owner | Named business or technical decision maker | Gives access a person accountable for it |
| Approval | None, per session, or per call | Defines the human control point |
| Evidence | Test, log reference, or implementation location | Proves the row matches reality |
| Review date | Date and reviewer | Stops old exceptions from becoming permanent |
Do not put “various,” “admin tasks,” “full API,” or “as needed” in an operation field. Those phrases mean the catalog has stopped before the work started. Split the entry until a person can say yes or no without guessing.
Here is a compact example for a development agent:
action_id: issue-tracker.create-bug
system: issue tracker, production tenant
operation: Create a bug report in the Engineering project
technical_route: POST /api/projects/engineering/issues
identity: service account agent-issues, scope issues:write
inputs: title, body, labels, repository reference
outputs: issue ID and URL
impact: internal write, reversible by project members
owner: Engineering operations manager
approval: per-session
review_date: 2026-09-30
The phrase “production tenant” belongs in this row even if the action only creates tickets. Many teams use a single production SaaS tenant for real customer, employee, and incident information. The environment label tells reviewers which boundary they are crossing.
Avoid a false precision problem. You do not need a separate row for every harmless field update when the destination, owner, identity, approval, and consequence are truly identical. You do need separate rows when a special field changes the outcome. “Update incident status” and “change incident commander” may travel through one endpoint, yet they should not receive the same approval decision.
Discover actions by following credentials and workflows
You will not find the whole action set by reading an agent prompt. Prompts describe intent; code, configuration, credentials, and observed traffic show what the agent can actually request.
Begin with the workflows people expect the agent to perform. Ask engineers to describe the last ten tasks they gave it or want to give it, using verbs. “Investigate a failed build” may expand into reading logs, querying a deployment service, opening an issue, restarting a test environment, and posting a message. Record every external boundary crossed.
Then work backward from each credential. Inspect API scopes, OAuth grants, service-account roles, SSH authorized keys, command wrappers, CI variables, and local secret stores. A credential often reveals operations nobody named in the workflow discussion. An API token with user administration scope is an action candidate even if the team insists the agent only files tickets.
Finally, compare intent with evidence. Network traces, API gateway logs, command audit records, and agent tool definitions reveal calls the workflow document missed. Do this in a safe test environment first when you can. Production logs still matter because agents and humans tend to discover shortcuts under time pressure.
Use this five-pass collection routine:
- List every agent workflow that reaches outside the local task.
- Extract each tool call, endpoint, and shell command pattern from agent configuration and code.
- Enumerate what each credential permits, including inherited roles and wildcard scopes.
- Review recent action logs for destinations or verbs absent from the list.
- Reconcile the differences with the person who owns the destination system.
The fourth pass is where uncomfortable findings appear. You may find an old token with broad repository administration, a staging SSH key accepted by production hosts, or an “internal” webhook that can trigger a release. Do not quietly reduce the entry to fit the original plan. Put the effective operation in the catalog and make someone decide whether it stays.
A useful test is to give a row to a colleague who did not build the integration. They should be able to explain what the agent sends, what it gets back, and the worst plausible mistake. If they cannot, the row is technical debris, not a control record.
Impact needs consequences, not a generic risk score
Classify impact by what a wrong action changes, exposes, spends, or commits. A single “high, medium, low” rating fails because it suppresses the reason an action needs human attention.
I use five consequence categories in the catalog: disclosure, integrity, availability, external commitment, and privilege change. A row can carry more than one. Reading a customer export creates a disclosure consequence. Deleting a deployment changes availability. Adding an administrator changes privilege. Sending a contract creates an external commitment even if the action is technically reversible.
Add two modifiers: reversibility and blast radius. Reversibility asks whether a competent person can undo the action without loss or confusion. Blast radius asks whether an error affects one draft, one project, many users, or an entire environment.
This produces decisions people can defend. “Delete temporary test branch” may be an integrity change that is reversible and limited. “Rotate production database credentials” may preserve security but also affect availability across many services. Both are write actions. They belong in different approval categories.
Do not let “the API supports undo” settle reversibility. A refund can be reversed in a ledger while the customer has already received a confusing email. A published package can be withdrawn while downstream systems have fetched it. A deleted account can be restored while its former owner loses access during an incident. Consider the operational consequence, not only the database operation.
Data returned by an action deserves the same attention as data sent. A harmless status query that returns full environment variables, support transcripts, or private keys is a disclosure action. Teams often overfocus on an agent's ability to write because writing feels active. An agent that can read every secret and then call an external endpoint has enough access to cause a serious incident.
Keep impact language concrete. Replace “high impact” with “can change production authorization for all workspace members” or “can transmit customer identifiers to a third-party API.” The first description tells the owner what to decide. The label alone does not.
Ownership must sit with the person who can say no
Every action needs one named owner who can deny it, reduce it, or remove it. That person owns the permission decision, not every operational result produced by the agent.
The best owner usually belongs to the destination system or bears the business consequence. An engineering lead may own production deployment actions. Finance owns refund submission. The security team may define conditions for access administration, but it should not become the default owner of every line because it is the security team.
Shared ownership is where catalogs rot. “Security and engineering” means each group assumes the other will review it. Record one accountable owner and list consulted teams in notes if you need them. If an owner changes jobs or teams, transfer the catalog rows as part of that handover.
Owners need a decision packet that fits in one screen. Give them the operation, system, effective identity, data involved, consequence, proposed approval, and a short reason the agent needs it. Do not hand them a raw OAuth scope list and call that governance.
The owner should answer four questions:
- Does the agent need this outcome, or does the workflow merely find it convenient?
- Can a narrower endpoint, role, account, target, or command provide the outcome?
- What mistake would create an unacceptable consequence?
- Who should approve use, and when should this decision expire?
The awkward question is usually the first one. Teams often grant a broad operation because it removes a future conversation. That is not a requirement. It is a deferred access review with a credential attached.
Make ownership visible in the execution path. If nobody can identify the owner during an incident, the catalog did not do its job. A named owner also makes periodic review workable, because the review asks a direct question: “Do you still authorize action X for this agent and this identity?”
Approval should match the moment of commitment
Approval is useful when it appears before the point where an agent causes a consequence and when the reviewer can understand what they are allowing. A button that says “allow tool use” after the agent has bundled ten unrelated operations is security theater.
Use three approval states in the catalog. “None” means the action can proceed after the agent has gained its session authority. “Per session” means a human approves a specific agent process before it can call any authorized actions. “Per call” means a human reviews each use of that action.
Per-session approval fits narrow, routine actions with modest consequences, such as reading build status or creating internal draft issues. It establishes that the intended agent process is active, then lets it complete ordinary work without asking a person to click through repetitive prompts.
Per-call approval fits actions that create a commitment or cross a difficult boundary. Use it for changing production access, deleting material records, triggering deployments that affect customers, sending messages outside the company, handling money, and exporting sensitive datasets. Requiring a human to inspect each request is appropriate friction here.
The approval record needs context. At minimum, display the calling process identity, operation, destination, target environment, and material parameters. “Agent requests POST” forces a reviewer to reconstruct the action under pressure. “Restart payments service in production, requested by signed process X” gives them a decision they can make.
Do not use approval prompts to compensate for a permission that should not exist. A per-call prompt for “execute arbitrary shell command on production” still leaves the reviewer approving a blank check repeatedly. Replace the broad shell capability with constrained commands or separate operations, then approve those where necessary.
The action gateway matters here because it can keep credentials away from the agent while placing the human decision near execution. Sallyport uses a fixed decision ladder: a locked vault denies every action, a new agent process gets per-session authorization by default, and selected keys can require approval on every use.
That structure avoids a common mistake: inventing a sprawling rule language before anyone has cataloged actions well enough to write safe rules. Complex policies look mature in a design document and become unreviewable once exceptions arrive. Start with clear operations, narrow identities, and approval that maps to impact.
A catalog exposes the failure path before production does
A catalog earns its keep when it catches a chain of ordinary choices that looks acceptable in isolation. Consider a coding agent asked to investigate why an order workflow failed.
An engineer gives it a service token because the token can read logs. The same token also has permission to query the order API. The agent finds a malformed order and is told to “clean up test data.” It calls a delete endpoint against the production tenant because the integration did not distinguish tenant names clearly. The endpoint accepts the request. A human later sees that the order was real, but restoring it requires reconciliation across payment, inventory, and customer support systems.
Each individual statement sounded harmless: read logs, query orders, remove test data. The action catalog would have broken the chain into rows:
| Operation | Hidden issue | Better decision |
|---|---|---|
| Read order workflow logs | Logs contain customer identifiers | Restrict returned fields and record disclosure impact |
| Query order by ID | Token has broad order access | Use a read-only identity scoped to the required tenant |
| Delete test order | Production and test share one endpoint family | Separate target environments and require per-call approval |
| Correct customer order | This is not cleanup | Assign ownership to operations staff and remove from agent scope |
The useful finding is not “agents make mistakes.” Humans make this same chain of mistakes when access boundaries are vague. Agents execute faster, retry more readily, and may follow an instruction that sounds locally reasonable without noticing the business context a human would infer.
Write failure paths in the notes for high-consequence rows. Use a plain format: trigger, wrong target or interpretation, action taken, immediate effect, recovery burden. This makes approval choices less abstract and gives reviewers a reason to reject broad access.
A catalog also catches dangerous combinations. Reading incident notes may be acceptable. Posting to a public status page may be acceptable with review. Allowing one agent to do both without a content boundary can expose internal incident details. Review combinations where one action supplies sensitive input and another action sends data outside the organization.
Make the catalog enforceable, then prove it matches reality
A catalog that lives only in a spreadsheet becomes a permission wish list. Connect each approved row to a technical boundary: a separate credential, a restricted API scope, a destination allowlist, a constrained SSH command, or an approval configuration.
Use action IDs in configuration and logs. That gives you a simple test: every observed external action should map to a catalog ID, and every active catalog ID should map to a current enforcement point. Investigate both mismatches. An observed action with no row is shadow access. A row with no enforcement may be a stale plan or an uncontrolled path.
For HTTP calls, verify the method, host, path pattern, target environment, and credential scope. For SSH, verify account, host group, command restrictions, and whether the helper can pass arbitrary arguments. “SSH access is approved” is not an enforceable statement.
For example, this catalog entry claims the agent can only retrieve a deployment status:
Action ID: deploy.status.read
Host: deploy.internal.example
Command: deployment-status --service <approved-service>
Identity: agent-deploy-read
Approval: per-session
This implementation defeats that claim:
command="/usr/local/bin/deployment-status $SSH_ORIGINAL_COMMAND" ssh-ed25519 AAAA... agent
The wrapper passes an arbitrary original command as an argument. If deployment-status invokes a shell or accepts an unchecked option, the catalog boundary is fiction. A safer design maps an approved service name to a fixed command and rejects every other input. Test the rejection path deliberately.
case "$1" in
checkout) exec /usr/local/bin/deployment-status --service checkout ;;
search) exec /usr/local/bin/deployment-status --service search ;;
*) echo "service not permitted" >&2; exit 1 ;;
esac
Do not copy that snippet blindly into an authorized-keys setup. It illustrates the property you need: the agent selects from defined actions, not from an arbitrary command language. Your environment still needs input validation, account restrictions, and testing by someone who understands the command's behavior.
For action evidence, record a test that proves both sides of the boundary. A positive test proves the approved call works. A negative test proves a nearby forbidden call fails. Teams often keep only the positive test, which is why broad credentials quietly survive.
Sallyport records agent sessions and individual calls from one encrypted, hash-chained audit log. Its sp audit verify command can verify that chain offline over ciphertext without access to the vault key. That evidence helps reconcile a catalog with actual behavior, but it does not replace the decision to remove an unnecessary action.
Review access when the work changes, not after a quarterly surprise
Review the catalog when you add a tool, alter an agent workflow, issue or rotate a credential, change a system owner, or discover a near miss. Those events change effective access. Waiting for a calendar review lets old assumptions persist while integrations accumulate.
Set a review date on every row anyway. High-consequence operations deserve a shorter interval than harmless internal reads. A review should not ask whether the spreadsheet still exists. It should ask whether the agent still needs this exact operation, whether the identity remains narrow, whether the owner is still correct, and whether observed use supports keeping it.
Remove unused actions aggressively. Teams resist removal because they fear an agent will need the permission later. If that happens, add it back through the same owner and approval decision. Re-granting a known operation takes less effort than cleaning up an action that should never have survived.
The first useful catalog does not need perfect coverage. Pick one agent, list every external operation it can perform today, and force an owner to decide on each row. You will find access that exists because nobody had previously needed to name it. That is the access worth removing before it gets used at the worst possible time.
FAQ
What is an AI agent action catalog?
An action catalog is an inventory of every external operation an agent may request or trigger. Each entry names the destination, exact action, credential or identity used, impact, business owner, and the approval required. It differs from an application inventory because it tracks what the agent can do, not merely which software exists.
When should a team create an action catalog for an AI agent?
Start before the agent can act autonomously. A catalog built after broad access is already connected tends to document excuses rather than make decisions. If an agent already has access, put new actions behind approval while you inventory them.
Is read-only agent access always low risk?
Treat read access as potentially sensitive if it can expose source code, customer data, credentials, security findings, or business plans. Read-only access can also support reconnaissance before a damaging write action. Classify the data returned, not only whether the request changes a record.
Which agent actions should require approval every time?
Use per-call approval for irreversible, externally visible, high-cost, or security-sensitive actions. Examples include deleting production data, publishing a release, changing access controls, sending bulk messages, and moving money. Approval should cover a clear action summary, destination, and relevant parameters.
Who should own an action in an agent access inventory?
A named owner must understand the system's business purpose and accept responsibility for granting or removing the action. The owner does not need to run the integration daily, but they must be able to decide whether the agent should retain access. “The platform team” is not an owner unless a specific person can make that decision.
How do I catalog actions that use shared service accounts?
Inventory the effective identity, not the friendly account label. Record whether the action uses a service account, OAuth grant, API token, SSH key, or delegated user session, plus the scopes and target environment. Shared credentials make accountability weaker, so split them when the action set differs.
Can I use a spreadsheet for an agent permission inventory?
A spreadsheet is enough at first if every action has one row, a stable identifier, an owner, a review date, and a decision. The failure is not using a spreadsheet. The failure is maintaining a system list that never reaches the people who approve access.
How should I score the impact of an AI agent action?
Do not label every write action as high impact. Separate reversible internal updates, such as creating a draft ticket, from irreversible or external actions, such as publishing, deleting, or granting access. The catalog should describe the consequence if the action is wrong, not reward vague severity labels.
Why are audit logs not enough for AI agent access control?
Logs tell you what happened after a credential or permission already existed. An action catalog asks whether the action should exist at all, who accepted it, and what approval applies before it happens. You need both, because a complete log does not shrink excessive access.
How often should an AI agent action catalog be reviewed?
Review the catalog when an agent gains a new integration, when a credential changes, when a system owner changes, and after an incident or near miss. Also set a regular review date for every entry, with shorter intervals for powerful actions. An unreviewed catalog becomes an archive of permissions nobody would grant today.