The ua module
Part of the SharedID Edge specification. The general rules for modules, including consent, time limits and modules on /sync, are there.
Name ua; no purposes, no gvlid. It runs only when listed in SID_MODULES, and on /v1 only. It maps the request's User-Agent Client Hints and User-Agent header to OpenRTB 2.6 ortb2.device fields, and flags self-identified bots in the shared traffic signal.
Client Hints are read as RFC 8941 structured fields:
Sec-CH-UAandSec-CH-UA-Full-Version-List: a list of strings, each with a stringvparameter. Members without one are left out. GREASE brands (Not,AandBrandseparated and surrounded by punctuation, such asNot A(Brand,Not_A Brandor(Not(A:Brand) MUST be left out. A malformed list is ignored as a whole. At most 8 brands are kept, of at most 64 characters each.Sec-CH-UA-Mobile:?1or?0.Sec-CH-UA-Platform,-Platform-Version,-Model,-Archand-Bitness: a string. Empty strings, strings over 64 characters, malformed values, and the platformUnknownare ignored.- Header values over 1024 characters are ignored.
- Low-entropy hints are
Sec-CH-UA,Sec-CH-UA-MobileandSec-CH-UA-Platform(browsers send them by default); the others are high-entropy.
The User-Agent is parsed by the parser the
parsersetting chooses (see Settings):isbot(the default) recognizes only bots;bowseralso recognizes the browser and its version, the OS and its version, the device class (phone, tablet, desktop, smart TV, set-top box), the maker and the model. What a parser recognizes in a given User-Agent is implementation-defined; the mapping below isn't. The first 512 characters are parsed. AUser-Agentof exactlyAmazon CloudFront(what CloudFront sends when it doesn't forward the visitor's) is treated as absent.Output, each field only when known:
deviceFrom suaFrom Client Hints, when any low-entropy hint is present: browsers(the full version list when high entropy is allowed and it was sent, elseSec-CH-UAwith major versions),platform(brandfromSec-CH-UA-Platform,versionfrom-Platform-Version),mobile(1or0),architecture,bitness,model. Versions are arrays of their dot-separated components (["131","0","6778","86"]); a version that isn't dot-separated digits is left out.sourceis2when any high-entropy field is included, else1. Without hints, from the parsed User-Agent when it gives a browser or OS:browserswith the one browser,platformwith the OS,mobilewhen the device type is known (1for a phone), andsource3. A User-Agent version of the formN.0.0.0(Chromium's reduced User-Agent) gives only[N].devicetypeSec-CH-UA-Mobile: ?1gives4(phone), or5if the User-Agent says tablet.?0with a desktop platform (Windows,macOS,Linux,Chrome OS,Chromium OS) gives2. Otherwise the parsed device class: phone4, tablet5, smart TV3, set-top box7, desktop2. Otherwise a desktop OS gives2.osSec-CH-UA-Platform, else the parsed OS name.osvSec-CH-UA-Platform-Version; on Windows,13and up is11,1to12is10, and0is left out. Else the parsed OS version, only when the parsed OS is the hinted one (or there's no hint). Values browsers freeze MUST NOT be sent: macOS10.15.7and10.15, WindowsNT 10.0(10 or 11), and Android10in Chrome's reduced User-Agent (Android 10; K).makeThe parsed device maker. A bot's operator isn't a maker. modelSec-CH-UA-Model, else the parsed model.uaThe User-Agentheader, only with theuasetting.ext.traffic{ "bot": true, "botKind": "declared", "sources": ["ua"] }when the User-Agent identifies the client as a crawler, bot or other automated client. Absent otherwise: the module never claims a request is human.Consent: high-entropy data (
sua.browsersfull versions,sua.platform.version,sua.architecture,sua.bitness,sua.model,osv,modelandua) is left out, andsua.sourceis then1or3, when:- the request has
Sec-GPC: 1, orcoppa=1; - the
us_privacystring opts out of sale (its third character isY); - there is a TC string that is invalid;
- GDPR applies and there is no TC string.
suabrowser brands with major versions,sua.platform.brand,sua.mobile,devicetype,osandmakeare always sent. The traffic signal is always sent, under GPC and COPPA too: it describes the traffic, not the person.- the request has
Settings,
SID_MODULE_CONFIG.ua:ua(optional boolean, defaultfalse) addsdevice.ua.parser(optional,"isbot"or"bowser", default"isbot") chooses the User-Agent parser; Client Hints take precedence over either, as in the table. An implementation MAY leavebowserout of a build (this one does by default, to keep bundles small); the module MUST then reporterrorwhen the setting asks for it, rather than ignore it. Any other key or a value of another type makes the module anerroron every request.The traffic signal: the module's
device.ext.trafficis its report to the traffic signal, merged by core with the other reports.When there's no field to return, it returns nothing (status
empty). Nothing is stored or logged.