
jSentinel — Lightweight Security for Core Java, REST and Vaadin.
Pluggable authentication, authorization, and annotation-driven protection — wired through Java SPI, no Spring or Jakarta required.
Annotation-Driven, Three Adapters
Same @RequiresRole / @RequiresPermission annotations protect Vaadin views (navigation listener), REST handlers (filter), and plain Java services (Secured.wrap(…) dynamic-proxy). One scanner, three call sites.
Framework-Neutral Core
security-core has no Vaadin, Servlet, or REST-framework dependencies. Adapters map a single decision model to navigation or HTTP status.
Java SPI by Design
Authentication, authorization, audit, action, login-attempt, session-policy, password-hashing, logout — every contract pluggable via META-INF/services/. One SecurityServiceResolver resolves them all.
Hardened First-Run Bootstrap
The first administrator is created via a one-time token. POSIX 0600 file, atomic creation, PBKDF2-HMAC-SHA256, never logged, never echoed.
Granted / 401 / 403 — That's It
AuthorizationDecision collapses to three outcomes. REST adapters map them to status codes; Vaadin maps them to navigation. Error bodies are short and generic.
Four Reference Demos
Standalone Vaadin (demo-vaadin), JDK-only REST server + CLI (demo-rest), two-tier setup (demo-vaadin-rest-client), and a pure Core-Java CLI library (demo-standalone) — one annotation set, four call shapes. Both Vaadin demos ship a role-admin UI, user CRUD, and an audit-log view.
Production Hardening
SecurityAuditService with 16 sealed event types and a ring-buffer sink. LoginAttemptPolicy brute-force protection with 429 + Retry-After and lockout UI. SessionPolicy with idle/absolute lifetime and session-id rotation after login.
Multi-Session Logout
LogoutService.logout(SubjectId, LogoutScope) — sign the subject out of the current session or every active session of theirs. Adapter-specific cleanup (Vaadin session, HTTP session, bearer token) plugs in via LogoutListener.
Action Authorization with Audit
Stable ActionAuthorizationService SPI for isAllowed / requireAllowed. Every denied action emits an ActionDenied audit event automatically — no manual instrumentation.
Mutation-Tested Library
Line coverage tells you tests executed the code.
Mutation testing changes the bytecode at runtime and asks the harder
question: did the tests catch the change?
A surviving mutation is a real gap. Here's where the library stands.
Test strength = killed mutations / covered mutations. A 91% value means: of every 100 mutations the tests reached, 91 were detected. Line coverage measures whether code runs; test strength measures whether the assertions actually catch the bugs the code paths produce. Demos have intentionally lower numbers (UI / wire code is harder to mutation-test in isolation); the library code is what carries the production-quality guarantee.
Need help integrating it?
Get the library into production with the engineer who designed it — or back the project so the next features ship faster.
Architecture review, SPI integration, bootstrap hardening, custom permissions, REST authorization, security review of changes. Pair-programming, sprints, or workshops.
- Free 30-min scoping call
- Fixed-scope or retainer
- Direct line to the author
All eight Konzept points and a fourth (standalone) adapter shipped in 00.60. Persistent audit backends, a JavaFX adapter, demo-side mutation coverage — that's what sponsorship pays for. Individuals via GitHub Sponsors, companies through tiered arrangements.
- From $5/month on GitHub Sponsors
- Corporate tiers with roadmap input
- Project stays EUPL 1.2