Skip to main content

Privacy statement

What the export scripts send, what they never send, and how to check that for yourself before you run anything. Read this before the how-to for your environment.

What runs, and where​

Two scripts, one per vendor: nc-export.py (Google Workspace, and the file-mode path for Entra ID) and nc-export-entra.ps1 (Entra ID, file mode or live against Microsoft Graph). In file mode, neither script opens a network socket. They read an export you already have on disk and write a result file next to it. Live mode is the one exception — covered in the PowerShell how-to — and even there, the only network traffic is the Graph API calls the script itself makes on your behalf; nothing is sent to NobleCloak until you upload the resulting file yourself.

What leaves your machine​

One file, and only when you choose to upload it: discover-export.ndjson. It is newline-delimited JSON — one header line, then one line per (user, application) grant. Here is a real grant line, taken verbatim from the project's own test fixtures, with the keys in the exact order the format requires:

{"userRef": "user_241aea1c1a593c74", "consentType": "Principal", "clientId": "bbbb2222-bbbb-2222-bbbb-222222222222", "appDisplayName": "Zoom", "scopes": ["Calendars.Read"], "firstSeen": "2026-02-15T00:00:00Z", "lastUsed": null}

Notice what is and is not in that line. There is an application name and the scopes it was granted — that is the risk signal the report is built from. There is no email address. userRef is a pseudonym, not an identifier.

What never leaves your machine​

Pseudonymization is on by default. Every user identifier is replaced with a userRef derived by HMAC-SHA256 over the user's normalized email/UPN, before the export file is even written — the raw identifier is never in discover-export.ndjson to begin with. Two files make that pseudonym reversible, and both are written only to your local disk, never transmitted, never referenced by anything you upload:

FileContents
salt.txtThe random salt used to derive every userRef in this run
mapping.csvThe userRef -> email mapping, one row per user

Both are written with owner-only file permissions. If your organization has decided raw email identifiers are acceptable to share, --no-pseudonymize / -NoPseudonymize turns pseudonymization off — and in that mode, neither file is written at all, because there is no pseudonym left to map back.

Nothing is silently dropped or guessed​

A source row with a missing, blank, or unresolvable identity field (email/UPN, client ID, app name) is skipped with a warning, never silently mangled or dropped without a trace. Every successful run ends by printing a summary to your terminal — Skipped rows: N, always printed even when N is 0 — immediately followed by:

Nothing has been sent anywhere. Review discover-export.ndjson, then upload it in the Discover app.

You do not have to take any of this on faith. Read the line count for yourself, and open the file before you upload it.

Coverage is handled the same way: when the script cannot determine an export's time window or a tenant's total user count, those fields are left null rather than guessed. See the export format page for the exact fields.

What NobleCloak Discover does with the file you upload​

The raw bytes of the file you upload are parsed in memory and are never persisted — the file itself is not written to storage. What is stored is the normalized grant rows extracted from it, plus the export's own header metadata (vendor, generatedAt, pseudonymized, and the other header fields described on the export format page).

For how long that stored data is retained, how it is isolated and encrypted, and what Discover's read-only access can and cannot do, see Discover Data Handling on the trust site, alongside the governing privacy policy — this page covers what the export scripts do on your machine, not NobleCloak's data-handling posture once you've uploaded.

The scripts are open and auditable​

nc-export.py and nc-export-entra.ps1 are not something you have to trust blind. Both live in the open-source noblecloak-tools repository, with test fixtures that pin their exact input/output behavior. Read them, run them under a debugger, diff them against the downloads page's published checksums — nothing about how they work is hidden from you.

Next​