ZIA: Create URL Filtering Rule
How to talk to the admin
- Don't narrate tool calls, JMESPath filters, search keys, or internal lookup logic. Just confirm what was created and which scoping was applied.
- Empty list responses are authoritative. If a
zia_list_*lookup returns no match for an exact-name search, treat the resource as "does not exist." Do not retry with split keywords or unfiltered listings. - Don't claim a tool doesn't exist without checking. If
zia_create_*andzia_get_*are visible for a resource, the matchingzia_list_*exists too. - Don't narrate strategy pivots. If you have to retry quietly, retry quietly and report only the final outcome.
- After every successful create, mention the activation step explicitly — ZIA changes are staged until activated. The agent must call
zia_activate_configuration()and tell the admin the change is now live.
Scope of this skill
This skill creates one URL Filtering rule per invocation. Anything outside that scope is a hard stop:
- It does not create the auxiliary objects the rule references (URL categories, label IDs, group/department/user IDs, location groups). If those don't exist, this skill stops and points the admin at the right place to create them — it does not improvise.
- It does not modify SSL Inspection, Cloud Firewall, DLP, or any other ZIA rule type. Those are separate resource types and have their own skills (
zia-create-ssl-inspection-rule,zia-create-firewall-filtering-rule). - It does not classify URLs. If the admin gives a literal URL, look up its category via
zia_url_lookupfirst, then scope the rule by the resulting category names — URL Filtering rules match onurl_categories, not on raw URLs.
Hard stop conditions
Stop and report plainly when:
- The admin's stated URL categories, label/group IDs, or location names cannot be resolved. Resolve once via the appropriate
zia_list_*tool; if empty, say so and stop. Do not skip the field, do not invent IDs. - A recurring schedule was requested but no schedule details were provided. Don't guess. Ask once for
start_time,end_time, anddays_of_week, then chain tozia-manage-time-interval. - An action was requested that doesn't exist on this rule type. Valid actions are exactly:
ALLOW,BLOCK,CAUTION,ISOLATE. Anything else (e.g.DECRYPT,INSPECT,BYPASS,BLOCK_DROP) belongs to other rule types and is a hard stop here. ISOLATEwas requested without Browser Isolation entitlement. ISOLATE requires a Browser Isolation subscription. If the admin asks for it on a tenant without entitlement, the API will reject the rule. Confirm the admin has the entitlement before proceeding; if unsure, suggestCAUTIONas the closest non-isolation alternative.block_override=Truewas requested withoutrule_action="BLOCK". Override only applies to BLOCK actions. Reject combinations that don't match.enforce_time_validity=Truewas requested without start/end timestamps. When validity windows are enforced,validity_start_time,validity_end_time, andvalidity_time_zone_idare required. Don't guess the dates.
Never improvise around a missing dependency — hand off or stop.
Action types (what each does)
Two kinds of "time" on this rule type
URL Filtering exposes two different time controls — they solve different problems:
-
time_windows— recurring schedule. Attach one or more Time Interval IDs to enforce the rule on a recurring time-of-day / day-of-week pattern (e.g. "block social media 09:00-17:00 Mon-Fri"). Usezia-manage-time-intervalto find or create the interval. Idempotent on name. -
enforce_time_validity+validity_start_time/validity_end_time/validity_time_zone_id— one-shot date range. A non-recurring window during which the rule is active (e.g. "this exception is valid from Mar 1 to Mar 15 only"). Outside the window, the rule has no effect.
The two are independent and can be combined (e.g. "valid from Mar 1 to Mar 31, and only during business hours within that window"). If the admin's request implies one or the other, pick the right field — don't conflate them. If the admin says "between 9am and 5pm Mon-Fri" → that's time_windows. If they say "until end of March" → that's enforce_time_validity.
Workflow
Step 1: Gather requirements from the admin
Required:
- Rule name
- Action — one of
ALLOW,BLOCK,CAUTION,ISOLATE
At least one matching criterion (otherwise the rule is too broad to be useful):
- URL categories (most common scope on this rule type)
- Protocols (e.g.
["HTTP_RULE", "HTTPS_RULE"]) - Request methods (
GET,POST,CONNECT, etc.) - User agent types (
CHROME,FIREFOX, etc.) - Users / groups / departments
- Locations / location groups
- Devices / device groups / device trust levels
- A time-of-day window (
time_windows) and/or a one-shot validity range (enforce_time_validity)
Optional:
- Description, rank (1-7), order (defaults to bottom)
block_override=Trueplusoverride_users/override_groups(BLOCK action only — lets specified users override)end_user_notification_url— custom block-page URLsize_quota,time_quota— bandwidth / time budgets per sessionciparule=True— flags the rule as a CIPA-compliance rule
Step 2: Resolve every named resource (read-before-write)
Shared rule targets — delegate to zia-look-up-rule-targets. For every user, group, department, location, location group, URL category, device, device group, workload group, label, or time interval the admin named, follow zia-look-up-rule-targets to get the IDs (or canonical UPPER_SNAKE strings, for url_categories — URL Filtering takes the string form, not numeric IDs). Stop and report if any lookup is empty — never invent IDs, never substitute. (URL Filtering accepts every shared rule-target field in that skill, including time_windows and workload_groups.)
URL-filtering-specific helpers — use here. The shared skill handles named URL categories. Use the tool below when the admin gives you a literal URL instead of a category name.
Don't skip a field that the admin named because lookup failed — the skill stops, the admin fixes the naming or creates the missing object first.
Step 3: Resolve the schedule (only if the admin asked for time-of-day scoping)
If the admin's request includes any time-of-day language ("during business hours", "after hours", "weekends only", "between 8am-5pm Mon-Fri", "block social media at work", etc.), chain to zia-manage-time-interval to find or create the Time Interval and obtain its interval_id. That ID becomes the time_windows=[<id>] value on the URL Filtering rule.
If the admin asked for a one-shot validity range ("only valid until April 30", "from Mar 1 to Mar 15"), that goes into enforce_time_validity=True plus validity_start_time / validity_end_time / validity_time_zone_id — not into time_windows.
If the admin did not mention a schedule at all, leave time_windows and enforce_time_validity unset. Don't invent a default.
Do not call zia_activate_configuration() from within zia-manage-time-interval when chaining — defer activation to the end of this skill so a single activation flushes both the new Time Interval and the new URL Filtering rule.
Step 4: Build the payload
Map admin language to canonical fields:
- "block adult content" →
rule_action="BLOCK",url_categories=["OTHER_ADULT_MATERIAL", ...] - "block social media during work hours" →
rule_action="BLOCK",url_categories=["SOCIAL_NETWORKING"],time_windows=[<business-hours-interval-id>] - "isolate risky sites for finance team" →
rule_action="ISOLATE",url_categories=[...],groups=[<finance-group-id>] - "warn users about gambling sites" →
rule_action="CAUTION",url_categories=["GAMBLING"] - "allow X but only for these users" →
rule_action="ALLOW",url_categories=[...],users=[...] - "block, but let admins override" →
rule_action="BLOCK",block_override=True,override_groups=[<admin-group-id>] - "exception valid through end of March" →
enforce_time_validity=True,validity_start_time=...,validity_end_time=...,validity_time_zone_id=... - "block by URL foo.com" → look up category via
zia_url_lookupfirst, then scope byurl_categories - "block downloads (POST/PUT only)" →
request_methods=["POST", "PUT"]
Step 5: Create the rule
Call:
Capture the returned id.
Step 6: Activate the configuration
ZIA changes are staged until activation. After every successful create, run:
Tell the admin: "URL Filtering rule created (ID <id>) and activated." If activation fails, surface the error — the rule exists but is not live.
Step 7: Echo back what was applied
Confirm in plain language:
- The rule name and action (
ALLOW/BLOCK/CAUTION/ISOLATE) - Each scoping dimension applied (one bullet per — categories, users, locations, schedule, etc.)
- The interval ID if a recurring schedule was attached, with the schedule in human form ("08:00-17:00 Mon-Fri")
- The validity window if
enforce_time_validity=True, in human form - Override config if
block_override=True - The activation status
Don't restate operand IDs or internal field names that the admin doesn't need to see.
Quick Reference
Tools used:
- Read:
zia_list_url_filtering_rules(search=...)— only on explicit admin request for ordering / duplicate checks - Read:
zia_url_lookup— when the admin gives a literal URL instead of a category name - Write:
zia_create_url_filtering_rule(name, rule_action, ...) - Activation:
zia_activate_configuration()
Schedule sub-skill:
zia-manage-time-interval— chain whenever the admin's request mentions recurring time-of-day or day-of-week. Not used forenforce_time_validity(that's a one-shot date range, not an interval).
Related ID-resolution tools (one call per resource, exact name):
zia_list_url_categories,zia_list_user_groups,zia_list_user_departments,zia_list_users,zia_list_locations,zia_list_rule_labels
Related skills
zia-manage-time-interval— find-or-create helper for recurring schedule scoping (see Step 3).zia-investigate-url-category— read-only audit of how a URL category is referenced across rules. Use before creating a new rule when the admin wants to understand existing coverage.zia-look-up-cloud-app-name— only relevant if the admin's "URL category" request is actually a cloud-application policy decision; URL Filtering does not match on cloud-app names directly.
Different ZIA rule types — do not chain through this skill:
zia-create-ssl-inspection-rule— SSL Inspection is a separate resource type and does NOT supporttime_windows. If the admin wants time-of-day enforcement on SSL behaviour, the schedule typically belongs on the URL Filtering layer instead.zia-create-firewall-filtering-rule— Cloud Firewall is L3/L4 (IPs, ports, network apps), not URL-based. If the admin's request is about hostnames or URL categories, this skill is the right one.- DLP / Sandbox / Cloud App Control — also separate resource types.
Typical chain when a recurring schedule is requested:
Don't pre-list rules before creating. Skip zia_list_url_filtering_rules unless the admin explicitly asks about ordering or wants to inspect existing rules — direct create + activate is the default flow.

