Skip to content
Flag of Europe
Made in the European Union · Independently built · Released under EUPL 1.2
Policy API

Policy API

Roles and permissions answer “does the subject hold X?”. A policy answers the richer question “may this subject perform this action on this resource, under these conditions?” — owner-or-admin checks, resource attributes, step-up requirements. jSentinel models that with a typesafe Java builder, no external text DSL.

Define a policy

Policy.named("document.owner-or-admin")
    .when(Action.is("document:update"))
    .allowIf(SubjectPredicates.hasRole("ADMIN"))
    .orIf(ResourcePredicates.ownerMatchesSubject("document"))
    .deny("Only admins or owners may update documents");

Register it once, evaluate it everywhere:

PolicyRegistry registry = PolicyRegistry.create();
registry.register(documentPolicy);

Sealed decision

PolicyRegistry.evaluate(...) returns a sealed PolicyDecision:

VariantMeaning
AllowedAction permitted
Denied(reason)Action refused, with a human-readable reason for the audit log
StepUpRequiredAllowed in principle, but requires a stronger authentication step first (wired to MFA / step-up in the v00.80 roadmap)

Every evaluation emits a PolicyEvaluated(name, decision, reason) audit event so reviewers can trace why a decision was made.

Bind to a method

@RequiresPolicy plugs into the same method-security machinery as @RequiresRole and @RequiresPermission:

public interface DocumentService {

  @RequiresPolicy("document.owner-or-admin")
  void updateDocument(DocumentId id, DocumentPatch patch);

  @RequiresPermission("document:read")
  Document load(DocumentId id);
}

Resource-aware evaluation

Policies can reason about concrete resources, not only abstract permissions. The resource model (Phase 1 of 00.70):

TypePurpose
ResourceRef(resourceType, resourceId, tenant)Tenant-aware handle for the resource under evaluation
ResourceAccessContext(accessContext, resourceRef)Composite passed to evaluators that need both subject and resource

ResourcePredicates.ownerMatchesSubject("document") reads the ResourceRef from the ResourceAccessContext and compares ownership against the current subject. The tenant slot ties straight into multi-tenancy.

Relationship to roles and permissions

  • @RequiresRole / @RequiresPermission — the common, cheap case.
  • RoleHierarchy + @RequiresAnyPermission / @RequiresAllPermissions — convenience shortcuts (00.70).
  • @RequiresPolicy — the override path for everything that needs conditions, resource attributes, or step-up.

All three are evaluated by the same SecurityEnforcer, so they compose cleanly within a single service.

The Policy API is marked @ExperimentalSecurityApi in 00.70 while the predicate library and builder surface settle.