jCustos — Lightweight Security for Core Java, REST and Vaadin.
Pluggable authentication, authorization, and annotation-driven protection — wired through Java SPI, no Spring or Jakarta required.
One-prompt setup — Claude Code skillsCapabilities
Annotation-Driven, Three Adapters
Same @RequiresRole / @RequiresPermission annotations protect Vaadin views (navigation listener), REST handlers (filter), and plain Java services (SecuredProxy.wrap(…) dynamic-proxy). One scanner, three call sites.
Framework-Neutral Core
jCustos-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 JCustosServiceResolver 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.
AI-Assisted Integration
Integrate the full stack from a single prompt — twelve Claude Code skills for Vaadin, REST and Standalone (plus persistence, hardening and OIDC layers). The docs ship an llms.txt map, so coding agents read the library too.
Production Hardening
JCustosAuditService with 27 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.
Method Security, Two Ways
Enforce @RequiresRole / @RequiresPermission / @RequiresPolicy on plain Java methods — a compile-time annotation processor generates <Type>Secured wrappers, or SecuredProxy.wrap(…) at runtime. Both route through one JCustosEnforcer.
Policy API
Beyond roles and permissions: a typesafe policy builder, @RequiresPolicy, and a sealed PolicyDecision (Allowed / Denied / StepUpRequired) with resource-aware, owner-or-admin style checks.
Multi-Tenancy + Active-Session Role Refresh
TenantId scopes every store key. JCustosVersion drift detection refreshes roles for live sessions — revoke a role and the next request is rejected (Vaadin reroute / REST 401), no waiting for expiry.
Store-Agnostic Persistence
11 small store SPIs with in-memory defaults, an Eclipse Store reference backend, and a contract testkit. Swap to durable storage with one dependency — no code change. Redis / JDBC are drop-in.
Credential Hardening + Compliance
A standards-aligned credential stack: Argon2id / bcrypt / scrypt, post-KDF HMAC pepper, breached-password checks (Have I Been Pwned), abuse detection — mapped to OWASP ASVS V2, NIST SP 800-63B and 40 CWE classes.
Multi-Session Logout & Action Audit
LogoutService.logout(SubjectId, LogoutScope) signs out one or every session. ActionAuthorizationService emits an ActionDenied audit event on every denial — no manual instrumentation.
Security Event Bus
New in 00.75 — typed security events in signed (Ed25519) envelopes with replay protection, per-(tenant, producer) ordering, producer policy and a REST/SSE bridge. Audit becomes a consumer; revoke a session and every node can hear it. Restart-safe Eclipse-Store stores.
JWT Validation
New in 00.76 — RFC-conformant JWT validation (jCustos-jwt): a disciplined JWKS client, a mandatory algorithm allow-list with hard algorithm-confusion defence (alg:none & key-confusion rejected), strict iss / aud — wired in three config lines via .jwt(...). JOSE stays isolated to one module.
OAuth2 Login (RP)
New in 00.77 — OAuth2 Relying-Party flows: Authorization-Code + PKCE, private_key_jwt client auth, refresh-token rotation with reuse-detection, introspection, revocation and the Device Grant — via .oauth2(...), across Vaadin / REST / Standalone.
OpenID Connect Login
New in 00.78–00.79 — OIDC Relying-Party: ID-token validation (nonce / azp / at_hash), discovery, UserInfo, claims→subject mapping and acr step-up via .oidc(...). One-line vendor profiles (Keycloak, Entra, Auth0, Okta, Google, GitHub) — and the JWT / OAuth2 / OIDC API is now stable.
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.
Mutation coverage = killed ÷ total mutations. PIT rewrites the compiled bytecode and checks whether the tests catch the change — a far harder bar than line coverage.
- Core & adapter tiles open a full, site-native report — per-mutator breakdown and the surviving-mutant list.
- Federation tiles (events, JWT, OAuth2, OIDC, DPoP) link to the release notes that measured them; several are a first PIT pass and still climbing, with a rendered per-module report to follow.
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
00.60 and 00.70 both shipped in full — persistence, multi-tenancy, method security and the Policy API are live. The 00.71 credential stack (Argon2id, breached-password checks, ASVS/NIST traceability), a JavaFX adapter and MFA / WebAuthn are 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