Lesson 5: State What the Agent Can Do
Training overview · Lesson 5 of 11 · Previous: Draw a tool that reaches any host · Next: Fix a finding with a fact
Goal
Some facts about an agent cannot be drawn. You state them as attributes on the agent.
After this lesson you know which questions to ask the team that runs an agent, and how their answers decide whether the agent can act on what it reads.
What you start from
Your model from lesson 4, or import L4-solution.zip.
The recipe step
Step 5: State what the agent can do
Answer the element facts the drawing cannot show: what the agent's tools can do and whether they need approval, the harness approval mode, egress restrictions, and who can write to each store. A yes-or-no field offers Yes, No and Not answered; it starts at Not answered, and choosing Not answered takes an answer back.
Why: Whether an agent can act on what it reads, and whether anything stops it, is not visible in a drawing.
Ask:
- Can the agent's tools change anything outside the conversation: send, post, update, delete, pay?
- Does every such action need a person's approval?
- Can the agent run code?
- Is the agent's network egress limited to an allowlist?
- Are the agent's tool credentials limited to the user it acts for?
- Does the chat frontend render images or links in model output?
Looks safe is the answer a guess would pick. Write it only when someone who knows has said so.
| On | Field | Looks safe | What it decides |
|---|---|---|---|
| Agent Service | Consequential Tools Present (consequential_tools_present, under Human Oversight) | false | Whether the agent can act at all; whether it holds tools that act |
| Agent Service | All Consequential Action Paths Require Approval (consequential_tools_all_require_approval, under Human Oversight) | true | Whether its actions wait for a person |
| Agent Service | Approval Gate Present (approval_gate_present, under Human Oversight) | — | Whether its actions wait for a person |
| Agent Chat Frontend | All Consequential Actions Require Blocking In-Chat Approval (consequential_tools_all_require_approval, under Authorization & RBAC) | true | Whether its actions wait for a person |
| Untrusted Content Source | Human Approval for High-Risk Actions (human_approval_for_high_risk_actions, under Authorization & RBAC) | required | Whether its actions wait for a person |
| Agent Code Execution Sandbox | Consequential Computer-Use Actions Confirmed (computer_use_consequential_actions_confirmed, under Computer Use) | true | Whether its actions wait for a person |
| Agent Service | Code Execution Tools Present (code_execution_tools_present, under Application Security) | false | Whether it can run code; whether it holds tools that act |
| Local MCP Server, Remote MCP Server | Destructive Tools Exposed (destructive_tools_exposed, under Authorization & RBAC) | false | Whether it holds tools that act |
| Agent Service | Network Egress Default-Deny Allowlist (network_egress_default_deny_allowlist, under Network & Connectivity) | true | Whether a way out is closed |
| Agent Tool Call | Agent Egress Restricted (agent_egress_restricted, under Network & Connectivity) | true | Whether a way out is closed |
| Agent Harness | Network Egress Default-Deny Allowlist (network_egress_default_deny_allowlist, under Network & Connectivity) | true | Whether a way out is closed |
| Local MCP Server | Server Network Egress Restricted (server_network_egress_restricted, under Data Handling & Residency) | true | Whether a way out is closed |
| Agent Chat Frontend | Markdown Image Rendering Policy (markdown_image_rendering_policy, under Output Rendering Exfiltration) | disabled, allowlisted_trusted_domains_only | Whether a way out is closed |
| Agent Harness | Harness Approval Mode (harness_approval_mode, under Authorization & RBAC) | default, plan (on-request, granular: the agents' own approval answers decide) | How the harness approves actions |
| Agent Harness | All-Approvals-Off Launch Flags in Use (dangerously_skip_permissions_in_use, under Authorization & RBAC) | false | A switch that skips approval whatever the mode |
| Context Ingress | Human Approval for Actions After Untrusted Ingress (human_approval_for_actions_after_untrusted_ingress, under Authorization & RBAC) | true | Whether a path into an action waits for a person |
| Context Ingress | Untrusted Ingress Can Trigger Consequential Actions (untrusted_ingress_can_trigger_consequential_actions, under Authorization & RBAC) | false | Whether a path into an action waits for a person |
| Agent Tool Call | Human Approval for Sensitive Tool Calls (human_approval_for_sensitive_tool_calls, under Authorization & RBAC) | true | Whether a path into an action waits for a person |
| Agent Service | Tool Credentials Least Privilege in User Context (tool_credentials_least_privilege_user_context, under Authorization & RBAC) | true | Whether the agent's tool credentials are limited to the user it acts for |
| Vector Database | Authentication Required for Every Request (authentication_required, under Authentication & Access) | true | Who can write to a store the agent reads |
| Vector Database | Writes Restricted to Ingestion Pipeline (index_write_restricted_to_pipeline, under Data Integrity) | true | Who can write to a store the agent reads |
| Vector Database | API Not Publicly Reachable (not_publicly_reachable, under Network & Connectivity) | true | Who can write to a store the agent reads |
| Agent Memory Service | Memory Writes Gated From Untrusted Content (memory_write_gated_from_untrusted_content, under Memory Integrity) | true | Who can write to a store the agent reads |
| Agent Memory Service | Memory Endpoints Require Authentication (memory_endpoints_require_authentication, under Authentication & Access) | true | Who can write to a store the agent reads |
| Agent Credential | Credential Expiry Enforced (credential_expiry_enforced, under Secrets & Credentials) | true | How strong a credential is |
| Agent Credential | Key Rotation Enabled (key_rotation_enabled, under Secrets & Credentials) | true | How strong a credential is |
| Agent Credential | Resource Scope Restricted (resource_scope_restricted, under Authorization & RBAC) | true | How strong a credential is |
| Agent Credential | Permission Scope Minimized (permission_scope_minimized, under Authorization & RBAC) | true | How strong a credential is |
| Agent Tool Call | Handoff Permission Mode Not Widened (handoff_permission_mode_not_widened, under Authorization & RBAC) | true | Whether a hand-off widens the permissions |
| Agent Server | Server Secrets Readable by Tool Code (server_secrets_readable_by_tool_code, under Secrets & Credentials) | false | Whether tool code can read the server's secrets |
| Agent Server | Runtime API Authentication Enforced (api_authentication_enforced, under Authentication & Access) | true | How an outsider gets a first foothold |
| Langflow | Custom Components Allowed (allow_custom_components, under Code Execution) | false | How an outsider gets a first foothold |
| Langflow | Auto-Login Enabled (langflow_auto_login, under Authentication & Access) | false | How an outsider gets a first foothold |
| Local MCP Server | Launcher Package Version Pinned (launcher_package_version_pinned, under Supply Chain Integrity) | true | How an outsider gets a first foothold |
| Local MCP Server | Server Package Provenance Vetted (server_package_provenance_vetted, under Supply Chain Integrity) | true | How an outsider gets a first foothold |
| Local MCP Server | mcp-remote Bridge Used (mcp_remote_bridge_used, under Application Security) | false | How an outsider gets a first foothold |
| Local MCP Server | mcp-remote Version Patched (mcp_remote_version_patched, under Application Security) | true | How an outsider gets a first foothold |
| Harness approval mode | The agent it runs |
|---|---|
default | waits for approval |
plan | waits for approval |
acceptEdits | acts without approval |
auto | acts without approval |
dontAsk | acts without approval |
bypassPermissions | acts without approval |
never | acts without approval |
on-request | does not decide: also answer the agent's own approval facts |
granular | does not decide: also answer the agent's own approval facts |
You ask the team that runs the copilot. They tell you:
- The copilot posts replies and updates tickets. Those actions change something outside the conversation.
- Nobody approves them: the copilot posts on its own.
- The copilot runs no code.
The code fact matters even for an agent without consequential tools: an agent that runs code counts as able to act.
The team does not say whether the copilot's network egress is limited to an allowlist. Nor do they say whether the copilot's tool credentials are limited to the customer it serves. Leave both facts unanswered. Lesson 8 is about why.
Steps
Double-click the support copilot. Its settings open in a panel at the bottom of the canvas, headed Process: Support copilot. Go to its Attributes tab. Its fields are grouped by category, and the lessons name the category with each field, for example "under Human Oversight". Click a category to expand it and see its fields. The first of the two small buttons at the top right of the Attributes tab switches the categories between foldable sections and tabs.
Each of these fields shows three buttons:
- Not answered means unanswered. Every field starts that way.
- Yes answers yes.
- No answers no.
Answer only the fields below. If you answer one by mistake, choose Not answered and save (see Yes/no fields). All Consequential Action Paths Require Approval is not shown until you choose Yes for Consequential Tools Present: it appears beside it once you do.
In the Human Oversight fields, a * and the hint "is a required property" mark a fact the class asks for, for example Approval Gate Present*. The model saves without it. Leave such a field unanswered unless the lesson tells you to set it.
- On Support copilot, set:
- Consequential Tools Present (
consequential_tools_present, under Human Oversight) =true - All Consequential Action Paths Require Approval (
consequential_tools_all_require_approval, under Human Oversight) =false - Code Execution Tools Present (
code_execution_tools_present, under Application Security) =false
- Consequential Tools Present (
Generate again.
What you should see
Findings: 2 systemic findings: 2 Confirmed · 0 Not ruled out.
| Finding | State | Legs |
|---|---|---|
| Lethal trifecta at Support copilot | Confirmed · unmitigated | U present · P present · X present · W present (aggravating) |
| Injection to action at Support copilot | Confirmed · unmitigated | untrusted input present · action tools present · no gate present · sensitive target present (aggravating) · broad identity undetermined (aggravating) |
Facts to establish: 1 question.
Facts that could raise a finding:
- Draw the Agent Tool Call from Support copilot to the harness that reads files for it, if there is one
Model gaps: No gaps these patterns can detect; not an attestation of completeness.
A second finding appears: Injection to action at the support copilot, Confirmed. The trifecta's W leg is now present. The model gap is gone. One question stays on Facts to establish: the CRM API key's, from lesson 2.
What changed and why
Injection to action is Confirmed. Its three required legs are present:
- untrusted input: from lessons 2 to 4, the copilot reads tickets and fetched pages that anyone can write;
- action tools: you stated that the copilot has consequential tools;
- no gate: you stated that those tools do not all need approval.
Untrusted content can trigger an action that nobody approves.
W turns present on the trifecta. The copilot writes without approval. W is aggravating: it only ranks the trifecta above otherwise equal findings. The trifecta was already Confirmed without it.
The harness question is settled. In lesson 1 the analysis asked you to tie the copilot to its harness, to find out how its actions get approved. The copilot has no harness. Its own answer, that its tools do not all need approval, now decides the question, so the question and the model gap both go.
The key's question stays, in new words. It still asks whether the copilot can read the files in its container, and so reach the CRM API key. You answered that the copilot runs no code, so the analysis no longer asks for that fact. Running no code does not rule out reading files, though: a harness can read them for the agent. Only a drawn Agent Tool Call to such a harness can show that, so the question now reads Draw the Agent Tool Call from Support copilot to the harness that reads files for it, if there is one. The copilot has no harness, so there is nothing to draw. The question stays open in every later lesson. No finding depends on it, so leave it.
Aggravating legs never decide a finding. The injection-to-action finding shows two aggravating legs: sensitive target is present and broad identity is undetermined. Aggravating legs only rank a finding above otherwise equal findings, by how many of them are present. The severity stays the pattern's band. Because they never decide the finding, Facts to establish does not ask about them. Inside the expanded finding, the broad identity leg still shows a to settle: line with an Answer it button. Its question names no attribute, so neither the line nor its dialog names one. The attribute is Tool Credentials Least Privilege in User Context (tool_credentials_least_privilege_user_context, under Authorization & RBAC). Leave it open.
Broad identity is still worth asking. The step asks: are the copilot's tool credentials limited to the customer it serves? The answer does not decide the finding, but it decides how much an injected copilot can reach. If the CRM API key can read every customer's records, one injected ticket can pull any customer's data, not only the data of the customer who wrote it.
You answered only what the team told you. The egress fact and the identity fact stay open. Answering either with a value nobody gave you would be a guess.
Exercise
This lesson has no exercise. Lesson 6 builds on it directly.
Next
Lesson 6: Fix a finding with a fact. The team adds approval, and you record it.
