Overview
Formal policies can enforce different actions at three evaluation stages: session, pre-request, and post-request. Each stage has specific actions available based on when the policy is evaluated.Evaluation Stages
Session
When: Connection establishment Actions:
allow, block, mfa Use
for: Authentication, connection-level access controlPre-Request
When: Before query reaches resource Actions:
allow, block,
rewrite Use for: Query validation, SQL rewriting, blocking writesPost-Request
When: After data returns from resource Actions:
allow, filter,
mask, decrypt Use for: Data masking, PII redaction, filtering resultsCommon Action Parameters
All actions support these parameters:| Parameter | Type | Description |
|---|---|---|
action | String | The enforcement action: allow, block, filter, mask, decrypt, rewrite, mfa |
reason | String | Explanation for the action (logged for compliance and auditing) |
contextual_data | String | Additional context that influenced the decision (e.g., “Zendesk ticket #123”) |
Block Action
Deny access and terminate the connection or query.Parameters
| Parameter | Type | Description |
|---|---|---|
type | Enum | One of block_with_formal_message or block_with_custom_message |
message | String | Custom message to show the user |
Example
Allow Action
Explicitly permit an operation. Use in combination with default deny policies.Example
Rewrite Action
Modify the query before it reaches the resource.Parameters
| Parameter | Type | Description |
|---|---|---|
rewritten_query | String | The new query to execute |
Example
Filter Action
Remove rows from the result set based on conditions.Example
Mask Action
Redact or obfuscate sensitive data in responses.Parameters
| Parameter | Type | Description |
|---|---|---|
type | String | Masking type (e.g., redact.partial, hash.with_salt, fake, nullify) |
sub_type | String | Specific masking method (e.g., email_mask_username) |
columns | []Column | List of columns to mask |
redact | String | Replacement value for redaction |
characters_count | Integer | Number of characters to mask |
typesafe | Boolean | Maintain column data type (default: false) |
typesafe_fallback | String | fallback_to_null or fallback_to_default |
Masking Types
| Type | Privacy Level | Description |
|---|---|---|
nullify | 4 (Highest) | Replace with NULL |
hash.with_salt | 4 | Hash with random salt |
fake | 3 | Generate realistic fake data |
redact.constant_characters | 3 | Replace with constant string |
hash.no_salt | 2 | Hash without salt (deterministic) |
redact.partial | 1 | Partially redact (e.g., mask email username) |
none | 0 (Lowest) | No masking |
Masking Subtypes
Email Masking
Email Masking
email_mask_username:****@example.com-email_mask_domain_name:user@*****.***-email_mask_while_preserving:a****@e******.com-email_mask_with_fake:fake.email@example.com
Personal Information
Personal Information
person_full_name_mask_with_fake-person_first_name_mask_with_fake-person_last_name_mask_with_fake-person_ssn_mask_with_fake
Location Data
Location Data
postal_address_mask_with_fake-city_mask_with_fake-state_mask_with_fake-zip_mask_with_fake-location_mask_except_state_country
Payment Data
Payment Data
payment_credit_card_number_mask_with_fake-payment_credit_card_cvv_mask_with_fake-payment_credit_card_exp_mask_with_fake-payment_ach_routing_with_fake-payment_bitcoin_address_with_fake
Network Data
Network Data
network_url_mask_with_fake-network_ipv4_mask_with_fake-network_ipv6_mask_with_fake-network_mac_mask_with_fake
General Redaction
General Redaction
redact.constant_characters: Replace with custom string -redact.first_n_characters: Mask first N chars -redact.last_n_characters: Mask last N chars -mask_everything_except_last: Show only last N chars
Examples
Mask email usernames:Decrypt Action
Decrypt previously encrypted columns (requires encryption policy).Example
MFA Action
Require multi-factor authentication before allowing access.Example
Rule Conflicts and Precedence
When multiple policies apply to the same query, Formal resolves conflicts using least privilege:| Scenario | Resolution |
|---|---|
| Block vs Allow | Block wins |
| Multiple Filter actions | Smallest row limit wins |
| Multiple Mask actions | Highest privacy level wins (nullify > constant > fake > partial) |
| Multiple Rewrite actions | Arbitrary (avoid conflicts with scoping) |
Example of Conflict Resolution
Scoping Policies with Connectors and Resources
To prevent policy conflicts when using thedefault keyword, you can limit which Connectors or Resources a policy applies to.
Include/Exclude Connectors
Useincluded_connectors to apply a policy only to specific connectors:
excluded_connectors to exclude specific connectors:
Include/Exclude Resources
Useincluded_resources to apply a policy only to specific resources:
excluded_resources to exclude specific resources: