Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ include migration notes.

## Unreleased

- Consolidated public integration, compatibility, release, and async-security documentation;
removed the speculative roadmap and pinned upstream evidence to certified versions.
- Corrected HS256 guidance to distinguish the 32-character validation boundary from required key
entropy, and clarified that concurrent reset-token completion must be serialized by the
application or shared storage.

## 7.2.0 - 2026-07-12

- Added stateless Spring MVC async and streaming support based on a request-attribute
Expand All @@ -23,8 +29,8 @@ include migration notes.

## 7.0.0 - 2026-06-23

- Certified Vigil for Spring Boot 4.1.x, Spring Framework 7.x, Spring Security
7.1.x, Java 25, Gradle 9.1.x, and Jackson 3.
- Certified Vigil for Spring Boot 4.1.0, Spring Framework 7.0.8, Spring Security
7.1.0, Java 25, Gradle 9.1.x, and Jackson 3.
- Updated build tooling to Spring Boot 4.1.0, Java 25 toolchains, Gradle 9.1.0,
JaCoCo 0.8.14, Checkstyle 13.6.0, and google-java-format 1.28.0.
- Added starter auto-configuration compatibility tests that prove Vigil core
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Contributions are welcome when they keep Vigil small, explicit, tested, and secu
## Development Requirements

- Java 25.
- Spring Boot 4.1.x compatibility.
- Use the exact platform versions in the [compatibility reference](docs/reference/compatibility.md).
- Use the Gradle wrapper, not a system Gradle requirement.

## Quality Gates
Expand Down Expand Up @@ -33,6 +33,8 @@ gradlew.bat build --no-daemon
- Security-sensitive errors must not expose secrets, raw tokens, or parser internals.
- Configuration should fail fast at startup when required security inputs are missing.
- Architecture changes should update the relevant public docs in the same change.
- Completed user-visible work belongs in `CHANGELOG.md`; speculative features belong in GitHub
Issues or Projects, not the active documentation tree.

## Scope Rules

Expand Down
28 changes: 10 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ JWT authentication infrastructure for Spring Boot applications.

[![Maven Central](https://img.shields.io/maven-central/v/io.github.sequelcore/vigil-spring-boot-starter.svg)](https://central.sonatype.com/artifact/io.github.sequelcore/vigil-spring-boot-starter)

Vigil provides JWT lifecycle, request authentication, cookie helpers, tenant consistency, revocation, reset tokens, and reusable step-up credential verification. Applications retain ownership of users, login routes, credentials, recovery delivery, and business authorization.
Vigil provides JWT lifecycle, request authentication, cookie helpers, tenant consistency,
revocation, reset tokens, and reusable step-up credential verification. Applications retain
ownership of users and business authorization; the complete boundary is documented in
[system boundaries](docs/architecture/system-boundaries.md).

## Compatibility

Vigil `7.2.x` is certified with Java 25, Spring Boot 4.1.0, Spring Framework 7.0.8,
Spring Security 7.1.0, Gradle 9.6.x, and Jackson 3. Later dependency patches are not claimed as
certified until they pass Vigil's complete gate. Vigil `6.0.x` was the final Java 21 / Spring Boot
3.5 line.
Vigil `7.2.0` is certified with Java 25 and Spring Boot 4.1.0. See the
[compatibility reference](docs/reference/compatibility.md) for the complete tested combination.

`7.2.0` is the current release line. Public consumers should pin an exact version and review the release notes before upgrading.

Expand All @@ -35,26 +36,17 @@ vigil:
audience: my-api
```

```java
http.addFilterBefore(vigilAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
```

The application must still configure route authorization. `ignored-paths` skips Vigil processing; it does not grant anonymous access.
Follow the complete [authentication guide](docs/guides/authentication.md) to install the filter,
request-scoped security repository, stateless session policy, and application authorization rules.
`ignored-paths` skips Vigil processing; it does not grant anonymous access.

## Documentation

Start at the [documentation index](docs/README.md).
Start at the [documentation index](docs/README.md). The primary integration references are:

- [Authentication guide](docs/guides/authentication.md)
- [Async and streaming security](docs/guides/async-streaming-security.md)
- [Configuration reference](docs/reference/configuration.md)
- [System boundaries](docs/architecture/system-boundaries.md)
- [Security model](docs/security/security-model.md)
- [Step-up authorization](docs/security/step-up-authorization.md)
- [Deployment and operations](docs/operations/deployment.md)
- [Java API contract](docs/api/java-api.md)
- [Testing and verification](docs/development/testing.md)
- [Release policy](docs/releases/release-policy.md)

## Verification

Expand Down
4 changes: 3 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## Supported Versions

Until a stable public support policy is adopted, only the current `main` branch receives security fixes.
Vigil 7.2.x and the current `main` branch receive security fixes. Older release lines are
unsupported unless a security advisory states otherwise. See the
[compatibility reference](docs/reference/compatibility.md).

## Reporting A Vulnerability

Expand Down
8 changes: 4 additions & 4 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Vigil documentation

Vigil is a Spring Boot starter for application-owned JWT authentication. It provides token lifecycle, request authentication, cookie helpers, tenant consistency, revocation, reset tokens, and step-up credential verification. It does not own users, product authorization, or identity-delivery flows.
Vigil is a Spring Boot starter for application-owned JWT authentication. Read
[system boundaries](architecture/system-boundaries.md) before integrating it into an application.

## Start here

- [Async and streaming security](guides/async-streaming-security.md) — preserve stateless authentication across MVC redispatches.

- [Authentication guide](guides/authentication.md) — configure JWTs, cookies, Spring Security, tenants, and reset tokens.
- [Async and streaming security](guides/async-streaming-security.md) — preserve stateless authentication across MVC redispatches.
- [Configuration reference](reference/configuration.md) — every `vigil.*` property and its defaults.
- [Compatibility reference](reference/compatibility.md) — certified platform and dependency versions.
- [System boundaries](architecture/system-boundaries.md) — understand ownership and extension points before integrating.
- [Java API contract](api/java-api.md) — public services, SPIs, and compatibility expectations.
- [Step-up proof decision](adr/0001-step-up-opaque-one-time-proofs.md) — why approvals are opaque and server-consumed.
Expand All @@ -22,6 +23,5 @@ Vigil is a Spring Boot starter for application-owned JWT authentication. It prov

- [Testing and verification](development/testing.md) — local gates and integration coverage.
- [Release policy](releases/release-policy.md) — compatibility, versioning, and publication controls.
- [Roadmap](roadmap.md) — supported scope and deliberately deferred work.

The root [README](../README.md) is the concise package landing page. This index is the canonical navigation surface for repository documentation.
2 changes: 1 addition & 1 deletion docs/api/java-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This guide names Vigil's public integration contracts. It is not generated Javad
| --- | --- |
| `VigilAuthService` | Validate application credentials before issuing, refreshing, or revoking tokens. |
| `VigilTokenService` | Use only when a lower-level token integration is genuinely needed. |
| `VigilResetTokenService` | Deliver the reset token and update the user's password after successful consumption. |
| `VigilResetTokenService` | Deliver the token, serialize concurrent completion in application/shared storage, and update the password only after successful consumption. See the [security model](../security/security-model.md). |
| `VigilPasswordService` | Store its returned hash; own password policy and user persistence. |
| `VigilTenantContext` | Read the validated request tenant. |

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Async and streaming security research
# Async and streaming security evidence

Research cutoff: 2026-07-12. Primary specifications, official documentation, upstream source,
tests, and issue discussions take precedence over secondary guidance.
Expand All @@ -10,26 +10,26 @@ tests, and issue discussions take precedence over secondary guidance.
| [Servlet 6.1 specification](https://jakarta.ee/specifications/servlet/6.1/jakarta-servlet-spec-6.1.pdf), [AsyncContext](https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/asynccontext), [AsyncListener](https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/asynclistener) | `startAsync` lets the filter/servlet chain return while the same response remains open. Async error and timeout notifications belong to the container lifecycle; a new async cycle requires listener registration again. | Preserve security evidence on the servlet request. Do not replay credentials, manually complete an emitter after failed send, or equate return from the initial chain with request completion. |
| [DispatcherType](https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/dispatchertype), [ServletRequest.getDispatcherType](https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/servletrequest#getDispatcherType()) | `REQUEST`, `ASYNC`, and `ERROR` are distinct filter-chain invocations. `ASYNC` is produced by `AsyncContext.dispatch`; `ERROR` is container error handling. | Authenticate credentials only during the initial request. Continue authorization on redispatch using saved request evidence. A dispatch without that evidence fails closed. |
| [ServletResponse](https://jakarta.ee/specifications/servlet/6.1/apidocs/jakarta.servlet/jakarta/servlet/servletresponse) | Flushing commits status and headers; reset after commit is illegal and later status/header changes cannot repair the response. | Prevent the secondary authorization failure. Do not attempt to render a new 401/403 over committed SSE output. |
| [Spring MVC async processing](https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-ann-async.html), [ResponseBodyEmitter](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.html), [SseEmitter](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.html) | `DeferredResult` and streaming return types finish through an `ASYNC` dispatch. An emitter `IOException` caused by client disconnect must be left to the container and MVC, which perform error notification, final dispatch, exception resolution, and completion. | Broken pipe remains an expected network event. Vigil preserves authentication for the final dispatch instead of catching or suppressing the `IOException`. |
| [OncePerRequestFilter](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/OncePerRequestFilter.html) | Async and error dispatch participation is opt-in; both can run on different threads. | Vigil keeps the authentication filter out of redispatch. JWT validation, blacklist lookup, tenant extraction, hooks, and context populators execute once. |
| [Spring MVC async processing](https://docs.spring.io/spring-framework/reference/7.0/web/webmvc/mvc-ann-async.html), [ResponseBodyEmitter 7.0.8](https://docs.spring.io/spring-framework/docs/7.0.8/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.html), [SseEmitter 7.0.8](https://docs.spring.io/spring-framework/docs/7.0.8/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.html) | `DeferredResult` and streaming return types finish through an `ASYNC` dispatch. An emitter `IOException` caused by client disconnect must be left to the container and MVC, which perform error notification, final dispatch, exception resolution, and completion. | Broken pipe remains an expected network event. Vigil preserves authentication for the final dispatch instead of catching or suppressing the `IOException`. |
| [OncePerRequestFilter 7.0.8](https://docs.spring.io/spring-framework/docs/7.0.8/javadoc-api/org/springframework/web/filter/OncePerRequestFilter.html) | Async and error dispatch participation is opt-in; both can run on different threads. | Vigil keeps the authentication filter out of redispatch. JWT validation, blacklist lookup, tenant extraction, hooks, and context populators execute once. |
| [Spring Security context persistence](https://docs.spring.io/spring-security/reference/7.0/servlet/authentication/persistence.html), [RequestAttributeSecurityContextRepository API](https://docs.spring.io/spring-security/reference/7.1/api/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepository.html) | Custom authentication must explicitly save. The request-attribute repository restores one request across dispatch types and never persists to later requests. `SecurityContextHolderFilter` loads and clears the holder. | Save the authenticated context explicitly to a request-attribute repository configured in the application chain. This is stateless and creates no `HttpSession`. |
| [Servlet authorization](https://docs.spring.io/spring-security/reference/7.0/servlet/authorization/authorize-http-requests.html), [Servlet async integration](https://docs.spring.io/spring-security/reference/7.0/servlet/integrations/servlet-api.html) | Authorization applies to dispatcher types by default. Async task propagation and redispatch persistence are related but distinct mechanisms. | Vigil does not install dispatcher `permitAll` rules. The application continues to own HTTP authorization, including any narrow error-rendering exception. |

## Upstream implementation and test evidence

- Spring Framework 7.0.x:
- [`ResponseBodyEmitterReturnValueHandler`](https://github.com/spring-projects/spring-framework/blob/7.0.x/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java)
- [`DeferredResultMethodReturnValueHandler`](https://github.com/spring-projects/spring-framework/blob/7.0.x/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/DeferredResultMethodReturnValueHandler.java)
- [`ResponseBodyEmitterReturnValueHandlerTests`](https://github.com/spring-projects/spring-framework/blob/7.0.x/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandlerTests.java)
- [`StreamingResponseBodyReturnValueHandlerTests`](https://github.com/spring-projects/spring-framework/blob/7.0.x/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandlerTests.java)
- Spring Security 7.0.x:
- [`RequestAttributeSecurityContextRepository`](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/main/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepository.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/test/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepositoryTests.java)
- [`SecurityContextHolderFilter`](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/main/java/org/springframework/security/web/context/SecurityContextHolderFilter.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/test/java/org/springframework/security/web/context/SecurityContextHolderFilterTests.java)
- [`AuthorizationFilter`](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/main/java/org/springframework/security/web/access/intercept/AuthorizationFilter.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/test/java/org/springframework/security/web/access/intercept/AuthorizationFilterTests.java)
- [`ExceptionTranslationFilter`](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.0.x/web/src/test/java/org/springframework/security/web/access/ExceptionTranslationFilterTests.java)
- Spring Boot 4.1.x:
- [`SecurityFilterAutoConfiguration`](https://github.com/spring-projects/spring-boot/blob/main/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/web/servlet/SecurityFilterAutoConfiguration.java)
- [`SecurityFilterAutoConfigurationTests`](https://github.com/spring-projects/spring-boot/blob/main/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/web/servlet/SecurityFilterAutoConfigurationTests.java)
- Spring Framework 7.0.8:
- [`ResponseBodyEmitterReturnValueHandler`](https://github.com/spring-projects/spring-framework/blob/v7.0.8/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java)
- [`DeferredResultMethodReturnValueHandler`](https://github.com/spring-projects/spring-framework/blob/v7.0.8/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/DeferredResultMethodReturnValueHandler.java)
- [`ResponseBodyEmitterReturnValueHandlerTests`](https://github.com/spring-projects/spring-framework/blob/v7.0.8/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandlerTests.java)
- [`StreamingResponseBodyReturnValueHandlerTests`](https://github.com/spring-projects/spring-framework/blob/v7.0.8/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/StreamingResponseBodyReturnValueHandlerTests.java)
- Spring Security 7.1.0:
- [`RequestAttributeSecurityContextRepository`](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/main/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepository.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/test/java/org/springframework/security/web/context/RequestAttributeSecurityContextRepositoryTests.java)
- [`SecurityContextHolderFilter`](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/main/java/org/springframework/security/web/context/SecurityContextHolderFilter.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/test/java/org/springframework/security/web/context/SecurityContextHolderFilterTests.java)
- [`AuthorizationFilter`](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/main/java/org/springframework/security/web/access/intercept/AuthorizationFilter.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/test/java/org/springframework/security/web/access/intercept/AuthorizationFilterTests.java)
- [`ExceptionTranslationFilter`](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java) and [tests](https://github.com/spring-projects/spring-security/blob/7.1.0/web/src/test/java/org/springframework/security/web/access/ExceptionTranslationFilterTests.java)
- Spring Boot 4.1.0:
- [`SecurityFilterAutoConfiguration`](https://github.com/spring-projects/spring-boot/blob/v4.1.0/module/spring-boot-security/src/main/java/org/springframework/boot/security/autoconfigure/web/servlet/SecurityFilterAutoConfiguration.java)
- [`SecurityFilterAutoConfigurationTests`](https://github.com/spring-projects/spring-boot/blob/v4.1.0/module/spring-boot-security/src/test/java/org/springframework/boot/security/autoconfigure/web/servlet/SecurityFilterAutoConfigurationTests.java)

The local executable baseline resolves Spring Boot 4.1.0, Spring Framework MVC 7.0.8, Spring
Security Web 7.1.0, Tomcat 11.0.22, and Servlet 6.1. Vigil does not claim unexecuted version ranges.
Expand Down
Loading
Loading