Skip to content

0.5.0 - 2026-10-15

Latest

Choose a tag to compare

@github-actions github-actions released this 16 Oct 07:12
b4b20b2

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[].flow is now findings[].flows, a
    list. Finding IDs hash the rule, the sink, needs_review and 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 (was properties.flow). explain prints every flow of a finding. diff
    counts an exposure that gained a flow or a category as changed.
  • A finding whose only category is unknown is uncertain under every rule: info,
    needs_review: true, and a message that starts uncertain: 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_personal names also stop request input under that name.
  • A whole claims list (User.Claims, ClaimsPrincipal.Claims,
    AuthenticateAsync().Principal.Claims) is personal data of category user, 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.
  • scan resolves requests through registered clients (ADR 0022).
    It uses the bindings datamap already 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 optional destination (internal or processor, with the
    registrations).
    • More clients bound: named HttpClients (AddHttpClient("name", …) with
      CreateClient("name")), ConfigureHttpClient chained 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
      and systems.yml.
  • Coverage gaps have an impact (ADR 0023).
    • Levels: high when personal data reaches the call, medium when only values that need
      review do or when the gap exists whatever the data, low when 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 at info at most, and SARIF results carry gap_impact.
    • Schema: gaps gain impact and impact_reason.
  • 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.

Added

  • device_storage, a sink class for a native app's storage on the device: .NET MAUI (and
    Xamarin.Essentials) SecureStorage.SetAsync and Preferences.Set, which were coverage gaps.
    Like browser storage, its flows are reported and no rule fires on them.

Fixed

  • piiflow datamap no 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's meta.privacy_flow.proposals for review, and is
    never filled in. Undecided declarations of such systems are listed in needs_review.
  • piiflow datamap no 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/piiflow

Download 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-flow

You 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