Purpose limitation at Meta scale
Meta’s Privacy Aware Infrastructure (PAI) program is built around enforcing purpose limitation on data as it moves through the company’s systems. The latest piece of that effort is Policy Zones, a runtime enforcement layer that applies Information Flow Control (IFC) principles to batch processing pipelines. Policy Zones sits atop Meta’s exabyte-scale data warehouse and stream processing infrastructure, which transports multiple petabytes per hour. It performs trillions of user consent checks per hour across hundreds of distinct data policy requirements for any given data flow.

Before Policy Zones, Meta relied on access control lists (ACLs) to protect datasets. That approach required physically separating data into coarse-grained groups, each with a single purpose. It worked at small scale but created heavy operational overhead, demanding frequent and exhaustive audits of individual assets to maintain a meaningful privacy control.
Policy Zones: Controlling data flow, not just access
Policy Zones extends beyond conventional access control. Instead of only checking who can read a dataset, it tracks how data is processed and transferred in real time, enforcing flow restrictions automatically. The core principle is monotonic: downstream data must carry restrictions that are equal to or more restrictive than those on upstream sources. If a processing step is incompatible with a dataset’s restrictions, it is blocked.
Meta’s data warehouse runs millions of batch jobs daily, transforming data through complex dependency graphs. Policy Zones controls access to millions of datasets and analyzes tens of millions of data flows per day across hundreds of thousands of distinct queries. The dependency web is dense — each dot in the following diagram is a dataset, and each line is a data dependency required to compute it.

That complexity drove the design choices shown below, which map the key challenges of batch processing governance to the solutions Policy Zones implements.
| Challenge | Approach |
| Coarse-grained data separation to compartmentalize purpose use: A common strategy for managing distinct purposes is to separate data and its processing entirely, a technique known as data compartmentalization. However, this approach can be difficult to implement due to the intricate web of data dependencies that exist within our systems. | Fine-grained information flow tracking: We track how data flows to ensure that the restrictions are at least as restrictive as the sources used to populate the output datasets. As a result, engineers do not need to coarsely compartmentalize their data. Fine-grained tracking allows us to more efficiently profile risk without needing to separate data and its processing to specific purposes. |
| Overly conservative labeling of data (label creep): By default, any incidental access of purpose-use limited data results in all of the derived datasets needing to be purpose-use limited, even if the access is spurious. We need a way to stop propagation (called reclassification) of sensitive data labels when the data is transformed to no longer be sensitive. | Policy Zone Manager (PZM): We built a suite of tools that aids in carefully propagating purpose-use limitations that will identify potential over-labeling situations; these are controlled through a reclassification system, which allow engineers to safely stop propagation. |
| Lack of governance, extensible data model: There are numerous internal data policies and individual privacy controls active at any given time, with new policies being created regularly by various public commitment-oriented teams. These teams need to have strong controls over how their data policies are being enforced. It’s also critical that each policy operates independently from other policies due to the different stages of rollout each policy is in. | Governable Data Annotations (GDAs) are precise, governed annotations on datasets that describe the kinds of data that are subject to purpose-use limitations. Their entire lifecycle is subject to precise controls; they limit who can create them, who can associate the annotation on a dataset, who can remove an annotation, among other controls. The annotation labels are human readable, e.g., MESSAGING_DATA describes user data from a messaging context. |
Protecting messaging metadata as a use case
Messaging data from apps like Facebook Messenger enters Meta’s warehouse through logging libraries and database scrapes. It streams through the Scribe message queue, where it can be processed in real time or partitioned by time for batch processing. The diagram below shows the overall flow from collection through stream processing to derived batch datasets.

Logging libraries use a fluent builder pattern. Setting a governable data annotation (GDA) on a logger is the key step. GDAs are human-readable labels — like MESSAGING_DATA for messaging metadata — that determine where annotated data may flow. The annotation restricts writes to downstream datasets carrying the same GDA and confines access to purposes allowed in a central configuration.

Once a logger is annotated, Policy Zones infrastructure enforces the restriction automatically. Any downstream dataset that depends on the annotated data must itself carry the annotation. The processor can only access the dataset if Policy Zones has verified the data flow is compliant.
The logging configuration generates code that writes to a corresponding Scribe category from web servers. Policy Zones validates that the messaging GDA is applied to the Scribe category before allowing the flow, as shown below.

From Scribe, stream processing ingests the data into time-partitioned warehouse datasets. Those feed the batch jobs that produce derived datasets for analytics, machine learning, and operational monitoring. Each hop in that chain is governed by the Policy Zones flow control mechanisms, so purpose limitation is preserved from the logging call all the way to the final derived output.
How Policy Zones governs warehouse queries
In Meta’s data warehouse, processing is largely expressed in SQL—the declarative language that underpins systems like Presto, which can handle petabytes of relational data with minimal code. This SQL-centric paradigm is what makes scalable policy enforcement practical. Distributed scheduling of these queries is handled by Dataswarm, which lets users define run frequencies and data dependencies. Given that warehouse data is primarily time-partitioned, job schedules align with the partitioning scheme, starting in a waiting state and executing as new partitions arrive.
A typical Dataswarm pipeline computes a derived metric—for instance, daily messages sent per user—by reading an input dataset, transforming it, and writing the output. The user writes a concise, templatized statement, and Dataswarm generates the fully expanded SQL that Presto executes as a distributed job across thousands of machines. This abstraction lets engineers focus on high-level transformations, and the same pattern applies across privacy-sensitive workloads.


To enforce policy at this scale, Meta built the Unified Programming Model (UPM), a SQL parser that intercepts queries from various processors and converts them into semantic trees. These trees capture the inputs, outputs, and transformations of each data movement, providing the signals needed for policy decisions. As queries flow, UPM sends transformation details to the Policy Evaluation Service (PES), the first key enforcement point. PES runs flow control checks to validate that data movement and transformations comply with privacy policies. Approved flows are passed to the compute engines, which then perform the underlying data accesses.

PES also forwards its decisions to the Warehouse Permission Service (WPS), which handles traditional access control and has been augmented for policy-aware reasoning. In this model, PES issues a cryptographically signed token—depicted as a key in the architecture—that the client passes through compute engines to WPS at access time. This gives WPS context beyond individual requests. Previously, WPS saw only isolated operations like “read table A by identity X” or “write table B by identity Y.” Now it understands complete flows, such as “read table A by identity X and PES confirms the read satisfies the GDA flow safety requirements on MESSAGING_DATA.”
Processors integrate with Policy Zones through a client-side library called PrivacyLib, which abstracts coordination logic, monitoring, and service calls to keep privacy checking separate from business logic.
Realtime and stream processing
Beyond bulk time-partitioned datasets, realtime stream processing systems operate directly on Scribe categories, often for latency-sensitive tasks like detecting spam bots from recent user events. Policy Zones extends to these systems as well. XStream, Meta’s next-generation stream processor, provides a SQL-like interface for streaming transformations and uses the same UPM parsing to determine safe data flows. Because XStream’s programming model is declarative, Policy Zones can statically analyze a streaming application before it processes any events—a key requirement for scaling and reliability. Function-based realtime systems are covered by the same Policy Zones integration described earlier.
At the core of fine-grained data separation is the Flows-To evaluator inside PES. After extracting source-sink dependencies, PES applies information-flow control checks to determine if a data flow is permissible. Typical checks include verifying that a consent check was performed by the processor (for example, confirming a user allows their data to be used for a specific purpose), or that the GDA labels on source tables also appear on destination tables. These checks fit a lattice model, where nodes represent GDA labeling states and purpose uses, and edges denote allowed transitions. The logic for one such purpose-use check, written in Rust, is shown below.

Together, PES and WPS give batch processing systems seamless flow safety checks against purpose-limitation requirements. Engineers no longer need coarse-grained separation of purpose-use-limited datasets into special silos; Policy Zones protects the data even when it is commingled with non-restricted datasets in the same warehouse. This capability becomes especially important for machine learning workflows.
Applying zones to AI training
Non-content messaging data trains models such as spam filters, which help block unwanted messages. Policy Zones enforces usage protections here by integrating PES directly into the APIs for reading and writing data and models. The enforcement happens at the control plane of AI training—analogous to validating SQL statements rather than inspecting every accessed row.

Training workflows begin as user-authored scripts, typically written in Python through internal authoring tools or custom code that interacts with schedulers like FBLearner. During training, large-scale dataframes are loaded from the warehouse or realtime batch services. In distributed settings, intermediate storage—such as temporary tables—holds data between operators. Final models go to the model storage system, from which they can be retrieved for transfer learning or incremental, recurring training.
Workflows receive purpose-use annotations in two ways:
- Automatic inference: PES derives annotations from upstream data dependencies and applies them to the current workflow and all downstream models or assets, provided no conflicts arise.
- Manual override: Users can set annotations explicitly when authoring workflows or on the linked “Model Type”—a concept at Meta that defines the clear business purpose for a machine learning effort.
A representative workflow definition is shown below:

Model types are linked to a GDA. For example, the messaging_spam_filter model type is annotated with the MESSAGING_DATA GDA, as shown in its configuration:

At runtime, every data access during the workflow is associated with a model type, and PES ensures that written assets—including intermediate datasets—carry the appropriate GDA annotations. The system retrieves annotations when data is read, applies the first one to the workflow, then tags all outputs with the workflow’s current annotation, keeping purpose-use restrictions consistent across the entire pipeline.
Two workflows, one manager
Policy Zones Manager (PZM) is the integration layer that lets engineers apply Policy Zones both to existing data processing and to new pipelines. The two workflows share components, but the experience for engineers differs significantly.
Applying zones to existing processing. When an engineer wants to add a GDA to a dataset, PZM first lets them seed a proposed annotation to understand downstream effects. Because Policy Zones is an enforcement mechanism, a GDA applied carelessly can break production workflows. PZM guides engineers through the correct sequence by simulating what enforcement would look like under the new labeling, then suspending any flows that would break. The engineer tracks and burns down those suspensions until the dataset is fully compliant with the GDA's purpose-use requirements.
Propagating zones from new processing. For newly built pipelines, PZM validates data flows and flags issues as they arise. Derived datasets must keep correct annotations as data moves through the warehouse. When a user derives a dataset from Policy Zones-protected data, the system can sometimes repair the flow automatically — for example, by propagating an annotation when the intent is unambiguous. When context is unclear, the user is shown an interstitial. Dr Policy Zone (Dr. PZ) is a debugger that helps engineers resolve these Policy Zones errors.
Consider the SQL example from earlier that reads from message_metadata and writes to messages_sent. If the output table lacks the correct GDAs, Dr. PZ shows the user the error and remediation options. Generative AI is used to explain the problem in plain terms and offer guidance. 
Reclassification prevents over-annotation from spurious flows. In the messaging example, reclassification makes it possible to stop propagating the MESSAGING_DATA GDA to an output table even when the source carries it. Reclassifications are governed by strict rules that keep higher-level data policies intact, and they're controlled by safeguards separate from Policy Zones. What counts as an allowed reclassification is specific to each GDA and can include different privacy systems Policy Zones doesn't natively understand, complex privacy-preserving transformations like differential privacy, or review by human subject matter experts.
Scaling lessons and remaining friction
Not all warehouse processing is SQL. Dataswarm, for instance, supports PhpMethodOperator, which lets engineers write arbitrary Hack transformations on small warehouse datasets. These opaque operators required processor-specific integration points to capture data-flow context. PrivacyLib makes integrations easier, but the real challenge was choosing where to hook in Policy Zones checking. Low-level data access call sites turned out to be the right place, since PrivacyLib can piece together dependency information by logging reads and correlating them with later writes by the same processor.
The original policy language was highly expressive, which meant reclassification was rarely needed because policies captured most edge cases. The trade-off became clear quickly: intricate policies were hard for engineers to understand and debug when flows were blocked. The team simplified to a nominal typing system of flat, hierarchy-free, human-readable labels, where safe transitions are expressed as moves from one set of GDAs to another. Nuances that were previously encoded in policy language are now handled by the reclassification system, giving engineers a simple policy model that covers most processing.
What's next for batch Policy Zones
Policy Zones has reached major milestones in the warehouse, and the remaining work is about reducing friction and closing coverage gaps.
- Generative AI for remediation: Dr. PZ already embeds an expert system that guides engineers through remediation. Work is underway to supplement that deterministic approach with generative AI that helps users understand why they're blocked and what path to take.
- Closing the opaque operator gap: For processing where data dependencies are hard to track, the current fallback is coarse-grained data separation and siloing. Improved PrivacyLib integrations are intended to shrink that gap so engineers get fine-grained tracking without the friction.
- Seamless hand-off between Policy Zones systems: The batch processing system described here is one of two versions of Policy Zones. A future post will cover the function-based system. Today, when data moves between the two, a manual process keeps requirements mirrored across them. The goal is to make that hand-off automatic so engineers don't have to reason about two separate runtimes.



