User guideShadow AIShadow AI settings
Shadow AI

Shadow AI settings

Manage API keys, syslog sources, rate limiting, data retention, and risk score calculation.

Overview

The Settings page is where you configure data sources, access controls and operational parameters for Shadow AI detection. It's divided into six sections: API keys, syslog sources, data formats, rate limiting, data retention and risk score calculation. Only Admins can manage API keys, syslog sources and the rate limit.

API keys

API keys authenticate events sent to the REST API, for example from a SIEM webhook, a script or a browser extension. Syslog sources do not use these keys; each source has its own key (see below).

Creating a key

  1. Click "Create API key"
  2. Optionally enter a label (e.g., "Zscaler proxy")
  3. Click "Create"
  4. Copy the full key immediately, it won't be shown again
Important
The full API key is only displayed once at creation time. Store it securely. If you lose it, revoke the old key and create a new one.

Managing keys

The API keys table shows each key's prefix, label, status (Active or Revoked), creation date and last-used date. You can:

  • Revoke: Deactivates the key. Integrations using this key will stop working. This cannot be undone. The server you are connected to refuses the key at once; with several backend replicas, the others can accept it for up to 5 minutes.
  • Delete: Permanently removes a revoked key from the list. Only revoked keys can be deleted.

Syslog sources

Syslog sources define where network traffic data comes from. Each source has a parser type, a secret key that every log line carries, and an optional allowed sender IP. Only Admins can manage them. The setup steps are in the Integration guide.

A line above the table shows whether the syslog listener is on and where to send logs (port 6514 by default, over TLS or plain TCP). The listener is off until the server operator sets SHADOW_AI_SYSLOG_ENABLED=true. If it is turned on but could not start, the line says so; the server log has the reason. The hosted service does not offer syslog yet.

Parser types

ParserDescription
ZscalerReads key=value lines with user, dst, method, uri, action, department and timestamp
NetskopeReads a JSON object with user, url (else domain or site), method, action, department and timestamp
Squid proxyReads the native Squid access log. A DENIED result code is blocked, anything else is allowed
Generic key-valueReads key=value lines and CEF extensions with suser, dhost, request, requestMethod, act, department and timestamp (or CEF rt, end, start). The default for a new source

The source table

ColumnMeaning
Allowed sender IPIf set, lines from other IPs are dropped. A value that is not an IP address is flagged for you to clear or fix.
ParserThe parser type for this source.
KeyThe first characters of the key, or "No key yet". Use "Generate key" or "Regenerate key" to create one.
Last receivedWhen the last event from this source was stored, or "Never".
AcceptedEvents stored.
DroppedLines that could not become events.
Last drop reasonWhy the last line was dropped, in plain words (see the table below).
StatusActive or Inactive.
Last drop reasonMeaning
No user email in the log lineThe user field is missing, empty or not an email address.
No destination host in the log lineThe line has no destination host or URL.
Line does not match the parser typeThe parser could not read the line, or the line repeats a field such as user, destination, action, method, department or timestamp.
Sent from an IP that isn't allowed or is shared with another sourceThe sender IP is not the source's Allowed sender IP, or two sources share an IP in IP-only mode.
Over the hourly event limitThe hourly rate limit was reached, or the listener's queue was full.

Source keys

When you add a source, the "Your source key" dialog shows the key once, with a copy button and a ready-made vw_source=<key> line. VerifyWise stores only a hash and the first characters of the key, so it cannot show the key again. If you lose it, click "Regenerate key". The old key stops working at once on the server you used and within 60 seconds on any other replica. Removing a source stops processing events from it.

Data formats

This section documents the exact data formats VerifyWise expects when ingesting Shadow AI events, whether through the REST API or via syslog forwarding.

REST API event schema

Send events via POST /api/v1/shadow-ai/events with a JSON request body containing an events array of up to 10,000 events. Authenticate using the X-API-Key header with a valid API key.

json
{
  "events": [
    {
      "user_email": "alice@company.com",
      "destination": "chat.openai.com",
      "timestamp": "2026-02-09T14:32:00Z",
      "uri_path": "/v1/chat",
      "http_method": "POST",
      "action": "allowed",
      "department": "Engineering",
      "job_title": "Senior Engineer",
      "manager_email": "bob@company.com"
    }
  ]
}
FieldRequiredDescription
user_emailYesEmail address of the user who made the request. Stored in lowercase, with surrounding spaces removed. Up to 255 characters
destinationYesHostname or domain of the AI tool (e.g., chat.openai.com). Stored in lowercase. Up to 512 characters
timestampYesISO 8601 timestamp of the event. A timestamp that cannot be read fails the whole request
uri_pathNoURL path of the request (e.g., /v1/chat). Left out if longer than 2,048 characters
http_methodNoHTTP method (GET, POST, etc.). Stored in upper case
actionNo"blocked" if the proxy refused the request. Any other value, or none, is stored as "allowed"
departmentNoDepartment of the user (e.g., Engineering, Finance). Used in risk scoring and department alerts
job_titleNoJob title of the user
manager_emailNoEmail address of the user's manager. Stored in lowercase
Authentication
All requests must include the X-API-Key header with a valid API key created from the API keys section above. Requests without a valid key receive a 401 response. The Integration guide lists every error response.

Syslog format examples

Syslog messages arrive over TCP (TLS by default), newline-delimited or octet-counted, up to 64 KiB each. An RFC 3164 or RFC 5424 header is removed when present. Every line must carry the source key as vw_source=<key> at the start or the end of the line, or as a top-level "vw_source" member when the line is a JSON object. A key anywhere else is ignored. VerifyWise removes the key before parsing and never stores it. Below is one example per parser, with the field added.

Zscaler (key=value)

text
user=alice@company.com dst=chat.openai.com method=POST uri=https://chat.openai.com/v1/chat action=allowed department=Engineering vw_source=YOUR_SOURCE_KEY

Netskope (JSON-in-syslog)

json
{"user":"alice@company.com","url":"https://chat.openai.com/v1/chat","method":"POST","action":"allow","department":"Engineering","timestamp":"2026-02-09T14:32:00Z","vw_source":"YOUR_SOURCE_KEY"}

Send the whole object on one line. With newline-delimited framing, a pretty-printed object is split into lines that cannot be read.

Squid (space-delimited)

text
1707489120.000 200 10.0.0.1 TCP_MISS/200 1024 POST https://chat.openai.com/v1/chat alice@company.com DIRECT/chat.openai.com vw_source=YOUR_SOURCE_KEY

Generic key-value (CEF-style)

text
suser=alice@company.com dhost=chat.openai.com requestMethod=POST act=allowed vw_source=YOUR_SOURCE_KEY

Field mapping

Each parser maps its fields to the normalized event schema. The user must be a valid email address; it is stored in lowercase. For the action, the first word of the value decides: block, deny, drop, reset or reject (and forms such as blocked, denied or dropped) become blocked, and allow, permit, pass or accept (and forms such as allowed or permitted) become allowed, so Blocked by policy is blocked. A negated allow such as Not allowed or disallowed is also blocked. Any other value, including words that only begin with one of these such as password_reset, or no action at all, is stored as allowed. The timestamp comes from the payload field when present, then from the syslog header, then from the time VerifyWise received the line. A timestamp without a time zone is read as UTC; a zone it states (an offset, Z, PST, CEST, also in brackets such as (Tokyo JST)) is used. A zone name VerifyWise does not know, such as IST, makes the payload time unreadable, so send an offset or Z if your source logs in another zone. A timestamp more than a year before the time the line was received, or more than a day after it, is ignored. A destination can be a host name, an IPv4 or IPv6 address (bare or in brackets) or a URL, and is stored in lowercase. A destination of -, N/A or none is skipped and the next field (such as the URL) is used. An email address longer than 255 characters or a destination longer than 512 drops the line, and a department is cut to 255 characters.

Normalized fieldZscalerNetskopeSquidGeneric KV
user_emailuseruserfield 8suser
destinationdst, else host of uriurl (hostname), else domain or siteurl (hostname)dhost, else host of request
uri_pathuri (path)url (path)url (path)request (path)
http_methodmethodmethodfield 6requestMethod
actionactionaction, else activityfield 4 (result code)act
timestamptimestamptimestampfield 1 (epoch)timestamp, else CEF rt, end or start
departmentdepartmentdepartment—department

Rate limiting

Rate limiting caps how many events your organization can ingest per hour, across the REST API and syslog. It protects the system from a misconfigured data source or a traffic spike. Only Admins can change it. The count is kept in memory by each backend process, so with several backend replicas the effective limit is the setting times the number of replicas.

  • Set a number to cap hourly ingestion. Set 0 or leave the field empty for no limit (the default).
  • The hour starts with the first event counted, not on the clock hour.
  • A REST request that would go over the limit is refused whole with a 429 response. Syslog events over the limit are dropped and show "Over the hourly event limit" on the source.
  • A change applies to the REST API at once and to syslog within 30 seconds.

Data retention

Data retention settings control how long different types of Shadow AI data are stored before automatic cleanup. Three categories can be configured independently:

CategoryDefaultDescription
Raw events30 daysIndividual event records from ingestion (highest volume)
Daily rollups365 daysAggregated daily statistics (lower volume)
Alert history90 daysRecords of triggered alert rules

Each period can be 1 to 3,650 days. Cleanup runs once a day, so a change applies at the next run. Raw events are removed by the time of the event, not the time it arrived. Admins can change these periods, and so can a custom role that has the organization admin permission. Each change is recorded in the audit ledger.

Storage tip
Raw events consume the most storage. If disk space is a concern, consider a shorter retention period for raw events while keeping daily rollups longer for trend analysis.

Risk score calculation

The bottom of the Settings page explains how the risk score is calculated. Each AI tool receives a score from 0 to 100, recalculated nightly using four weighted factors:

FactorWeightDescription
Approval status40%Unapproved tools (not in model inventory or not approved) receive the maximum score.
Data & compliance25%Based on training-on-data policy, SOC 2, GDPR, SSO and encryption at rest.
Usage volume15%Normalized against the organization average. Higher usage increases the score.
Department sensitivity20%Uses the highest sensitivity among departments that used the tool in the last 30 days. Finance, Legal and HR are rated highest (80). Events without a department add nothing here.
PreviousAlert rules
NextIntegration guide
Shadow AI settings - Shadow AI - VerifyWise User Guide