Skip to main content
Policies are evaluated at three stages: session (connection time), request (before query execution), and response (after data retrieval). Each stage provides different input data for making policy decisions.
For available enforcement actions at each stage, see Enforcement. If you have existing policies using pre_request / post_request, see Legacy Stage Names.

Policy Scope

By default, policies apply universally to all users, resources, and data locations. You can narrow the scope within each policy using conditions.

User Context Quick Reference

Access user information via input.user and input.end_user:

Resource Context Quick Reference

Filter by resource via input.resource:

Policy stages

Session stage

Available inputs

Available actions

For this policy stage, two types of actions are possible: allow and block.

Request stage

Request rules are evaluated by the proxy when it intercepts a request (query) just before sending it to the resource. This evaluation stage is especially useful in blocking write requests.

Available inputs

Available actions

For this policy stage, four types of actions are possible: allow, block, rewrite, and decrypt.

Response stage

Response rules are evaluated by the proxy when it intercepts data received from the resource. This evaluation stage is particularly useful in the context of masking or filtering read requests.

Available inputs

Available actions

For this policy stage, four types of actions are possible: allow, filter, mask, and encrypt.

Standard input data

Policies can access various data types, including user information, resource information, SQL query information, and HTTP request information. The following sections describe the available data types.

Session object

Request object

User object

Connector object

Resource object

Column object

input.row lists all columns extracted from your SQL query. A single returned column can come from multiple source columns (e.g. when using wildcards, joins, or unions), and thus result in several policy columns. When the Connector cannot resolve a source, the returned column itself stands in as its own policy column. This column lineage mapping is then used by the Connector’s policy engine: a response rule that masks a policy column will be able to mask every returned column whose lineage includes it. For example, in SELECT email FROM users UNION SELECT email FROM customers, the returned email column has two source columns: users.email and customers.email. Either one alone is enough to mask it for the entire result.

Function object

Function categories are used to group functions into different categories. The following categories are available: aggregate, bitwise, conditional, context, conversion, data_generation, date_time, differential_privacy, encryption, file, geospatial, hash, metadata, notification, numeric, scalar, semi_structured, string_and_binary, system, table, vector_similarity, window. These categories are inspired by the Snowflake documentation.

Space object

HTTP object

Native users

You can enforce policies on native users, the user used by the proxy to connect to the underlying resource. For example, here is a policy that allows the connection only if the native user is reader:

Native user assignment

The native_user_assignment field tells you how the native user was resolved for the current session. Possible values are: For example, the following policy blocks connections where the user explicitly overrides their native user assignment:

Snowflake resources

You can enforce policies on Snowflake resources based on the role used to connect to the resource.

Snowflake object

SQL resources

Formal can also enforce policies specific to SQL queries. SQL Query Object

Example: Run all SQL statements in a transaction in order

You can use a workflow to create a policy suspension that ensures a sequence of SQL statements is executed in the correct order within a transaction. The workflow below accepts a list of ordered statements via its API trigger and creates a suspension that validates each statement matches the expected sequence using transaction_history.

AWS resources

Formal can also enforce policies on specific AWS Resources. These policies can be actively used for the SSH or Kubernetes.

AWS object

ECS object

EC2 object

EKS object

Kubernetes resources

Formal can enforce policies on Kubernetes API requests based on the resource being accessed. The Kubernetes context is available via input.kubernetes.

Kubernetes object

LLM resources

Formal can enforce policies on LLM API sessions. Use session rules to block a connection before it reaches the upstream provider, request rules to inspect and rewrite outgoing request headers or bodies, and response rules to evaluate model responses.
Tool calls are part of the model response, so policies that inspect input.llm.tool_calls should use the response rule.

LLM object

Message object

Content part object

Tool object

Tool call object

Example: Rewrite request headers

The following policy adds request headers before the LLM request is sent to the upstream provider. Header values must be arrays of strings. Set a header to an empty array to remove it.

Example: Redact SSNs from request messages

Use a request-stage rewrite with regex.replace on input.http.body to strip sensitive values from prompts without blocking the session. This keeps coding agents usable when SSNs appear in the context window.
The rewrite replaces the full HTTP body string. Keep replacements JSON-safe so the upstream request stays valid. See HTTP body rewrites.

Example: Block specific tool calls

The following policy blocks any LLM response that includes a Bash tool call with a specific command:

MCP resources

Formal can enforce policies on MCP tool calls. The MCP context is available via input.mcp at the request and response stages when the request is a tool call.

MCP object

Example: Block a specific tool

To seal OAuth Bearer tokens for MCP clients, see Encrypt MCP OAuth Tokens.

Device

Formal can also enforce policies on specific device attributes.
This feature is only available for devices using the Formal Desktop App.

Device info object

Hardware info object

Software info object

AI agents

Formal tracks connections that originate from AI coding agents running through the Formal Desktop App. When an agent is detected, input.agent is populated with context about that agent.
input.agent is only populated for connections made via the Formal Desktop App. It is empty for direct connections.

Agent object

Example: block Claude Code in YOLO mode

Use input.agent.yolo_mode to block autonomous agents from accessing sensitive resources without per-action approval:

Policy Input Retention

Formal can optionally retain these inputs for policy backtesting where you can test policies on historical data.

Extending Policies with External Data

You can extend policies with custom data fetched by Policy Data Loaders. The data is accessible via the data object using the loader’s configured key. Example:
For more information, see Policy Data Loaders.

Legacy Stage Names

Prior to Connector v1.31.19, the Rego rule names for the request and response stages were pre_request and post_request. These legacy names still work and existing policies do not need to be updated. To migrate, rename pre_request to request and post_request to response in your policy code. Different policies can use different naming conventions.