Authorization you can read, test, and trust.
Policies that stay current. Decisions that stream. A testing DSL that proves correctness.
sapl.io · Get Started · Playground · Scenarios · Docs · Demos · Discord
SAPL is an authorization engine with a human-readable policy language, streaming decisions that update in real time when context changes, and a dedicated testing DSL with coverage reporting. It runs embedded in your application or as a standalone server.
policy "freeze during peak hours"
deny
subject.role == "engineer";
action == "deploy";
resource.environment == "production";
<time.localTimeIsBetween("09:00", "17:00", "Europe/Berlin")>;
obligation {
"type": "notify",
"channel": "ops-alerts",
"message": "Deployment blocked: peak hours"
}
Policies can do more than allow or deny. Obligations and advice attach machine-readable instructions to decisions: redact fields, rewrite queries, log access, require human approval, or trigger notifications. The framework enforces them automatically.
- Streaming authorization. Subscribe to decisions. The PDP pushes updates when attributes change. No polling, no stale decisions.
- Human-readable policies. Not Datalog, not YAML, not XML. Policies read like structured English.
- Testing DSL. The only authorization engine with a dedicated test language. Mock attribute sources, emit streaming changes, assert decision sequences, enforce coverage thresholds in CI.
- Obligations and advice. Every decision can carry structured instructions that the framework executes automatically.
- AI agent authorization. Control tool calls, RAG retrieval, and MCP operations with per-tool policies and human-in-the-loop approval workflows.
Try in the browser. The Playground runs entirely in your browser. Write policies, create subscriptions, observe decisions. No install needed.
Try on the command line. Download the sapl binary from the releases page. Write a policy:
policy "Dr. House is allowed to use the MRT!"
permit
subject == "housemd" & action == "use" & resource == "MRT";
Evaluate it:
sapl decide-once -s '"housemd"' -a '"use"' -r '"MRT"'
# {"decision":"PERMIT"}
sapl decide-once -s '"cuddy"' -a '"use"' -r '"MRT"'
# {"decision":"DENY"}The Getting Started guide covers the full CLI workflow including streaming decisions and testing.
Spring Boot integration
Add the starter:
<dependency>
<groupId>io.sapl</groupId>
<artifactId>sapl-spring-boot-starter</artifactId>
<version>4.2.0-SNAPSHOT</version>
</dependency>Annotate a method:
@PreEnforce(action = "'read'", resource = "'patient'")
public Patient getPatient(String id) {
return repository.findById(id);
}Write a policy in src/main/resources/policies/:
policy "doctors read patients"
permit
subject.role == "doctor";
action == "read";
resource == "patient";
The Spring scenario walks through a complete application step by step.
| Integration | How |
|---|---|
| Spring Boot | Annotations (@PreEnforce, @PostEnforce), embedded PDP, reactive support |
| FastAPI | Decorators with lambda resource builders |
| Django | Decorators with request context |
| NestJS | Guards and interceptors |
| .NET | Attributes with subscription customizers |
| Flask | Decorators |
| FastMCP | MCP server authorization |
| Java API | Programmatic, no framework required |
SAPL is the only authorization engine with a dedicated testing language. Mock attribute sources, emit streaming changes, assert decision sequences, and enforce coverage thresholds in CI.
policy "permit on emergency"
permit
action == "read" & resource == "time";
"status".<mqtt.messages> == "emergency";
scenario "decision changes when emergency status changes"
given
- attribute "statusMock" "status".<mqtt.messages> emits "emergency"
when "user" attempts "read" on "time"
expect permit
then
- attribute "statusMock" emits "ok"
expect not-applicable
then
- attribute "statusMock" emits "emergency"
expect permit;
> sapl test --policy-hit-ratio 100 --condition-hit-ratio 100
permit_on_emergency.sapltest
PASS permit when MQTT status is emergency
PASS not-applicable when MQTT status is ok
PASS alternating permit and not-applicable with multiple status changes
Tests: 10 passed, 10 total
Coverage: Policy Hit 100.00% Condition Hit 100.00%
Working demos with code walkthroughs:
- Spring Security -- method-level ABAC in a Spring Boot application
- AI Tool Authorization -- per-tool gating for Spring AI
- RAG Pipeline -- dynamic query rewriting for retrieval-augmented generation
- Human-in-the-Loop -- policy-driven approval workflows for AI tool calls
- MCP Server -- authorize tool calls, resources, and prompts in MCP servers
- Playground -- try SAPL policies in the browser, no install needed
- Get Started -- add SAPL to your first project
- Documentation -- language reference, functions, integrations
- Demos -- runnable example projects
- Discord -- questions, ideas, help from the team
The SAPL language server provides syntax highlighting, diagnostics, content assist, formatting, and more for .sapl and .sapltest files in any LSP-compatible editor. See the IDE setup guide for IntelliJ, VS Code, Neovim, and other editors.
| SAPL | Java | Spring Boot |
|---|---|---|
| 4.1.x | 21+ | 4.1.x |
| 4.0.x | 21+ | 4.0.x |
| 3.0.x | 17+ | 3.x |
SAPL is maintained by Dominic Heutelbeck and developed in the context of work at FTK e.V., the Research Institute for Telecommunication and Cooperation in Dortmund, Germany.
SAPL originated in European research and has received funding from the European Union's Horizon 2020 research and innovation programme under Grant Agreement No. 957852 (VPP4Islands) and from the European Union's Horizon Europe programme under Grant Agreement No. 101080923 (SMILE). The views expressed are those of the authors and do not necessarily reflect those of the European Commission.
See CONTRIBUTING.md.
See SECURITY.md.
See CODE_OF_CONDUCT.md.
Apache 2.0. See LICENSE.
Using snapshots
Snapshots provide the newest development state. Add the snapshot repository to your build:
Maven
<repositories>
<repository>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>Gradle
repositories {
maven { url = uri("https://central.sonatype.com/repository/maven-snapshots") }
}Quality gates
The public SonarCloud project tracks code quality and security analysis. Release CI waits for the SonarCloud quality gate, so releases are cut from a passing gate. False positives are tracked in SonarCloud rather than suppressed in source code.
SBOM
Need a Software Bill of Materials? The SAPL Node executable JAR embeds a CycloneDX JSON SBOM at META-INF/sbom/application.cdx.json.
jar xf sapl-node-4.2.0-SNAPSHOT.jar META-INF/sbom/application.cdx.jsonFor repository dependency visibility, see the public GitHub dependency graph.