| name | halo-policy-config |
| description | Configure Glasswall Halo post-setup — create or modify content management policies (engine, ICAP, XML validation) and set up storage monitors for SharePoint, OneDrive, and Outlook. Use whenever the user asks to change Halo policy, ICAP profile, XML validation, or to attach storage monitors to drives, sites, or mailboxes. |
Halo Policy & Storage-Monitor Configuration
Glasswall Halo is a file security platform — it protects files from file-borne threats by reconstructing them into a known-clean form rather than scanning them for known signatures. Content Disarm and Reconstruction (CDR) is its primary protection capability. Halo runs as a deployable service exposing administrative APIs for policy management, ICAP profile management, XML validation policy management, and cloud-storage monitoring (SharePoint, OneDrive, Outlook).
Use this skill when a user wants to change settings on a running Halo deployment by hitting its administrative APIs. This covers four areas:
- Engine policies (used by sync/async CDR APIs and storage monitors)
- ICAP profiles (used by Halo's ICAP server)
- XML validation policies (used by the XML validation API)
- Storage monitors (SharePoint, OneDrive, Outlook → policy bindings)
You execute API calls on the user's behalf. You do not write integration code — for that, use the halo-workflow-integration skill instead.
Before you act
Never execute a POST, PUT, PATCH, DELETE, reset, or bulk-monitor operation against Halo without explicit user confirmation in the current turn. Show the user the method, URL, body (and affected-resource count for bulk operations), and wait for explicit agreement before sending. Halo policy and storage-monitor changes affect production processing — be deliberate.
You need three things from the user. Ask for any that are missing:
- Halo base URL — e.g.
https://halo.customer.example.com. There is no fixed Glasswall-hosted URL; every Halo deployment has its own.
- Auth credentials — either:
- A Bearer token (preferred):
Authorization: Bearer <token>
- Basic auth:
Authorization: Basic <base64(user:pass)>
- What they want to change, in their own words.
Never invent a base URL or hardcode credentials. If the user has set environment variables (HALO_BASE_URL, HALO_TOKEN), use those.
If those env vars aren't already set, offer to write them to a .env file (CWD or .claude/.env) — the wrappers auto-load it on startup, no shell export needed each session. The file is gitignored.
Workflow
- Identify the area. Map the user's request to one of: engine policy, ICAP profile, XML policy, storage monitor.
- Read the relevant reference file before constructing requests — these contain the exact route, body shape, enum values, and quirks you must not guess at.
- Discover before you mutate. Always run a discovery call first (
GET /api/v1/schemas, GET /api/v1/policies, GET .../monitors, etc.). This confirms the deployment supports what you think it does, and gives you the current state.
- Construct the call. Prefer
Invoke-RestMethod on PowerShell (Windows) or curl on POSIX shells, unless the user has asked for code in a specific language. For multi-step or templated work, use the helper scripts in scripts/.
- Show before you send mutating requests. For any
POST, PUT, PATCH, DELETE, print the URL, method, headers (token redacted), and body, and confirm with the user before executing. Halo policy changes affect production processing — be deliberate.
- Mutating the
default policy is a louder confirmation. If the user asks to update, delete, or reset the policy literally named default, the wrappers will permit it — but the agent must not. Before sending, name the consequence explicitly: every CDR consumer that doesn't pass a policyName= query parameter currently falls through to this policy, so a reset takes everyone with it. Require the user to confirm with the literal word "default" in their response. If they hesitate or rephrase, treat that as a "no". This guard lives here — not in the wrappers — so that a user who genuinely wants the action can have it.
- Verify. After a write, do a
GET on the resource and show the user what's now live.
Reference files (read on demand, not all at once)
| When the user mentions… | Read |
|---|
| Auth, token, login, 401 | references/auth.md |
| Policy, sanitize, allow/disallow content, PDF/Word/Excel macros, embedded files, hyperlinks | references/engine-policy.md and references/content-management-flags.md |
| ICAP, profile, MIME-type rules, processing rules, block/process/bypass | references/icap-profile.md |
| XML validation, XSL, XInclude, blocked tags, encodings, doctype, CDATA | references/xml-validation-policy.md |
| SharePoint, OneDrive, Outlook, mailbox, monitor, drive, tenant | references/storage-monitors.md |
| Routes don't match docs / 404 on a known endpoint | references/api-routing.md |
Examples (read for templates, not as canon)
examples/ contains working-shape JSON bodies you can adapt:
engine-policy-strict.json — block macros, embedded files, hyperlinks
engine-policy-balanced.json — sanitise everything dangerous, allow benign content
icap-profile-default.json — process Office formats, bypass plain text
xml-policy-default.json — Halo's default XML rules
These are starting points. Adjust per the user's stated risk appetite.
Helper scripts
For repetitive operations, prefer the scripts under scripts/. Two tools are provided, each shipped in four interchangeable runtimes — pick whichever is available:
apply_policy — create/update/get/delete/reset a policy from a JSON file. Handles the dual-routing quirk (schemas-prefixed vs. flat), URL-encodes policy names. Pass --dry-run to preview the request before sending. Wrappers will perform mutations on the default policy if asked — the louder confirmation lives in this SKILL.md's workflow (step 6), not in the script.
python scripts/apply_policy.py <schema> <policyName> [bodyFile] [--mode MODE] [--dry-run]
bash scripts/apply_policy.sh <schema> <policyName> [bodyFile] [--mode MODE] [--dry-run]
node scripts/apply_policy.js <schema> <policyName> [bodyFile] [--mode MODE] [--dry-run]
dotnet run --project scripts/ApplyPolicy.csproj -- <schema> <policyName> [bodyFile] [--mode MODE] [--dry-run]
create_storage_monitors — bulk-create monitors across SharePoint/OneDrive/Outlook from a CSV. Supports --dry-run.
python scripts/create_storage_monitors.py <csvFile> [--dry-run]
bash scripts/create_storage_monitors.sh <csvFile> [--dry-run]
node scripts/create_storage_monitors.js <csvFile> [--dry-run]
dotnet run --project scripts/CreateStorageMonitors.csproj -- <csvFile> [--dry-run]
All four runtimes read HALO_BASE_URL and HALO_TOKEN (or HALO_BASIC_AUTH) from env and accept identical positional arguments. Read each script's header comment before running.
Runtime-specific notes:
- Python (reference): needs Python 3.8+ and
requests (pip install -r scripts/requirements.txt).
- bash: needs bash 4+, curl, base64.
apply_policy.sh uses jq when available for pretty output; create_storage_monitors.sh requires jq outright (for safe JSON construction).
- Node: needs Node 18+ for built-in fetch. No npm packages.
- .NET: needs .NET 8+ SDK. No NuGet packages. Each tool ships its own
.csproj.
Critical rules
- Policy names must be alphanumeric — letters and numbers only. Halo rejects hyphens, underscores, spaces, and punctuation with
400 "Policy name should only contain letters and numbers". Use financeStrict, not finance-strict.
- Mutating the policy literally named
default requires the louder confirmation from workflow step 6. It's the deployment-wide fallback used by every CDR consumer that doesn't pass a policyName= query parameter — a reset takes them all with it. The wrappers will execute the call; the guard is your job. Whether Halo itself permits the mutation is deployment-dependent and has not been verified across versions.
- Never reset a policy without confirming.
PUT .../{policyName}/reset is destructive — it overwrites every flag with schema defaults.
- Always include the policy schema name when you're unsure which API is in play. ICAP profiles and XML policies live on different routes from engine policies.
- Bulk monitor operations affect many users at once. Always show the count and a sample of affected items before executing.
When you're stuck
If a route returns 404 and the reference says it should exist, the deployment may use a different routing convention. See references/api-routing.md — try the alternate path before giving up. If still stuck, fetch the live OpenAPI/Redoc page from https://api.docs.glasswall.com/ for the relevant API; the public docs may be slightly behind or ahead of the deployment, and that diff is the lead.
Runtime requirements
Pick the helper variant whose runtime is already available — they're functionally interchangeable. In rough order of preference when more than one would work:
- Python (
apply_policy.py, create_storage_monitors.py) — Python 3.8+ with requests. The reference implementation.
- bash + curl (
apply_policy.sh, create_storage_monitors.sh) — bash 4+, curl, base64 (plus jq as noted above). Common on POSIX systems.
- Node (
apply_policy.js, create_storage_monitors.js) — Node 18+ with built-in fetch.
- .NET (
ApplyPolicy.cs + .csproj, CreateStorageMonitors.cs + .csproj) — .NET 8+ SDK.
If none of those four runtimes is available — locked-down container with no Python/bash/Node/.NET, no package install permitted, restricted network egress — construct the equivalent HTTP request manually using the relevant references/*.md file. The request shapes, headers, and response semantics are the same; only the surrounding plumbing differs.
Never ask the user to paste credentials into source files or chat. Always read them from environment variables (HALO_BASE_URL, HALO_TOKEN, HALO_BASIC_AUTH) or the host agent's secret-injection mechanism.