Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Nebula support for P3A/Constellation #22522

Merged
merged 10 commits into from
Jun 21, 2024
Merged

Add Nebula support for P3A/Constellation #22522

merged 10 commits into from
Jun 21, 2024

Conversation

DJAndries
Copy link
Collaborator

@DJAndries DJAndries commented Mar 9, 2024

Resolves brave/brave-browser#35841

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

Ensure requests are being sent to star-randsrv.bsg.brave.com and collector.bsg.brave.com as usual. Each collector request should have the Brave-P3A-Constellation-Threshold header set with a value of 20 or 50. Ensure the metrics get marked as sent in local state as usual.

@DJAndries DJAndries force-pushed the nebula-p3a branch 2 times, most recently from ba21e34 to da4b4b4 Compare March 23, 2024 01:19
@DJAndries DJAndries marked this pull request as ready for review March 23, 2024 01:19
@DJAndries DJAndries requested a review from a team as a code owner March 23, 2024 01:19
@DJAndries DJAndries requested a review from rillian March 23, 2024 01:20
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"

namespace p3a {

namespace {

constexpr std::size_t kP3AConstellationCurrentThreshold = 50;
constexpr double kNebulaParticipationRate = 0.105;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to describe what these two parameters do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the ParticipationRate meant to be 1.0 in the future (after the test) or will we always keep both rates?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The participation rate is derived from the threshold, privacy budget ε and expected population size δ. It isn't ever expected to become one, but we could of course adjust the trade-offs in the future.

@@ -25,6 +25,9 @@ class SharedURLLoaderFactory;

namespace p3a {

inline constexpr size_t kConstellationDefaultThreshold = 50;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, an explanation would be nice.

I think they are both the number of reports that need to be identical (i.e. k-anonymity), but one is for people who are enrolled into Nebula and the other is the current system?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right. @AliShahin determined we could lower the threshold number of identical reports needed for recording under differential-privacy sampling. So this is the value used for the current system, but questions for which we turn on Nebula will use the lower threshold.

components/p3a/metric_names.h Show resolved Hide resolved
@@ -21,6 +21,9 @@ BASE_FEATURE(kTypicalJSONDeprecation,
BASE_FEATURE(kOtherJSONDeprecation,
"BraveP3AOtherJSONDeprecation",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kNebula,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs short explanation and / or link to a doc

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some doc comments in b89ce25.

// mark request as successful to avoid transmission.
constellation_prep_log_stores_[log_type]->DiscardStagedLog();
constellation_prep_schedulers_[log_type]->UploadFinished(true);
delegate_->OnMetricCycled(log_key, true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we return here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, good catch. thanks

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a return in 5da6c5f.

constexpr double kNebulaParticipationRate = 0.105;
constexpr double kNebulaScramblingRate = 0.05;

bool CheckParticipationAndScrambleForNebula(std::vector<std::string>* layers) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps this is "MaybeScrambleForNebula" ? it feels like "check & scramble" implies both actions are done no matter what

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 1289c83 with a comment, since the function still does two different things.

MetricLogType log_type,
uint8_t epoch,
StarRandomnessMeta* randomness_meta,
::rust::Box<constellation::RandomnessRequestStateWrapper>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps we can move lib.rs.h include to .cc now

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not yet. This file still uses types from rust cxx reflection in the public definition of StarRandomnessPoints.

Copy link
Contributor

@iefremov iefremov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with nits
please use const for local vars to improve readability

@iefremov
Copy link
Contributor

also we could make randomness parameters configurable via Griffin (as feature parameters)

@rillian
Copy link
Collaborator

rillian commented May 30, 2024

also we could make randomness parameters configurable via Griffin (as feature parameters)

NB this makes the most sense for kNebulaScramblingRate which we want to check the value of based on how test telemetry performs. The other values are calculated from the differential privacy budget and shouldn't need heuristic adjustment.

@rillian
Copy link
Collaborator

rillian commented Jun 17, 2024

Rebased to work around the unrelated noplatform ci failure.

rillian and others added 10 commits June 21, 2024 11:11
Describe where the new constants come from and link to the original
issue which describes the protocol design.
Use `const` annotations for local variables that don't need
multiple assignment to make the flow contract more obvious.

Addresses a review comment.
Halt with an assert violation instead of dereferencing a null.

Addressses a review comment.
This really does two things, which I've tried to make more clear
with a comment, but `MaybeFoo` is a more common idiom in our code,
and it avoids the misleading idea that scrambling happens most of
the time.
Return early after discarding Histograms which won't be submitted
so we don't waste time trying to process them further.
Copy link
Contributor

[puLL-Merge] - brave/brave-core@22522

Description

This PR implements the Nebula differential privacy protocol for P3A (Privacy-Preserving Product Analytics) in Brave. The changes introduce sampling and randomization techniques to enhance privacy protection for certain metrics while maintaining the ability to collect aggregate data.

Changes

Changes

  1. components/ai_chat/core/browser/ai_chat_metrics.cc & .h:

    • Added a temporary histogram for Nebula experiment: kChatCountNebulaHistogramName
  2. components/misc_metrics/general_browser_usage.cc & .h:

    • Added a temporary histogram for Nebula experiment: kWeeklyUseNebulaHistogramName
  3. components/p3a/constellation_helper.cc & .h:

    • Implemented MaybeScrambleForNebula function to apply Nebula protocol
    • Added constants for Nebula participation and scrambling rates
    • Updated ConstructFinalMessage to include threshold parameter
    • Added kNebulaThreshold constant
  4. components/p3a/features.cc & .h:

    • Added a new feature flag kNebula for enabling Nebula differential privacy
  5. components/p3a/message_manager.cc & .h:

    • Updated OnNewConstellationMessage to handle Nebula protocol
    • Modified StartScheduledUpload and StartScheduledConstellationPrep to check for Nebula-specific histograms
  6. components/p3a/metric_names.h:

    • Added kNebulaOnlyHistograms set for metrics that should be protected by Nebula
  7. components/p3a/p3a_message.cc & .h:

    • Modified GenerateP3AConstellationMessage to support Nebula format
  8. components/p3a/star_randomness_points.cc & .h:

    • Refactored to use callback-based approach for handling randomness data
  9. components/p3a/uploader.cc & .h:

    • Added is_nebula parameter to UploadLog method
    • Included Nebula-specific threshold header in requests

Possible Issues

  • The temporary nature of some added metrics and TODOs suggests that this implementation might require further refinement or removal after the experiment is complete.
  • The hardcoded values for participation and scrambling rates might need adjustment based on real-world performance and privacy requirements.

Security Hotspots

  1. The MaybeScrambleForNebula function is critical for maintaining privacy. Any flaws in its implementation could potentially leak sensitive information.
  2. The randomization process in MaybeScrambleForNebula relies on base::RandDouble() and base::RandBytes(). Ensure these provide cryptographically secure random numbers.
  3. The kNebulaThreshold value is crucial for privacy guarantees. Any changes to this value should be carefully considered and validated.

@DJAndries DJAndries merged commit 8b35b86 into master Jun 21, 2024
19 checks passed
@DJAndries DJAndries deleted the nebula-p3a branch June 21, 2024 22:33
@github-actions github-actions bot added this to the 1.69.x - Nightly milestone Jun 21, 2024
@GeetaSarvadnya
Copy link

GeetaSarvadnya commented Jun 24, 2024

Verification PASSED on

Brave | 1.69.44 Chromium: 126.0.6478.114 (Official Build) nightly (64-bit)
-- | --
Revision | da765e582c092d04ea7277304e412f200b373445
OS | Windows 10 Version 22H2 (Build 19045.4529)

And

Brave | 1.69.49 Chromium: 126.0.6478.126 (Official Build) nightly (64-bit)
-- | --
Revision | c33444fc19e6209b33c70ce2aa22f77ff7ceb113
OS | Windows 10 Version 22H2 (Build 19045.4529)

Test Plan

Test plan verification_PASSED
  • Confirmed that each collector request have the Brave-P3A-Constellation-Threshold header value 20 or 50
slow express typical slow express typical
image image image image image image

Regression test

  • Verify requests are sent to star-randsrv.bsg.brave.com and collector.bsg.brave.com endpoints as usual
Step 1_PASSED
  • Confirmed that JSON metrics are sent as usual to the endpoint p3a-json.brave.com
  • Confirmed that each metric is sent to the server and marked as "sent" = true in the local state file

randomness metrics at http://p3a-json.brave.com/

Example Example Example Example Example Example Example Example Example Example Example Example
image image image image image image image image image image image image
  • Confirmed that if the metric is in the logs object (in local state), then the cadence is typical and the same is displayed in p3a-json.brave.com endpoint in the server
Example Example Example Example
image image image image
  • Confirmed that, If the metric is in logs_slow then the cadence is slow and same is displayed in the p3a-json.brave.com endpoint in the server

  • Confirmed that, If the metric is in logs_express then the cadence is express and the same is displayed in p3a-json.brave.com endpoint in the server

  • Only 3 metrics are shown under the logs_express but in p3a-json endpoint, I could see only two cadence express metrics sent to the endpoint p3a-json.brave.com and one metric is sent to the endpoint https://p3a-creative.brave.com

Example Example Example https://p3a-creative.brave.com
image image image image
Example Example Example
image image image
  • Confirmed that the cadence field in the payload contains the correct value
  • The metrics Brave.Shields.AdBlockSettings response value is 1 in both local state file and p3a-json... endpoint
Step 2_PASSED
  1. Confirmed that requests are being made to star-randsrv.bsg.brave.com to prepare Constellation metrics
  2. Confirmed that the URL path is /instances/<cadence type>/randomness
  3. Confirmed that when one request is sent for a particular cadence, check to see that metrics are being marked as "sent" as they are being sent to the server, by checking the correct "logs" object in local state.

46 randomness requests are sent to this endpoint star-randsrv.bsg.brave.com

Step 1,2 Step 1, 2(1)
image image

46 typical logs metrics are shown under Logs in brave://local-state

Step 3 Step 3(1) Step 3(2)
image image image
  1. There are 46 metrics listed under Logs as shown in the images above Step 3, Step 3(1) and Step 3(2) and 46 metrics are listed under logs_constellation_prep shown in the images below Step 4(1), Step 4(2) and Step 4(3)
    All the metrics under Logs and logs_constellation_prep are marked as sent:true, when we look at the https://star-randsrv.bsg.brave.com endpoint at the server, 46 typical metrics are sent to the server in the form of randomness instances as shown in the images above Step 1,2(1) and Step 1,2(2)

46 metrics are shown under logs_constellation_prep

Step 4(1) Step 4(2) Step 4(3) Step 4(4)
image image image image
  1. Confirmed that no. of metrics shown under logs_constellation_prep_express are same as the no. of metrics shown under logs_express and express instances at the star-randsrv.bsg.brave.com server endpoint as expected
logs_constellation_prep_express logs_express express
image image image
  1. Confirmed that no. of metrics shown under logs_constellation_prep_slow are same as the no. of metrics shown under logs_slow and slow instances at the star-randsrv.bsg.brave.com server endpoint as expected
logs_constellation_prep_slow logs_slow slow
image image image
Step 3_PASSED
Ensure final measurements are being sent to collector.bsg.brave.com. The URL path should be /<cadence type>. Before metrics are sent to this server, they should appear under constellation_logs, constellation_logs_express and constellation_logs_slow after being prepared (from the requests being made in step 2). As soon as the metrics are sent to the collector, the metric should disappear in the relevant local state object.
  1. Confirmed that, before the metrics are sent to server they are prepared to sent and hence appear under logs_constellation_prep_express, logs_constellation_prep_slow and logs_constellation_prep after that the metrics are appear under constellation_logs, constellation_logs_express and constellation_logs_slow .
    But the metrics listed under constellation_logs, constellation_logs_express and constellation_logs_slow are removed once the metrics are sent to the server

metrics prepared

Example Example Example Example
image image image image

constellation logs
image

  1. Confirmed that the final measurements are sent to the endpoint collector.bsg.brave.com
    • Two slow metrics are sent to the endpoint collector.bsg.brave.com as expected
    • Two express metrics are sent to the endpoint collector.bsg.brave.com instead of three
    • There is one creative cadence type metrics are sent to the endpoint collector.bsg.brave.com - Not sure whether this is expected or not there is no mention of this metrics in the test plan (this is expected as per the response below)
    • There are 46 typical metrics are sent to the endpoint collector.bsg.brave.com as there are 46 typical metrics are listed under Logs in brave://local-state file
Example Example
image image

@GeetaSarvadnya
Copy link

GeetaSarvadnya commented Jun 24, 2024

@DJAndries: All the requests are not sent to star-randsrv.bsg.brave.com endpoint to prepare Constellation metrics, most of them are failing due to 504 Gateway Time-out
image

@GeetaSarvadnya
Copy link

cc: @kjozwiak @LaurenWags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants