Skip to main content
Shadow AI enforces on the device: the AI tool only receives what the verdict allows. The verdict itself comes from the engine, and what the engine is shown of the prompt is a setting you control — so where prompt text goes, and what is recorded, depends on that setting and on the deployment mode you choose.

The data lifecycle

1

Inspected locally

Every paste, prompt, or upload to a covered AI vendor is inspected on the employee’s own device. The agent extracts text (including from PDF, DOCX, XLSX, and plain-text files) and runs on-device secret and PII detection — entropy plus known-prefix matching — before anything reaches the AI tool.
2

A verdict is produced

The agent masks first, then asks. Every masker finding is replaced by its placeholder on the device, and it is that masked prompt — with the text extracted from attachments, and any images or audio — that goes to the /guard engine (30-second timeout; by default it fails open). The engine sees [EMAIL], never jane@acme.co. Raw prompt text is not something the agent sends anywhere — there is no setting that turns masking off.So that masking doesn’t blind the engine, each request also carries the request’s device findings: a category and a count per masker family — {"category": "pii_leak", "count": 2}, and never a value. The three families are secret_key_leak, api_key_leak and pii_leak. Your fleet dashboard sees what was caught without anyone transmitting it.With the metadata-only disclosure (below), the engine is sent no prompt text, attachment text, image or audio content at all.With the on-device pre-filter enabled (below), most clearly-benign prompts are resolved locally and never reach the engine at all — no round trip, nothing transmitted.
3

Only verdict + masked metadata is logged

What’s recorded is the verdict, threat type, and masked metadata — not the raw prompt. The local event log is PII-redacted.

What the engine is shown

There are two disclosures — two answers to “what does the engine get to see?” Raw prompt text is not one of them. You do not have to choose. Left unset, the disclosure follows the engine the device is pointed at:
  • PromptGuard’s cloud engine → masked. It’s our engine and our retention terms cover it.
  • Any other engine — Hybrid, Air-gapped, or anything else → metadata_only. An engine we don’t run defaults to being told the least.
Set it explicitly with the disclosure key in managed configuration, where it is also locked against local change.
metadata_only means the engine has nothing to judge, so it implies the local pre-filter setting below: the device decides, and an on-device detection redacts rather than blocks. Coverage narrows accordingly — the engine’s models are what catch novel semantic attacks, and under metadata_only they are never shown the prompt. A verdict reached this way is recorded as not fully scanned, not as a clean allow.
Masking hides what was caught from the engine, not from the device. The on-device detection floor, the recorded preview and the redaction of what actually reaches the AI tool all still read the raw text — so a secret the engine only ever saw as a placeholder is still blocked, and an engine allow is still overruled by an on-device finding.

On-device pre-filter (minimize what leaves)

A small classifier runs entirely on the device as a first pass. It scores each prompt and, combined with the always-on secret/PII floor, decides whether the engine even needs to see it:
  • Clearly benign → resolved locally. No engine call; the prompt stays on the device. (In testing, this covers the large majority of everyday traffic.)
  • Uncertain or attack-like → escalated to the authoritative engine, exactly as before.
It is conservative by design: the “resolve locally” bar is calibrated so a novel or ambiguous attack is escalated, never confidently allowed on-device — safety is never traded for keeping traffic local. It scores the masked text — the same thing the engine would be shown — so escalating a prompt over a value the engine will only ever see as a placeholder buys nothing; the on-device floor is what catches that value. Three settings. Set triage_setting in managed configuration for a fleet, or PGSHADOW_LOCAL_CLASSIFIER on a single machine: escalate was spelled hybrid until recently, because “Hybrid” is a deployment mode and reusing the word here caused exactly the confusion you’d expect. The old spelling still works for one release. local is the maximum-privacy setting: prompt text never leaves the machine, a confidently benign or merely uncertain prompt is settled on the device, and a confident attack is blocked there. Pair it with metadata_only and nothing the engine receives carries content at all. escalate is the recommended balance — it keeps the engine’s full detection for anything ambiguous while cutting egress and cost for the benign majority. The model is a tiny, auditable linear classifier embedded in the agent; a missing or corrupt model simply disables the pre-filter (the agent behaves exactly as off).

If the engine cannot be reached

By default the agent fails open: the prompt goes through with only the on-device maskers still redacting what they recognize. An agent that stops people’s AI tools every time something it depends on has a blip gets uninstalled, and an uninstalled agent protects nothing. That is the wrong trade for some organizations, so it is a setting — on_engine_unreachable, in managed configuration or PGSHADOW_ON_ENGINE_UNREACHABLE on one machine: What hold covers, precisely:
  • Only prompts to AI tools you monitor. An engine outage must not break someone’s unrelated work, so anything that isn’t a prompt to a monitored host goes through as usual.
  • Only a genuine failure to answer. A refused connection, the 30-second timeout, a 5xx, or a 200 that isn’t a guard response at all (a captive portal). A 401, 403 or any other 4xx is an answer and is never held.
  • Everything the device would have sent, including a masked copy. Forwarding a masked prompt would still send the engine something it never saw, which is the whole thing hold was chosen to prevent.
  • A hold is not a block. It found nothing — it is the absence of a finding. It is recorded as its own kind of event, carries no threat type, findings or preview, and is not counted among your allowed, redacted or blocked decisions. A prompt the device itself blocked stays a block: nothing was sent either way, and the device really did find something.
  • The person is told why, and nothing about their prompt. The message says the engine couldn’t be reached, that nothing was sent, and that the hold isn’t because of anything in what they wrote. Sending it again once the engine is back goes through normally.
Under hold, an engine outage is an outage of AI tools on monitored hosts for those devices, for as long as it lasts. That is the trade; choose it deliberately. A timeout means up to 30 seconds of waiting before the hold answers, though an engine that is down usually refuses the connection at once.

Every prompt that went out unchecked is counted and reported

Failing open is a deliberate deviation from the OWASP principle to fail securely, which says a check that cannot complete should deny. We keep allow as the default because an MSP’s clients, and most teams, would rather keep working through an outage. The condition for that choice is that it is never silent: it is configurable (hold, above), and every time it happens you can see it. The agent counts each prompt it sent without the engine’s verdict, by reason, and reports the counts to your organization with its regular check-in — within minutes, because it checks in early while the count is growing. Only the counts and the reason leave the device, never the prompt. A prompt that was held, or that the device blocked itself, was not sent and is not counted. Under hold the first two reasons stop happening; the others are answers from the engine, so hold does not stop them, and they are still counted. Where you see it:
  • The Shadow AI devices table. A device that sent prompts unchecked today shows N prompts sent without a PromptGuard verdict in its Capture column, with the reasons on hover.
  • Your alert destinations. When one device has sent 10 prompts unchecked that no alert has mentioned yet, every webhook and SIEM destination on the project gets one device_fail_open event naming the organization and the device — at most one per device per hour, each carrying only what is new. See SIEM export.
To stop sending prompts unchecked instead, set on_engine_unreachable: hold in managed configuration (or PGSHADOW_ON_ENGINE_UNREACHABLE=hold on one machine).

Where the data lives

Events are written to a local SQLite event log on the device, with PII redaction applied. This log is the system of record for activity on that machine. What reaches the cloud depends on your deployment mode: See Deployment Modes for the full configuration.
Enforcement is on the device in every mode, but scanning is not. Two separate hops, two separate controls: the disclosure decides what the device sends its engine (masked, or no content at all), and the deployment mode decides whose servers that engine is and what it forwards onward. Pointing a device at your own engine changes both — the disclosure it defaults to, and where the verdict is recorded.

Retention

  • Local event log: retained on the device until the agent is uninstalled (pgshadow uninstall deletes it; --keep-data retains it).
  • Cloud dashboard: events follow your plan’s log-retention window — see the pricing page (24 hours / 7 days / 30 days / custom).
  • Air-gapped: retention is whatever your local instance is configured for; nothing is held in our cloud.

Subject rights (GDPR / CCPA)

PromptGuard supports data-subject rights for the activity it records:
  • Access / export — export the events attributable to a given device or employee.
  • Deletion — delete a subject’s recorded events.
On the desktop, deleting local data is immediate via pgshadow uninstall. For cloud and hybrid deployments, export and deletion are available through the platform’s GDPR endpoints (Enterprise) — see Audit Logs and Compliance. For a specific request or a DPA, contact support@promptguard.co.

Audit trail

Verdicts across every surface (desktop · browser · sdk · proxy) roll up into one audit trail in the dashboard, attributable per device in a fleet. For tamper-evident, hash-chained audit logs see Audit Logs.

Next steps

Deployment modes

Cloud, hybrid, or air-gapped — controls what leaves your network.

Known limitations

What’s out of scope, including image OCR.