Website • Documentation • Pricing
Discover, Govern, and Secure APIs, Agents, and AI Across Any Cloud, Gateway or Technology.
A native C++ IIS agent for Windows Server 2022 / 2025 that passively monitors JSON API traffic and sends data to Treblle. Zero impact on API availability or latency.
IIS Worker Process (w3wp.exe)
└── TreblleAgent.dll
├── OnBeginRequest → route check → capture request headers + body
├── OnSendResponse → capture response headers + body chunks
└── OnEndRequest → build JSON payload → push to background queue
│
└── Background thread
└── WinHTTP HTTPS POST → ingress.treblle.com
- Zero blocking: The IIS request thread only pushes a string to an in-memory queue. All network I/O happens on a dedicated background thread.
- Bounded memory: The queue holds at most 5,000 pending payloads. If it fills up, the oldest entry is dropped rather than blocking.
- No dependencies: The agent uses only Windows built-in APIs (WinHTTP, Windows SDK). No VC++ Redistributable or third-party packages are required.
- Static CRT: The agent links the C runtime statically (
/MT) so it works on any Windows Server without additional installs.
| Requirement | Version |
|---|---|
| Windows Server | 2022 or 2025 |
| IIS | 10.0 |
| Architecture | x64 only |
| Privileges | Local Administrator (install only) |
| Visual Studio (to build) | 2022 with "Desktop development with C++" |
| Windows SDK (to build) | 10.0 |
Open TreblleAgent.sln in Visual Studio 2022, select Release | x64, and build. The output is:
x64\Release\TreblleAgent.dll
Alternatively, build from the command line:
msbuild TreblleAgent.sln /p:Configuration=Release /p:Platform=x64Pre-built release: Download
TreblleAgent.dllfrom the Releases page and skip this step.
Downloaded from Releases? Windows marks files downloaded from the internet as blocked and IIS may refuse to load them. Before running the installer, unblock the DLL:
Unblock-File -Path "TreblleAgent.dll"Alternatively: right-click the file → Properties → tick Unblock → OK.
Copy TreblleAgent.dll into the installer\ directory (or build in place), then run:
# Right-click PowerShell → Run as Administrator
cd path\to\treblle-iis\installer
.\install.ps1Script blocked? If PowerShell refuses to run with "running scripts is disabled on this system", allow scripts for the current session and retry:
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process .\install.ps1The
-Scope Processflag applies only to the current window and reverts when the session closes — no permanent system change is made.
The installer will:
- Copy
TreblleAgent.dlltoC:\iismodules\treblle\ - Prompt you for your API Key, SDK Token, and optional exclusion patterns
- Write
C:\iismodules\treblle\treblle.config - Register the agent globally in IIS
- Restart IIS
On some servers the new C:\iismodules\treblle\ directory does not inherit ACEs for IIS worker-process accounts, which prevents the DLL from loading. If IIS fails to start or the module never appears after installation, grant read and execute access:
# Recommended — covers every application pool via the built-in IIS_IUSRS group
icacls "C:\iismodules\treblle" /grant "IIS_IUSRS:(OI)(CI)RX" /T
# Alternative — grant a single named application pool only
icacls "C:\iismodules\treblle" /grant "IIS AppPool\DefaultAppPool:(OI)(CI)RX" /TReplace DefaultAppPool with the name of your app pool. To list all pools:
%windir%\system32\inetsrv\appcmd.exe list apppoolAfter granting permissions, restart IIS:
iisresetThe (OI)(CI) flags make the ACE inherit to all files and subdirectories. RX grants Read + Execute, which is required for Windows to load a DLL into the worker process.
# List all registered IIS modules
%windir%\system32\inetsrv\appcmd.exe list module
# Should include:
# MODULE "TreblleAgent" (image:C:\iismodules\treblle\TreblleAgent.dll)Make a request to one of your configured API endpoints and check your Treblle dashboard.
The config file lives at C:\iismodules\treblle\treblle.config. Edits take effect immediately — no IIS restart needed. The agent checks the file modification time on every request and reloads it if changed.
{
"api_key": "YOUR_TREBLLE_API_KEY",
"sdk_token": "YOUR_TREBLLE_SDK_TOKEN",
"treblle_url": "https://ingress.treblle.com",
"debug": false,
"disabled": false,
"exclude_routes": [
{ "host": "internal.yourdomain.com" },
{ "host": "api.yourdomain.com", "path": "/health" },
{ "host": "api.yourdomain.com", "path": "/metrics" }
],
"masked_keywords": [
"password", "pwd", "secret",
"password_confirmation", "passwordConfirmation",
"cc", "card_number", "cardNumber", "ccv",
"credit_score", "creditScore", "ssn"
]
}| Field | Type | Default | Description |
|---|---|---|---|
api_key |
string | Required. Your Treblle API key. | |
sdk_token |
string | Required. Your Treblle SDK token. | |
treblle_url |
string | https://ingress.treblle.com |
Treblle ingress endpoint. Override only if directed by Treblle support. |
debug |
bool | false |
When true, errors are written to the Windows Application Event Log (source: Treblle). Leave false in production. |
disabled |
bool | false |
When true, the agent stops monitoring entirely. Takes effect immediately — no IIS restart needed. |
exclude_routes |
array | [] |
List of route objects to exclude from monitoring. Empty = monitor all JSON API traffic. |
masked_keywords |
array | (see below) | List of field names whose values are redacted before sending to Treblle. Omit to use the built-in defaults. Set to [] to disable masking entirely. |
Each object in exclude_routes:
| Field | Type | Required | Description |
|---|---|---|---|
host |
string | Yes | Hostname to exclude (case-insensitive). Must match the HTTP Host header, excluding port. |
path |
string | No | URL path prefix to exclude (case-insensitive). If omitted, the entire host is excluded. |
The agent monitors all JSON API traffic by default. Use exclude_routes to opt specific hosts or paths out.
A request is tracked unless:
- Its
Hostheader matches an entry'shostfield, and - Its URL path starts with the entry's
pathprefix (if specified)
All non-JSON responses (HTML, CSS, JS, images) are automatically ignored — no configuration needed for those.
A request is tracked only when:
- The response
Content-Typecontainsapplication/json - The HTTP method is one of:
GET POST PUT PATCH DELETE HEAD OPTIONS - It does not match any
exclude_routesentry
Common scenarios:
// Exclude an entire internal host
{ "host": "internal.yourdomain.com" }
// Exclude health/metrics endpoints on a specific host
{ "host": "api.yourdomain.com", "path": "/health" },
{ "host": "api.yourdomain.com", "path": "/metrics" }
// Exclude a legacy API version
{ "host": "api.yourdomain.com", "path": "/v1" }If exclude_routes is omitted or empty, all JSON API traffic across all hosts is monitored.
The agent redacts the values of fields whose names match masked_keywords before any data leaves the server. Masking is applied to:
- Request body (JSON)
- Response body (JSON)
- Request headers
- Response headers
Each character of a matched value is replaced with * so the length is preserved:
"password": "hunter2" → "password": "*******"
"cc": "4111111111111111" → "cc": "****************"
The following fields are masked automatically when masked_keywords is omitted from the config:
password, pwd, secret, password_confirmation, passwordConfirmation, cc, card_number, cardNumber, ccv, credit_score, creditScore, ssn
Add or remove keywords by specifying your own list. The list replaces the defaults entirely, so include any defaults you want to keep:
"masked_keywords": [
"password", "pwd", "secret",
"password_confirmation", "passwordConfirmation",
"cc", "card_number", "cardNumber", "ccv",
"credit_score", "creditScore", "ssn",
"api_token", "access_token", "private_key"
]To disable masking completely:
"masked_keywords": []- Build or download the new
TreblleAgent.dll - Run the installer again — it handles re-registration automatically:
The installer removes the old agent registration and adds the new one.
.\installer\install.ps1
Alternatively, for a manual update:
iisreset /stop
Copy-Item new\TreblleAgent.dll C:\iismodules\treblle\TreblleAgent.dll
iisreset /startConfig changes never require a restart — just edit treblle.config and the next request picks up the changes.
Open a Developer PowerShell for VS 2022 (or any terminal with the VS environment loaded) and run from the repo root:
# Configure (one-time, or after adding new test files)
cmake -S tests -B build/tests -G "Visual Studio 17 2022" -A x64
# Build
cmake --build build/tests --config Release
# Run all tests
ctest --test-dir build/tests -C Release --output-on-failureTo run a specific suite or test, use the test binary directly:
# All tests with verbose output
build\tests\Release\TreblleTests.exe
# One suite
build\tests\Release\TreblleTests.exe --gtest_filter=DataMasker.*
# One specific test
build\tests\Release\TreblleTests.exe --gtest_filter=DataMasker.SamplePayload_MaskedField
# List all available tests
build\tests\Release\TreblleTests.exe --gtest_list_tests| Suite | What it covers |
|---|---|
DataMasker |
MaskJson — string/number/object/boolean masking, nesting, case-insensitivity, 500 KB size limit; MaskHeaders — header value redaction |
Utils |
JsonEscape, ToLower, StartsWithCI, ParseQueryPath, ParseQueryString, ComputeHostId |
Config |
JSON parsing of all fields, default values, exclude_routes array, masked_keywords array, IsExcluded with host-only and host+path rules |
AsyncQueue |
FIFO ordering, empty-queue timeout, shutdown signalling, 5 000-item drop-oldest limit, concurrent push/pop |
BodyCapture |
IsLikelyJson — object, array, whitespace trimming, plain text, XML, mismatched braces |
PayloadBuilder |
Full JSON structure against the sample payload, api_key/sdk_token placement, masking applied before assembly, truncated-body error object |
Google Test is fetched automatically by CMake (FetchContent) — no manual install needed. An internet connection is required on the first build; subsequent builds use the cached download.
.\installer\uninstall.ps1This removes the agent from IIS and optionally deletes C:\iismodules\treblle\ including your treblle.config.
To diagnose issues, set "debug": true in treblle.config. The agent will write errors to the Windows Application Event Log under source Treblle.
Open Event Viewer → Windows Logs → Application, filter by source Treblle.
Common log entries:
Treblle: WinHttpCrackUrl failed for URL: ...— checktreblle_urlformatTreblle: WinHttpSendRequest failed (0x...)— network connectivity issueTreblle: ingress returned HTTP 401— checkapi_keyandsdk_token
Always set debug back to false in production — Event Log writes have a small overhead.
Agent doesn't appear in appcmd list module
- Confirm you ran the installer as Administrator
- Check
C:\Windows\System32\inetsrv\forappcmd.exe - Look in Event Viewer → Windows Logs → System for IIS startup errors
Agent is registered but no data appears in Treblle
- Confirm the API returns
Content-Type: application/jsonin the response - Check that the host/path is not matched by an
exclude_routesentry - Enable
debug: trueand check the Application Event Log - Verify network access from the server to
ingress.treblle.com:443
IIS fails to start after installing the agent
- Confirm the DLL was compiled for x64 (not x86)
- Confirm the DLL path in
C:\Windows\System32\inetsrv\config\applicationHost.configmatches the actual file location - Temporarily rename
TreblleAgent.dlland restart IIS to confirm it is the cause
Request bodies are empty in Treblle
- Confirm the request includes
Content-Type: application/json - Bodies larger than 2 MB are intentionally not captured
MIT — see LICENSE.