ICAP and third-party gateways
Connect an existing secure web gateway to the CID222 inspection service — the wire contract, how the listener decides who may call it, and how to prove the path works.
- Version: 0.4
- Feature: icap
- Role: admin_user
- Type: task
Where the customer already runs a secure web gateway, that product is already the endpoint of the employee's encrypted session and its certificate authority is already on every managed device. CID222 becomes the scanner it calls. You open the listener, add one service entry in the gateway's console, scope it to the provider hostnames, decide who may call in, and prove a detection fires.
What do I need?
- Licence
- Any
- Role
admin_user
Prerequisites
- The appliance has completed the first-boot setup wizard and you can sign in to the dashboard.
- The customer's secure web gateway already decrypts outbound sessions with a certificate authority its endpoints trust.
- A network path exists from the gateway to the appliance on TCP 1344, or from the gateway's cloud to the appliance over HTTPS.
- You know the gateway's source addresses, because the listener admits callers by address alone.
- Saving the appliance-wide inspection policy requires the superadmin account.
What the gateway talks to
CID222 exposes two ingress shapes for the same pipeline. Which one you use is decided by the gateway product, not by CID222.
| ICAP listener | HTTP inspection endpoint | |
|---|---|---|
| Address | TCP 1344 on the appliance | POST /inspect/v1/:hostname over the appliance's HTTPS front |
| Protocol | Internet Content Adaptation Protocol, RFC 3507 | JSON request, JSON response |
| Typical caller | On-premises gateways: FortiProxy, Forcepoint, Symantec ProxySG, Cisco WSA | Cloud-delivered gateways: Netskope, Prisma Access, and Zscaler where it prefers a callout |
| Authentication | None available — see below | A gateway API key as a bearer token, optionally a client certificate |
The listener answers three methods. An OPTIONS request returns the service's capabilities:
Four properties of that answer decide how a gateway must be configured.
- No preview is advertised, deliberately. A gateway therefore sends the whole body up front rather than withholding it pending a continue that CID222 does not send. Advertising a preview deadlocks strict clients into a fail-closed error.
- A bare 204 is returned for a clean request when the gateway offered
Allow: 204, with no encapsulated section at all. Some gateways reject a 204 that carries one. - The reply echoes the section matching the method — request sections for a request modification, response sections for a response modification. A mismatch makes strict gateways fail closed.
- The capability answer is cached for 60 seconds, so a change on the appliance is picked up within a minute.
CID222 does not route on the ICAP service path. Whatever path your gateway's console requires —
/inspect, /reqmod or another — reaches the same service.
The three verdicts are the same on both ingress shapes: allow the request unchanged, forward a redacted body in place of the original, or refuse it. On refusal CID222 returns a 403 page, and the gateway serves it or substitutes its own template.
Warning
A single buffered message is capped at 64 MB. No preview is advertised, so the gateway sends every body in full — without that ceiling an unauthenticated peer would decide how much memory the appliance holds.
Who may call the listener
The ICAP listener cannot authenticate its peer. None of the gateway products CID222 integrates with exposes a credential or a custom-header field on its inspection profile, so there is nothing for a peer to send. Admission is by source address alone, and an admitted peer is believed down to the identity it claims: the listener takes its word for the authenticated user on every request. Treat network placement as the real control, and the address list as a second lock.
| Allowed ICAP peer IPs / CIDRs | Who may connect |
|---|---|
| Empty | Any address in private space — the historical default |
| Set | Exactly the listed addresses, and nothing else |
A list replaces the private-range default; it does not extend it. The field has to do two opposite jobs: widen admission for a cloud-delivered gateway dialling from public egress ranges, and narrow it on a customer network where private space admits every host in the building. So the moment it holds one entry, every other caller is refused — including on-premises gateways that worked a minute earlier, and any probe you run from the appliance host itself. List every peer.
Other behaviour worth knowing before you set it:
- Entries may be bare addresses, CIDR ranges or IPv6 literals. An entry that could never match — a hostname, a typo, an impossible prefix length — is rejected when you save, because a list of typos would refuse every peer and take inspection offline.
- The list is cached and refreshed every five minutes, and immediately when an administrator saves it. A failed refresh keeps the previous list rather than changing who may connect.
- The check runs when a connection is opened. Gateways hold ICAP connections open and reuse them, so tightening the list does not interrupt traffic already flowing. Force the gateway to reconnect and read the log rather than assuming the new list is in force.
- A refused peer gets a closed socket with no ICAP response, and the appliance logs a warning naming the peer and the rule that refused it.
- The list does not gate the HTTP inspection endpoint, the inline proxy or the browser extension.
Danger
Upgrading to this release clears any previously stored value of the peer list and the client subject name, and records the old values in the event log. Both fields were stored and read by nothing before, so applying them for the first time unattended during an upgrade could have refused every caller. Re-apply them deliberately, on a running system, where you can see the effect.
Connect the gateway
Expose the listener to the gateway
The listener binds inside the container on every interface, but the appliance publishes the
port on ICAP_PUBLISH, which defaults to 127.0.0.1. A gateway elsewhere on the network
cannot reach that. Set ICAP_PUBLISH=0.0.0.0 in the appliance's environment file and restart
the gateway service, then firewall TCP 1344 to the addresses that must reach it.
ICAP_ENABLED is true by default; the appliance log line ICAP listener bound to 0.0.0.0:1344
confirms the listener started.
Confirm the path from the gateway
From a host on the gateway's own network, check the port answers:
The connection succeeds. If it does not, fix routing and firewalling before touching the gateway console — every later symptom looks the same from there.
Add CID222 as an inspection service
In the gateway console, add an external inspection service pointing at
icap://<appliance-ip>:1344/inspect, with request modification enabled.
The exact menu, field names and defaults differ per product; follow the page for yours in this section. Leave response modification off for a first deployment — it scans the model's reply, which is noisier and adds latency.
Scope it to the provider hostnames
Bind the service to a category or address group holding only the provider hostnames, and leave everything else to a policy that does not decrypt.
Include the hosts that carry uploaded file bytes, not only the conversation hosts. A policy listing only the chat domains inspects the metadata and sends the file itself straight to storage uninspected.
Decide who may call in
Select Detection & Filtering → Browser Inspection, and in Policy configuration set Allowed ICAP peer IPs / CIDRs to every address that legitimately calls the listener. Select Save policy.
The panel reports Inspection policy updated. Leave the field empty only where the port is reachable from nothing but the gateway.
Agree what happens when inspection is slow
Set the gateway's on-failure behaviour and the appliance's Fail closed (BLOCK) on timeout to the same posture.
They must agree. A gateway that bypasses on failure while the appliance refuses on timeout gives you the worst of both: a refusal the gateway ignores.
Who the event belongs to
The gateway is the only thing that can name the person, and it does so in a header CID222 cannot verify. Resolution runs in a fixed order and the first hit wins: the gateway's authenticated-user header; a real-time directory lookup, where the user identification agent is configured; a dashboard-managed rule mapping an address range to a label; and finally the enrolled-device fleet used as an address directory. When all four miss, the event keeps its source address and shows a dash.
Usernames are normalised before use, so a domain-qualified name, a directory URI form and a user-principal name for one person collapse to one identity rather than four.
Verify
-
Ask the listener for its capabilities from a host that is allowed to connect:
The reply is
ICAP/1.0 200 OKfollowed by the capability headers shown above. A closed connection with no reply means the peer list refused this host. -
From a workstation behind the gateway, open a provider site and send a prompt containing a recognisable test value. The provider receives it masked, or the browser shows a block page.
-
Select Detection & Filtering → All Detections and filter to browser traffic. The attempt appears within seconds as
MESSAGE_MASKEDorMESSAGE_BLOCKED, carrying the hostname, the source address, the verdict and — where the gateway forwards it — the username. -
On Browser Inspection, the gateway appears in the connected-sources table with a recent timestamp. That table is the fastest way to tell "the gateway is not calling" from "the gateway is calling and nothing matched".
If it fails
- The port test fails → the listener is not published (
ICAP_PUBLISH), a firewall is in the way, orICAP_ENABLEDwas turned off. - The gateway reports the service unreachable and the appliance logs a refused connection naming the peer → the peer list does not include this gateway. Remember it replaces the private-range default.
- Every caller arrives with the same address and the list admits all or none → Every ICAP caller arrives as the same docker bridge address.
- The gateway reports invalid headers or fails closed on every request → the profile advertises a preview, or expects the encapsulated sections of the other method. Capture the exchange on 1344 and send it with the gateway's own trace.
- Prompts are inspected but uploads are not → the host carrying the file bytes is out of scope, or the profile's method set excludes the upload method.
- Events arrive with no username → the gateway is not forwarding its authenticated-user header. Enable it in the service's advanced settings, or attribute by address instead.
Next steps
- FortiProxy and FortiGate — the one integration validated end to end in the laboratory, with an acceptance test plan.
- Interception topologies — what this deployment cannot see.
- Deploy the inline proxy — the alternative where there is no gateway to connect.
Last updated on