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:
| Variant | Meaning |
|---|---|
Allowed | Action permitted |
Denied(reason) | Action refused, with a human-readable reason for the audit log |
StepUpRequired | Allowed 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):
| Type | Purpose |
|---|---|
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.
@ExperimentalSecurityApi in 00.70 while the
predicate library and builder surface settle.