| name | halo-workflow-integration |
| description | Generate code that integrates Glasswall Halo APIs into an application or document-ingestion workflow. Use when a user wants to call Halo from their app — e.g. submit uploaded files for protection (CDR) before storing, validate XML against a Halo policy, or build an asynchronous processing pipeline. Produces Python, JavaScript, C#, curl, or any other language as requested. |
Halo Workflow Integration (API Query Builder)
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. Customers integrate Halo into their applications and document pipelines so that any file crossing a trust boundary is protected before it's stored or forwarded.
Use this skill when a user wants to integrate Halo into their own application — they're writing code that calls Halo's file-processing APIs, not changing Halo's configuration. Typical asks:
- "Add Halo CDR to my Express upload handler"
- "Write Python that submits PDFs and waits for results"
- "Show me a curl command to rebuild this file"
- "Set up an async pipeline that submits to Halo and polls"
- "Validate this XML against my company's Halo policy"
For configuring Halo itself (creating policies, setting up storage monitors), use the halo-policy-config skill instead.
What you produce
Working integration code in the user's chosen language. Default to Python or JavaScript if they don't specify. The reference docs are language-neutral — they describe the HTTP contract — so you can write the integration in any language the user asks for, including Go, Rust, Ruby, Java, PHP, C#, or Bash.
Before you write code
Ask the user (or look for in their environment) for these:
- Halo base URL —
<HALO_BASE_URL>. Every customer deployment has its own; there is no Glasswall-hosted public endpoint.
- Auth — Bearer token (preferred) or Basic credentials. See
references/auth.md.
- Sync vs async — both APIs run the same CDR engine; the choice is about how the caller handles the response, not about Halo's capabilities:
- Sync (one request, one response) when the caller can hold an HTTP connection open until processing finishes — interactive scripts, simple web handlers, anything where a person is waiting.
- Async (submit + poll) when the caller can't or shouldn't sit on a long connection — Lambda/Azure Function with timeout limits, message-driven workers, callers that want to decouple ingestion from processing.
Large-file and high-throughput cases tend to push toward async because keeping a connection open through long processing becomes impractical — that's a downstream consequence, not a Halo capability difference. See
references/sync-cdr-api.md and references/async-cdr-api.md for the full trade-off.
- Policy name — which Halo engine policy to apply. If the user doesn't know, default to
"default" and call out that they should pick a real policy in production.
- Input shape — multipart file upload, base64 in JSON, file path on disk, stream from another service?
Don't bake credentials into source files. Generate code that reads them from env vars or a secrets manager.
For testing the generated code locally, the user can drop HALO_BASE_URL / HALO_TOKEN (or HALO_BASIC_AUTH) into a .env file (CWD or .claude/.env) — the bundled halo-protect and halo-policy-config wrappers auto-load it, so the same convention works end-to-end. The file is gitignored.
Workflow
- Pick the API. Sync v3 (
/api/v3/cdr-file, /api/v3/cdr) is the default for new integrations. Async v1 (/api/v1/cdr-file-async) is right when the caller can't hold an HTTP connection open through processing — serverless functions with execution-time limits, message-queue workers, anything that decouples ingestion from processing. Both APIs use the same CDR engine. Sync v2 (/api/Rebuild/file, etc.) exists for legacy compatibility — use only if the user's code is already on it.
- Read the relevant reference. Don't guess at field names, header names, or response shapes — they're documented.
- Pick a template.
templates/ has working starting points in Python, JavaScript, and curl. Adapt rather than write from scratch.
- Wire in error handling. Halo returns specific status codes that mean different things — see
references/sync-cdr-api.md#errors. Don't write a blanket except Exception.
- Show the user the generated code, run it once if possible, and iterate based on what they hit.
Reference files
| File | What it covers |
|---|
references/auth.md | Bearer + Basic; token acquisition patterns |
references/sync-cdr-api.md | /api/v3/cdr-file, /api/v3/cdr, /api/v3/export*, /api/v3/import* — request/response/headers |
references/async-cdr-api.md | /api/v1/cdr-file-async submit + poll; status codes (200/204/206) |
references/xml-validation-api.md | /api/v1/validate-xml |
references/legacy-v2-api.md | V2 controllers (/api/Analyse, /api/Rebuild, /api/Composite, /api/FileTypeDetection) |
references/error-handling.md | Status code semantics, retry guidance, response headers |
references/language-guide.md | How to translate the HTTP contract into any language; common gotchas (multipart in fetch, base64 line-wrapping, etc.) |
Templates
Each template is runnable. They read HALO_BASE_URL and HALO_TOKEN from the environment. For deployments that use Basic auth instead of Bearer, swap the Authorization: Bearer … header construction for the Basic equivalent — see references/auth.md for the Bearer-or-Basic fallback pattern in each language.
templates/python/sync_rebuild.py — POST a file to /api/v3/cdr-file, save the rebuilt result
templates/python/async_rebuild.py — submit + poll loop with backoff
templates/python/validate_xml.py — XML validation
templates/javascript/sync_rebuild.js — Node 18+ fetch; multipart via FormData and Blob
templates/javascript/async_rebuild.js — submit + poll
templates/curl/examples.sh — bash one-liners for sync, async, validate-xml
templates/csharp/SyncRebuild.cs — minimal HttpClient example
Key design choices the agent should default to
These match how Halo is built and tested. Override only with a clear reason.
- Use sync v3 for new code unless the user specifies otherwise.
- Send files as multipart (
/cdr-file) when the input is binary on disk. Use base64 (/cdr) only when JSON-only transport is required (e.g. webhook gateways that strip multipart).
- Send the policy via
?policyName=... in the query string, not in the body. Halo accepts inline policy bodies but it's verbose and the policyName form is the supported customer-facing pattern.
- Read response headers, not just the body.
x-processing-status, x-filetype (no hyphen between File and type), x-file-id, x-transaction-id are the real signals — the body is the rebuilt bytes.
- Honour 206 Partial Content as a partial-success — Halo rebuilt some content but flagged issues. Do not treat as failure unless the user wants strict mode.
- Set a session ID via
x-session-id for traceability. Most customer logs and Halo's own processing logs key on this. Generate UUIDs unless the user has their own correlation ID.
- Stream large files — don't load multi-GB files into memory. Use chunked reads/streams. Halo accepts up to 3 GB on import endpoints.
Things to flag to the user
- Halo's deployment URL is not public — they need to get their own base URL from their Halo deployment or their Glasswall contact.
- Auth tokens expire — long-running services need a token-refresh loop or per-request auth fetch.
- Rate limits exist (429); production code needs back-off.
- Halo is per-deployment; customers in different regions may have different versions of the API. If a route 404s, check what version they're on (sync v2 vs v3).
- File-type detection (
/api/v3/cdr-file will tell you in x-filetype) is sometimes useful as a free first step — you can skip the rebuild entirely for types you don't accept.
Runtime requirements
This skill produces code, not API calls — the runtime constraints belong to whatever the user is building, not the skill itself. The bundled templates assume reasonable defaults (requests for Python, native fetch for Node 18+, HttpClient for .NET 8+, GNU curl); when the user's stack differs, fall back to the language-neutral guidance in references/language-guide.md and references/sync-cdr-api.md — the HTTP contract is the contract, and any language that can issue HTTPS requests with a multipart/form-data body or a JSON body can call Halo.
Never put credentials in generated source. Generate code that reads them from environment variables (HALO_BASE_URL, HALO_TOKEN, HALO_BASIC_AUTH) or the deployment's secrets manager.