PrivacyLib: Privacy Controls at the Data Access Boundary Meta detailed PrivacyLib, a common library running inside the clients of hundreds of its data and processing systems at the point of data access, which performs billions of privacy checks every second. PrivacyLib separates system integration from requirement implementation, letting a system integrate once and new privacy capabilities plug in as enforcing or observing modules, replacing per-system enforcement that Meta said could take months to roll out. Meta also added an Agent Observability module that propagates agent context through tool calls on supported paths, linking each data access to its session so modules can observe data use and block disallowed operations by internal AI agents. - This latest deep dive into Meta’s Privacy Aware Infrastructure PAI https://about.fb.com/news/2024/01/investing-in-privacy/ takes a look at PrivacyLib. - A privacy requirement must hold as data moves through Meta’s diverse data and processing systems. Historically, supporting a new requirement meant implementing the same enforcement logic separately in each system. PrivacyLib replaces this with a common library that runs inside the clients of Meta’s data and processing systems. - A system integrates with PrivacyLib once, and new privacy capabilities plug in as modules that reuse that integration. PrivacyLib performs billions of checks every second, and changes are simulated and rolled out per module. - For internal AI agents, whose data access paths may not be known in advance, tool calls on supported paths carry agent context to PrivacyLib. The propagated context links each access to its session, so modules can observe data use and block operations that are not allowed. At Meta, many privacy requirements ultimately come down to the same question: Can we prove that a piece of data goes only where it is allowed? At Meta’s scale, rather than relying solely on manual privacy audits, which can go out of sync as systems change, we have developed Privacy Aware Infrastructure PAI https://about.fb.com/news/2024/01/investing-in-privacy/ to answer this question within the infrastructure itself. PAI offers efficient and reliable first-class privacy constructs embedded in Meta’s infrastructure so that products can keep evolving quickly. In previous posts, we have covered how data understanding https://engineering.fb.com/2025/04/28/security/how-meta-understands-data-at-scale/ , data lineage https://engineering.fb.com/2025/01/22/security/how-meta-discovers-data-flows-via-lineage-at-scale/ , and Policy Zones https://engineering.fb.com/2025/07/23/security/policy-zones-meta-purpose-limitation-batch-processing-systems/ our information flow control technology play a role in PAI. Now, we are diving deep into PrivacyLib , a common library that runs inside the clients of hundreds of our data and processing systems at the point of data access. PrivacyLib plays an important role in the final stage of the broader PAI workflow: continuously enforcing and monitoring data flows. Before PrivacyLib, we integrated privacy enforcement separately into the clients of each data and processing system for each requirement. With this approach, implementing a new requirement across systems could take months. Each new requirement, whether purpose limitation or data flow discovery, needed the same set of capabilities: covering a wide range of systems; deploying in weeks rather than months; running on every data access without becoming a latency problem; and rolling out enforcement changes without taking the fleet down. Over time, this approach became harder to scale as requirements and systems evolved. PrivacyLib separates system integration from requirement implementation. We integrate each system once. When a requirement can be met at the point of data access, we implement it as a PrivacyLib module shared across the systems already integrated, so a new requirement no longer needs a separate implementation in each system. There are two kinds of modules: - Enforcing modules can block a data access. For example, Policy Zones https://engineering.fb.com/2025/07/23/security/policy-zones-meta-purpose-limitation-batch-processing-systems/ enforces purpose limitation https://engineering.fb.com/2024/08/27/security/privacy-aware-infrastructure-purpose-limitation-meta/ . - Observing modules only record a data access. For example, Privacy Probes https://engineering.fb.com/2025/01/22/security/how-meta-discovers-data-flows-via-lineage-at-scale/ collects the runtime signals used to discover data flows. As internal AI agents became a new way of accessing data, we also added the Agent Observability module to observe agent-related data access events and help safeguard the data that agents can reach. Systems already integrated with PrivacyLib picked it up without new integration work, which is what integrating once buys: each new privacy capability arrives as a module, not as a project. Engineering Challenges and Approaches of PrivacyLib at Meta’s Scale PrivacyLib operates across a broad range of data access paths at Meta: - More than a hundred libraries used to access data services, from key/value stores to AI features. - Thousands of production services with versions of the deployed library. - Millions of assets being accessed daily. - Billions of checks every second. Operating at this scale creates three engineering challenges: | Challenge | Approach | |---|---| | Coverage: Systems can have multiple client libraries and legacy integrations, accept direct network calls, and offer direct database access to backing stores. All of them need to be handled to ensure requirements hold no matter the access path. | We integrate at two levels: typed client libraries, where PrivacyLib has full request context, and lower network boundaries on remaining RPC paths to get full coverage. Each integrated system maps its native APIs to PrivacyLib’s common operations and provides the inputs required by its configured modules. Once those pieces are in place, the same module can be enabled in multiple systems without a separate system-specific integration. | | Scale: At billions of checks per second, even a small per-check computational cost becomes consequential across the fleet. Every service in the hot path pays that cost. | We compile requirements at build time into their simplest evaluable form and answer most checks from caches inside the process, so the common path avoids a network call. | | Reliability: Privacy logic runs in the hot path of critical systems, owned by teams that release on their own schedules. A change has to be testable in isolation and reversible on its own, because a fleet-wide rollback cannot be the recovery path. | Enforcement is deployed as part of the service that owns it, so a change reaches production through that service’s own pipeline instead of a fleet-wide config push. | Walkthrough: Protecting Messaging Metadata To illustrate how everything comes together at Meta’s scale, let’s walk through a privacy requirement that needs to be upheld when processing messaging metadata. Users exchange messages through apps like Messenger, which supports end-to-end encryption https://engineering.fb.com/2023/12/06/security/building-end-to-end-security-for-messenger/ . As Messenger routes and delivers those messages, subject to applicable law, its backend systems process non-content messaging data i.e., messaging metadata , such as information about when messages are sent or delivered, to improve product performance, detect abuse, and protect users from harmful conduct. A variety of these backend services use Logger, a client library that runs in the service process, to write this metadata to data warehouse tables. Before writing a record, the PrivacyLib integration inside Logger invokes Policy Zones, an enforcing module, to check whether the metadata may flow to the destination table. This check is broken down into two parts: what inputs need to be available to make a decision, and how the check is actually evaluated at runtime. After examining these two parts, we look at how PrivacyLib scales across systems and how changes roll out without disrupting the services in the path. Annotating Messaging Metadata Every Logger destination table has a LoggerConfig that describes the records written to it. MetadataTraceLoggerConfig defines one such configuration for message-delivery traces and marks it as containing messaging metadata: final class MetadataTraceLoggerConfig extends LoggerConfigBase { use MessagingTrafficMetadataPolicyTrait; public function configure LoggerFieldDefiner $fd, : LoggerFieldDefiner { $this- annotateWithTableLevelPolicy ; // Field and destination definitions } } A logging destination can have many writers, so the annotation describing its output data belongs to the destination rather than to each service that writes to it. If every service declared the annotation separately, the declarations could disagree, or a new writer could omit it entirely. Declaring it once in LoggerConfig gives every writer the same description of the data. For this destination, MessagingTrafficMetadataPolicyTrait supplies the MESSAGING TRAFFIC METADATA table-level annotation, and annotateWithTableLevelPolicy attaches it to the destination. LoggerConfig is Logger’s own schema, and each system describes its data in its own format. To give PrivacyLib a single form to consume, Logger’s code-generation pipeline translates the configuration into a PrivacyLib-compatible artifact. The generated MetadataTraceLoggerConfigPrivacyLibArtifact is derived from MetadataTraceLoggerConfig and carries the destination identity and the messaging annotation: / @codegen-source MetadataTraceLoggerConfig / class MetadataTraceLoggerConfigPrivacyLibArtifact extends LoggerInputPrivacyLibArtifact { final public static function getAssetIDImpl : LoggerInputAssetID { return LoggerInputAssetID::get 'MetadataTraceLoggerConfig', ; } protected static function getPurposePolicyVars : TPurposePolicyVars { return PurposePolicy::makeVars TPurposePolicyName::MESSAGING TRAFFIC METADATA, ; } // Other generated fields omitted. } The generated class above is used by Logger’s client in Hack https://engineering.fb.com/2014/03/20/developer-tools/hack-a-new-programming-language-for-hhvm/ , Meta’s typed PHP language. For its C++ and Python clients, Logger publishes destination identities and annotations to a central catalog. PrivacyLib uses that information to generate language-specific artifacts. In the C++ example in the next section, PrivacyLib uses the LoggerConfig name to load the C++ artifact for the destination. Running the Check The artifact from the previous section describes one Logger destination. PrivacyLib also needs to know what a Logger write means and which modules should run. Logger’s Hack integration defines that once for all destinations: php $config- libraryConfig - enablePrivacyLib PrivacyLibOperation::write - input PrivacyLibInput::instance nameof ILoggerInputPrivacyLibPayloadProvider, , - enforcements PrivacyLibWriteEnforcement::zones ZoneDataType::LOGGER, - withPropagation - enabled , PrivacyLibWriteEnforcement::telemetryLogging - enabled , // Other modules , ; PrivacyLibOperation::write declares PrivacyLib’s write operation for Logger, and enforcements lists the modules that run on it. The Policy Zones module can affect the result, while the Telemetry Logging module records the evaluation without affecting it. Adding a module here requires no changes to individual destinations or Logger call sites. ZoneDataType::LOGGER tells Policy Zones that it is checking a Logger destination. In C++ services, Logger constructs the PrivacyLib request as follows: js const auto assetList = std::vector