What leaves your browser, and how to check
This page is written for whoever has to sign off on running a tool against study metadata. It states what the SDTMIG v4.0 Impact Scanner reads, what it transmits, and how to confirm both from your own devtools without trusting a word of it.
The short version
The Define-XML you drop in is parsed by JavaScript running in your browser tab. It is not uploaded, not proxied, not queued, and not logged. The scanner page is served with connect-src 'none', which means the browser will not let it open a network connection to anywhere — not to a third party, and not back to us either. There is no destination for your file to go to. Your browser enforces that whatever we do, and the section below is how to read it off the wire in ten seconds rather than believe it.
Nothing you type on that page leaves it either, because there is nothing to type: it has no form, no field and no account. If you want the rules-catalogue mailing list, the scanner shows a link to a separate page — /impact/subscribe/ — and that page, which is an ordinary page and says so, posts the address you enter to /.netlify/functions/subscribe on this domain. It is a different page under a different policy, you get there by choosing to, and nothing about your scan travels with you: the link carries no query string, and the page it opens has never seen a file name, a study identifier or a result.
Your report does not travel either — in either direction. It is written by the same JavaScript that read your file and downloads out of the tab as HTML, Markdown or JSON. We never receive it, which is also why we cannot email it to you and do not offer to.
What a Define-XML contains, and what the scanner reads
A Define-XML is study metadata, not study data: the datasets in a submission, the variables in each, their types, lengths and roles, the codelists and their terms, value-level metadata, comments, computation methods and origins. It normally carries the study identifier and protocol name, and it can carry free text that someone wrote by hand — comments and method descriptions are the usual places.
It does not contain subject data. No USUBJIDs, no visits, no results, no adverse events. Whether your organisation nonetheless treats a Define as confidential is your call, and a reasonable one: it describes the shape of a trial.
The scanner reads the dataset and variable definitions, codelists, value-level metadata and the standards declarations. It reads them to decide which SDTMIG v4.0 changes apply to your study. Everything it reads stays in the tab's memory and is gone when you close it — nothing is written to localStorage, sessionStorage, IndexedDB, or a cookie. Reload the page and the scan is gone with it.
What the scanner page is permitted to contact
Every response under /scanner/ carries this Content-Security-Policy header:
default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'none'; script-src 'self'; style-src 'self'; font-src 'self'; img-src 'self' data:; connect-src 'none'
connect-src 'none' is the directive that matters, and 'none' is the strongest value it has. It means the page's JavaScript can open a network connection to no origin at all: not to an analytics service, not to a font host, not to a CDN, not to an error reporter — and not back to this domain either. A browser enforces this; it is not a setting the page can opt out of.
There is no remaining destination to reason about, and that is the difference between 'none' and 'self'. This page used to say something weaker, because the policy used to be weaker. It explained that the header ruled out every destination except our own domain, and that what kept your Define-XML out of that last one was the scanner's own code, which builds no request. Both halves were true. Only one of them could be checked from the wire; the other asked you to trust a code review you had not done.
What changed, and why. The only thing on the scanner page that ever needed a destination was the mailing-list signup, and it has moved to its own page at /impact/subscribe/. The scanner now shows a plain link to it once a scan has finished, and a link is a navigation rather than a connection — it costs the policy nothing. With the form gone the page had nothing left to send, so the policy stopped permitting anything. Your Define-XML now stays in that tab for exactly the reason the page cannot reach an analytics service: there is nowhere for it to go.
The code still builds no request either. The scanner's own JavaScript contains no fetch call: it reads the file with the File API, parses it in a Worker bundled into its own assets, and renders the result from memory. That is now a second lock on a door the header has already welded shut, rather than the load-bearing half of the claim — but it is still true, and the build enforces it. A deploy whose scanner page names an endpoint fails instead of shipping, which is what stops the form quietly coming back.
The same page also makes no third-party request of any kind — not a script, not a stylesheet, not a font. The scanner's own JavaScript, its stylesheet, the signup link and the typefaces you are reading this in all come from this domain. Our marketing pages are different: they use Plausible, a cookieless analytics service, and they load their fonts from Google. The scanner does neither, and neither does this page. That is the whole reason this page serves its own copy of the fonts rather than linking them: a page arguing that nothing reaches a third party should not reach one to render the argument.
Verify it yourself, in about two minutes
- Open clindar.eu/scanner and open devtools before you do anything else (F12, or Cmd-Option-I on a Mac).
- Read the policy. In the Network tab, reload, click the first document request, and look at the response headers. You should see content-security-policy with connect-src 'none' in it. It is also repeated in a <meta> tag in the page source, which the browser enforces as well.
- Watch the scan. Loading the page is itself network activity: you will see the HTML, the scripts, the worker chunk and the stylesheet arrive, which is every visitor collecting the same files. Let that settle. Then tick "Preserve log" and drop in a Define-XML. Nothing further appears. No XHR, no fetch, no beacon, no image request with your data hidden in the query string. The score arrives without a single new request, because the work happened in the tab.
- Test the policy, including against us. In the Console, run fetch('https://example.com'). The browser refuses it and says why: that is connect-src 'none' closing off every third-party destination. Now run fetch('/impact/privacy/') — a path on our own domain, the friendliest possible destination. That is refused too, with the same error. This is the step worth doing slowly: it is the one that shows the policy is not merely pointed at other people's servers. There is no destination we could send your file to from that page, including one of ours.
- Then look at the signup, which is a different page. Click "Join the list" under your result and watch what the click does: it is a navigation to /impact/subscribe/ with no query string, and no request goes out before it. On that page — an ordinary page, under the ordinary site policy — submitting the form produces a single POST to /.netlify/functions/subscribe. Click it and read the request payload: it is {"email":"…"} and nothing else — no file name, no study identifier, no score, no rule ids. Nothing could have carried them there; that page was never told a scan happened.
- Download the report and watch nothing happen. Click "Download HTML report". The file appears with no network request behind it, because the page built it from what was already in memory. That is the same fact from the other side: a document we never receive is a document we cannot email you. Try every format — HTML, Markdown, PDF, JSON, the Excel checklist. The network panel stays empty for all of them.
If any of that does not match what you see, we would rather hear about it than not: info@clindar.eu. The configuration is what would be wrong, and we would fix it.
The email address, if you give us one
- Who is responsible
- Clindar, UAB, company code 308107046, registered at Laisvės pr. 78-11, LT-05263 Vilnius, Lithuania. Contact: info@clindar.eu. That is the "we" everywhere on this page, and the data controller for the email address described below and for running this site. Not for what you scan: a Define-XML is read in your browser and no copy of it reaches us, so there is nothing in it for us to control.
- What is collected
- The email address you type. It goes to our email service provider and is stored there, which is what a mailing list is; that is the only place a copy lives on purpose.
- What our own endpoint writes down
- One line per request: the event name, which provider was used, how it turned out — subscribed, failed, rate-limited — and the hour. Not the address. Not your IP address, your browser, the page you came from, or anything you scanned. The address is passed to the provider and dropped; it is never handed to a logging call at all, so there is no redaction step that could one day be forgotten.
- Telling repeat attempts apart
- If we ever have to distinguish one address retrying forty times from forty addresses arriving once, the endpoint can log a keyed HMAC of the address in place of the address: a short string that cannot be turned back into an email without a secret that never leaves the server and is never printed. It is off unless a specific operational question needs it, and rotating that secret makes every identifier already written unlinkable to any written after.
- Why
- To send you the SDTMIG v4.0 change checklist, and to tell you when the rules catalogue changes. It is a mailing list: every subscriber receives the same emails, because your scan is not something we hold and could tailor them to.
- What is never sent to you
- Your scan report. It is produced in your browser and downloaded from it, and no copy reaches us — so no email we send can contain it, whatever you subscribe to.
- Legal basis
- Consent, GDPR Article 6(1)(a). You gave it by typing the address and asking to join the list. Withdraw it at any time with the unsubscribe link on every email, or by writing to us.
- Who else sees it
- Our email service provider, as a processor, which stores the address and sends the list. It is never sold, never shared for anyone else's marketing, and never joined to anything you scanned — we do not have that to join it to.
- How long
- Until you unsubscribe, or after two years without a single opened email, whichever comes first. That is a retention rule configured at the email provider rather than something our code enforces, so it is a commitment we keep by administration — ask and we will tell you what it is currently set to.
- Your rights
- Access, rectification, erasure, restriction, portability and objection, under GDPR Articles 15–21. Write to info@clindar.eu and we will action it. You may also complain to your national supervisory authority.
- Rate limiting
- The endpoint counts recent submissions per caller for an hour, keyed by a salted hash of the IP address, held in memory and nowhere else. Your IP address itself is never written down, the salt is random per process and discarded when the process restarts, and the counts go with it. Nothing about this is logged.
- Infrastructure logs
- Our hosting platform keeps request logs of its own, as every web host does. We will not tell you what a platform records by default, because that is its behaviour and not something we can show you in our source code. We treat it as something to configure rather than something to claim: retention is kept short, access is limited to people who need it, and a deletion request is actioned against the provider's stored data and any operational log still in hand. If a DPIA needs the current retention period in writing, ask and you will get the figure we have set.
There are no cookies on the scanner. Not analytics cookies, not preference cookies, not "essential" cookies. There is no consent banner because there is nothing to consent to.
If a browser is still the wrong place
Some organisations will not run study metadata through a web page whatever the headers say, and that position is defensible. The same engine — the same rules catalogue, the same scoring — runs as a command-line tool inside your own network, with no browser and no network access at all. Write to us and we will get you a build.