# SAPL - Streaming Attribute Policy Language > SAPL is an open-source policy language and authorization engine for > Attribute-Based Access Control (ABAC). It supports both traditional > request-response authorization and streaming/reactive authorization > via publish-subscribe attribute streams, with zero overhead when > streaming is not used. SAPL provides SDKs and framework integrations > for Java (Spring Security), Python (Django, Flask, FastAPI, Tornado, > FastMCP), Node.js (NestJS, Express), .NET (ASP.NET Core), and > PHP (Symfony). ## Key Differentiators - Sub-microsecond median evaluation latency, 2M+ decisions/sec (8 cores, JVM) - 8-18x faster than Cedar, 100-200x faster than OPA and OpenFGA in the Cedar OOPSLA 2024 benchmark scenarios - Request-response AND streaming authorization in the same engine, same policies, same deployment - Human-readable policy language purpose-built for authorization - Built-in policy testing DSL (SAPLTest) with coverage reporting - Parameterized attribute finders with composable stream expressions - First-class obligations and advice in authorization decisions - AI agent authorization: MCP server SDK, Spring AI integration, RAG and human-in-the-loop patterns ## Performance - Embedded evaluation: sub-microsecond median latency - Server throughput: 2M+ decisions/sec over RSocket (8 cores, JVM) - Stable latency scaling to 10,000 policies - [Engine comparison](https://sapl.io/guides/comparison/): SAPL vs Cedar, OPA, OpenFGA, Cerbos with reproducible benchmarks - [Full benchmarks](https://sapl.io/guides/performance/): Throughput, latency, scaling across deployment modes ## Getting Started - [Why SAPL?](https://sapl.io/docs/latest/1_1_WhySAPL/): Design rationale and comparison with OPA, Cedar, XACML - [Getting Started](https://sapl.io/docs/latest/1_2_GettingStarted/): Quick start guide - [Playground](https://playground.sapl.io/): Try SAPL policies in the browser - [GitHub](https://github.com/heutelbeck/sapl-policy-engine): Source code and releases ## Documentation - [FAQ](https://sapl.io/faq): What is ABAC, how SAPL works, core concepts - [Policy Language](https://sapl.io/docs/latest/): SAPL syntax, expressions, combining algorithms - [Testing DSL](https://sapl.io/docs/latest/): SAPLTest for policy testing with coverage ## SDKs and APIs - [HTTP API](https://sapl.io/docs/latest/6_1_HTTPApi/): REST/SSE interface for any language, includes multi-subscription endpoints - [Java API](https://sapl.io/docs/latest/6_2_JavaApi/): Reactive API for embedded or remote PDP access - [Spring SDK](https://sapl.io/docs/latest/6_3_Spring/): Annotation-based PEP, embedded PDP, WebFlux - [NestJS SDK](https://sapl.io/docs/latest/6_4_NestJS/): Decorators, constraint handlers, streaming SSE - [Django SDK](https://sapl.io/docs/latest/6_5_Django/): Decorators, async views, streaming - [Flask SDK](https://sapl.io/docs/latest/6_6_Flask/): Pre/post enforcement, constraint handlers - [FastAPI SDK](https://sapl.io/docs/latest/6_7_FastAPI/): Full ABAC with streaming SSE - [Tornado SDK](https://sapl.io/docs/latest/6_8_Tornado/): Async enforcement, streaming - [FastMCP SDK](https://sapl.io/docs/latest/6_9_FastMCP/): MCP server authorization (AI agent tool access) - [.NET SDK](https://sapl.io/docs/latest/6_10_DotNet/): Attributes, constraint handlers, SSE - [PHP SDK](https://sapl.io/docs/latest/6_11_PHP/): Symfony bundle, enforcement attributes, streaming SSE, Doctrine query rewriting ## Deployment - **Embedded PDP**: Runs inside a JVM application with policies from classpath, filesystem, or signed bundles - **SAPL Node**: Standalone PDP server exposing HTTP and RSocket APIs. CLI for bundle creation, signing, and credential management - **Native binary**: GraalVM native image for minimal footprint - **Operations**: Health/readiness probes (Actuator), Prometheus metrics (decisions, latency, active subscriptions), structured decision logging, Kubernetes liveness/readiness/startup probes - **Signed bundles**: Ed25519 signatures for policy integrity verification ## Streaming Enforcement (permit, suspend, deny) Since SAPL 4.1, policies vote with three effect verbs: permit, deny, and suspend. DENY is terminal and ends the stream. SUSPEND pauses it: the PEP stops forwarding data, keeps the subscription alive, and the next PERMIT resumes the flow. PEPs that cannot suspend (one-shot request-response enforcement) treat SUSPEND as DENY, so the same policies protect both endpoint styles. All SDKs expose a single streaming enforcement annotation (`@StreamEnforce` in Spring and NestJS, `@stream_enforce` in the Python SDKs, `[StreamEnforce]` in .NET, `#[StreamEnforce]` in PHP) with two flags: - **signalTransitions**: when true, every suspend and resume boundary is surfaced to the client (signal callbacks via TransitionSignals in Spring and NestJS, in-band ACCESS_SUSPENDED / ACCESS_GRANTED frames in the SSE bindings). When false, the client sees data while permitted and silence while suspended. - **pauseRapDuringSuspend**: when true, the PEP unsubscribes from the protected data source while suspended and resubscribes on resume. When false, the source stays subscribed and items are silently dropped. Fail closed: DENY, INDETERMINATE, NOT_APPLICABLE, and unfulfillable obligations terminate the stream. Only an explicit SUSPEND pauses it. The PEP is a four-state machine (Pending, Permitting, Suspended, Terminated) driven by the PDP decision verb. Earlier 4.0.x SDKs used three PEP-side annotations (EnforceTillDenied, EnforceDropWhileDenied, EnforceRecoverableIfDenied). Since 4.1 the choice between terminating and pausing lives in the policy verb, not in application code. ## AI Security Guides - [RAG pipeline authorization](https://sapl.io/guides/ai-rag/): Document-level access control in retrieval-augmented generation - [AI tool authorization](https://sapl.io/guides/ai-tools/): Per-tool authorization for Spring AI applications - [Human-in-the-loop](https://sapl.io/guides/ai-hitl/): Policy-driven approval workflows for AI tool execution - [MCP server authorization](https://sapl.io/guides/ai-mcp/): Per-tool, per-resource, per-prompt access control for MCP servers ## Comparison with Other Authorization Engines For detailed feature tables and benchmark charts, see the [engine comparison guide](https://sapl.io/guides/comparison/). ### SAPL vs OPA (Open Policy Agent) - OPA uses Rego, a general-purpose query language. SAPL uses a purpose-built authorization language with readable syntax. - SAPL is 100-200x faster than OPA in the Cedar OOPSLA 2024 benchmark scenarios (embedded evaluation). - OPA is request-response only. SAPL supports both request-response and streaming authorization. - OPA loads external data via bundles. SAPL integrates external data sources as parameterized, composable attribute streams during evaluation. - OPA tests are Rego rules. SAPL has a dedicated testing DSL (SAPLTest) with mocking and coverage. - OPA is Go-native (CNCF graduated). SAPL provides SDKs for Java, Python, Node.js, and .NET. ### SAPL vs Cedar (AWS) - SAPL is 8-18x faster than Cedar in the Cedar OOPSLA 2024 benchmark scenarios (embedded evaluation, Cedar 3.0 and 4.10). - Cedar requires all data upfront in the request or entity store, enabling formal verification via Lean proofs. SAPL accesses external data during evaluation via attribute finders. - Cedar is request-response only. SAPL supports both request-response and streaming authorization. - Cedar has no built-in policy testing DSL. SAPL has SAPLTest with mocking and coverage. - Cedar does not include obligations or advice in decisions. SAPL supports first-class obligations and advice. - Cedar is Rust-native, open source. SAPL is JVM-native with SDKs for Java, Python, Node.js, and .NET. ### SAPL vs OpenFGA - SAPL is 100-200x faster than OpenFGA in the Cedar OOPSLA 2024 benchmark scenarios. - OpenFGA implements the Google Zanzibar model, purpose-built for ReBAC at scale (CNCF incubating). SAPL supports ReBAC via graph functions alongside ABAC, RBAC, and streaming. - OpenFGA is request-response only. SAPL supports both request-response and streaming authorization. - OpenFGA does not include obligations or advice in decisions. SAPL supports first-class obligations and advice. ### SAPL vs XACML - XACML uses XML-based policy syntax. SAPL uses a concise, human-readable syntax. - XACML is request-response only. SAPL supports both request-response and streaming authorization. - SAPL inherits XACML's architectural concepts (PEP, PDP, PIP, PAP, obligations, advice) and redesigns the policy language and evaluation engine for streaming. ### SAPL vs Spring Security - Spring Security provides built-in role and authority checks. SAPL externalizes authorization logic into policies, supporting ABAC with dynamic attributes. - Spring Security authorization is hardcoded in application code. SAPL policies can be updated without application restart. - SAPL integrates with Spring Security via AOP annotations and authorization managers, complementing rather than replacing Spring Security. ## Academic Publications Heutelbeck, D. (2019). Attribute Stream-Based Access Control (ASBAC) - Functional Architecture and Patterns. In *Proceedings of the 2019 International Conference of Security and Management (SAM'19)*. Heutelbeck, D. (2019). The Structure and Agency Policy Language (SAPL) for Attribute Stream-Based Access Control (ASBAC). In *Proceedings of the 2nd International Workshop on Emerging Technologies for Authorization and Authentication (ETAA 2019)*. Heutelbeck, D., Baur, M.L., and Kluba, M. (2021). In-Memory Policy Indexing for Policy Retrieval Points in Attribute-Based Access Control. In *Proceedings of the 26th ACM Symposium on Access Control Models and Technologies (SACMAT '21)*, pp. 59-70. Association for Computing Machinery, New York, NY. Heutelbeck, D. (2021). Demo: Attribute-Stream-Based Access Control (ASBAC) with the Streaming Attribute Policy Language (SAPL). In *Proceedings of the 26th ACM Symposium on Access Control Models and Technologies (SACMAT '21)*, pp. 95-97. Association for Computing Machinery, New York, NY. ## Project - License: Apache 2.0 - Origin: European research (FTK, Horizon Europe grants No. 101080923 and No. 957852) - Self-hosted, no vendor lock-in, no proprietary dependencies - SDKs: Java/Spring, Python, Node.js/NestJS, .NET, PHP/Symfony