Skip to main content
CID222 Docs

Configure security filters

Define what the gateway detects in prompts and in model responses, and whether it masks, flags or rejects what it finds.

  • Version: 0.4
  • Role: admin_user
  • Type: task

Security Filters is where you decide what CID222 looks for in a prompt or a model response, and what it does when it finds it. A rule can mask the match, flag it and let it through, or reject the whole message. The same page holds the response-side rules on a second tab.

What do I need?

Licence
Any
Role
admin_user

Prerequisites

  • You are signed in as admin_user or superadmin. A viewer can read the page and is refused every change.
  • At least one tenant group exists if you want a rule to behave differently for one department.
  • You know which entity types the detectors already produce — see the generated entity type reference.

Three objects stack. A filter group holds filters and can switch all of them off at once. A filter carries the action, the priority and the model entity types it reacts to. A pattern is one regular expression under a filter. A filter with no patterns and no entity types detects nothing, whatever its Active toggle says.

Warning

Filter Type (Regex, Keyword, PII Detection, Content Policy) is a label for the list only — the input pipeline never reads it, and Keyword has no implementation. What a filter matches is decided by its patterns and its ML Entity Types.

Create an input filter

Open the page

Select Detection & Filtering → Security Filters.

The page opens on the Input Filters tab with Editing: set to Base policy — everyone.

Start a new filter

Select Add input filter.

The Add Input Filter dialog opens. The button appears only on the base policy; a group scope can change existing rules but cannot create one.

Name it and place it in a group

Enter a Filter Name of at most 100 characters and pick a Filter Group.

The group is required. Switching the group's own Active toggle off later disables every filter inside it.

Bind it to model entity types, if it uses the model

Enter comma-separated labels in ML Entity Types — for example EMAIL, PERSON_NAME.

Leave the field empty for a pattern-only filter. The dialog states the consequence: per-tenant action overrides only reach filters that have an entity type.

Choose the action

Set Action Type to Mask, Flag or Reject.

Mask replaces the match with a placeholder, Flag records it and lets the message through, Reject blocks the message.

Set the priority

Enter a Priority between 0 and 999. The default is 0.

Priority is a tie-break between rules of equal action strength only. Where two rules match the same text, the stricter action wins first: REJECT beats MASK beats FLAG beats ALLOW.

Save

Select Create Filter.

A Filter created toast appears and the row is added. The detection caches reload within about a second, so the rule is live without a restart.

Add and test a pattern

A new filter matches nothing until it has a pattern or an entity binding. The Edit dialog does not contain patterns — they live behind the row menu.

Open the pattern screen

On the filter's row select Open menu → Patterns.

Patterns — {filter} opens with two tabs, Write it myself and Describe it.

Write the pattern

On Write it myself, select Add pattern, then fill Pattern name, Pattern and Replacement.

A bare pattern is case-sensitive. Start it with (?i) for case-insensitive matching, and wrap the part you want redacted in parentheses — TC: (\d{11}) keeps the label and masks only the number.

Try it on your own text

Paste a sample into Try it on your own text.

The gateway runs the pattern and reports {n} matches or No match — this text would pass through untouched, highlighting the spans it would redact. The sample is sent to the gateway and is not stored.

Save the pattern

Select Save changes.

The toast reads Pattern added — it is live within a few seconds. Saving is blocked while the pattern cannot be verified, and refused outright if it is unsafe (see below).

Tip

Turkish letters do not case-fold as expected: case-insensitive matching is ASCII-only, so matlı holding never matches MATLI HOLDING. Write each ambiguous letter as a class — ı[Iıİi], ş[şŞsS], ğ[ğĞgG], ç[çÇcC], ö[öÖoO], ü[üÜuU] — or use Describe it and let the draft cover the spellings.

Regex safety

Every pattern runs against every request, so the gateway refuses a pattern that

  • fails to compile, or exceeds 1000 characters;
  • has a catastrophic-backtracking shape — a quantified group whose body is quantified ((a+)+), repeated alternation with duplicate branches ((a|a)*), or chained open wildcards (.*.*);
  • exceeds a 50 ms budget on adversarial probe input.

Breadth concerns — a pattern that matches everything, an unanchored short pattern, an absurd repetition count — come back as warnings beside the field and do not block the save.

Draft a rule from a description

Describe it turns plain language plus examples into candidate patterns, compiles them and runs them against your examples before anything is written.

Describe what should be caught

On the Describe it tab, fill Describe what should be caught, then Should be caught and Should be left alone, one example per line.

The notice states that the description and examples are sent to the configured AI provider.

Generate and review

Select Generate filter.

Each drafted pattern is listed with its safety verdict, and each example is marked Caught as expected, Should have been caught, but was not, or Should have been left alone, but was caught.

Keep the patterns

Select Add {n} patterns.

Nothing is persisted before this step — the draft endpoint writes nothing.

Override a rule for one tenant group

Switch the editing scope

Set Editing: to {group} — overrides base.

A warning tile appears: Editing overrides for {group}. It states that an override replaces the base policy for that group and can relax it as well as tighten it, and that where a tenant is in several groups the strictest of those groups' overrides applies.

Change the action for the group

In the Action column pick an action, or Use base to follow the base policy again.

The toast reads Filter override saved or Filter override removed. The Active column stays global in this mode — the hint says Filters are enabled or disabled globally. Switch to the base policy to change this.

Precedence is base < group < tenant. A tenant-level override is the most specific and wins outright; per-tenant overrides are written through the /admin/filter-overrides API, not from this page.

Turn a detection engine off for a group

The five tiles above the table — PII detection, Secrets & data leakage, Content safety, Jailbreak & injection, Code safety — group the filters that share one detector call.

Select the group first

Set Editing: to the tenant group. On the base policy the toggles are disabled.

Each tile shows Running or Skipped, the number of filters in the family, and the detector behind it.

Switch the engine off

Turn the tile's Enabled switch off.

A {family} turned off toast confirms it. Switching a family off sets every filter in it to allow for that group, so the detector is not called at all — the check costs nothing rather than being ignored.

Warning

A filter group whose name the family map does not recognise is listed under Unmapped filter groups. Its filters take no part in the skip decision, so an engine can read Skipped while one of those filters still rejects.

Export, import, or apply a baseline

Export the current scope

Select Import / Export → Export configuration.

A JSON bundle downloads for the selected scope. Tenant-group overrides ride along; tenant-scoped overrides are never exported.

Choose what to apply

Select Import / Export → Import from file… to upload a bundle, or Apply baseline… to pick one of the shipped policies: GDPR Strict, HIPAA, KVKK/Finance or Permissive.

The dialog names the target: the base policy, or the selected tenant group.

Pick the mode

Choose Add new only, Apply policy or Replace policy.

Add new only creates missing groups, filters and patterns and never changes an existing action or on/off switch. Apply policy also sets actions (as overrides when a group is selected). Replace policy additionally switches off anything in scope the bundle does not mention; definitions are never deleted.

Preview, then confirm

Select Preview changes, read the change list and the warnings, then select Apply {n} changes.

Nothing is written until you confirm. The apply recomputes the preview and refuses if the configuration moved underneath you. The toast reads Filter configuration imported.

Baselines are action-policy bundles: they carry identity plus action and on/off state only, so the mode selector is disabled for them and an unknown reference degrades to a warning instead of failing the import. Output filters have no override table, so a group-targeted import skips the output section with a warning.

Output filters

The Output Filters tab holds the rules applied to the model's response. They are a separate table with their own actions and no regex patterns of their own.

  • Filter types are PII Detection, Content Policy, Hallucination and Regex.
  • Actions are Mask, Reject, Flag and Warn. Warn shows a warning and keeps the response, so it leaves the same residual exposure as a flag.
  • Create one with Add output filter; the dialog asks for Group, Filter Name, Filter Type, Action Type, Validation Entity Type, ML Entity Types and Priority.
  • Output rules are global. There is no output override layer: ai_filter_overrides addresses input filter ids, so a tenant or group override never reaches a response rule.

Warning

A hallucination filter's hallucination_threshold and min_supported_ratio (both 0–1) exist on the API and in the stored row but have no field in the dialog. Set them through /admin/output-filters if you need a value other than the one already stored.

Fields reference

Add Input Filter / Edit Filter

FieldRequiredRuleWhat it does
Filter NameYesMax 100 charactersNames the rule in the table and in audit records
Filter GroupYesAn existing groupGroups the rule; the group's own Active toggle gates every filter in it
Filter TypeYesOne of four valuesA label only. The input pipeline does not read it
ML Entity TypesNoComma-separated labelsModel labels this filter reacts to. Required for per-tenant action overrides to reach it
Validation Entity TypeNoMax 50 charactersJoins this filter's detections to validation rules
Action TypeYesMask, Flag or RejectWhat happens when the rule matches
PriorityNo0999, default 0Tie-break between rules of equal action strength only
ActiveNoDefault onWhether the detection engine loads the rule at all

Input filters table

ColumnShows
Filter nameThe rule's name, with a Broken tag when a pattern fails to compile
GroupThe filter group it belongs to
TypeThe Filter Type label
ActionThe action dropdown; in group scope it also offers Use base
PriorityThe tie-break number — the higher number wins
Detection methods{n} patterns, ML ({n}), or a Detects nothing badge
ActiveWhether the engine loads this rule
PseudonymizationWhether masked values can be restored in the response for this filter
CreatedCreation date

Verify

  1. The rule appears in the table with the action, priority and Active state you set, and its Detection methods cell is not Detects nothing.
  2. Send a message that should match through AI Chat, then open All detections and confirm a row with the verdict you expect.
  3. Open Event logs. Changing an action or an Active toggle writes one POLICY_PROTECTION_CHANGED row per changed field, with the value before and after, so a weakening is distinguishable from a re-enable. Renames and priority edits write nothing.
  4. Exporting writes a FILTER_BUNDLE_EXPORTED row; a completed import writes a RESOURCE_UPDATED row against the resource type filter_bundle, carrying the mode, the target scope, the checksum and the change counts.

If it fails

  • The rule matches in the pattern tester and does nothing in real traffic — check Active on the filter and on its group. An inactive rule still matches in the tester.
  • Detects nothing on the row — the filter has neither a pattern nor an ML Entity Types value. Open Open menu → Patterns and add one.
  • Nested quantifiers detected …, Repeated alternation contains duplicate branches …, or Multiple consecutive .* / .+ sequences … — the pattern is refused as a catastrophic-backtracking risk. Bound the quantifier, for example {1,20}.
  • Pattern is {n} characters; the maximum is 1000. — shorten the pattern or split it into two.
  • Could not check this pattern — the server did not respond. Saving is blocked until it can be verified. — the gateway is unreachable from the dashboard; the editor refuses to save an unverified pattern.
  • Filter group "{name}" still contains {n} filter(s): … Delete them first, or repeat this request with ?cascade=true to remove them together. — the group is not empty.
  • The filter configuration changed after this preview was taken. Re-run the preview and confirm the new diff. — someone else changed a filter between your preview and your confirm. Preview again.
  • Bundle failed validation; nothing was imported. — the bundle is malformed or references objects this appliance cannot resolve. The response lists the errors.
  • This is a read-only demo account (viewer role) — actions and changes are disabled. — the request was refused with READ_ONLY_ROLE. Sign in with an account that is not a viewer.

Next steps

  • Filter testing — prove a rule catches what you think it catches before it reaches production.
  • All detections — see what the rules are actually catching, across every capture point.
  • Tenant groups — create the group whose overrides this page edits.

Last updated on