An AI Fusion agent acts on real customer data and decides for itself which tools to call. Securing it means controlling three things: who can run the agent and read its conversations, what data each conversation can reach, and what the model is allowed to do with it. This article describes the controls AI Fusion gives you for each, what it deliberately does not do (such as masking), and how conversation data is retained and audited.
All AI Fusion endpoints are Fabric web services and use Fabric's standard authentication — a Fabric session, an API key, a JWT, OAuth or Basic authentication. See Fabric Web Services Security.
The agent and Observation endpoints run with the caller's permissions; none of them runs with elevated privileges. Authorization is therefore Fabric role-based access control:
agent, stop-session, session-status, chats, conversation-history and feedback. Observation endpoints such as retrieve-conversations, chat-review, the widget endpoints and the trace endpoints are for operators and analysts.Endpoints that take a sessionId — conversation-history, trace-history, trace-conversation, session-status, stop-session and feedback — do not check that the session belongs to the caller. Anyone allowed to call them can read or stop a session whose ID they know. Always use unguessable session IDs (random UUIDs), and do not expose the trace endpoints to end users.
chats is the exception: it always lists the authenticated user's own chats; the user cannot be passed as a parameter.
retrieve-conversations (the Observation conversation list) accepts a submitted-by filter with any user name, so a caller with access to it can list other users' conversations. Restrict it, and the rest of the Observation module, to the roles that review conversations. See Observation.
Endpoints that change evaluation assets or snapshots — agent/case/save, agent/case/update, agent/case/duplicate, agent/case/load, agent/{luName}/{agentName}/testRun, suite/enabled and case/history/delete — work only in AI Fusion Studio. In any other environment they return HTTP 403. Path-like names (/, \, ..) are rejected with HTTP 400.
The values that decide whose data a conversation may access — typically a customer ID — must come from your application, never from the model.
initParams on every request (see Invoking Agents). Derive them from the authenticated user, not from anything the end user types.AgentInitParams actor returns the main agent's init parameters, session ID, step ID, agent name and LU. These values are immutable — the model cannot change them, even inside a sub-agent. See Hooks and Agent Inputs.external: declarations become the agent's inputs, and mandatory: true makes one required — a request without it fails before the turn starts. But a sub-agent's inputs can be supplied by the parent model through task arguments, so a sub-agent flow that enforces authorization must read the scope from AgentInitParams, not from its own external.query, sessionId, tool_name or result are dropped from the arguments a parent model passes to a sub-agent, so the model cannot override the values the runtime supplies to hook flows.now is privileged. A pinned date and time is written into the persisted step record, so the REST API rejects an initParams containing now with HTTP 400. Only Evaluation runs may pin it.An agent works on one entity at a time. The step_start hook loads the entity's instance (for example with FabricGet, or GetWithSnap when snapshots are wanted) using the trusted customer ID, and the built-in query tool then runs SQL against that instance's micro-database. Each micro-database holds the data of a single entity, so a correctly scoped agent cannot see another customer's rows. See Tools.
Design points:
step_start, on every turn and in every sub-agent that queries data.query has no read-only enforcement. The model writes the SQL, and the statement is executed on the agent's Fabric session as written; it is not limited to SELECT. If that is not acceptable, attach a before hook to query that blocks anything other than a read-only statement, or turn query off (list tools: without it) and give the agent purpose-built flow tools instead.AgentInitParams.fabric tool off. The built-in fabric tool runs arbitrary Fabric commands with the session's permissions. It is off by default; do not enable it in a customer-facing agent. If an internal agent needs it, attach a before hook that allows only the commands you expect.| Control | What it does |
pre_tool_call hook |
Runs before every tool call and returns ALLOW or BLOCK. A blocked call is not executed; the model receives "Tool call blocked by agent policy". Fail-safe: if the hook flow itself fails, the call is blocked. |
Per-tool before hook |
The same contract, scoped to one tool. The global pre_tool_call runs first, and a global BLOCK wins. |
post_tool_call hook and per-tool after hook |
Inspect a tool's result; returning stop: true ends the run, optionally with your own result. Use it to stop on sensitive output or audit tool use. |
step_end hook |
Validates the final answer and can send the agent back for a correction (bounded by max_step_continuations). |
constraints |
Non-negotiable rules appended last to the system prompt. When a turn is delegated, the caller's constraints are added to the sub-agent's own, so a chain of delegations can only narrow what may be said. See Sub-Agents and Delegation. |
| Tool-name guard | Always on. A tool call whose name was not advertised to the agent is blocked, so the model cannot invoke a flow just by guessing its name. |
max_iterations |
Caps the LLM iterations per turn (default 20). At the limit, tools are blocked and the model must answer. |
| Delegation depth | Sub-agents can be nested at most 3 levels deep. |
Prompt instructions alone are not a security boundary. Put anything that must hold — authorization, data scope, forbidden actions — in hooks and flows, and use constraints and response_prompt for how the agent speaks. See Hooks and Agent Inputs.
AI Fusion does not mask data in the agent pipeline. Whatever a tool returns — query results, flow output, MCP responses — is sent to the LLM provider as is, and is stored in the session's trace.
To keep sensitive values away from the model:
Do not keep provider API keys or cloud credentials in plain text in the project. Use Fabric's secret manager and environment-level interface settings, and prefer identity-based authentication — the instance IAM role for Bedrock, Application Default Credentials for Google. Google's CREDENTIAL property is stored through the secret manager. See Secrets Management.
Conversations, traces and snapshots are kept until a cleanup process removes them. Two globals of the aifusion LU control the retention windows:
Values outside the range are clamped. A session counts as closed once the Observation analyzer has processed it; sessions that were never analyzed are not removed by the cleanup.
To run the conversation cleanup on demand, call POST /api/v1/cleanup/start (optional retention_days). To schedule it, run the aifusion.cleanupJob flow once: it registers a Broadway job that runs the cleanup daily at 02:00. aifusion.cleanupEvaluationStorageJob likewise registers the evaluation-storage cleanup weekly (Sunday 03:00). Because cleanup/start deletes data, grant it only to administrators.
| What | Where |
| Every question and answer, with timestamps | The session's step records; also used for conversation-history. |
| Every message, tool call (with arguments and result), agent and sub-agent execution, and token usage | The session's trace tables, written when observability is on. Read them with the trace endpoints or the Studio trace panel. See Sessions and Context. |
| Who started each conversation, with which agent and Data Product | The session record in the Insights database, used by the Observation module and the chats API. |
| End-user feedback | The feedback table; the submitting user is taken from the authenticated session (submitted_by). See Feedback. |
| Stopped turns | The partial answer followed by <ABORTED BY USER> in the step record. |
| Runtime errors | The Fabric server log. The end user only sees a generic message (or the one your on_error hook returns). |
The trace contains the data the agent saw, including any unmasked values. Protect the trace endpoints, the Insights database and the retention settings accordingly. For the overall runtime picture, see Architecture.
An AI Fusion agent acts on real customer data and decides for itself which tools to call. Securing it means controlling three things: who can run the agent and read its conversations, what data each conversation can reach, and what the model is allowed to do with it. This article describes the controls AI Fusion gives you for each, what it deliberately does not do (such as masking), and how conversation data is retained and audited.
All AI Fusion endpoints are Fabric web services and use Fabric's standard authentication — a Fabric session, an API key, a JWT, OAuth or Basic authentication. See Fabric Web Services Security.
The agent and Observation endpoints run with the caller's permissions; none of them runs with elevated privileges. Authorization is therefore Fabric role-based access control:
agent, stop-session, session-status, chats, conversation-history and feedback. Observation endpoints such as retrieve-conversations, chat-review, the widget endpoints and the trace endpoints are for operators and analysts.Endpoints that take a sessionId — conversation-history, trace-history, trace-conversation, session-status, stop-session and feedback — do not check that the session belongs to the caller. Anyone allowed to call them can read or stop a session whose ID they know. Always use unguessable session IDs (random UUIDs), and do not expose the trace endpoints to end users.
chats is the exception: it always lists the authenticated user's own chats; the user cannot be passed as a parameter.
retrieve-conversations (the Observation conversation list) accepts a submitted-by filter with any user name, so a caller with access to it can list other users' conversations. Restrict it, and the rest of the Observation module, to the roles that review conversations. See Observation.
Endpoints that change evaluation assets or snapshots — agent/case/save, agent/case/update, agent/case/duplicate, agent/case/load, agent/{luName}/{agentName}/testRun, suite/enabled and case/history/delete — work only in AI Fusion Studio. In any other environment they return HTTP 403. Path-like names (/, \, ..) are rejected with HTTP 400.
The values that decide whose data a conversation may access — typically a customer ID — must come from your application, never from the model.
initParams on every request (see Invoking Agents). Derive them from the authenticated user, not from anything the end user types.AgentInitParams actor returns the main agent's init parameters, session ID, step ID, agent name and LU. These values are immutable — the model cannot change them, even inside a sub-agent. See Hooks and Agent Inputs.external: declarations become the agent's inputs, and mandatory: true makes one required — a request without it fails before the turn starts. But a sub-agent's inputs can be supplied by the parent model through task arguments, so a sub-agent flow that enforces authorization must read the scope from AgentInitParams, not from its own external.query, sessionId, tool_name or result are dropped from the arguments a parent model passes to a sub-agent, so the model cannot override the values the runtime supplies to hook flows.now is privileged. A pinned date and time is written into the persisted step record, so the REST API rejects an initParams containing now with HTTP 400. Only Evaluation runs may pin it.An agent works on one entity at a time. The step_start hook loads the entity's instance (for example with FabricGet, or GetWithSnap when snapshots are wanted) using the trusted customer ID, and the built-in query tool then runs SQL against that instance's micro-database. Each micro-database holds the data of a single entity, so a correctly scoped agent cannot see another customer's rows. See Tools.
Design points:
step_start, on every turn and in every sub-agent that queries data.query has no read-only enforcement. The model writes the SQL, and the statement is executed on the agent's Fabric session as written; it is not limited to SELECT. If that is not acceptable, attach a before hook to query that blocks anything other than a read-only statement, or turn query off (list tools: without it) and give the agent purpose-built flow tools instead.AgentInitParams.fabric tool off. The built-in fabric tool runs arbitrary Fabric commands with the session's permissions. It is off by default; do not enable it in a customer-facing agent. If an internal agent needs it, attach a before hook that allows only the commands you expect.| Control | What it does |
pre_tool_call hook |
Runs before every tool call and returns ALLOW or BLOCK. A blocked call is not executed; the model receives "Tool call blocked by agent policy". Fail-safe: if the hook flow itself fails, the call is blocked. |
Per-tool before hook |
The same contract, scoped to one tool. The global pre_tool_call runs first, and a global BLOCK wins. |
post_tool_call hook and per-tool after hook |
Inspect a tool's result; returning stop: true ends the run, optionally with your own result. Use it to stop on sensitive output or audit tool use. |
step_end hook |
Validates the final answer and can send the agent back for a correction (bounded by max_step_continuations). |
constraints |
Non-negotiable rules appended last to the system prompt. When a turn is delegated, the caller's constraints are added to the sub-agent's own, so a chain of delegations can only narrow what may be said. See Sub-Agents and Delegation. |
| Tool-name guard | Always on. A tool call whose name was not advertised to the agent is blocked, so the model cannot invoke a flow just by guessing its name. |
max_iterations |
Caps the LLM iterations per turn (default 20). At the limit, tools are blocked and the model must answer. |
| Delegation depth | Sub-agents can be nested at most 3 levels deep. |
Prompt instructions alone are not a security boundary. Put anything that must hold — authorization, data scope, forbidden actions — in hooks and flows, and use constraints and response_prompt for how the agent speaks. See Hooks and Agent Inputs.
AI Fusion does not mask data in the agent pipeline. Whatever a tool returns — query results, flow output, MCP responses — is sent to the LLM provider as is, and is stored in the session's trace.
To keep sensitive values away from the model:
Do not keep provider API keys or cloud credentials in plain text in the project. Use Fabric's secret manager and environment-level interface settings, and prefer identity-based authentication — the instance IAM role for Bedrock, Application Default Credentials for Google. Google's CREDENTIAL property is stored through the secret manager. See Secrets Management.
Conversations, traces and snapshots are kept until a cleanup process removes them. Two globals of the aifusion LU control the retention windows:
Values outside the range are clamped. A session counts as closed once the Observation analyzer has processed it; sessions that were never analyzed are not removed by the cleanup.
To run the conversation cleanup on demand, call POST /api/v1/cleanup/start (optional retention_days). To schedule it, run the aifusion.cleanupJob flow once: it registers a Broadway job that runs the cleanup daily at 02:00. aifusion.cleanupEvaluationStorageJob likewise registers the evaluation-storage cleanup weekly (Sunday 03:00). Because cleanup/start deletes data, grant it only to administrators.
| What | Where |
| Every question and answer, with timestamps | The session's step records; also used for conversation-history. |
| Every message, tool call (with arguments and result), agent and sub-agent execution, and token usage | The session's trace tables, written when observability is on. Read them with the trace endpoints or the Studio trace panel. See Sessions and Context. |
| Who started each conversation, with which agent and Data Product | The session record in the Insights database, used by the Observation module and the chats API. |
| End-user feedback | The feedback table; the submitting user is taken from the authenticated session (submitted_by). See Feedback. |
| Stopped turns | The partial answer followed by <ABORTED BY USER> in the step record. |
| Runtime errors | The Fabric server log. The end user only sees a generic message (or the one your on_error hook returns). |
The trace contains the data the agent saw, including any unmasked values. Protect the trace endpoints, the Insights database and the retention settings accordingly. For the overall runtime picture, see Architecture.