Purpose limitation at Meta’s scale

Purpose limitation — ensuring data is processed only for its explicitly stated purposes — becomes exponentially harder as data moves across dozens of interconnected systems. Meta’s data ecosystem comprises millions of data assets powering products, machine learning models, and analytics. Traditional “point checking” controls, which use conditional statements in code or access control lists on datasets, require constant audits and often break as codebases evolve. Physical separation of data into single-purpose assets also creates operational complexity that does not scale.

To handle this, Meta built Policy Zones, a technology that applies an information flow control (IFC) model to enforce purpose limitation across its infrastructure. This work is part of the company’s Privacy Aware Infrastructure (PAI) initiative, which embeds privacy constructs directly into Meta’s software stack. Policy Zones controls not just data access but also how data is processed and propagated in real time, eliminating the need for fragile point checks or out-of-band audits.

Instead of relying solely on ACLs or manual code reviews, Policy Zones uses data flow signals to build “data lineage” graphs that track relationships between source and sink data assets. Static code analysis, logging, and post-query processing feed these graphs, enabling permissions to be applied based on actual source-to-sink relationships. While the combination of point checks and data lineage is viable at small scale, Meta found it unsustainable for larger purpose limitation requirements spanning multiple systems. Policy Zones addresses this by providing a durable, IFC-based alternative.

Key design drivers

Meta’s experience deploying purpose limitation solutions revealed several themes that shaped Policy Zones’ design:

Needs Problem Solution
Programmatic Control: We needed to rely more on programmatic controls instead of point checking human audits to control data flows, and do so in real-time Traditional point checking controls, combined with data lineage checks, can detect data transfers within a specific time frame but not in real-time. Addressing these risks requires implementing resource-intensive human audits at access points. In contrast, PAI is designed to check data flows in real-time during code execution, blocking problematic data flows from occurring, facilitated by UX tooling, thus making it more scalable.
Granular Flow Control: We needed to maximize the reuse of existing data and business logic on complex infra Access control is easy to roll out when data is separated physically, but poses significant costs, complexity, and limitations when dealing with Meta’s complex infrastructure, where data for different purposes is often processed by shared code. PAI solves this by providing precise decision making at the granular level of individual requests, function calls, or data elements, achieving logical data separation at a relatively low compute cost even on complex infrastructures where it’s needed.
Adaptable and Extensible Control: We needed to handle ever-evolving requirements, even multiple for the same data assets We are facing a rapidly changing world for privacy. Data use restrictions can vary over time depending on evolving privacy and product requirements. A single data asset or different parts of it might be subject to multiple privacy requirements. While “point checking” can address this to some extent, it struggles to control downstream data flows, even combined with data lineage. PAI is designed to check multiple requirements involved in data flows and is highly flexible to adapt to changing requirements.

How Policy Zones works

Policy Zones provides a mechanism to encapsulate, evaluate, and propagate privacy constraints for data both in transit and at rest, including when data transitions between systems. It performs runtime evaluation of constraints and context propagation, with deep integration into Meta’s data and code frameworks, including HHVM, Presto, and Spark.

To illustrate, consider a new requirement: banana data can be used for making smoothies and fruit baskets but not for banana bread.

First, developers assign a metadata label (a “data annotation,” e.g., BANANA_DATA) to data assets at various granularities. Each annotation is associated with a set of data flow rules that describe the allowed purposes for the data.

When annotated data is processed, Policy Zones checks whether the processing is allowed — whether data can flow downstream. The technology is built into two main system types:

  • Function-based systems, where data is loaded, processed, and propagated through stacks of function calls in different programming languages. Examples include web frontends, middle-tier services, and backends.
  • Batch-processing systems, which process data rows in batch, mainly via SQL. Real-time and data warehouse systems that power Meta’s AI and analytics workloads fall into this category.

In function-based systems, data moves through parameters, variables, and return values in a call stack. Take this example:

  1. A web request, “BananaRequest,” loads annotated data from BananaDB. Policy Zones flags a data flow violation because the request’s intent is unknown.
  2. To remediate, annotate BananaRequest with the BANANA_DATA label, creating a “Banana Zone” for the request.
  3. At runtime, Policy Zones checks all data flows against the flow rules, flagging violations from BananaRequest to logB and logC.
  4. Annotate logB as banana and remove logging into logC to cut off the disallowed flow.
  5. Once all violations are remediated, the zone moves from logging mode to enforcement mode. Any future write to a sink outside the zone is automatically blocked.

In a more complex scenario, a function like makeBananaSmoothie() called from a “BreakfastRequest” might invoke another function, makeBanana(). If makeBanana() returns banana data to makeBananaSmoothie(), a violation occurs. creating a Banana Zone from makeBananaSmoothie() that encompasses all functions it calls directly or indirectly resolves the issue.

Batch-processing systems work analogously. When a job runs a query — typically SQL-based — against annotated tables, a zone is created and Policy Zones flags any data flow violations, with remediation options similar to function-based systems. Once all violations are resolved, the zone can be moved from logging to enforcement mode. Data annotation can happen at table, column, row, or potentially cell granularity.

Data flowing across systems — from frontends to data warehouses, then into AI pipelines — remains protected because Policy Zones ensures annotation is applied correctly at each hop. For systems where Policy Zones is not yet integrated, Meta retains point checking controls as a stopgap.

From annotation to enforcement: the Policy Zone Manager workflow

Rolling out Policy Zones across hundreds of systems is rarely a one-engineer job. A single purpose limitation requirement may touch dozens or even thousands of code and data assets owned by different teams. To make this tractable, PAI includes Policy Zone Manager (PZM), a set of UX tools that walks requirement owners through enforcement in four stages: identifying assets, discovering flows, remediating violations, and monitoring enforcement.

Step 1: Identify relevant assets

The first step is locating the data assets tied to a requirement — request parameters, database entries, or event logs collected through product entry points such as mobile apps, web requests, and databases. These assets and their fields are represented ("schematized") at various granularities. For example, a banana database table might consist entirely of banana data, a single banana column, or a mix of banana and other fruit data.

Manual code inspection is supplemented by Meta's scalable ML-based classifier to automatically identify relevant data assets.

Step 2: Discover relevant data flows

Once assets are annotated, the requirement owner traces downstream data flows and sinks. This can get tedious when flows extend one or multiple hops from the same origin — a common situation when applying a new requirement to existing data flows. Data lineage helps here. Although it carries significant operational overhead for point checking, lineage efficiently reveals where Policy Zones should be integrated. PZM incorporates data lineage so owners can discover multiple downstream assets at once. After implementation is complete, Policy Zones alone enforce the requirement.

Step 3: Remediate data flow violations

By default, a data flow from source to sink must satisfy every requirement attached to the source. Otherwise, it is flagged as a violation and must be remediated, with Policy Zones enforcing the decision programmatically at runtime. There are three remediation paths:

  • Safe flow — the data is used for an allowed purpose: assign the banana annotation to the sink asset.
  • Unsafe flow — the data is used for a disallowed purpose: block data access and code execution to stop further banana data processing.
  • Reclassified flow — banana data from the source is not used or propagated to the sink: annotate the flow as reclassified and permitted.

Step 4: Continuously enforce and monitor data flows

PAI checks data flows at runtime across Meta's major data systems. During initial rollout, Policy Zones can run in "logging mode" to allow remediation while collecting violation data. Once enforcement is enabled, any flow with unremediated violations is denied, including new violations introduced by future code changes. PZM also provides verifiers that continually check the accuracy of asset annotations and control configurations.

Lessons from scaling PAI across Meta

Widespread adoption of PAI across many purpose limitation requirements has surfaced several recurring lessons.

Solve one end-to-end use case first

Policy Zones were initially built for batch-processing systems with basic use cases. Designs for function-based systems remained abstract, and adopting them for a large-scale use case exposed significant gaps — mapping patterns to customer needs required substantial effort, and APIs and operational support had to be refined before the approach worked end-to-end across multiple systems. Only after that could the design be generalized across extensive platforms.

Streamline integration complexity

Integrating PAI into Meta's diverse systems was complex and took years. Early on, product teams spent considerable effort schematizing data assets across different data systems. The breakthrough came with reliable, computationally efficient PAI libraries in Hack, C++, Python, and other languages, which smoothed integration across a broad range of Meta's systems.

Invest in computational and developer efficiency early

Initial annotation APIs imposed high cognitive overhead on engineers, and data flow checking was too expensive for Meta's high-throughput systems. Multiple iterations simplified the policy lattice representation and evaluation, added language-level features for native Policy Zones context propagation, and canonicalized policy annotation structures — yielding a 10x improvement in computational efficiency.

Simplified, independent annotations are required for scale

A monolithic annotation API that modeled intricate data flow rules worked initially but broke down as data from multiple requirements was combined. Propagation from sources to sinks grew complex, and annotation conflicts were hard to resolve. The fix was decoupling data from requirements and separating data flow rules per requirement, which streamlined annotation and improved developer experience.

Tooling is not optional

Early PAI adoption was manual and error-prone — engineers struggled to annotate assets correctly, creating cleanup work later. The PZM tool family, with built-in automated rules and classifiers, now guides teams through standardized workflows, reducing engineering effort by orders of magnitude during rollout.

Toward durable privacy protection

Meta positions PAI as a foundation for sustainably addressing privacy challenges and meeting high reliability standards, with the ability to handle future privacy issues more efficiently than traditional solutions. The work continues: expanding capabilities and controls for a wider range of privacy requirements, improving the developer experience, and exploring new frontiers in privacy engineering.

The authors acknowledge the contributions of many current and former Meta employees who have played a crucial role in productionizing and adopting PAI over the years, including Adrian Zgorzalek, Alex Gorelik, Amritha Raghunath, Anuja Jaiswal, Brian Sniffen, Brian Romanko, Brian Spanton, Daniel Ramagem, David Detlefs, David Mortenson, David Taieb, Gabriela Jacques da Silva, Ian Carmichael, Itai Gal, Iuliu Rus, Jafar Husain, Jerry Pan, Jiang Wu, Joel Krebs, Jun Fang, Komal Mangtani, Marc Celani, Mark Konetchy, Matthieu Martin, Michael Levin, Nirman Gupta, Oliver Dodd, Parthiv Patel, Perry Stoll, Peter Prelich, Pieter Viljoen, Prashant Dhamdhere, Rajesh Nishtala, Rajkishan Gunasekaran, Ramnath Krishna Prasad, Rishab Mangla, Sergey Doroshenko, Seth Silverman, Sriguru Chakravarthi, Sushaant Mujoo, Tarek Sheasha, Thomas Georgiou, Uday Ramesh Savagaonkar, Vitalii Tsybulnyk, Vlad Fedorov, Wolfram Schulte, and Yi Huang. The authors also thank all reviewers, including Aleksandar Ilic, Benjamin Renard, Emil Vazquez, Emile Litvak, Harrison Fisk, Jason Hendrickson, Jessica Retka, Nimish Shah, Sabrina B Ross, and Sam Blatchford, as well as Emily DiPietro for championing the idea and leading the editorial effort.