Skip to content

For CISOs

The control exists. It runs. You can prove it.

A control you cannot demonstrate does not exist as far as an auditor is concerned. Neverseen is built around those three questions, in that order.

  1. 01

    Does the control exist?

    An agent on every endpoint, masking before anything is sent. It is a technical leakage-prevention measure on the channel your other tools do not cover: command-line AI tools and SDKs launched by your own people.

  2. 02

    Is it actually running?

    The fleet console separates three states: active, silent, never seen. An agent reports every five minutes; past sixteen it is called silent and raises an alert by email and by webhook — once per episode rather than once per sweep, because a channel that repeats itself is one people filter. Without that alert, monitoring is passive and does not amount to evidence of supervision. There is a fourth state, less obvious and more dangerous: active, but masking less than its catalogue. An endpoint can carry all three locales and no longer mask dates of birth. So the heartbeat reports what the agent actually applies — full, partial or none — with the names of the categories switched off and the secret level it is running at.

  3. 03

    Can you prove it?

    Every meaningful event — enrolment, heartbeat received, agent gone silent, configuration change, alert raised — is timestamped and hash-chained to the previous one. Altering any link breaks the chain and shows.

Proof log

The deliverable you put in the audit file.

An export per period, in CSV or JSONL, that replays and verifies offline: the auditor recomputes the hash chain without needing access to your console.

And a monthly report per organisation, written to be filed as-is: which endpoints were protected, over what period, under which policy, and which deviations were detected and dealt with.

What our backend receives — the complete list

POST /v1/heartbeat

{
  "schema": 2,
  "agent_id": "ag_7f3c1a9e",
  "sent_at": "2026-08-25T10:35:00Z",
  "state": {
    "version":      "1.4.2",
    "platform":     "darwin/arm64",
    "started_at":   "2026-08-25T08:02:11Z",
    "locales":      ["fr", "gb"],
    "substitution": "fake",
    "providers":    ["anthropic", "openai"],
    "addresses":    ["10.4.2.87"],
    "hostname":     "poste-47.exemple",
    "masking":      "partial",
    "switched_off": ["DOB"],
    "secret_level": "medium",
    "console":      false,
    "tracing":      false,
    "exposed":      false,
    "rerouted":     [],
    "allowlisted":  12
  },
  "buckets": [
    {
      "window": {
        "start": "2026-08-25T10:30:00Z",
        "end":   "2026-08-25T10:35:00Z"
      },
      "counters": {
        "requests": 412,
        "masked": {
          "EMAIL": 138, "PHONE": 61, "NIR": 4,
          "IBAN": 12,   "SIREN": 27, "SECRET_ANTHROPIC_KEY": 9
        },
        "models": {
          "claude-opus-5": {
            "input": 84900, "output": 96430,
            "cache_write": 21400, "cache_read": 1200000
          },
          "gpt-5.2": { "input": 210400, "output": 18220 }
        },
        "restarts": 1,
        "dropped": 0,
        "refused": 1,
        "providers": { "anthropic": 380, "openai": 32 },
        "upstream": {
          "ok": 404, "rate_limited": 5, "rejected": 2,
          "failed": 1, "unreachable": 0
        },
        "clients": { "claude-code": 371, "openai-sdk": 32, "cursor": 8, "other": 1 },
        "policy": { "applied": 1, "refused": 0 },
        "degraded": 1,
        "sessions": {
          "active": 6, "opened": 2, "closed": 3,
          "duration":   [0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
          "requests":   [0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
          "input":      [0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0],
          "output":     [0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0],
          "tool_calls": [1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
          "masked":     [0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
        },
        "tools": {
          "calls": 96, "restored": 7,
          "names":    { "Bash": 54, "Read": 31, "mcp": 8, "other": 3 },
          "programs": { "git": 21, "grep": 14, "python3": 6, "other": 13 },
          "classes":  { "network": 3, "privilege": 1 }
        }
      }
    }
  ]
}
  • No prompt, no response, no detected value — not even truncated. No file name, no URL.
  • Two exceptions, written here rather than discovered in a database. The first: the machine’s own local IP addresses. Not content — nothing about the traffic travels in them — but an address identifies a machine, and through it a person. It is there because a fleet view without it does not work: “ag_7f3c1a9e is silent” sends nobody anywhere, “the laptop at 10.4.2.87 is silent” sends somebody to a desk.
  • The second, more direct and knowingly so: the name the workstation calls itself. A machine is often named after the person using it, so “marie-macbook” names somebody where an address only names a machine. That is exactly why it is reported: it is the identifier an operator already recognises, and the only one that survives a laptop moving between networks. It is sent as the operating system gives it, never resolved and never hashed — hashing would keep the personal data and lose the use.
  • State reports what the agent applies, not what a file intends: switched-off categories, secret level, loaded locales. An agent carrying three locales that has stopped masking email addresses shows up here, where a console reading configuration alone would paint it green. It also reports how the agent itself is exposed: values printed in clear to a console, exchanges written to disk, listening beyond loopback, a provider rerouted, values exempted from masking.
  • The counters describe the control as much as the traffic: requests refused because the body could not be read, windows lost beyond the buffer, answers restored piecemeal. They also carry the inventory nothing else gives you — which AI tools are running on the workstations, which providers answered and how, and what the models asked the workstation to run: how many tool calls, how many put back a value the model never saw, and what class the commands fell into. Words from closed vocabularies, never the arguments.
  • The telemetry contract is public and versioned, and a test walks the type itself, refusing any text field that has not been argued for, line by line. The invariant is verified on every build, not promised in a sales call.

ISO/IEC 27001:2022

ISO/IEC 27001:2022 mapping

A control only counts if it exists, if it runs, and if you can prove it. Neverseen covers all three.

ControlWhat the auditor expectsWhat you show
A.8.12 — Data leakage preventionA DLP measure exists on the AI channel.The agent, installed and running on every endpoint.
A.8.16 — Monitoring activitiesYou know the measure is actually running.Live fleet view and alerting on silent agents.
A.8.15 — LoggingLogs that hold up: timestamped, tamper-evident, exportable.Hash-chained proof log, CSV and JSONL export.
A.5.36 — Conformance with policiesEvery endpoint applies the policy you decided on.Version, locales, substitution mode and the categories actually masked, in every heartbeat.
A.5.19 to A.5.23 — Suppliers and cloud servicesThe processor is identified and auditable.EU hosting, and a backend that receives no content at all.

Processing and sovereignty

Hosted in the European Union

The backend and its database run in the EU. That is a deployment constraint, not an intention.

No content, so a trivial scope to describe

The question “what does your processor do with our data?” has a short answer: it receives none. Your impact assessment gets considerably shorter.

The agent stays autonomous

Cut the backend off, cancel your subscription, blocklist it at the firewall: masking carries on identically. Monitoring observes; it is never on the request path.

Readable code, measured detection

The agent — the part that touches your data — is public: your teams can read it, build it and verify what it sends. Detection is not asserted but measured. A corpus of cases written as prose declares the values that must be found, and also the ones that must come out untouched — a version string, a commit SHA, an internal reference. A floor of true positives, false positives and misses is committed per category, and the build fails if any of them slips. A category added with no corpus case behind it does not compile.

Private beta

Request beta access

We open in waves, about ten fleets at a time. We reply within two working days.