Repository navigation
Release Notes
Findings a person can act on. A finding is now an exposure: one rule at one sink, with its flows
as evidence, so the same personal data no longer repeats as one finding per field and hop (on
dotnet/eShop, 214 findings become 60). Data whose category cannot be determined is reported as
uncertain, identifiers of things are not personal data, requests through registered clients
resolve to the system they reach, and coverage gaps are ranked by impact. piiflow datamap always
writes valid Fideslang. The flow-facts document is schema 0.2 and finding IDs change once; see
Changed.
Changed
- A finding is an exposure: one rule at one sink, with every flow the rule fires on there as
its evidence (ADR 0020). A log call that receives a
whole address is one PF001 finding with five categories, not five. Flows that need review are a
separate finding at the same sink. On dotnet/eShop 214 findings become 67; on the benchmark
corpus 13,705 become 3,617. Flows are unchanged. - The flow-facts document is schema version 0.2:
findings[].flowis nowfindings[].flows, a
list. Finding IDs hash the rule, the sink,needs_reviewand the categories, so every finding
about flows has a new ID. - Dispositions carry forward by ID, or by the flows a new finding shares with decided ones when
those covered all its categories. Decisions in a 0.1 document carry to the exposures whose
flows were all decided alike. - SARIF: a code flow per flow, the sources as
relatedLocations, the flow IDs in
properties.flows(wasproperties.flow).explainprints every flow of a finding.diff
counts an exposure that gained a flow or a category as changed. - A finding whose only category is
unknownis uncertain under every rule:info,
needs_review: true, and a message that startsuncertain: data of undetermined category.
Request input the analysis cannot name (req.body, a query parameter) kept the rule's
severity before, so a logged request body failed the default policy; its classified fields
still do (ADR 0021). - Identifiers of things are not personal data: names made of entity words and an identifier
suffix (item_id,catalogItemId,BrandIds,item_type_id) are never classified, request
input under such a name (Blazor[Parameter]and[SupplyParameterFromQuery]properties,
FastAPI path parameters) is not a source, and request input read through one
(Request.Query["itemId"]) is not reported. The words are in
catalogue/classification.yml. Person identifiers (user_id,customer_id) are unchanged. - A project's
not_personalnames also stop request input under that name. - A whole claims list (
User.Claims,ClaimsPrincipal.Claims,
AuthenticateAsync().Principal.Claims) is personal data of categoryuser, no longer
unknown: logging it, or sending it to a model, is a finding at the rule's severity again. A
single claim looked up by type is still classified by the type (FindFirst("email")), and a
claim read off the list into a classified field is reported as that field. scanresolves requests through registered clients (ADR 0022).
It uses the bindingsdatamapalready made: an HTTP call whose client's base address names a
system of the repository is internal, not a PF006 finding. One that names an outside host names
that processor. Sinks gain an optionaldestination(internalorprocessor, with the
registrations).- More clients bound: named
HttpClients (AddHttpClient("name", …)with
CreateClient("name")),ConfigureHttpClientchained on a registration, and base addresses
read from configuration: service discovery keys, connection strings, and keys the .NET Aspire
app host sets to another project's endpoint (WithEnvironment). - Catalogue digest. The flow catalogue's digest now covers
catalogue/topology/clients.yml
andsystems.yml.
- More clients bound: named
- Coverage gaps have an impact (ADR 0023).
- Levels:
highwhen personal data reaches the call,mediumwhen only values that need
review do or when the gap exists whatever the data,lowwhen the call only presents data in
the app's interface (catalogue/presentation.yml: .NET MAUI dialogs, navigation, bindable
properties, animations). - Where it shows: gaps are listed most urgent first, the PFC01 message names the impact, a
low-impact gap is reported atinfoat most, and SARIF results carrygap_impact. - Schema: gaps gain
impactandimpact_reason.
- Levels:
- On dotnet/eShop, against the exposures above:
- PF006 5 → 3 findings (35 → 10 flows): the web app's order request and the webhook client's
calls are internal; - PFC01 27 → 25, with 16 high, 4 medium and 5 low;
- flows 208 → 221.
- PF006 5 → 3 findings (35 → 10 flows): the web app's order request and the webhook client's
Added
device_storage, a sink class for a native app's storage on the device: .NET MAUI (and
Xamarin.Essentials)SecureStorage.SetAsyncandPreferences.Set, which were coverage gaps.
Like browser storage, its flows are reported and no rule fires on them.
Fixed
piiflow datamapno longer writes privacy declarations with an empty name or data use, which
Fides rejects. They came from privacy-datamap manifest systems the code does not have: their
declarations were copied in whole, including ones nobody had decided. A declaration without a
name or a data use now goes to its system'smeta.privacy_flow.proposalsfor review, and is
never filled in. Undecided declarations of such systems are listed inneeds_review.piiflow datamapno longer writes a map that fails its Fideslang checks. It exits 3 and names
each problem; before, it only warned. A declaration without a name is now one of those problems.
Install privacy-flow 0.5.0
Install prebuilt binaries via Homebrew
brew install noru-tech/tap/piiflowDownload privacy-flow 0.5.0
| File | Platform | Checksum |
|---|---|---|
| privacy-flow-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| privacy-flow-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| privacy-flow-aarch64-unknown-linux-musl.tar.xz | ARM64 MUSL Linux | checksum |
| privacy-flow-x86_64-unknown-linux-musl.tar.xz | x64 MUSL Linux | checksum |
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo noru-tech/privacy-flowYou can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation> --repo noru-tech/privacy-flow