On-prem SIEM relay
PermitUSB's cloud cannot reach a SIEM appliance sitting inside your network, so the relay runs on a box on your LAN, pulls your device and tamper events outbound over HTTPS with an API key, and forwards each one to your SIEM (NeQter, rsyslog, syslog-ng, QRadar, ...) as a CEF record over syslog. Nothing inbound from the internet is required.
If your SIEM already collects Windows event logs from your endpoints, you may not need the relay at all - the agent also writes the same CEF records to each endpoint's Windows Application event log under the source PermitUSB. The relay is for centralized pull when you would rather not collect endpoint event logs, and its records are richer (they carry the cloud-side public IP and canonical rule names).
Prerequisites
- An always-on Windows box on your LAN with Windows PowerShell 5.1 or later.
- Outbound HTTPS from that box to
siem.permitusb.com. - A PermitUSB API key with the
events:readscope - create one on the API keys page (it is shown once; copy it then).
1. Download
From the API keys page, download PermitUSB-SIEM-Relay.ps1 and the sample relay-config.json.sample onto the relay box (for example into C:\PermitUSB\).
The relay is EV code-signed (verified publisher: JJMK Studios, LLC), so Windows runs it under a RemoteSigned or AllSigned execution policy without the Mark-of-the-Web block - no Unblock-File step needed. You can confirm the signature before trusting it:
Get-AuthenticodeSignature C:\PermitUSB\PermitUSB-SIEM-Relay.ps1It is an ASCII-only PowerShell script - open it in any editor to review exactly what it does before you run it.
2. Configure
Copy the sample to relay-config.json beside the script and fill it in:
{
"ApiBaseUrl": "https://siem.permitusb.com",
"ApiKey": "puk_live_...",
"SyslogHost": "10.0.0.50",
"SyslogPort": 514,
"SyslogProtocol": "udp",
"PollIntervalSeconds": 30
}- ApiBaseUrl - your PermitUSB base URL.
- ApiKey - the
events:readkey. To keep the secret off disk, omit it here and set thePERMITUSB_API_KEYenvironment variable instead (it wins over the file). - SyslogHost / SyslogPort - your SIEM's syslog listener.
- SyslogProtocol -
udp,tcp, ortls(TLS validates the server against the machine trust store; import an internal CA there rather than disabling validation). - Optional:
PollIntervalSeconds(default 30),BatchSize(default 200),StatePath(cursor file; defaults beside the script).
3. Test it
Run a single batch and exit, to confirm connectivity and that records land in your SIEM:
powershell -NoProfile -ExecutionPolicy Bypass -File .\PermitUSB-SIEM-Relay.ps1 -OnceA bad or revoked key exits with an authentication error; a syslog outage backs off and does not advance the cursor, so nothing is lost.
To see exactly what the relay would forward before you have a SIEM listening, add -Preview: it prints each CEF record to the console and sends nothing (and does not save the cursor, so it never disturbs a real relay). SyslogHost / SyslogPort / SyslogProtocol are not required for a preview.
powershell -NoProfile -ExecutionPolicy Bypass -File .\PermitUSB-SIEM-Relay.ps1 -Preview -OnceIf it prints nothing, your cursor is already caught up - set SinceIso in the config, or point StatePath at a throwaway file, to replay history.
4. Run it continuously
Without -Once the relay loops forever. Register it as a Scheduled Task that runs at startup as SYSTEM and restarts on failure:
schtasks /Create /TN "PermitUSB SIEM Relay" /SC ONSTART /RU SYSTEM /RL HIGHEST ^
/TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\PermitUSB\PermitUSB-SIEM-Relay.ps1 -ConfigPath C:\PermitUSB\relay-config.json"The -ExecutionPolicy Bypass argument applies only to that invocation and does not change your system-wide policy. The relay keeps a cursor in its state file, so a restart resumes where it left off (delivery is at-least-once; dedupe SIEM-side on the CEF externalId, the PermitUSB event id).
Linux (systemd)
Prefer a service on a Linux box to a script on Windows? Download the relay for your CPU arch from the API keys page (amd64 or arm64), unpack it, and run the installer:
tar xzf relay-linux-arm64.tar.gz
sudo bash install.shThat installs a static binary to /usr/local/bin, an unprivileged permitusb-relay service account, and a systemd unit. Put your API key in /etc/permitusb-relay/relay.env (PERMITUSB_API_KEY=puk_live_...) and the syslog destination in /etc/permitusb-relay/config.json, then dry-run and enable:
# preview (reads the env as root; prints CEF, sends nothing)
sudo bash -c 'set -a; . /etc/permitusb-relay/relay.env; \
permitusb-siem-relay -config /etc/permitusb-relay/config.json -preview -once'
sudo systemctl enable --now permitusb-siem-relay
journalctl -u permitusb-siem-relay -fSame config shape and CEF output as the Windows relay; systemd handles start-at-boot and restart-on-failure, and there's no TLS setup to do.
What gets forwarded
Every device-control and security event, as CEF, with stable signature IDs you can alert on:
- 1001 / 1002 - device connected / disconnected (Information).
- 2001-2004 - the enforcement verdict: allowed (2001), blocked (2002, Warning), read-only (2003), audited (2004).
- 3001 - tamper attempt (Warning); 3002 / 3003 / 3004 - suspected / confirmed / user-allowed HID injection.
- 4001 - policy stale on an endpoint (Warning); 4002 - kernel enforcement unavailable (Error).
The relay drains two feeds automatically (device events and tamper / policy events) - no extra configuration. If your SIEM applies a severity floor, note that routine allow / connect events are below Warning; blocks, tamper, and HID-injection events are Warning or above and survive a Warning-and-above filter.
Updating
When a new relay version ships, download the script again and replace the copy on the relay box - no Unblock-Fileneeded now that it's signed. Your relay-config.json and state file are untouched.