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 emails, quoted values, hex object ids, UUIDs and standalone numbers replaced, in
that order: an email becomes "<email>", a double or single quoted run becomes "<str>", "0x"
plus 4 or more hex digits becomes "0x", a UUID becomes "<uuid>" and a run of digits becomes
"<n>". A single quote, a UUID and a number count 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 emails, quoted values, hex object ids, UUIDs and standalone numbers replaced, in
that order: an email becomes "<email>", a double or single quoted run becomes "<str>", "0x"
plus 4 or more hex digits becomes "0x", a UUID becomes "<uuid>" and a run of digits becomes
"<n>". A single quote, a UUID and a number count 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.