Monocle Assessment
Monocle can be used exclusively as a passive means of gathering statistics about your users' connections, requiring no backend integration.
In addition, you can also choose to implement real-time actions based on the contents of the Monocle Assessment on your backend. Here are a couple of scenarios:
- Blocking risky form submissions from anonymizing VPNs
- Logging the anonymizing status of newly created accounts
- Reducing user friction for known-good Zero Trust networks like ZScaler and Netskope
- Flagging in your database logins and account creation from residential proxies
By default, the Monocle Assessment appends itself as a hidden field (named monocle) to any <form> elements present on the page with a class of monocle-enriched.
For example:
<form class="monocle-enriched" action="/submit" method="POST"><input type="text" name="email" /><input type="password" name="password" /><button type="submit">Submit</button></form>
This allows the backend server to log and/or take action using the Monocle Assessment.
Because the Monocle Assessment is encrypted (to prevent viewing and tampering by the client), it must first be decrypted in one of two ways:
- Using your Monocle Secret Key to authenticate with the Monocle Decryption API.
- Using your Monocle Private Key to decrypt the Monocle Assessment directly on the backend.
Either method will provide you with the decrypted Monocle Assessment, whose schema is outlined in the section below.
The Monocle Assessment object
Attributes
Flag indicating whether or not this connection was detected to be originating from a VPN
Flag indicating whether or not this connection was detected to be originating from a proxy of any type (datacenter or residential)
Flag indicating whether or not this connection was detected to be originating from IP space known to host anonymizing infrastructure - this is a modifier to vpn and proxied and will never be true by itself
Flag indicating whether or not this connection was detected to be originating from a remote desktop service
Flag indicating whether or not this connection was detected to be originating from a datacenter
Country code of the source IP address (ISO 3166 ALPHA-2)
Source IPv4 address as seen by Monocle
Source IPv6 address as seen by Monocle
ISO 8601 datetime format of the Monocle Assessment generation
Flag indicating if the Monocle process completed fully; a false value is indicative of a higher chance of false positives/negatives
Unique Monocle-generated ID identifying the generated Monocle Assessment
The name of your Monocle Application
If Monocle is able to identify the service in use, it will be labeled here. This value corresponds to the service tags found here. This field is only exposed to Enterprise Monocle users.
Customer-provided data originally passed into the Monocle load. Truncated after 1024 characters.
{"vpn": true,"proxied": false,"anon": true,"rdp": false,"dch": false,"cc": "US","ip": "198.51.23.210","ipv6": "2001:db8:e214:9f67:711:f03e:a141:3871","ts": "2022-10-17T14:03:19-04:00","complete": true,"id": "580f12c9-8030-4d49-b39f-35dfe560fa9e","sid": "example-sign-up-form","service": "MULLVAD_VPN","cpd": "test-cpd-value"}
Monocle Assessment Verification
Because Monocle is stateless, verifying the veracity of an incoming Monocle Assessment is the responsibility of the integrating user.
The client cannot modify the decrypted contents of the Monocle Assessment, but they could tamper with it (thereby breaking its ability to be decrypted) or replay it in subsequent requests.
Spur recommends the following methods for validating a Monocle Assessment:
- Verify that the Monocle Assessment is included (if tied to a form submission).
- Verify that the Monocle Assessment successfully decrypts, indicating it has not been modified.
- Verify that
ipmatches the IP address of the form submission request (note: see the below section for caveats of this approach). - Verify that
tsis within an acceptable range of the current datetime. We suggest ~5 minutes or a time frame commensurate with your use case. - Check the value of
complete. Under normal operation, this will betrue. Afalsevalue indicates Monocle was unable to complete its evaluation, suggesting a higher possibility of false positives or negatives.
IP Verification Caveats
Apart from replayed Assessments, there are several instances where the IP you might see in an Assessment may not exactly match the IP your backend sees.
Multiple Egress IPs Within the Same Network
In some cases, a single logical network (such as a large WiFi deployment or carrier-grade NAT environment) may route traffic through multiple egress IP addresses. These IPs often fall within the same subnet. When strict validation is applied—requiring an exact match between the request IP and the assessment IP—this can result in unnecessary false failures. Recommended handling: Instead of requiring an exact IP match, validate that the assessment IP belongs to the same subnet (e.g., /24 or /23, configurable) as the request IP. This relaxed validation still ensures network consistency while accounting for multi-egress network architectures.
Split-Tunnel or ZTNA/Routing Discrepancies Across Managed Networks
In more complex network environments—such as corporate, educational, or otherwise managed networks—traffic may be routed through different providers or appliances depending on the destination. For example, a Zero Trust Network Access (ZTNA) or similar appliance may selectively proxy outbound requests. This can result in the request originating from a completely different network or autonomous system than the assessment IP, even though the user is on a single device behind a managed gateway. Recommended handling: These scenarios often cannot be resolved through subnet-based validation. The typical solution is to prompt the user to retry the action from a different network or ensure no split-tunnel/ZTNA routing rules are interfering.
Customer-provided data
Optionally, in the event you wish to attach a custom session ID, nonce, CSRF token, etc., you may provide an arbitrary string (limited to 1024 characters) during the initial Monocle script load.
The value for this additional URL parameter called cpd (customer-provided data) will be present in a field of the same name in the resulting Monocle Assessment.
You can use the cpd parameter to add an arbiratary, session-based tag to the Monocle Assessment. This can in turn be used for custom session verification, tracking, and analysis on your backend.
Example implementation:
<scriptasyncsrc="https://mcl.spur.us/d/mcl.js?tk=<your monocle token>&cpd=test-cpd-value"id="_mcl"></script>
As with the interpretation of the Monocle Assessment, how you handle verification errors depends on your use case. This could range from accepting the form submission anyway, returning a validation error requiring the user to retry the form, logging the event in a backend database, or rejecting the form submission outright.
Common Scenarios
The primary value of Monocle is delivered in the first three fields: vpn, proxied, and anon.
In the matrix below, we've provided a few possible scenarios covering different combinations of values for these flags.
The anon flag will never be true unless either vpn or proxied is also true.
| Possible Interpretation | anon | vpn | proxied |
|---|---|---|---|
| - Proxy through a VPN - VPN service that uses proxies | X | X | X |
| - Residential Proxy - Datacenter Proxy | X | X | |
| - Commercial VPN service | X | X | |
| - Non-anonymizing/corporate VPN | X | ||
| - Non-anonymizing/corporate proxy | X | ||
| - No proxy or VPN detected |