Privacy Model and Guarantees¶
Enforced export policy¶
Evaluation reports are local-only. Creating a shareable JSON artifact requires an
explicit release-policy/v1 policy and successful disclosure checks. A missing,
invalid, disabled, or failed policy produces local results and a local
*.shareable.release-audit.json; it removes any stale shareable file.
Add a release section to an evaluation config, or pass a policy file to
plb compare --release-policy release.yaml. For example:
release:
schema_version: release-policy/v1
id: reviewed-study-2026
enabled: true
min_samples: 20
min_cell_size: 5
require_privacy_audit: true
The standalone comparison policy file contains these fields without the outer
release key. Dry-run an existing local receipt with:
plb release-check reports/run_receipt.json --policy release.yaml
Dry runs do not export, upload, or consume a release approval. The writer also checks local repeated-release history; a successful dry run alone does not guarantee that a later export will be permitted.
Every upstream privacy/aggregate gate must explicitly pass when present. A missing
required audit is not_run; unrecognized audit evidence is inconclusive.
An audit passing a configured policy is empirical evidence, not proof of privacy.
Synthetic examples explicitly waive the audit requirement; review that decision
before adapting their configuration to private data.
The prediction demo's separate risk policy specifies thresholds but its table has no membership-audit split. Its export is therefore blocked even though the demo release policy waives a general audit requirement. Waiving that requirement never overrides a failing upstream gate.
The exporter selects known metric and uncertainty fields. It omits local paths,
configurations, artifact names/hashes, sample identifiers, private model/project
labels, free-form metadata, and arbitrary plugin fields. Input column names are
withheld unless include_input_schema: true is deliberately approved. Benchmark
identity must be supplied explicitly through public_benchmark in the policy.
Undefined numeric metrics are represented by JSON null.
Slices stay local by default. A policy may approve one disjoint partition and its
exact public labels, such as slices: {site: [a, b, c]}. If any category is missing,
unexpected, or smaller than min_cell_size, the whole partition is withheld,
including its counts. Multiple overlapping partitions are rejected. Clean
intervals and clean slice metrics are withheld when overall metrics are perturbed.
The output directory's local .plb-release-ledger.json records approved aggregate
content by policy ID. Unchanged releases may be reproduced. Changed content under
the same ID requires a deliberate reviewed_repeat: true and a local
review_reference identifier. The override is audited and never bypasses other
gates or cell thresholds. Keep policy IDs and the ledger stable for a study;
moving directories or changing IDs starts a separate approval scope. This is a
local safeguard, not a global privacy accountant or a defense against a malicious
owner releasing additional information through other tools.
Writes use a local ledger lock and atomic file replacement. A failed export or invalid ledger fails closed. A leftover lock from an interrupted process requires local inspection before removal. These controls do not establish differential privacy or guarantee that overlapping studies cannot disclose information.
PrivateLabBench separates privacy mechanisms, privacy audits, and release policies. These are different tools and must not be interpreted as equivalent evidence.
1. Exact reporting (mode: none)¶
Exact aggregate metrics are computed and reported locally. There is no privacy guarantee for the reported aggregate itself.
2. Heuristic metric perturbation (mode: metric_perturbation)¶
This is the successor to the historical mode: dp option.
privacy:
mode: metric_perturbation
epsilon: 8
sensitivity: 1
seed: 13
The implementation adds independent Laplace noise to already-computed aggregate metrics using:
noise_scale = user_supplied_sensitivity / epsilon_like_parameter
This mode is intentionally labeled:
guarantee_level: heuristic_no_dp_guarantee
formal_dp: false
What it can be useful for¶
- experimenting with privacy/utility tradeoffs;
- reducing precision of released aggregate metrics;
- testing downstream workflows that expect perturbed metrics.
What it does NOT establish¶
It does not prove differential privacy because PrivateLabBench does not establish, for arbitrary model metrics:
- the global sensitivity of each released query;
- the adjacency relation over private datasets;
- clipping/bounding assumptions for every metric;
- privacy loss from releasing several statistics together;
- implementation-level numerical guarantees.
The name epsilon is retained for backward-compatible configuration, but in metric_perturbation it is an epsilon-like noise parameter, not a certified privacy budget.
Legacy mode: dp¶
mode: dp remains accepted temporarily to avoid breaking existing configs, but it is a deprecated alias for metric_perturbation. It emits a warning and reports formal_dp: false.
3. Bounded-query DP primitives¶
PrivateLabBench includes a separate reference API for queries where sensitivity can actually be established.
Bounded mean threat model¶
BoundedMeanQuery assumes:
- a fixed-size dataset;
- replace-one adjacency: adjacent datasets differ in one individual's record but have equal size;
- public lower/upper value bounds chosen independently of the sensitive data;
- each value is clipped locally to those bounds before aggregation.
For n records in [lower, upper], the mean has L1 sensitivity:
(upper - lower) / n
release_bounded_mean adds Laplace noise with:
scale = sensitivity / epsilon
Under the stated adjacency/bounds assumptions, this is the standard pure epsilon-DP Laplace construction in the mathematical real-arithmetic model.
The returned metadata explicitly records:
- bounds;
- sample count;
- computed sensitivity;
- epsilon/delta;
- adjacency model;
- noise scale;
- guarantee label.
Composition¶
PrivacyBudget tracks sequential composition. release_bounded_means allocates a declared total epsilon budget across several releases and refuses to exceed it.
The ledger reports both total spend and per-query spends.
Numerical implementation note¶
The built-in bounded-mean mechanism is a small reference implementation using NumPy floating-point arithmetic and random sampling. It is useful for making query contracts, bounds, sensitivity, and accounting explicit.
Its serialized release excludes the exact clipped mean; that attribute is for
local inspection only. A supplied seed enables deterministic tests and labels
the result none_deterministic_test_seed, with no DP guarantee. Never publish a
known-seed result as a private release. The optional OpenDP API has no seed.
For high-assurance deployment where numerical details and end-to-end transformations must be inside a vetted privacy proof, use a specialized DP system such as OpenDP rather than treating this reference implementation as the final production backend.
Optional OpenDP backend¶
Install the optional backend with pip install 'private-lab-bench[opendp]'.
It supports a bounded column mean with public, fixed sample size and replace-one
row adjacency. One row must represent one individual's bounded contribution.
It does not provide person-level privacy for repeated measurements without an
appropriate contribution-bounding transformation.
from privatelabbench.privacy import OpenDPBoundedMean, PrivacyBudget
# Choose these values from public policy, before inspecting the private data.
budget = PrivacyBudget(epsilon_limit=1.0)
query = OpenDPBoundedMean(
name="public-normalized-score", lower=0.0, upper=1.0,
public_size=3, epsilon=0.5,
)
result = query.release([0.1, 0.5, 1.2], budget=budget)
print(result.as_dict()) # noisy value and public query/backend metadata only
# Reuse this SAME budget for another release about the protected population.
The complete chain uses OpenDP's clamp, mean, and Laplace constructors. It checks the upstream privacy map at symmetric distance 2, corresponding to replacing one row. Calibration uses the upstream numerical sensitivity bound, including floating-point effects. OpenDP supplies the randomness; this API has no seed and does not fall back to NumPy if the optional dependency is missing.
The ledger rejects nonfinite spends and compares the exact binary floating-point
spends without absolute slack. Usage rounds upward and remaining budget rounds
downward. Boundary allocations may need headroom: 0.1 + 0.2 exceeds the binary
float 0.3, so that combination is rejected. Batch reference allocations are
normalized exactly and rounded down. A spend is charged before sampling, including when sampling
fails. This ledger is in memory and sequential: retain it for every query on
the population. Applications must provide durable accounting and synchronization
across restarts, processes, exports, and other systems. Starting a new ledger does
not reset a population's actual privacy loss.
The result excludes exact means, rows, IDs, file paths, and input hashes. Bounds, size, query names, epsilon, the choice of queries, and the decision to publish must all be public and independent of private values. Keep validation errors and local diagnostics private. Publishing exact evaluation receipts beside a DP mean can invalidate the intended protection; this API does not convert existing reports or release policies into an end-to-end DP pipeline.
The supported backend line is OpenDP 0.16. Its constructors currently require the
upstream contrib feature, which this backend explicitly enables. OpenDP's
mean guide
and Laplace proof
describe the primitives and their assumptions. Use this specialized backend for
its numerical mechanisms and checked maps; this wrapper has not received an
independent privacy/security audit, and enabling an upstream feature does not
certify the surrounding application.
4. Privacy attacks are empirical audits, not guarantees¶
The built-in loss-threshold membership-inference attack is registered as:
loss-threshold-membership-inference
baseline: true
evidence_level: empirical_audit
guarantee: none
A high attack score can identify a meaningful leakage signal. A low attack score does not prove privacy, differential privacy, or resistance to stronger attacks.
The threshold diagnostic gives members and nonmembers equal weight, even when
their sample counts differ. It checks both loss directions; attack_auc reports
the stronger orientation and directional_attack_auc retains the lower-loss
orientation. threshold_attack_accuracy is balanced accuracy, with its basis and
threshold direction recorded alongside it. Thresholds are selected on the audit
sample itself, so these are descriptive diagnostics, not held-out attack accuracy.
Inputs must contain aligned, finite scores; classification requires binary targets
and probabilities in [0, 1].
Risk policies reject unknown fields, nonboolean require_attack, and thresholds
outside [0, 1], including NaN and infinity. Heuristic metric perturbation also
requires finite positive parameters and a representable positive noise scale.
The attack registry exists so the community can add stronger audits without changing the meaning of any formal privacy mechanism.
5. Release policies¶
Privacy-risk gates and minimum-client/sample release guards are policy decisions over observed metadata. They can block sharing when evidence is insufficient or risky.
They are not cryptographic or differential-privacy guarantees.
Safe interpretation checklist¶
Before describing a PrivateLabBench output as differentially private, verify all of the following:
- The release was produced by an explicitly bounded formal query API, not
metric_perturbation. - The adjacency model matches the intended privacy unit.
- Bounds are public/non-sensitive and valid for the problem.
- The reported sensitivity follows from that query and adjacency model.
- The privacy budget includes all released DP queries under the relevant composition rule.
- The implementation/backend is appropriate for the assurance level required by the application.
If any item is missing, describe the output as an exact aggregate, heuristic perturbation, empirical privacy audit, or policy gate as appropriate—not as a formal DP guarantee.