2021-04-15

 15 Apr 2021  guides

Opting your Website out of Google's FLoC Network

Google recently announced the rollout of their Federated Learning of Cohorts (FLoC), a new advertising-surveillance initiative that seeks to replace third-party cookies with a new user profiling technique that garners data generated by the browser itself.

The EFF has written an overview of FLoC and it’s threats  and has also developed a useful tool  to test if a user’s browser is being used for data collection and fingerprinting.

Plausible Analytics has also chimed in with an article explaining FLoC in relation to users and developers  — which was the inspiration for this short guide.

The FLoC Header

The primary way an end-user can avoid being FLoC’d is to simply not use Chrome, and instead choose a privacy-respecting browser such as Mozilla Firefox .

But website owners can also ensure that their web servers are not participating in this massive network by opting-out of FLoC.

To do so, the following custom HTTP response header needs to be added:

Permissions-Policy: interest-cohort=()

In this guide you’ll find instructions on how to add custom HTTP response headers to common web and proxy server configurations.

NGINX

Add the following in your NGINX configuration file:

# default.conf

server {
    location / {
      add_header Permissions-Policy interest-cohort=();

    ...
    }
}

Restart NGINX with the command service nginx restart

The only caveat to be aware of is that the add_header directive needs to be added within each server block if a single configuration file is used for multiple websites.

Apache

Add the following directive to your Apache configuration file:

# .htaccess 

<IfModule mod_headers.c>
  Header always set Permissions-Policy: interest-cohort=()
</IfModule>

Restart Apache with the command service apache2 restart

OpenLiteSpeed

Add the following context to your OpenLiteSpeed configuration file:

# vhost.conf 

  context / {
  location                $DOC_ROOT
  allowBrowse             1
  note                    This header disables FLoC
  extraHeaders            set Permissions-Policy interest-cohort=()
}

Restart OpenLiteSpeed with the command service lsws restart

Caddy

Add the following to your Caddyfile:

# Caddyfile

example.com {
    header Permissions-Policy "interest-cohort=()"

    ...
}

Restart Caddy with the command caddy reload

Varnish

Add the following to your Varnish configuration file:

# default.vcl

sub vcl_deliver {
    ...

    set resp.http.Permissions-Policy = "interest-cohort=()";

    ...
}

Restart Varnish with the command service varnish restart

HAProxy

Add the following directive to your HAProxy configuration:

# frontend, listen, or backend section

http-response set-header Permissions-Policy interest-cohort=()

Restart HAProxy with the command service haproxy restart

Traefik

Add the following to your Traefik TOML configuration file:

# traefik.toml

[http.middlewares]
  [http.middlewares.floc.headers]
    [http.middlewares.floc.headers.customResponseHeaders]
        Permissions-Policy = "interest-cohort=()"

Or the following if you’re using a YAML configuration file:

# traefik.yml

http:
  middlewares:
    floc:
      headers:
        customResponseHeaders:
          Permissions-Policy: "interest-cohort=()"

And if you’re using Traefik with Docker, add the following to your docker-compose.yml file:

# docker-compose.yml

labels:
  - "traefik.http.middlewares.floc.headers.customresponseheaders.Permissions-Policy=interest-cohort=()"

Lighttpd

Add the following to your Lighttpd configuration file:

# lighttpd.conf

server.modules += ( "mod_setenv" )

setenv.add-response-header = ( "Permissions-Policy" => "interest-cohort=()" )

Restart Lighttpd with the command service lighttpd restart

H20

Add the following to your H20 configuration file:

# h2o.conf

hosts:
  "example.com":
  ...

  header.set.ifempty: "Permissions-Policy: interest-cohort=()"
 
  ...

Restart H20 with the command service h2o restart

Netlify

Add the following to your Netlify configuration file:

# netlify.toml

[[headers]]
  for = "/*"
  [headers.values]
    Permissions-Policy = "interest-cohort=()"

If you prefer to use a _headers file instead of a TOML configuration file, then add the following to that file instead:

# _headers

/*
  Permissions-Policy: interest-cohort=()

On your next build or deploy, Netlify will add and serve the headers.

Vercel

Add the following to your Vercel configuration file:

# vercel.json

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Permissions-Policy",
          "value": "interest-cohort=()"
        }
      ]
    }
  ]
}

As with Netlify, on your next build Vercel will add and serve the headers.

GitHub Pages

GitHub announced on 2021-04-27  that they will add the necessary FLoC protection header to all GitHub Pages sites served from the github.io domain.

However, there is no way to add custom HTTP response headers (as yet) when using GitHub Pages with a custom domain.

GitLab Pages

If you use the Community Edition of GitLab you can set HTTP headers by adding the following to your gitlab.rb file:

# gitlab.rb

gitlab_pages['headers'] = [ "Permissions-Policy: interest-cohort=()" ]

You can also specify headers when running the GitLab Pages binary:

./gitlab-pages -header "Permissions-Policy: interest-cohort=()"

Cloudflare Workers

You can create the following to set response headers:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  let response = await fetch(request)
  let newHeaders = new Headers(response.headers)
  newHeaders.set("Permissions-Policy", "interest-cohort=()")

  return new Response(response.body, {
    status: response.status,
    statusText: response.statusText,
    headers: newHeaders
  })
}

Add that Worker script to a domain by setting that domain as the Worker Route.

WordPress

WordPress allows headers to be set from within it’s codebase via hooks. Add the following at the end of your active theme’s functions.php file:

# functions.php

add_filter(
	'wp_headers',
	function ( $headers ) {
		if ( empty( $headers['Permissions-Policy'] ) ) {
			$headers['Permissions-Policy'] = 'interest-cohort=()';
		} elseif (
			! empty( $headers['Permissions-Policy'] )
			&& false === strpos( $headers['Permissions-Policy'], 'interest-cohort' )
		) {
			$headers['Permissions-Policy'] .= ', interest-cohort=()';
		}

		return $headers;
	}
);

Save the file in the WordPress admin backend and all new requests will contain the necessary header.

If you’re using any caching mechanisms or plugins (such as NGINX’s FastCGI Cache, W3 Total Cache, etc.) you’ll also need to clear the cache so that it be re-populated with the above addition.

It’s also possible to use a plugin that inserts the Permissions-Policy header.

The only plugin I’ve tested and can recommend is Disable FLoC by Roy Tanck  as it takes into consideration the existence of other headers, and is written by a WP Core Contributor.

Notes

Adding <meta http-equiv="Permissions-Policy" content="interest-cohort=()"/> to the <head> of each page in an attempt to set the FLoC opt-out header not work.

This is due to both technical  and usability  reasons as only a small subset  of headers can be set using http-equiv — of which Permissions-Policy isn’t one of them.

As an aside, HTTP headers should ideally be set by a web or proxy server  in order for them to work as expected.

Acknowledgements

The following people helped to expand the information contained in this blog post:

  • Don Marti for clarifying the <meta> tag issue that led to it being removed
  • ‘Chronm’ for suggesting the addition of Traefik
  • Bryce Wray for providing the Vercel configuration snippet
  • Daniel Corbett for providing the HAProxy configuration snippet
  • Jeremy Herve for providing the WordPress code snippet
  • Bob Marksie for providing the Cloudflare Workers snippet
  • Gina Häußge and Martin Woodward (Sr. Dir. of DevRel @ GitHub) for notifying me about the GitHub Pages blog update where they’ve automatically enabled FLoC
Webmentions & Comments

Copyright © Paramdeo Singh. Built with Jekyll and ☕️ in Guyana. All Rights Reserved.

Last Site Build on Mon, 02 Aug 2021 12:05:40 -0400

1MB Club Badge

Paramdeo Singh Guyana

Riding the wave of consciousness in this treacherous mortal sea.

Technology Design Strategy Literature Personal Blogs