This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-oauth-client.git
The following commit(s) were added to refs/heads/master by this push:
new 2d7d0c3 docs: update AGENTS.md and README with project layout,
gotchas, and API notes (#49)
2d7d0c3 is described below
commit 2d7d0c37a9fa5265ea7ddc8d9137e02480009648
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Thu Jul 16 14:16:55 2026 +0200
docs: update AGENTS.md and README with project layout, gotchas, and API
notes (#49)
Co-authored-by: Maia <maia@noreply>
---
AGENTS.md | 20 ++++++++++++++------
README.md | 35 +++++++++++++++++++++++++++++++++--
2 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index a3fae48..e9e7c8f 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,11 +1,14 @@
# Project overview
-Apache Sling OAuth Client (`org.apache.sling.auth.oauth-client`) is an OSGi
bundle that adds OAuth 2.0 authorization-code flow and OpenID Connect (OIDC)
authentication to Apache Sling. It ships entry-point and callback servlets,
pluggable token stores (in-memory, JCR, Redis), an OIDC authentication handler,
and a public API/SPI for downstream bundles. Packaged with the Sling Feature
Model; targets Sling Starter 13 + Oak 1.40.
+Apache Sling OAuth Client (`org.apache.sling.auth.oauth-client`) is an OSGi
bundle that adds OAuth 2.0 authorization-code flow and OpenID Connect (OIDC)
authentication to Apache Sling. It ships entry-point and callback servlets,
pluggable token stores (in-memory, JCR, Redis), an OIDC authentication handler,
and a public API/SPI for downstream bundles. Packaged with the Sling Feature
Model and built against Sling Starter 13 features.
+
+> [!IMPORTANT]
+> The exported Java APIs are marked `@ProviderType` and are considered
experimental; incompatible changes may happen in future minor releases.
# Core commands
```bash
-# Compile and run unit tests
+# Build bundle and run tests
mvn clean install
# Unit tests only (skip integration tests)
@@ -20,6 +23,9 @@ mvn install -DskipITs
# Run Sling locally with this bundle (interactive, waits for input to stop)
mvn feature-launcher:start feature-launcher:stop
-Dfeature-launcher.waitForInput
+# Same as above, via Makefile target
+make sling-run
+
# Start Keycloak (for local dev/manual testing)
make keycloak-run-import
@@ -49,7 +55,7 @@ src/
org/apache/sling/auth/oauth_client/
*.java # Public API: OAuthTokenAccess, ClientConnection,
OAuthTokenResponse
impl/ # All OSGi DS components; not part of the public API
- spi/ # Extension points: UserInfoProcessor,
LoginCookieManager
+ spi/ # Extension points: UserInfoProcessor,
LoginCookieManager, OidcAuthCredentials
support/ # Base classes for consumers
(OAuthEnabledSlingServlet)
test/
java/ # Unit and integration tests (mirrors main package
structure)
@@ -68,6 +74,8 @@ Makefile # Developer convenience targets
(keycloak, sling config
- **Code formatting** — Spotless is configured; run `mvn spotless:apply`
before committing if the build fails on formatting.
- **Package visibility** — `impl` classes are not exported. Keep public API in
the root package, SPI in `.spi`, consumer helpers in `.support`.
- **Redis is optional** — `bnd.bnd` marks `redis.clients.jedis` as
`resolution:=optional`. The bundle must deploy and function without Redis on
the classpath.
+- **OIDC metadata vs explicit config** — `OidcConnectionImpl` requires either
`baseUrl` (discovery) or full explicit endpoint configuration
(`authorizationEndpoint`, `tokenEndpoint`, `userInfoUrl`, `jwkSetURL`,
`issuer`), but not both.
+- **OIDC logout hardening** — if `enableSPInitiatedSingleLogout=true` on
`OidcAuthenticationHandler`, `logoutRedirectAllowedHosts` must be configured.
- **4-space indentation**, no trailing whitespace, LF line endings.
- All source files must carry the Apache License 2.0 header (enforced by
`apache-rat-plugin`).
@@ -82,14 +90,15 @@ Makefile # Developer convenience targets
(keycloak, sling config
- **Framework**: JUnit Jupiter (JUnit 5) + AssertJ assertions.
- **Unit test mocking**: Mockito, Sling Mock (`sling-mock.junit5`), OSGi Mock
(`osgi-mock.junit5`), Sling Mock Oak for JCR-backed tests.
-- **Integration tests** (`*IT.java`): run with `maven-failsafe-plugin`; use
Testcontainers to spin up Keycloak and Redis containers — Docker must be
available.
+- **Integration tests** (`*IT.java`): run with `maven-failsafe-plugin`; use
Testcontainers (including `testcontainers-keycloak` and `testcontainers-redis`)
and require Docker.
- Test files live under `src/test/java/` mirroring the main source package
structure.
- Coverage is not enforced by a Maven plugin; no coverage thresholds to
maintain.
- Disable Keycloak ITs: `mvn verify -Dit.keycloak.enabled=false`.
# Gotchas
-- **Docker required for ITs** — Testcontainers pulls
`quay.io/keycloak/keycloak` and a Redis image at test time. Without Docker the
`verify` phase fails.
+- **Docker required for ITs** — integration tests start Keycloak
(`quay.io/keycloak/keycloak:26.4`) and Redis containers via Testcontainers;
without Docker `verify` fails.
+- **Local Keycloak version differs from ITs** — `make keycloak-run-import`
uses `quay.io/keycloak/keycloak:20.0.3` for local manual testing.
- **Port reservation** — `build-helper-maven-plugin` reserves a random
`http.port` for the embedded Sling instance during ITs. Do not hard-code port
8080 in tests.
- **IT startup timeout** — controlled by `-Dit.startTimeoutSeconds=60`
(default). Increase on slow machines.
- **`org.apache.sling.jcr.resource` is compile-scope** — it is embedded in the
bundle. Changes to that dependency version affect the bundle size and content.
@@ -101,4 +110,3 @@ Makefile # Developer convenience targets
(keycloak, sling config
<!-- sling-security-default:start -->
The threat model for this project is
https://github.com/apache/sling/blob/master/docs/threat-model.md .
<!-- sling-security-default:end -->
-
diff --git a/README.md b/README.md
index cf8aaca..bf7f75a 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,31 @@ It focuses on secure access to OAuth/OIDC tokens and
supports authorization code
- Build bundle and run tests: `mvn clean install`
- Unit tests only: `mvn test`
-- Full build including integration tests: `mvn verify`
+- Full build including integration tests (Docker required): `mvn verify`
- Skip integration tests: `mvn install -DskipITs`
- Disable Keycloak-based ITs explicitly: `mvn verify
-Dit.keycloak.enabled=false`
+- Run one unit test class: `mvn test -Dtest=OidcConnectionImplTest`
+- Run one integration test: `mvn verify -Dit=AuthorizationCodeFlowIT`
+
+## Project layout
+
+```text
+src/
+ main/
+ features/
+ main.json # Base feature model
+ redis.json # Optional Redis token store feature overlay
+ java/
+ org/apache/sling/auth/oauth_client/
+ *.java # Public API
+ impl/ # OSGi DS components (internal)
+ spi/ # Extension points for auth integration
+ support/ # Consumer helper base classes
+ test/
+ java/
+ resources/
+ keycloak-import/ # Local dev / IT realm data
+```
## Usage
@@ -116,6 +138,7 @@ Notable capabilities:
- `redirect` request parameter support to return users to a specific local
path after authentication
- Resource Indicators support (`resource`) for RFC 8707
- Configurable max age for the transient `sling.oauth-request-key` cookie
(`requestKeyCookieMaxAgeSeconds`)
+- Optional PKCE support (`pkceEnabled`)
- Optional SP-initiated logout support (`enableSPInitiatedSingleLogout`) with
host allow-list enforcement (`logoutRedirectAllowedHosts`)
### Clearing access tokens
@@ -215,6 +238,8 @@ Validated providers include:
Base bundle dependencies (on top of Sling Starter) are defined in
`src/main/features/main.json`.
Additional dependencies for Redis token storage are in
`src/main/features/redis.json`.
+Redis support is optional at runtime (`redis.clients.jedis` is imported as
optional), so the bundle also works without Redis on the classpath.
+
### CryptoService configuration
Because OAuth state values are encrypted/signed, `CryptoService` must be
configured:
@@ -241,7 +266,7 @@ Configure one (or more) client connections:
#### OIDC variant (`OidcConnectionImpl`)
-You can configure OIDC either with `baseUrl` metadata discovery **or** by
explicitly setting all endpoints (`authorizationEndpoint`, `tokenEndpoint`,
`userInfoUrl`, `jwkSetURL`, `issuer`).
+Configure OIDC either with `baseUrl` metadata discovery **or** by explicitly
setting all endpoints (`authorizationEndpoint`, `tokenEndpoint`, `userInfoUrl`,
`jwkSetURL`, `issuer`) — but not both.
```json
"org.apache.sling.auth.oauth_client.impl.OidcConnectionImpl~provider": {
@@ -326,6 +351,7 @@ Tokens are stored at `oauth-tokens/$PROVIDER_NAME` under
the user home.
- `mvn clean install -DskipITs`
3. Start Sling:
- `mvn feature-launcher:start feature-launcher:stop
-Dfeature-launcher.waitForInput`
+ - or `make sling-run`
4. Create OIDC connection config in Sling:
- `make sling-create-config`
@@ -339,3 +365,8 @@ Then:
- Integration tests use Testcontainers (Keycloak + Redis) and require Docker.
- To skip only Keycloak-based integration tests, use
`-Dit.keycloak.enabled=false`.
+
+## Security
+
+The project threat model is documented at
+https://github.com/apache/sling/blob/master/docs/threat-model.md .