Problem/Motivation
Google is introducing what it calls Federated Learning of Cohorts, which is a way to gather user data without cookies, regardless of whether a website is loading any Google-related trackers. This is enabled starting in Chrome 89, and only in select countries on a trial basis.
Although other major browser vendors are likely against this technology and will presumably not be implementing it, given Chrome’s market share this will become a concerning issue, because it largely remove users’ ability to easily opt out of being tracked—particularly true in the case of less-savvy users.
See a very informative post by Plausible.
Since no one can reasonably expect users to just stop using Chrome, it will be up to responsible developers to block FLoC at the source.
Steps to reproduce
Proposed resolution
Blocking FLoC is as easy as adding this header to the HTTP response:
Permissions-Policy: interest-cohort=()
Remaining tasks
User interface changes
None.
API changes
None.
Data model changes
None.
Release notes snippet
Introduce Permissions-Policy
header to block Google’s Federated Learning of Cohorts.
Tasks Remaining
Create MRAdd testsCreate Change Record
Issue fork drupal-3209628
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
xjmComment #3
Wim LeersAlso relevant reading: https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea.
As described in https://www.theverge.com/2021/4/16/22387492/google-floc-ad-tech-privacy-..., Brave and Vivaldi condemned it, while Edge, Firefox and Safari have "no plans to implement yet".
IMHO Drupal should disable it by default; at a minimum until it's been proven to not be a privacy risk.
Comment #4
e0ipsoI support this feature! Software freedom should be on the side of the user. Free open source software like Drupal has ethical motivations. Therefore I think it makes sense for this feature to be the default for all Drupal installs, and optionally turned off.
I think that an approach like the FLoC Blocker module would work in core.
The most important impact of this issue is that this becomes the default for all the future Drupal installs. Ethics included. 😄️
Comment #5
Wim LeersFor the record: our friends at WordPress are planning to block it too over at https://make.wordpress.org/core/2021/04/18/proposal-treat-floc-as-a-secu... — it's only a proposal, but the comments on this proposal are overwhelmingly in favor of blocking.
Comment #6
rachel_norfolkWhilst we absolutely should work towards a core module that handles lots of privacy features, Wim has it right here - implement this by default until we incorporate it into something bigger.
Seems like a quick win to publicly declare our intentions.
Comment #7
Simon Georges CreditAttribution: Simon Georges at Makina Corpus commentedIt seems the header will not be enough in some cases: https://seirdy.one/2021/04/16/permissions-policy-floc-misinfo.html.
Comment #8
mtiftI support this issue and agree that it makes sense in Drupal core.
Comment #9
phenaproximaI, too, support blocking FLoC out of the box, for the utterly basic torches-and-pitchforks reason that I despise targeted advertising (actually all advertising, but that's a different discussion) with every fiber of my being and would like to do everything possible to harm, hamper, and stymie it. I'm a simple man, but +1 for this.
Comment #10
antiorario CreditAttribution: antiorario commentedI’m very happy this issue has gained some visibility and support. That said, the post Simon Georges is linking to in #7 is hitting some of my initial doubts on the head, and particularly:
I agree with most of that, but as a developer I feel like I’m swimming against an unstoppable tide of small (and less small) acts of prevarication coming from Google, and I personally have no way to make Chromium developers change their ways—or grow an ethical conscience. So I act at the level I have the most control over, and hope others will follow.
(The part I don’t agree with is the framing of this and other similar situations as Google going to war against its users, since this is more like hunting for prey—but I digress.)
Sharply aware of that. However:
With tools like Google Tag Manager at the disposal of any marketing department, this is a lost battle. And I’ll leave it at that.
But I will submit my code later today.
Comment #11
xmacinfoIn addition to blocking Google’s FLoC directly in core we should also make sure that Drupal.org (and sub-sites) implements it's own blocking mechanism now.
Comment #12
rachel_norfolk...noted
Comment #13
longwave@xmacinfo I raised #3209738: Add Permissions-Policy header to block Google FLoC on drupal.org to deal with this on drupal.org itself.
Comment #14
xmacinfoContrib module for those who want to implements the FLoC shield now:
https://www.drupal.org/project/flocblock
Comment #15
rachel_norfolkSo, if we have some code in core, we need to ensure that it also checks that this header has not also been added by other means, or does that matter?
Comment #16
beltoftePermissions Policy is a web platform API which gives a website the ability to allow or block the use of browser features in its own frame or in iframes that it embeds. It operates on the principle that top-level documents should generally have access to the web's powerful features (often at the discretion of the user, who needs to grant permission), but that embedded content should not have such access automatically. A document which embeds another document should be able to declare which features it trusts that embedded content to use.
The Permission-Policy header has other purposes, so we can't just overwrite it. If it exists will we have to add the value "interest-cohort=()" to the existing list of header values. Find more info about the header in w3c documentation.
Comment #17
rootwork100% in favor of this. And while I read with interest the post linked from #7 and share most of its worries, especially:
I also think this section is important:
While Drupal developers could choose to use this header or not, end-user Drupal site admins/authors/clients may not have the power/interest/familiarity to take care of this themselves. And as noted by @antiorario in #10, there's the easily imagined scenario with a marketing department and Google Tag Manager.
With WordPress (noted above) and PHP.net already on board, I strongly support Drupal taking this step as aligning with our values and principles.
Comment #18
antiorario CreditAttribution: antiorario as a volunteer commentedI made a commit to the issue fork: https://git.drupalcode.org/issue/drupal-3209628/-/commit/0ae3abe402d1690....
I considered what rachel_norfolk and beltofte said in #15 and #16, and decided against checking for existing
Permissions-Policy
headers, since this gets called so early in the game that we’re most likely not overwriting anything else. However, if the consensus is to still add that check, I can do that.Perhaps something like this (although I might be overthinking it):
Comment #19
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI haven't read the spec and some of the other links in this issue yet, but I'm wondering if it's enough to only set the header from PHP. That would mean that it isn't set for requests to static files: whether that's images/css/js, or whether that's public files uploaded into a file field / media entity.
If Google honors the header from an HTML response and applies it to images/css/js loaded by that HTML as well, that would cover most static files, but would still leave public files. We could potentially add the header in the .htaccess file for the public files directory to address that if needed. It would be good to not have to add it to the docroot's .htaccess, but that's also a last resort option if the other places aren't sufficient.
Comment #20
beltofte@antiorario Your solution makes sense when thinking more about it. If a large organization wants to use this header to block or restrict some of the supported browser features, then would they probably do it in their reverse proxy or webserver and not on application level. This should work fine with the implementation in your fork.
Comment #21
Wim LeersFor the record: our friends at Joomla are likely going to block it by default as well: https://github.com/joomla/joomla-cms/pull/33212.
Comment #22
beltofteOne more for the record :-) The Umbraco team is currently discussing doing the same https://github.com/umbraco/Umbraco-CMS/issues/10147.
Comment #23
DamienMcKennaShould I open a separate issue to backport this to D7?
Comment #24
xmacinfo> Should I open a separate issue to backport this to D7?
Yes, please do. Drupal 7 does not have a contrib module to block Google’s FLoC, so dealing with in core will be welcome.
Comment #25
beltofteThere is a D7 version on this project https://www.drupal.org/project/flocblock :-)
Comment #26
antiorario CreditAttribution: antiorario as a volunteer commentedI wouldn’t leave D7 behind 🙂
(But I’m also not sure what I did for D7 is the best solution, with
hook_init()
and all.)Comment #27
DamienMcKennaI created a D7 issue for this: #3209976: Add Permissions-Policy header to block Google FLoC (D7)
Comment #28
Cellar Door CreditAttribution: Cellar Door commentedI'll chime in here and say I think this is a great addition to core and one that as a community allows us to highlight that privacy is important to our work. To Rachel's point, eventually this should be taken into larger work around privacy and ensuring that site builders and owners are aware of the privacy implications of the various modules and capabilities of the site. Documentation around this change may be worthwhile as well, so eventually should a site owner want to reverse it they know how.
I'll give my +1 for the solution and the code in the branch by @antiorario.
Comment #29
steinmb CreditAttribution: steinmb as a volunteer commentedI support blocking it out of the box, both D7 and 8/9/10.
Comment #31
phenaproximaThis code looks very straightforward to me, though I requested one small nitpicky change.
More important is that we'll need test coverage, so marking this as "needs work" for that. I would suggest following the lead of
\Drupal\Tests\system\Functional\System\ResponseGeneratorTest
. Create a new test in the same namespace which does similar stuff, but checks for the appropriate Permissions-Policy header. (You can probably just copyResponseGeneratorTest
wholesale and tweak it appropriately. It might be a good idea to eventually merge this new test withResponseGeneratorTest
, maybe even before this is committed, but the easiest thing to do for now is to have them be separate tests.)If we end up doing more complex logic to merge the interest-cohort directive with an existing Permissions-Policy header, we'll probably need to add another test as well -- most likely a unit or kernel test -- to prove that it behaves the way we expect it to. But right now, this code is very simple, so I think a simple test in the mold of
ResponseGeneratorTest
is appropriate.Comment #32
rachel_norfolkHmm. Whilst I absolutely think we need this in core and we need it to be the default behaviour, I also think that a site owner should be able to disable it, even if we don't necessarily provide a UI to do so right now (until we have a comprehensive privacy section in Drupal core?).
Could we check for a Drupal setting, like
$settings['interest_cohort_blocker_subscriber'] = FALSE;
perhaps? If it is TRUE OR it is not defined, then assume that we can bloc FLoC but, if it is false, then don't block?Think of the "I absolutely support the use of FLoC" site owner. We may not agree with their approach but we should cater for it, even minimally.
Comment #33
longwaveRe #32 this is very similar to the issue that has stalled #3104566: Implement Server Timing performance metrics where there is the opinion that some site owners might want to turn this feature off, but there is no consensus on the best way of allowing them to do so. Whatever we decide here might also help move that issue along.
Comment #34
Dries CreditAttribution: Dries commentedI'd love to see this added to core and enabled by default. We should provide an option/mechanism to disable it though.
I already use a Permissions-Policy header on my personal blog, for example.
Comment #35
rachel_norfolkOkay, if we have something like
to add in a check, then
are we heading in the right direction?
Comment #36
rachel_norfolkOoooh - whoops - that's what you get for writing code before breakfast...
Should be
because we only to progress to setting the header if there is no setting or a setting is TRUE...
(I'm off to mess with spreadsheets and chat with community on Slack instead - clearly, that's where my skills lie these days 🤣)
Comment #37
phenaproximaYup, that seems correct to me! Plus test coverage, of course. :)
Comment #38
longwaveSo these are the options that were proposed in the Server-Timings issue:
1. doesn't apply here because we want this in more than just development sites.
2. is what the current patch implements; this enables it by default but makes it difficult for most site owners to remove again.
3. would enable it by default on new sites (e.g. if we added it to the Standard profile), and makes the feature both quite visible to site owners and easy to disable again if they don't want it (they can just uninstall the module). This is equivalent to adding https://www.drupal.org/project/flocblock to core.
4. is similar to 2. but easier to disable (they can add a line to services.local.yml)
5. is what is proposed in #35, there are multiple sub-options here; we can either do it in settings.php (less visible to site owners) or as a checkbox somewhere in an admin form with associated config storage (more visible, but where would it go?)
Comment #39
phenaproximaIMHO, the easiest way to get this implemented quickly, while ensuring there is an escape hatch for savvy site operators, is a setting. Doing it in config means the MR will be bigger and potentially have an update path (to create the new config option). Adding anything in the UI means we'll probably have to undergo UX review. All of these things take time.
If we add it as a setting, then we get the best of all worlds: this gets done as soon as possible, but technical people can change the behavior. Dunno about you, but that sounds good to me!
Comment #40
rachel_norfolkOkay, added the code above and an entry in default.settings.php
Also adding some tasks to the Issue Summary...
Comment #41
trebormcI am activating right now https://www.drupal.org/project/flocblock in my websites. I think it is the easiest/fastest way right now.
I think it would be better to include this module in the core and let the installation profile be in charge of activating it by default. Users can always disable the module. Similar to what happens with other core modules like RDF.
Comment #42
xmacinfoI like the setting approach.
Marked as needs review. But this won't make it a candidate for RTBC until tests are cooked in.
Comment #43
phenaproximaTo keep the status accurate, this should probably be "needs work" until tests are completed. :)
Comment #44
rachel_norfolkJust adding same changes to the scaffolding default.settings.php
Comment #45
rachel_norfolkJust to address @trebormc's comment in #41 for a moment, the reason to make this a self-contained event subscriber in core, rather than an extra module, even an extra core module, is to ensure that we can easily enable it for currently deployed sites. To try and add a new module in such a fashion would require new/changed configuration etc etc.
It also means that, should FLoC no longer be a thing Google choose to reply long term, deprecating this will be easier, too. We could simply remove it (with all due deprecation notices etc etc) without cause yet further config alternations etc.
Comment #46
trebormcThanks @rachel_norfolk , that makes sense.
It's true that it makes sense to be as simple and transparent to the common user as possible. And with this we avoid modifying configurations of currently active websites.
And it is true that if google abandons FLoC deprecar this is much more complex if it is a module.
I hadn't thought about it!!
Comment #47
neclimdulAdditional point against the core module, there's a lot of cost to modules so for a single subscriber built directly into core there just doesn't seem to be a reason to take on all that cost.
Bike shed but the setting name might be better as something descriptive instead of tied to the description. Something like 'block_interest_cohort'. Makes the behavior changed by the setting a little clearer and self documenting(IMHO).
Comment #48
effulgentsia CreditAttribution: effulgentsia at Acquia commentedNormally, I would say that something like this should be a config, not a setting. The vast majority of the time, that would require a UI as well, but occasionally we do allow new config to go in and defer the UI to a followup. Config (whether it has a UI or not) can be controlled via settings.php via the
$config
variable that's in that file, as well as via whatever config deployment process that the site uses.As a general rule,
$settings
should only be for things that can't or shouldn't be in config (such as database connection info, or where your config sync directory is) or for environment-specific technical settings (like information about your reverse proxy if you're using one).However, @phenaproxima is right that adding a new config object would require a post_update function, and we try to avoid those for patch releases. So from the perspective of backporting this to 8.9/9.0/9.1, adding a new key to $settings would be more expedient.
To balance the trade-offs, I think my preferred option at the moment would be to do it as a key in $settings for now, then have a follow-up for Drupal 9.3 to move it to a $config object and deprecate the $settings key, and then remove the $settings key in Drupal 10.0.
I pinged the other committers to get their opinion on this as well.
Comment #50
longwaveRenamed the setting as in #47 and added a test.
Two questions:
1. Should we only set the header if it's not already set?
If we pass FALSE as the third argument to
set()
it will not override the header if something has previously set it.2. It seems unlikely that the setting will be changed regularly. Instead of checking the setting in
onKernelResponse()
should we move it togetSubscribedEvents()
so it is only checked when the event subscribers are built, and then the event subscriber won't run at all once it has been set to FALSE?Comment #51
phenaproximaDid a quick review of the merge request; a few small points!
Comment #52
phenaproximaI'm not sure. The problem here is that any contrib or custom code which innocently adds a Permissions-Policy header before our event subscriber runs could inadvertently allow FLoC, which may not be desired behavior.
It probably makes sense for us to set the header if it doesn't already exist, or append to an existing header if it does. My cursory research suggests that Permissions-Policy directives are separated by a semicolon.
That seems a little more complicated than it needs to be, and I'm not aware of any core precedent for such a pattern. AFAIK, the current settings are stored in memory for the duration of the request, so I imagine it'd be pretty trivial to check them at runtime. Unless there's some other potential benefit that I'm not seeing?
Comment #53
longwaveStill not sure what to do about the case where the header is already set. I checked contrib and flocblock is the only module that sets the header so far, so perhaps we can just do nothing or log a warning if the header exists.
I don't know if splitting on semicolon is enough, the spec for parsing a dictionary in an HTTP header seems non trivial if I follow all the links in https://www.w3.org/TR/permissions-policy-1/#algo-process-response-policy down to https://tools.ietf.org/html/rfc8941
AFAIK event subscribers are collected once when the container is built. Therefore if this is implemented when the setting is disabled the class will never even be loaded when the onKernelRequest event is fired, as it was already excluded at container build time. This is perhaps a micro-optimization that we don't need, though.
Comment #54
longwavehttps://github.com/gapple/structured-fields is a PHP library for handling HTTP structured fields to the RFC 8941 spec but that seems a bit much to add for what is likely to be an edge case.
Comment #55
phenaproximaI'm actually not even suggesting we parse the header at all; just append to it if it's already set. Something like this (pseudocode):
So basically, just "append to an existing header, if there is one". No parsing involved!
Comment #56
longwaveWhat if
interest-cohort
already appears in the header?Comment #57
rachel_norfolkWhen does this event subscriber run, in the course of a response? Is there actually any chance at all that there could be anything there already? Do *any* contrib modules get hold of the response before this core event subscriber?
Comment #58
phenaproximaGood question. I think we could probably just add the directive if it's not already there. Something like:
Not sure. I think a bunch of event subscribers will act upon the response (including ones from contrib). Event subscribers can be prioritized explicitly, but if several subscribers have the same priority, I don't know how or if they are sorted.
There is definitely a chance. It would be fairly trivial for code to have a higher-priority event subscriber that sets a Permissions-Policy header. I do think it's an edge case, although I'm have no evidence to support that assumption.
Comment #59
longwaveI've had a look through existing code and wonder if we are over engineering this. Perhaps this should just be added to
FinishResponseSubscriber::onRespond()
which already adds a number of headers:This event subscriber is also responsible for adding the various cacheability headers including the ones used for debugging.
Note here that in a number of cases we use FALSE as the third argument to avoid overwriting any headers that might have already been set.
Comment #60
effulgentsia CreditAttribution: effulgentsia at Acquia commented+1
However, these examples are for headers that only have a single value. Because
Permissions-Policy
can have a list of features, I think checking if the header is already set but without theinterest-cohort
feature included, and in that case appending that feature, is a good idea.Comment #62
Maeglin CreditAttribution: Maeglin commentedAnother factor that should be noted with the "Is the header already set?" question is web server config, and when headers are set that way compared to PHP setting them. In my Apache config, I have a Permissions-Policy header set to block hosted sites from using camera or microphone APIs (not hosting any web-based conferencing systems, so that makes sense), and I add interest-cohort to the list for sites that aren't really meant for public eyes, since it wouldn't make sense to include those in an advertising interest group.
Incidentally, policies stated in a Permissions-Policy header are separated by commas, not semicolons. Semicolons were used with the older Feature-Policy header.
Comment #63
longwaveAddressed #59/#60 by merging the event subscriber into FinishResponseSubscriber. Also added extra code and test cases to cover #60.2.
@Maeglin we cannot know what the web server config is, as the response is generated inside Drupal and then the web server is free to further modify that response. The underlying problem here is similar to #2854817: Duplicate X-Content-Type-Options headers both with the value nosniff. I can only suggest that if you are already adding Permissions-Policy at the web server level then you will need to disable the additional header in settings.php via the new flag.
Also thanks for the note about commas vs semicolons, I checked the spec and this is correct - the most recent code uses a comma to append a new policy if an
interest-cohort
is not already present.Comment #64
rachel_norfolkUpdating tasks needed in the Issue Summary.
Can someone confirm we do indeed need a change record here?
Going to have a look at the User Guide now…
Comment #65
rachel_norfolkRemoving requirement to add to User Guide, having spoken with @Jhodgdon.
Back to Needs Review and the first review needed is whether we need a change record...
Comment #66
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI think we do need a change record. One, to let people know about the new setting in settings.php. Two, this is a potential BC break for the rare case where someone is conditionally setting the Permissions-Policy header (whether for the
interest-cohort
feature or for some other feature, likegeolocation
) in their .htaccess file or in a reverse proxy, if the header doesn't already exist. In the case of.htaccess
that can be easily fixed by using the merge action instead of a conditionalset
. In the case of reverse proxies, it would need to be done using whatever syntax is available by that software.Comment #67
rachel_norfolkHere's a start on a change record. Trying to keep it as simple as possible - it's on by default and here's how to switch it off.
https://www.drupal.org/node/3213197
Comment #68
rootworkMade some edits:
Other thoughts:
Comment #69
xmacinfoI think that we should mention this in Tweets, Blog posts, Newsletter. Dries could write something. 🙂
No need to mention in the CR that other projects did the same thing.
Comment #70
rachel_norfolkThanks for those change record updates, @rootwork, they help a lot.
That is all the remaining tasks completed. I'm going to set to RTBC and see what happens!
Comment #71
AaronMcHaleThis is a positive addition to Core.
Perhaps the momentum here could also be used to consider other additions relating to privacy and security, for instance adding support to Core for configuring Content Security Policy.
Content Security Policy contrib module
Comment #72
larowlanReview the MR and it looks good to me. Leaving to @effulgentsia to see this home, as he's been involved for some time
Comment #73
DamienMcKennaMight there be any chance of this being added to 9.2.0, or is it too late for that?
Comment #74
webchickTechnically it missed the 9.2 alpha deadline, but due to strategic importance, there seems to be general concurrence that if it makes it in before beta, we can still get it into 9.2. 🙏
Comment #75
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThe MR looks great. I'm going to commit this to 9.3.x and 9.2.x. In the default.settings.php file, I'm going to change the docs to link to https://en.wikipedia.org/wiki/Federated_Learning_of_Cohorts instead of https://plausible.io/blog/google-floc to match the change record. I can do that on-commit, no need to update the MR.
Adding issue credit to folks who reviewed the patch and/or CR. I'm not adding credit to people who only commented on the idea to do it, though I do appreciate everyone's input on that as well, thank you!
Comment #78
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThanks all!
Comment #79
gappleI'm a little late on awareness of this issue, but it is... relevant to my interests... (Refactoring and updating the Feature Policy module to a Permissions Policy module is on my list of things [and was, but is no longer held up by needing to write the Structured Fields Values php library first]).
The name and documentation for
$response->headers->set()
's third parameter is misleading, as it toggles between replacing an existing header or appending a new header of the same name (which raises some questions about whether it's being appropriately used on the existing calls within FinishResponseSubscriber...), so the has+set that was implemented is the right way to go.I think appending to an existing header, is maybe not the right thing to do.
- If someone has a custom subscriber already setting a Permissions-Policy header, I think they're likely aware of FLOC and able to update their policy, and core shouldn't be making the intervention.
- I think more importantly though non-core service definitions are loaded after core's, and AFAIK that will cause module event subscribers with the same priority to execute later. As a result, core will (1) most likely never execute the append line of code, and (2) always have its header overwritten by any other implementation anyways (unless the custom subscriber was given a higher priority to execute earlier so that core could append to it, which would be an odd choice over just setting the desired value directly).
- (If subscriber order of equal priority was not deterministic, that would probably be a bigger issue as it would be inconsistent if core would append to a value set elsewhere or not).
---
Given the current concerns about FLOC, default configuration for the Permissions Policy module will include
interest-cohort=()
by default.---
A tangent on @AaronMcHale's comment about Content Security Policy in core - I'm of mixed opinion given there are some gotchas that possibly prevent core from implementing anything other than a policy so permissive as to be meaningless without frustrating users who don't have some knowledge of CSP (and users with knowledge would be capable of installing and configuring a contrib module which could have a more restrictive default configuration than core would be able to).
My efforts for now are: improving core to no longer require policy exceptions (see the upstream issues in the CSP issue queue); supporting other contrib modules in integrating with CSP (and also not requiring unsafe policy exceptions); increasing the ease of implementing, monitoring, and improving a policy using the CSP module; and increasing awareness of CSP as a tool to mitigate XSS and other security risks.
Comment #81
gappleComment #82
ChaseOnTheWebIf you set
$settings['block_interest_cohort'] = FALSE;
, then core doesn't try to set the header at all. Doesn't this address your concern? Any contrib module wanting to manage this header could recommend this setting. The settings.default.php documentation could even be updated to something like, "If you don't wish to disable FLoC, or wish to manage the Permissions-Policy header via a module, set this value to FALSE."Comment #83
Gábor Hojtsy@gapple: this issue already has a commit. To keep credits properly, change records properly and other things, in core we use separate issues for followup changes. If this issue needs to be rolled back, that would necessitate reopening the issue. Please open a followup for further changes.
Comment #84
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI agree with #82. In addition to that,
I disagree with that assumption. If there's a subscriber that sets
Permissions-Policy: geolocation=()
, I don't see why we should assume that it's expressing any awareness of or opinion about FLOC. And in the absence of it expressing an opinion about FLOC, or$settings['block_interest_cohort']
expressing an opinion about it, we should implement Drupal's default, which is to disable it. If that subscriber does intend to express an opinion about FLOC, it can do so withPermissions-Policy: geolocation=(), interest-cohort=(*)
if it wants FLOC enabled for all origins, or it can set a specific list of origins if it wants that.Comment #85
rowan_m CreditAttribution: rowan_m commentedChrome DevRel here, I understand you've already added this to the beta but I'd like to add some context and sources for ongoing discussion.
I don't see the FLoC proposal itself linked in this discussion, so I'd certainly recommend reading through for appropriate context to any implementation: https://github.com/WICG/floc
FLoC is currently in origin trial which is a mechanism Chrome uses to allow developers to test early proposals in real world conditions with a limited percentage of Chrome users. That means that nothing about FLoC is final, including the site opt-out mechanism via Permissions-Policy. Origin trials are explicitly designed to have an end point and gap between the experiment and any stable functionality expressly to prevent sites relying on origin trial functionality in production. You can read more on the origin trial details here: https://developer.chrome.com/blog/floc/
As such, I would not recommend making core changes based on an origin trial. Given you've already committed code, it would make sense to proactively raise a new issue to track this as the trial progresses and watch for any necessary changes.
It's also worth noting that the origin trial inclusion criteria for a site being used as part of a user's FLoC are: does the site use FLoC itself or does the site use any ads-tagged resources. The inclusion of sites with ads-tagged resources was a way of approximating a selection of sites that are already using third-party cookies in order to deliver interest-based advertising. Again, while an origin trial means no details are fixed, a stable version of FLoC would be far more likely to be opt-in, e.g. using FLoC means the site is included in the FLoC calculation.
What this means is that a default Drupal site is not included in the FLoC origin trial. The only way a Drupal site would be part of the FLoC origin trial is if it either calls the API or if it includes ads-tagged resources.
The effect of setting this header is purely that it prevents a developer from making use of FLoC on their own site without updating the configuration first.
To help understand what FLoC is trying to achieve, it may be useful to look at it in the context of drupal.org. If I arrive as a fresh visitor to the site, I'm presented with the banner, "Can we use first and third party cookies and web beacons to understand our audience, and to tailor promotions you see?" The third-parties that drupal.org adds to the site use a cookie to identify an individual user as they browse across different sites.
FLoC is exploring the option of enabling the use case of tailored promotions without requiring third-parties to track individual users. Instead, the browser is able to present a shared FLoC cohort instead. Any given FLoC cohort is shared across thousands of other users. Instead of needing to track an individual, third-parties can look at the aggregate behaviour of the FLoC cohort instead.
So, the opt-out here raises the barrier for developers to experiment with and contribute to a proposal for the web platform that's focused on improving privacy. Conversely, adding services with individual cross-site tracking to a Drupal site faces no such friction.
Additionally, it's worth understanding the Permissions-Policy header in more detail. This is the format that Feature-Policy is migrating to and the syntax more closely resembles that of Content-Security-Policy. The intent is to allow a site to expressly allow access to specified functionality to listed origins. The module from @gapple looks like a solid base here. I would expect use of the Permissions-Policy header to continue to grow, it's required for functionality such as delegating access to User-Agent Client Hints as they start to replace the user-agent string.
Very happy to discuss this more, but to sum it up: default Drupal sites are not included in FLoC and adding the Permissions-Policy to the core on the basis of an origin trial is not advised.
Comment #86
rachel_norfolkThanks for the information, from a Chrome DevRel point of view.
If, at the end of the trial, there are changes that need to be made, then we would welcome a follow-up issue.
Comment #87
gappleI've opened a new issue: #3218139: Stop altering existing Permissions-Policy header in FinishResponseSubscriber
My primary concern was my second point:
This results in a section of code that is normally unreachable, but with the potential for unexpected behaviour in non-typical circumstances.
--
A module which wants to ensure full control over the header can set its subscriber to priority
-1
so that it's guaranteed to execute later, and modify/replace/remove as desired.There's an issue on the Permissions Policy module looking for feedback on the expected behaviour when the module's configuration is disabled or empty, but it ignores core's attempted modification of any existing value because it's not relevant: #3216790: Overriding core header value in certain cases
I don't see a reason for a module subscriber that sets a Permission Policy to specify a higher priority so that it executes before core's subscriber, which is the one case that it would allow core to append to the existing value. (Instead of just unconditionally overwriting core's default, and adding
interest-cohort
or not as desired)--
Some more context on my statement
My inference from that is that currently there's a limited number of people implementing a Permissions Policy header, and they are likely to be relatively informed early adopters.
If their intent is to implement a strict policy, it is necessary to periodically review the available features to block new ones.
And FLoC and interest-cohort have received some pretty prominent coverage that I think would have caught the attention of anyone who has already implemented a policy.
But relevant to my earlier point, I don't think in either of the cases that someone currently has implemented their policy through web server config or through a custom response event subscriber would the core code to modify an existing value on the response object ever execute, and the value now set by core would just be overwritten by the custom value.
--
A tangent - this issue highlighted some likely unexpected/undesired behaviour in how core currently sets some other headers in the same subscriber: #3214208: FinishResponseSubscriber could create duplicate headers
Comment #88
nod_from mozilla : https://blog.mozilla.org/en/mozilla/privacy-analysis-of-floc/
Comment #89
izmeez CreditAttribution: izmeez commented@nod Thanks for the link. Interesting detailed article. Bottom line is targeted ads are wrong! The way they're done now and the proposed cohort methods are all wrong. People who use the Internet are not subjects to be treated as data and profiled. This sort of data is an addiction. We should go back to generic ads. Let the user decide if it has merit; no coercion, no selection, no targeting.
Comment #91
anoopjohn CreditAttribution: anoopjohn at Zyxware Technologies commentedGoogle has killed FLoC. So should this ability and the corresponding config remain in core. Browsers have started stopping support for this and throwing errors around the header.
#3284706: Error in Edge browser - Error with Permission-policy header: origin trial controlled feature not enabled 'interest cohort'
Comment #92
rachel_norfolkGood question. Regardless of the answer, the correct thing to do would be to create a follow up issue, referencing this one, to propose that.
Comment #93
rootworkThis is happening over at #3260401: Google is abandoning FLoC - so remove the header
Comment #94
Graham Leach CreditAttribution: Graham Leach commentedHello,
I am getting the following error in the CHROME console (press F12 to see it) with respect to my D7U3 site:
Error with Permission-Policy header: Origin trial controlled featured not enabled: 'interest-cohort'.
I was able to remove this error by adding the following line:
$conf['block_interest_cohort'] = FALSE;
To the end of:
After the line was added, I also needed to perform a cache flush and reload of the page.
The error then disappeared from the console.
Cache Flush:
Reload: