Security and Privacy

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.

Authentication and Authorization

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:

  • Grant each role only the web services it needs. End-user applications typically need 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.
  • Grant the role access to the Data Products the agent's flows read.
  • To restrict a caller to a single entity instance, use Fabric's IID-based access control. See JWT Custom Claims and IID Access Control.

Session-Level Access

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.

Studio-Only Endpoints

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.

Trusted Inputs

The values that decide whose data a conversation may access — typically a customer ID — must come from your application, never from the model.

  • initParams are the trusted channel. Your application sends the agent's inputs in initParams on every request (see Invoking Agents). Derive them from the authenticated user, not from anything the end user types.
  • Read them with the AgentInitParams actor. In any hook or tool flow the runtime invokes directly, the 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.
  • Hook externals are inputs, not proof. A hook flow's 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.
  • Reserved names cannot be spoofed through delegation. Runtime field names such as 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.

Entity Scoping

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:

  • Load the entity from the trusted input in 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.
  • Flow tools receive model-supplied arguments. Validate them in the flow, and take identity and scope from AgentInitParams.
  • Keep the 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.

Guardrails on Agent Behavior

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.

Masking and Data Sent to the Model

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:

  • Mask inside your tool and hook flows, before the data is returned to the agent, using Fabric's masking capabilities. See Data Masking.
  • Return only what the agent needs. A flow tool that returns a few columns exposes less than open SQL over the whole micro-database; a skill can steer which tables and columns the agent queries.
  • Use provider-side controls where available. On AWS Bedrock, set GuardrailID (and GuardrailVersion) on the interface to apply a Bedrock Guardrail — content filters, denied topics or PII redaction — to every call. See LLM Connectors.
  • Keep data in your network when required by running models through a private endpoint, or on your own infrastructure with the Ollama connector (preview).

Secrets

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.

Data Retention

Conversations, traces and snapshots are kept until a cleanup process removes them. Two globals of the aifusion LU control the retention windows:

Global Default Range Applies to
RETENTION_DAYS 30 7–365 Conversations: closed sessions older than this are deleted — their Insights rows, session and instance records, local snapshots and the session's aifusion instance.
EVALUATION_STORAGE_RETENTION_DAYS 90 30–365 Evaluation storage: snapshot files older than this that no evaluation suite references any more.

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.

Audit Trail

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.

Security and Privacy

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.

Authentication and Authorization

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:

  • Grant each role only the web services it needs. End-user applications typically need 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.
  • Grant the role access to the Data Products the agent's flows read.
  • To restrict a caller to a single entity instance, use Fabric's IID-based access control. See JWT Custom Claims and IID Access Control.

Session-Level Access

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.

Studio-Only Endpoints

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.

Trusted Inputs

The values that decide whose data a conversation may access — typically a customer ID — must come from your application, never from the model.

  • initParams are the trusted channel. Your application sends the agent's inputs in initParams on every request (see Invoking Agents). Derive them from the authenticated user, not from anything the end user types.
  • Read them with the AgentInitParams actor. In any hook or tool flow the runtime invokes directly, the 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.
  • Hook externals are inputs, not proof. A hook flow's 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.
  • Reserved names cannot be spoofed through delegation. Runtime field names such as 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.

Entity Scoping

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:

  • Load the entity from the trusted input in 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.
  • Flow tools receive model-supplied arguments. Validate them in the flow, and take identity and scope from AgentInitParams.
  • Keep the 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.

Guardrails on Agent Behavior

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.

Masking and Data Sent to the Model

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:

  • Mask inside your tool and hook flows, before the data is returned to the agent, using Fabric's masking capabilities. See Data Masking.
  • Return only what the agent needs. A flow tool that returns a few columns exposes less than open SQL over the whole micro-database; a skill can steer which tables and columns the agent queries.
  • Use provider-side controls where available. On AWS Bedrock, set GuardrailID (and GuardrailVersion) on the interface to apply a Bedrock Guardrail — content filters, denied topics or PII redaction — to every call. See LLM Connectors.
  • Keep data in your network when required by running models through a private endpoint, or on your own infrastructure with the Ollama connector (preview).

Secrets

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.

Data Retention

Conversations, traces and snapshots are kept until a cleanup process removes them. Two globals of the aifusion LU control the retention windows:

Global Default Range Applies to
RETENTION_DAYS 30 7–365 Conversations: closed sessions older than this are deleted — their Insights rows, session and instance records, local snapshots and the session's aifusion instance.
EVALUATION_STORAGE_RETENTION_DAYS 90 30–365 Evaluation storage: snapshot files older than this that no evaluation suite references any more.

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.

Audit Trail

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.