If you are here, you probably found this line in your access logs:
Root92-MigrationScanner/1.0 (+https://scanner.test.root92.net/about-scanner)
That is us. This page explains exactly what that request did, and how to stop it. If that is all you want, skip to “How to stop us” at the bottom.
Who we are#
Root92. We migrate apps built with AI app builders to code the owner actually controls.
The surface check is how that conversation starts: the owner of an app pastes its address, ticks a box confirming they own it or are authorised to have it analysed, and gets a report on what an outsider can see from the outside. There is no crawler, no list, no discovery of sites. We only ever look at an address somebody typed in themselves, and we follow its links only in the deeper check described below: inside that one hostname, at most 10 pages, and only after its owner has proven control of it and asked for it.
Legal contact: Root92 sh.p.k., NIPT (Albanian tax ID) M52111038D, Don Bosko, Njesia Administrative Nr.11, Zyre F-101, shkalla F.kati , ambienti 1, Tirane, Albania.
What we read from your server#
In one session, within a total budget of 20 seconds and 20 MB across everything:
/robots.txt, first, before anything else.- The HTML of the home page, following at most 3 redirects.
- Up to 40 first-party JavaScript bundles that the markup itself declares — via
<script src>,<link rel="modulepreload">or<link rel="preload" as="script">. Third-party scripts are not fetched. - Nothing a browser would not ask for on a first visit. In particular, the surface check never asks whether
/.env,/.git/config, your source maps,/sitemap.xml,/.DS_Store,/.htpasswdor your API documentation exist, and never sends the CORS request with a made-up origin: ticking the box does not prove the site is yours, so those requests wait for the deeper check described below. - One TLS handshake on port 443, to read the protocol version and the certificate’s expiry date. No data is exchanged on it.
- Public DNS records of your domain: SPF, DMARC, MTA-STS and TLS-RPT (
TXT),MXandCAA. When your SPF record points to other SPF records (include:,redirect=), we read those public records too, at most 10 moreTXTlookups, only to count the DNS lookups a mail server would need.
On an app builder’s own subdomain we skip both the TLS handshake and the DNS records: they belong to the platform, not to the app.
From that session the check produces a short technical summary: which builder produced the site, whether a backend is referenced, which security headers were present, sizes and timings. We do not keep the content of your pages. We have put in place appropriate technical and organisational measures to keep that information secure.
Ownership verification: the few extra requests#
Before a deeper check, the person who asked has to prove they control the hostname. They choose one method, publish a token we give them, and ask us to look. Nothing below happens unless someone starts a verification for your exact hostname, and each look is one of these:
- DNS: a TXT lookup of
_root92-verify.<your hostname>, and of its parent names up to your registrable domain, for a value starting withroot92-verify=. That is a query to DNS, not a request to your server. - File:
GET https://<your hostname>/.well-known/root92-verification.txt, and nothing else. HTTPS only, at most 1 KB read, redirects followed only on the same hostname and at most 3. This one path does not consultrobots.txt: the file only exists if the owner put it there, so there is nothing of yours for us to read if they did not — you will see one404in your logs. A redirect to any other path leaves this exception and asksrobots.txtfirst. - Meta tag: the home page, looking for
<meta name="root92-verification">inside<head>. This obeysrobots.txtexactly like the surface check.
At most 50 verification looks per hour against the same hostname, whoever asks; of those, at most 10 from a single browser session, and 30 per hour from the same person. The token is tied to their browser session and to your exact hostname: it does not cover your other subdomains, and it expires with the session.
Once a DNS, file or meta proof has been found, we look for it again about every 60 minutes while the verification is open, with the same request and inside an hourly limit of its own. We also look for it once more right before the deeper check starts, right before its report is emailed to the owner, and each time we show the owner the findings that are hidden from the public, unless we found it less than 10 minutes earlier. If the proof now carries a different token, or robots.txt now forbids the look, the verification lapses at once. If the proof is simply missing, we do not end the verification on one look: a DNS cache or a deploy can hide a proof that is still there. It lapses only if it is still missing at least 60 minutes after we first missed it, or if the hourly look fails 3 times in a row. When a verification lapses, everything it had unlocked is closed again.
The person who starts a verification authorises the deeper check together with the token lookup, in the same consent. Once ownership is proven, the deeper check starts as soon as the owner confirms it. It is the same session described above — same budget, same paths, robots.txt obeyed — on the verified hostname only, plus one thing the surface check never does: a HEAD request — status code only, never the body — on these fixed paths only: /.env, /.git/config, any .map file a bundle we already downloaded declares, /sitemap.xml, /.DS_Store, /.htpasswd, and the default addresses of API documentation /openapi.json, /swagger.json and /v3/api-docs. When one of them seems to answer as a file, or answers only “forbidden”, one more HEAD to a made-up address (random, new every scan) tells a real answer apart from a site that answers every address the same way. For a file whose name starts with a dot (/.DS_Store, /.htpasswd) a second made-up address also starts with a dot, for a site that answers every such name the same way; for API documentation the made-up address is in the same folder, so one such HEAD per folder. One HEAD to your home page over plain http://, after reading that origin’s robots.txt, only to see whether it sends visitors on to https://; no redirect is followed. And one HEAD to your home page carrying an Origin header with a made-up address under the reserved .example domain, only to read whether your server allows any website to read its responses with the visitor’s cookies; the body is never read.
The owner can also tick separate boxes. Each one adds only what is described here:
- Source maps: the deeper check downloads the source maps your scripts point to and rebuilds the code in memory, only to report the file and line of an exposed key. The code is never written to disk or kept.
- Code composition: the deeper check uses the same rebuilt code, with no extra requests, to measure unused code and libraries included more than once. We keep only file paths (without user names), library names and versions, and sizes in bytes.
- Accessibility on rendered pages: an isolated browser, carrying the same user-agent, opens at most 10 pages of the verified hostname — the home page and the pages it links to, up to 2 links away, each one checked against
robots.txtbefore we open it — and runs their JavaScript, within 3 minutes. It can reach only your hostname, it sends onlyGETandHEADrequests (forms, uploads and WebSockets are blocked inside the browser), it starts with no cookies and is destroyed at the end. We keep only the page paths and the measurements. - Network requests: the same isolated browser opens the home page once, if
robots.txtallows it, runs its JavaScript for the first seconds after loading without clicking anything, and records the requests the page makes: methods, addresses without their values, parameter and header names and third-party hosts, never the values. To judge the page’s performance — in a desktop-size window, without slowing down the network or the processor, so the times are a lab measurement and not what a visitor on a phone sees — it also reads how many bytes each response transferred, its file type, the protocol it came over and whether it was compressed, when the first content and the largest element appeared and how much the layout moved; and, in the loaded page, whether the main image and the images further down are set to load late, how many stylesheets hold back the first paint, and whether the stylesheets use@importor fonts withoutfont-display. Only the yes/no results of fifteen checks are kept, never the numbers, the addresses or the page’s content; for now those fifteen checks are switched off, and until they are switched on none of their results is kept. It reaches only your hostname and sends onlyGETandHEADrequests, like the accessibility check.
None of these boxes reads your database or tries a key we find.
If the owner ticks the secure-connection box, and the server is theirs rather than a shared platform, the deeper check opens up to 7 more TLS connections to it, one at a time, within 20 seconds: one like a current browser’s, one for each TLS version from 1.0 to 1.3, and two that offer only older cipher suites. No HTTP request is sent over them, so they carry no user-agent; they end once the encryption has been agreed. For the other boxes the owner can tick, the deeper check asks outside services about your site and sends nothing to your server: the site address to a public dataset of real-visitor speed, the domain name to the registry of its extension, the hostname to the browsers’ public HTTPS list, the name and exact version of the libraries we recognise to an open database of security advisories, the domain name to a public database of known data breaches and to a public code-hosting platform. The privacy policy lists what each one receives and what we keep.
What we never read#
- We never read data from your database. Not a row, not a count, not “just to see if it answers”.
- We never use a key or token we find. A public key in a bundle gets decoded and reported; it is never presented to your backend, in any form.
- We never download the body of
/.env,/.git/config,/.DS_Store,/.htpasswdor an API documentation file, even when they answer200. We record the status code and close the connection. The finding says only “this is reachable”, and it has no field for the contents. - We never download source maps outside the deeper check described above, and only that check asks whether they exist.
- We never guess. No wordlists, no
/.env.local, no/backup.zip, no table names. The paths above, including the verification requests, and in the deeper check the pages your own site links to, are the entire list. - We never write anything anywhere.
- We never disguise the request. The user-agent above is the only one we use.
Why we were allowed to#
Because the owner of the application asked us to, one address at a time, with a tick box, before the first request went out.
That consent is recorded with the version of the text it was given under, and it is the only thing that starts a scan. There is no code path that scans an address nobody submitted: no batch, no list, no crawler. The only checks that repeat on their own are the ones described above for a verified owner: the periodic look for their proof and, if they ask for it, a repeating deeper check.
If you are reading this and you are not the person who asked, then somebody submitted an address that was not theirs. Tell us at the address below and we will handle it.
A verification is the same kind of request: someone who says the hostname is theirs asks us to look for a token they published. If they could not publish it, the looks find nothing and nothing further happens.
Why we do not ask the owner for proof#
The surface check reads only what your server already hands to any browser, so we ask for a declaration rather than proof of ownership. What keeps a false declaration harmless is the shape of the check itself: one address at a time, at most 3 checks an hour against the same hostname whoever asks (except the owner, once ownership is proved), your robots.txt respected, no key used, nothing downloaded beyond the public surface, and every check logged with the time, the address and where the request came from. Anything that would go further — such as testing whether a database answers without a login — is never part of this automatic check.
How much load this puts on your server#
Very little, by design: a tool that overloads the site it is checking would be the wrong tool.
- One session per check, capped at 20 seconds and 20 MB in total — not per request. When the budget runs out the scan stops and reports what it managed to establish.
- At most 40 bundles.
- In the deeper check, only if the owner asks for it: at most 10 page loads in a browser, one page at a time, within 3 minutes — about what one visitor reading a few pages would cause.
- In the deeper check, only if the owner asks for it and the server is theirs: at most 7 TLS connections, one at a time, within 20 seconds, with no page requested.
- At most 3 checks per hour against the same hostname, no matter who asks, and 20 per hour from the same submitter. One check can mean up to two scan sessions: the report is computed when the address is submitted, and computed again if that person then asks to be contacted, so the saved report is the fresh one. That is why you may see up to 6 sessions in an hour and not 3. The cap follows redirects: if the address we were given forwards to yours, it is your hostname that is counted. The only exception is you: once you have proved you own the site, your own checks do not count against this cap, and do not use up anyone else’s.
How to stop us#
There are two ways.
Add a rule for us to your robots.txt. We read it before the home page and we respect it — if the path is disallowed for our token, we do not fetch it, and the check closes as blocked with nothing collected:
User-agent: Root92-MigrationScannerDisallow: /
That stops everything except the single verification file described above (/.well-known/root92-verification.txt), which only an owner can create and which is a 404 otherwise. To stop that too, do not publish the file — or write to us.
Or write to us at info@root92.it, telling us the hostname, and we will block the address on our side, verification included.
If a request from us caused you a real problem, say so in that email. We would rather know.