Strict privacy (Configuration.t/0's strict_privacy) is for apps that can't let personal or
health data leave their own servers: an event carries only structured facts (the error's type,
its stack frames, release, environment, server, which route it happened in), never free text a
person could have typed. The rules, and the vectors every client's tests check against, are in
this repo's sdks/STRICT_PRIVACY.md; the server applies the same rules again on arrival
(app/services/strict_privacy.rb) when the project's own Strict privacy setting is on.
Summary
Functions
An error event's payload (ForgeOpsTracker.EventBuilder.build/7's shape) reduced to what strict
privacy sends: "message" is "" and "message_fingerprint" is added; breadcrumbs, endpoint,
SQL statement and source context are dropped; a raw-path "transaction_name" keeps only its first segment (see
transaction_name/1); context and tags keep only allowed_fields keys
with plain values (left out when nothing is left); the user keeps only its id.
The first 32 hex characters of the SHA-256 of normalize_message/1's UTF-8 bytes: lets ForgeOps
group errors whose messages differ only in ids, without the message being sent.
The message with hex object ids, UUIDs and standalone numbers replaced, in that order: "0x"
plus 4 or more hex digits becomes "0x", a UUID becomes "<uuid>" and a run of digits becomes
"<n>", the last two only where no ASCII word character touches them.
One finished span under strict privacy: its name per span_name/1, and its data reduced to
"db.statement" and "db.system" (left out when neither is there).
A span's name under strict privacy: an outbound call keeps its method and host
("GET https://api.example.com/patients/42?x=1" is "GET api.example.com"), a request named by
its path goes through strict_path/1 ("GET /patients/42/notes" is "GET /patients/:path"), so
does a bare path ("/42/edit" is "/:id/:path"), and any other name
("OrdersController#create") is kept.
A request or page path under strict privacy, with no query or fragment. A route template
("/patients/:id/notes", "/orders/{id}") is kept as it is: its words are a developer's and its
parameters are already placeholders. A raw path keeps only its first segment (":id" when it
holds an ASCII digit or is longer than 40 characters), then "/:path" if there was more, since
anything after it can name a person: "/patients/jane-doe/12" is "/patients/:path". No
segments at all is "/".
A transaction name under strict privacy: a route or a controller action is kept, but a raw path
keeps only its first segment, by the same rule as span_name/1. A blank name is returned as it is.
Functions
An error event's payload (ForgeOpsTracker.EventBuilder.build/7's shape) reduced to what strict
privacy sends: "message" is "" and "message_fingerprint" is added; breadcrumbs, endpoint,
SQL statement and source context are dropped; a raw-path "transaction_name" keeps only its first segment (see
transaction_name/1); context and tags keep only allowed_fields keys
with plain values (left out when nothing is left); the user keeps only its id.
The first 32 hex characters of the SHA-256 of normalize_message/1's UTF-8 bytes: lets ForgeOps
group errors whose messages differ only in ids, without the message being sent.
The message with hex object ids, UUIDs and standalone numbers replaced, in that order: "0x"
plus 4 or more hex digits becomes "0x", a UUID becomes "<uuid>" and a run of digits becomes
"<n>", the last two only where no ASCII word character touches them.
One finished span under strict privacy: its name per span_name/1, and its data reduced to
"db.statement" and "db.system" (left out when neither is there).
A span's name under strict privacy: an outbound call keeps its method and host
("GET https://api.example.com/patients/42?x=1" is "GET api.example.com"), a request named by
its path goes through strict_path/1 ("GET /patients/42/notes" is "GET /patients/:path"), so
does a bare path ("/42/edit" is "/:id/:path"), and any other name
("OrdersController#create") is kept.
A request or page path under strict privacy, with no query or fragment. A route template
("/patients/:id/notes", "/orders/{id}") is kept as it is: its words are a developer's and its
parameters are already placeholders. A raw path keeps only its first segment (":id" when it
holds an ASCII digit or is longer than 40 characters), then "/:path" if there was more, since
anything after it can name a person: "/patients/jane-doe/12" is "/patients/:path". No
segments at all is "/".
A transaction name under strict privacy: a route or a controller action is kept, but a raw path
keeps only its first segment, by the same rule as span_name/1. A blank name is returned as it is.