{
  "schemaVersion": 2,
  "lastUpdated": "2026-07-26T00:00:00.000Z",
  "organization": "DPAFlow",
  "policyUrl": "https://dpaflow.com/bot",
  "contact": "mailto:crawler@dpaflow.com",
  "scope": "Covers the request classes we have identified as reaching a site we monitor or verify. It excludes traffic to our own service providers and to customer-configured webhooks. If you see something from us that is not described here, tell us and we will add it.",
  "crawlerIdentities": [
    {
      "name": "DPAFlow Source Scan",
      "role": "source-scan",
      "userAgent": "Mozilla/5.0 (compatible; DPAFlowSourceScan/1.0; +https://dpaflow.com/bot)",
      "userAgentPattern": "Mozilla/5.0 (compatible; DPAFlowSourceScan/1.0; +https://dpaflow.com/bot)",
      "setsExplicitUserAgent": true,
      "userAgentVaries": true,
      "identifiesAsBot": true,
      "linksToPolicy": true,
      "isBrowser": false,
      "transport": "relay-host",
      "executedBy": "Source-scan worker",
      "purpose": "Reads the public subprocessor list page a customer monitors, including downloading it when it is a PDF."
    },
    {
      "name": "DPAFlow Probe",
      "role": "browser-probe",
      "userAgent": "Mozilla/5.0 (compatible; DPAFlowProbe/1.0; +https://dpaflow.com/bot)",
      "userAgentPattern": "Mozilla/5.0 (compatible; DPAFlowProbe/1.0; +https://dpaflow.com/bot)",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": true,
      "linksToPolicy": true,
      "isBrowser": false,
      "transport": "relay-host",
      "executedBy": "Browser-probe worker, first attempt",
      "purpose": "Checks that a candidate URL is reachable and is the page it claims to be, before we monitor it."
    },
    {
      "name": "DPAFlow Probe (rendered)",
      "role": "browser-probe-render",
      "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/<version> Safari/537.36",
      "userAgentPattern": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/* Safari/537.36",
      "setsExplicitUserAgent": false,
      "userAgentVaries": true,
      "identifiesAsBot": false,
      "linksToPolicy": false,
      "isBrowser": true,
      "transport": "relay-host",
      "executedBy": "Browser-probe worker, second attempt (headless Chromium)",
      "purpose": "Retries the same check in a real browser when the plain read did not settle it — which is often straight after a site blocked the first attempt. Carries no DPAFlow token."
    },
    {
      "name": "DPAFlow Source Verification",
      "role": "source-verification",
      "userAgent": "DPAFlowSourceVerification/1.0",
      "userAgentPattern": "DPAFlowSourceVerification/1.0",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": true,
      "linksToPolicy": false,
      "isBrowser": false,
      "transport": "not-fixed",
      "executedBy": "Scheduler, and super-admin remediation actions",
      "purpose": "Re-checks a source URL after it was reported broken, moved or blocked."
    },
    {
      "name": "DPAFlow Website Verification",
      "role": "website-verification",
      "userAgent": "DPAFlow-WebsiteVerification/1.0 (+https://dpaflow.com)",
      "userAgentPattern": "DPAFlow-WebsiteVerification/1.0 (+https://dpaflow.com)",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": true,
      "linksToPolicy": false,
      "isBrowser": false,
      "transport": "app-host",
      "executedBy": "Dashboard, when a customer adds a website",
      "purpose": "Confirms that a website a customer registered is reachable and belongs to them."
    },
    {
      "name": "DPAFlow Website Technology Scan",
      "role": "website-technology-scan",
      "userAgent": "DPAFlow-WebsiteTechnologyScan/1.0 (+https://dpaflow.com)",
      "userAgentPattern": "DPAFlow-WebsiteTechnologyScan/1.0 (+https://dpaflow.com)",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": true,
      "linksToPolicy": false,
      "isBrowser": false,
      "transport": "either",
      "executedBy": "Dashboard, or the scheduler on a schedule",
      "purpose": "Reads a customer's own registered website to record the technology it uses."
    },
    {
      "name": "DPAFlow Website Legal-Page Scan",
      "role": "website-legal-page-scan",
      "userAgent": "DPAFlow-VendorTechDetector/1.0 (+https://dpaflow.com)",
      "userAgentPattern": "DPAFlow-VendorTechDetector/1.0 (+https://dpaflow.com)",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": true,
      "linksToPolicy": false,
      "isBrowser": false,
      "transport": "app-host",
      "executedBy": "Onboarding website scan, through the shared page fetcher",
      "purpose": "When a customer asks us to scan their own website, reads its home page, follows the links on it that look like legal or privacy pages, and reads a small number of those. Shares the technology detector's User-Agent."
    },
    {
      "name": "DPAFlow URL discovery",
      "role": "url-discovery",
      "userAgent": "node",
      "userAgentPattern": "node",
      "setsExplicitUserAgent": false,
      "userAgentVaries": true,
      "identifiesAsBot": false,
      "linksToPolicy": false,
      "isBrowser": false,
      "transport": "relay-host",
      "executedBy": "URL-discovery worker",
      "purpose": "Looks for a vendor's subprocessor page by reading robots.txt and sitemap.xml and trying a short list of common paths. Sets no User-Agent of its own, so our HTTP client's default goes out instead."
    },
    {
      "name": "DPAFlow evidence capture",
      "role": "evidence-capture",
      "userAgent": "node",
      "userAgentPattern": "node",
      "setsExplicitUserAgent": false,
      "userAgentVaries": true,
      "identifiesAsBot": false,
      "linksToPolicy": false,
      "isBrowser": false,
      "transport": "relay-host",
      "executedBy": "Protected evidence-capture worker",
      "purpose": "Re-reads an approved source page to store the evidence snapshot. Sets no User-Agent of its own, so our HTTP client's default goes out instead."
    },
    {
      "name": "DPAFlow screenshot capture",
      "role": "screenshot-capture",
      "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/<version> Safari/537.36",
      "userAgentPattern": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/* Safari/537.36",
      "setsExplicitUserAgent": false,
      "userAgentVaries": true,
      "identifiesAsBot": false,
      "linksToPolicy": false,
      "isBrowser": true,
      "transport": "relay-host",
      "executedBy": "Screenshot worker and source-scan evidence capture (headless Chromium)",
      "purpose": "Renders the same public page to store a dated screenshot as evidence that the disclosure existed."
    },
    {
      "name": "DPAFlow browser validation",
      "role": "browser-rescue",
      "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/<version> Safari/537.36",
      "userAgentPattern": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/* Safari/537.36",
      "setsExplicitUserAgent": false,
      "userAgentVaries": true,
      "identifiesAsBot": false,
      "linksToPolicy": false,
      "isBrowser": true,
      "transport": "relay-host",
      "executedBy": "Hermes agent, including its proof-screenshot capture (headless Chromium)",
      "purpose": "Loads a public page in a real browser when a plain HTTP read cannot render it, and captures the proof screenshot for it. On this path a challenge page is recorded and the read stops."
    },
    {
      "name": "DPAFlow portal login",
      "role": "portal-login",
      "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
      "userAgentPattern": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": false,
      "linksToPolicy": false,
      "isBrowser": true,
      "transport": "not-fixed",
      "executedBy": "Hermes research agent, when an operator configures portal credentials",
      "purpose": "Signs in to a vendor portal to read documents that are not published publicly. The account is one DPAFlow operates and an operator configures, not one the site owner set up for us, and the sign-in flow can register an account where none exists. It runs only for a job an operator authorised for account login, against a domain on the operator's allow-list, and it presents a desktop Windows User-Agent rather than the browser it really runs; see the page."
    },
    {
      "name": "DPAFlow URL verification tool",
      "role": "url-verification-tool",
      "userAgent": "Mozilla/5.0 (compatible; DPAFlowBot/1.0; +https://dpaflow.com/bot)",
      "userAgentPattern": "Mozilla/5.0 (compatible; DPAFlowBot/1.0; +https://dpaflow.com/bot)",
      "setsExplicitUserAgent": true,
      "userAgentVaries": false,
      "identifiesAsBot": true,
      "linksToPolicy": true,
      "isBrowser": false,
      "transport": "not-fixed",
      "executedBy": "Operator tooling, run by hand",
      "purpose": "Checks a batch of candidate source URLs when we are curating the vendor catalogue. It runs from whatever machine the operator uses, so it has no fixed address."
    }
  ],
  "egress": [
    {
      "type": "ipv4",
      "value": "92.4.90.125",
      "transport": "relay-host",
      "roles": [
        "source-scan",
        "browser-probe",
        "browser-probe-render",
        "website-technology-scan",
        "url-discovery",
        "evidence-capture",
        "screenshot-capture",
        "browser-rescue"
      ]
    },
    {
      "type": "ipv4",
      "value": "178.105.142.154",
      "transport": "app-host",
      "roles": [
        "website-verification",
        "website-technology-scan",
        "website-legal-page-scan"
      ]
    }
  ],
  "robotsTokens": [
    "DPAFlowSourceScan",
    "DPAFlowProbe",
    "DPAFlowSourceVerification",
    "DPAFlow-WebsiteVerification",
    "DPAFlow-WebsiteTechnologyScan",
    "DPAFlow-VendorTechDetector",
    "DPAFlowBot"
  ],
  "knownGaps": [
    "Our research agent can fetch a vendor page over plain HTTP without a browser. It leaves from 92.4.90.125 like the rest of the relay traffic, but its User-Agent is set by a third-party agent runtime we have not measured, so it is not listed above. Match it by address until we can state it."
  ],
  "egressStability": "These addresses can change, and an operator-configured route could add another or replace one. Re-read this document rather than treating it as a permanent allow-list, and use the User-Agent tokens as well where you can.",
  "conventions": {
    "userAgentPattern": "A literal string except for '*', which matches any run of characters. Match on this rather than on userAgent, which may contain a placeholder.",
    "transport": {
      "relay-host": "Leaves through our egress relay.",
      "app-host": "Connects directly from our application host.",
      "either": "Either of the above, depending on which of our services runs it.",
      "not-fixed": "No address we can promise: it runs from an operator's machine, or it can be routed elsewhere by configuration. Deliberately absent from the egress list."
    },
    "absentFromEgress": "A role whose transport is not-fixed appears in no egress entry. That means its source address is unknown, not that it sends no traffic.",
    "robotsTokens": "The tokens we will match once we honour robots.txt Disallow. We do not parse Disallow today, so a rule built from these has no effect yet. Block by address or User-Agent instead."
  }
}
