Skip to content

Pluggable, competition-neutral modules with a technical permission model #777

Description

@jwrosewell

Overview

Trusted Server hard-wires several request-time decisions (how the Edge Cookie identity is minted, how a request is classified for the bot gate, how geolocation is resolved) and gates Edge Cookie creation on a country rule baked into the core. This epic makes each capability a configuration-selected module behind a small trait, named by its crate folder, with neutral defaults that make no host-specific call, and replaces the baked-in gate with a technical permission model.

Privacy is a spectrum, not a binary, and Trusted Server is technology that is neutral on policy. Different deployers operate under different laws and run different policies, so it is the deployer who decides how to configure the stack. This work provides the mechanisms and respects the deployer's choices, rather than deciding on their behalf. The default deployment makes no host-specific call, creates no identifiers, and resolves no location until an operator enables these features via a module. The existing implementations are retained.

The permission model: separating legal policy from the core

The Trusted Server core does not encode any jurisdiction's law or any single policy. Instead, a module declares the technical permissions its data use requires, and the core runs the module only when those permissions are held.

How a permission becomes held is established outside the core, from one or more sources (permission signal modules):

  • (a) Country, when known. Resolved from the country the geo module returns, keyed by ISO 3166-1. When no country is identified, the deployer's required default country ([geo] default_country) applies. Trusted Server does not assume a jurisdiction, so a default is always declared and startup fails without one.
  • (b) Interaction with the user. A publisher may interact with the user to establish their preference. This is the publisher's choice and need not be driven by a legal requirement. A publisher may do it because they want to, not only because a law requires it.
  • (c) Data provided from another source. For example a browser extension, or a person's profile provided by an external service.

The permission vocabulary uses the IAB TCF Europe purpose set only as technical identifiers. No policy framework is implemented in the core. Trusted Server provides the mechanism to establish and check permissions, and the deployer brings the policy that decides how permissions are established and what they permit. The model is source-agnostic. It gates on whether a permission is held, not on how it was established, so the sources above plug into the same mechanism.

Tasks

Delivered by the stacked pull requests #1043, #1044, #1045, #1046, #1047 and #1094, with the design in #1084, which close each task on merge. In that series every module is named by its crate folder and selected from the table of its type, as [ec] module, [device] module, [geo] module and [permission-signal] modules, and the auction's [demand] modules and [ad-server] module select the same way.

Related

Activity

  1. jwrosewell commented on Jun 21, 2026

    @jwrosewell
    CollaboratorAuthor

    Provider wiring: dependency injection

    Recording the provider-wiring approach here, as it is part of this rework rather than a separate issue. Delivered by the neutral-providers PR.

    The pluggable providers are wired by dependency injection rather than handed a fixed evidence struct. A provider's constructor takes the services it needs as trait objects, and the adapter, acting as the composition root, supplies concrete instances per request. Core defines the service interfaces and the host-neutral defaults. The interfaces are RequestInfo (the client IP, User-Agent, and headers) and HostSignals (the TLS JA4 and HTTP/2 fingerprints). Host-specific implementations such as FastlyHostSignals live in their own crates and are injected by the adapter, so core never calls a host SDK and the default request path makes no host-specific call. A provider that needs a service the host cannot supply cannot be built, so the request stops rather than minting a degraded identifier.

    As implemented:

    • Core defines the RequestInfo and HostSignals service traits, with an owned default (OwnedRequestInfo).
    • RuntimeServices carries the optional host-signal service, supplied by the adapter composition root.
    • build_provider and build_device_provider inject the services each provider needs.
    • A provider whose required service the host does not supply fails to build, and the request stops.
    • The neutral built-in providers require no host service, so the default path makes no host-specific call.
  2. added theissue type on Oct 1, 2026
  3. changed the title [-]Pluggable, competition-neutral providers with a technical permission model[/-] [+]Pluggable, competition-neutral modules with a technical permission model[/+] on Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions