Skip to content

Minimax#2

Open
piomin wants to merge 2 commits intomasterfrom
minimax
Open

Minimax#2
piomin wants to merge 2 commits intomasterfrom
minimax

Conversation

@piomin
Copy link
Copy Markdown
Owner

@piomin piomin commented Feb 16, 2026

Summary by CodeRabbit

  • New Features

    • Launched Person Service REST API with full CRUD operations for managing person records.
    • Integrated JWT-based authentication and security controls.
    • Added PostgreSQL persistence layer for person data storage.
  • Documentation

    • Added comprehensive README with API endpoints, configuration options, and local/production deployment guidance.
  • Tests

    • Implemented unit and integration tests for service validation.
  • Chores

    • Added CI/CD pipeline configuration and Docker containerization.
    • Configured Kubernetes deployment manifests and local development tooling.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a complete Spring Boot microservice for managing Person entities. The implementation includes REST API endpoints, PostgreSQL persistence, JWT-based security, Docker containerization, Kubernetes deployment manifests, and CircleCI CI/CD pipeline configuration.

Changes

Cohort / File(s) Summary
CI/CD & Containerization
.circleci/config.yml, Dockerfile, docker-compose.yml, skaffold.yml
Adds CircleCI build-and-test pipeline with Maven, Dockerfile for multi-stage Java build, Docker Compose setup with PostgreSQL service and health checks, and Skaffold configuration for local development.
Project Configuration
pom.xml, CLAUDE.md
Updates POM with Spring Boot 3.2.2 parent, dependencies (web, data-jpa, security, OAuth2, PostgreSQL, JJWT, validation), packaging configuration, and build plugin. Updates CLAUDE.md to include README update directive.
Java Application Core
src/main/java/pl/piomin/services/person/PersonApplication.java, src/main/java/pl/piomin/services/person/controller/PersonController.java, src/main/java/pl/piomin/services/person/service/PersonService.java
Adds Spring Boot application entry point, REST controller with CRUD endpoints at /api/persons, and service layer with transactional operations and DTO mapping.
Data Layer & DTOs
src/main/java/pl/piomin/services/person/entity/Person.java, src/main/java/pl/piomin/services/person/repository/PersonRepository.java, src/main/java/pl/piomin/services/person/dto/PersonRequest.java, src/main/java/pl/piomin/services/person/dto/PersonResponse.java
Introduces JPA entity with validation constraints, Spring Data JPA repository with PESEL lookup, and request/response DTOs with validation annotations for firstName, lastName, pesel, birthDate, email, phone, and address fields.
Security & Configuration
src/main/java/pl/piomin/services/person/config/SecurityConfig.java, src/main/resources/application.yml
Configures JWT-based OAuth2 resource server, stateless session management, CSRF disabled, allows unauthenticated access to /actuator/**. Application properties define PostgreSQL connection, JPA dialect, security, health probes, and logging.
Kubernetes Manifests
src/main/kubernetes/deployment.yml, src/main/kubernetes/deployment.yaml, src/main/kubernetes/service.yml, src/main/kubernetes/configmap.yml, src/main/kubernetes/secret.yml
Adds Kubernetes Deployment with liveness/readiness probes, Service exposing port 80 to 8080, ConfigMap for database/JWT configuration, and Secret for PostgreSQL credentials.
Testing & Documentation
src/test/java/pl/piomin/services/person/PersonControllerTest.java, src/test/java/pl/piomin/services/person/PersonServiceTest.java, src/test/resources/application.yml, README.md
Introduces integration and unit tests using MockMvc and Mockito, test configuration with H2 in-memory database, and comprehensive README documenting REST API, features, local running, and configuration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A service springs to life with Spring,
With Persons stored and databases that sing,
From Docker's nest to Kubernetes' care,
This microservice blooms beyond compare!
With JWT secure and tests in place,
Our Person Service conquers cyberspace!

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Minimax' is unrelated to the changeset, which introduces a complete Person Service REST API with Spring Boot, Docker, Kubernetes manifests, and CI/CD configuration. Replace with a descriptive title like 'Add Person Service REST API with Spring Boot, Docker, and Kubernetes deployment' to clearly reflect the main changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch minimax

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

🤖 Fix all issues with AI agents
In @.circleci/config.yml:
- Around line 10-18: The CI job saves the Maven cache but never restores it,
causing full dependency downloads on each run; add a restore_cache step before
the Maven build using the same cache key (v1-dependencies-{{ checksum "pom.xml"
}}) and paths (~/.m2) so the saved cache from save_cache is reused; place the
restore_cache step immediately before the run step named "Build with Maven" in
the steps sequence.

In `@docker-compose.yml`:
- Around line 34-35: The docker-compose JWT placeholders will break startup;
update JWT_ISSUER_URI and JWT_JWK_SET_URI in docker-compose.yml to point to a
reachable dev IdP (e.g., your local OIDC provider like http://localhost:9000 and
its /.well-known/jwks.json) or add a clear comment plus a toggle env (e.g.,
DISABLE_SECURITY=true) that your app checks to skip JWT validation for local
runs; ensure you modify the JWT_ISSUER_URI and JWT_JWK_SET_URI environment
entries referenced in the compose file accordingly so the resource-server can
fetch the JWK set at startup.

In `@Dockerfile`:
- Around line 8-12: The Dockerfile runtime stage runs the JVM as root (FROM
eclipse-temurin:17-jre-alpine + ENTRYPOINT ["java", "-jar", "app.jar"]), so add
a non-root user and switch to it: create a dedicated user/group (non-root uid
e.g. 1000 or a named user like appuser), chown the WORKDIR (/app) and the copied
artifact (app.jar) to that user, and add a USER instruction before ENTRYPOINT to
drop privileges at container runtime; ensure the user has a valid home and no
password and that file ownership is set after COPY so the JVM can read the jar.

In `@pom.xml`:
- Around line 63-79: Remove the unused JJWT dependencies by deleting the
<dependency> entries for artifactId jjwt-api, jjwt-impl, and jjwt-jackson
(version 0.12.3) from the POM; these are not referenced by your security config
which uses Spring Security’s oauth2ResourceServer().jwt() (Nimbus) so removing
jjwt-api, jjwt-impl, and jjwt-jackson reduces unused surface area—after removal,
rebuild and run mvn dependency:tree to confirm they are no longer present.
- Around line 7-12: The project currently uses Spring Boot parent version 3.2.2
which has known security vulnerabilities; update the <parent> version element
(the <version> under the <parent> block referencing
org.springframework.boot:spring-boot-starter-parent) to a secure release
(recommended minimum 3.3.11 or 3.4.5+) so the build picks up fixes (and ensure
any direct Spring Framework dependencies are aligned to 6.1.13+ if present);
after changing the parent <version>, run a build and tests to resolve any
dependency or API breakages and update the pom dependencyManagement entries if
needed to keep versions consistent.

In `@README.md`:
- Around line 76-78: The fenced code block showing the authorization header in
README.md is missing a language specifier (markdownlint MD040); update that
fenced block containing "Authorization: Bearer <token>" to include an explicit
language tag (e.g., text) after the opening ``` so the block becomes ```text and
resolves the lint error.

In `@skaffold.yml`:
- Around line 12-18: The skaffold configuration references a non-existent
kustomize path (kustomize.paths -> "k8s") which will cause deployment failures;
either remove the entire kustomize deployer block (the "kustomize:" key and its
"paths:" entry) so skaffold uses only the kubectl deployer with "manifests: -
src/main/kubernetes/*.yml", or create the missing "k8s/" directory and add a
valid kustomization.yaml (and any required resources) so the "kustomize"
deployer can succeed.
- Around line 14-15: The manifests glob under the "manifests" key currently uses
"src/main/kubernetes/*.yml" which will omit files like "deployment.yaml"; update
the glob to "src/main/kubernetes/*.{yml,yaml}" so both .yml and .yaml files
(e.g., deployment.yaml, configmap.yml, secret.yml, service.yml) are included by
the pipeline.

In `@src/main/java/pl/piomin/services/person/controller/PersonController.java`:
- Around line 35-40: The current findByPesel method exposes a PESEL in the URL
path via `@GetMapping`("/pesel/{pesel}") which risks logging PII; change the API
to accept PESEL in a non-URL channel (e.g., move to a POST endpoint that reads
PESEL from the request body or switch to a GET that takes `@RequestParam` but
ensure it isn't logged) by updating the controller method signature
(findByPesel) and mapping annotation accordingly and adjust any callers; also
ensure any logging around personService.findByPesel scrubs or omits the PESEL
value before writing logs.

In `@src/main/java/pl/piomin/services/person/dto/PersonRequest.java`:
- Around line 20-22: The PESEL field in PersonRequest currently only uses
`@NotBlank` and `@Size` so non-numeric characters slip through; add a `@Pattern`
constraint on the pesel field (e.g. pattern enforcing exactly 11 digits like
"^[0-9]{11}$" or "\\d{11}") to allow digits-only and update the validation
message accordingly, keeping the existing `@NotBlank` and `@Size` or replacing `@Size`
with the regex-based length check on the pesel field.

In `@src/main/kubernetes/configmap.yml`:
- Around line 5-9: Add a matching jwt.jwk-set-uri key to the ConfigMap so the
JWK set URI is configurable alongside jwt.issuer-uri; ensure the new key name is
jwt.jwk-set-uri and set its value to the issuer’s well-known JWKS endpoint (for
example by appending /.well-known/jwks.json to the jwt.issuer-uri value) so that
the environment variables referenced in application.yml (JWT_ISSUER_URI and
JWT_JWK_SET_URI) remain consistent when jwt.issuer-uri is changed.

In `@src/main/kubernetes/deployment.yaml`:
- Around line 1-72: There are two nearly identical Kubernetes manifests
(deployment.yaml and deployment.yml); remove one to avoid duplication and keep a
single canonical deployment file. Choose the file you want to keep, ensure it
contains the intended imagePullPolicy line ("imagePullPolicy: IfNotPresent") and
all env/config/secret refs (POSTGRES_*, JWT_ISSUER_URI), and delete the other
duplicate file so only the canonical manifest remains. Update any CI/deployment
references to point to the retained filename if necessary.

In `@src/main/resources/application.yml`:
- Around line 26-49: The YAML contains duplicate top-level management blocks so
the second one overrides the first; consolidate into a single management block
that merges the settings — ensure management -> endpoints -> web -> exposure ->
include contains "health,info", management -> endpoint -> health -> probes ->
enabled is true, and include show-details: always under endpoint.health, then
remove the duplicate block so all keys are present together (look for the
management, endpoints.web.exposure.include, endpoint.health.probes.enabled and
endpoint.health.show-details entries).

In `@src/test/java/pl/piomin/services/person/PersonServiceTest.java`:
- Line 40: The test uses a 10-character PESEL ("1234567890") which violates the
domain constraint on PersonRequest (`@Size`(min = 11, max = 11)); update the test
data to use an 11-character PESEL (e.g. "12345678901") wherever PESEL is set:
change validRequest.setPesel(...) in PersonServiceTest, update the corresponding
person entity setup (the Person instance used in the test), and update the
mocked repository interaction/assertion that references findByPesel(...) so all
three places use the same valid 11-character value to keep test data consistent
with the domain constraint.
- Line 1: The package declaration in the PersonServiceTest class is incorrect
for its file location: update the package statement in the PersonServiceTest
source so it matches the directory structure (change package from
pl.piomin.services.person.service to pl.piomin.services.person) or move the file
into a matching folder (pl/piomin/services/person/service) so the class
PersonServiceTest compiles; adjust the package line in the PersonServiceTest
file accordingly to resolve the mismatch.
🧹 Nitpick comments (14)
Dockerfile (1)

5-6: Prefer a Maven wrapper or dedicated Maven image over apk add maven.

The system-packaged Maven from Alpine repos may lag behind and introduces a version you don't control. Consider using maven:3-eclipse-temurin-17-alpine as the build stage base image, or include the Maven wrapper (mvnw) in the repo.

♻️ Example: use a Maven base image
-FROM eclipse-temurin:17-jdk-alpine AS build
+FROM maven:3-eclipse-temurin-17-alpine AS build
 WORKDIR /app
 COPY pom.xml .
 COPY src src
-RUN apk add --no-cache maven
 RUN mvn clean package -DskipTests
docker-compose.yml (1)

1-1: version key is obsolete in Docker Compose V2+.

Modern Docker Compose (V2) ignores the version field and emits a deprecation warning. You can safely remove it.

♻️ Proposed fix
-version: '3.8'
-
 services:
src/test/resources/application.yml (1)

12-13: Explicit H2Dialect is unnecessary with Hibernate 6+ (Spring Boot 3.x).

Hibernate 6 auto-detects the dialect from the JDBC URL. The explicit org.hibernate.dialect.H2Dialect reference may also produce a deprecation warning. You can safely remove the dialect property.

♻️ Proposed fix
   jpa:
     hibernate:
       ddl-auto: create-drop
     show-sql: true
-    properties:
-      hibernate:
-        dialect: org.hibernate.dialect.H2Dialect
src/main/resources/application.yml (2)

10-11: ddl-auto: update is unsafe for production deployments.

Using update lets Hibernate alter your schema automatically, which can cause data loss or unexpected migrations in production. Consider using validate for production and managing schema changes via a migration tool (Flyway/Liquibase). If this is intentionally dev-only, consider overriding it per profile.


5-7: Default database credentials are hardcoded as postgres/postgres.

While environment variable overrides are provided, the fallback defaults expose a well-known credential pair. If someone accidentally deploys without setting the env vars, the service connects with these defaults. Consider removing defaults for POSTGRES_PASSWORD so the app fails fast when the variable is unset, or gate them behind a Spring profile (e.g., local).

src/main/java/pl/piomin/services/person/entity/Person.java (1)

20-21: Consider adding @Column(length = 11) for pesel to enforce the constraint at the DB level.

The DTO validates pesel as exactly 11 characters, but the entity defaults to varchar(255). Adding length = 11 ensures the schema also enforces this invariant, protecting against data inserted outside the API layer.

Proposed change
-    `@Column`(unique = true, nullable = false)
+    `@Column`(unique = true, nullable = false, length = 11)
     private String pesel;
.circleci/config.yml (1)

3-4: Unused maven orb declaration.

The maven orb is declared but never referenced — both jobs use inline steps. Either remove the orb or refactor the jobs to use it.

src/main/kubernetes/deployment.yaml (2)

16-72: Add a securityContext to harden the container.

Both Checkov and Trivy flag the missing security context. The container currently runs with default privileges (root, writable filesystem, privilege escalation allowed). This is a valid security posture concern.

🛡️ Proposed fix — add securityContext at pod and container level
     spec:
+      securityContext:
+        runAsNonRoot: true
       containers:
         - name: person-service
           image: person-service:latest
           imagePullPolicy: IfNotPresent
           ports:
             - containerPort: 8080
+          securityContext:
+            allowPrivilegeEscalation: false
+            readOnlyRootFilesystem: true
+            runAsNonRoot: true
+            capabilities:
+              drop:
+                - ALL
           env:

Note: If the application writes to /tmp, you may need to mount an emptyDir volume at /tmp.


19-19: Avoid using latest as the image tag.

person-service:latest is not reproducible and can cause unexpected behavior when pods are rescheduled. Pin to a specific version or digest.

src/test/java/pl/piomin/services/person/PersonServiceTest.java (1)

110-124: shouldUpdatePerson doesn't assert the updated values in the response.

The test only verifies save was called but doesn't check that the response contains the updated first/last name. Additionally, the mock returns the original person object (with "John"/"Doe"), so the response won't reflect the update input ("Jane"/"Smith"). Consider using an Answer or a second Person to return updated values and assert them.

src/test/java/pl/piomin/services/person/PersonControllerTest.java (1)

15-29: Test correctly validates security enforcement — consider expanding coverage.

The 401 test is good for verifying JWT security. Consider adding tests with a mock JWT token (via @WithMockUser or SecurityMockMvcRequestPostProcessors.jwt()) to exercise the controller's happy-path and error-handling logic.

src/main/java/pl/piomin/services/person/service/PersonService.java (2)

23-28: findAll() loads all records without pagination — potential scalability issue.

As the dataset grows, this will cause increasing memory pressure and response latency. Consider accepting Pageable and returning Page<PersonResponse> via personRepository.findAll(pageable).


24-27: Minor: prefer toList() over Collectors.toList() on Java 17+.

Spring Boot 3.2.x requires Java 17+, where Stream.toList() is available and returns an unmodifiable list.

Proposed fix
     public List<PersonResponse> findAll() {
         return personRepository.findAll().stream()
                 .map(this::toResponse)
-                .collect(Collectors.toList());
+                .toList();
     }
src/main/java/pl/piomin/services/person/dto/PersonResponse.java (1)

5-78: Consider using a Java record for this DTO.

Since this is a simple data carrier with no behavior, a record would eliminate the boilerplate and provide immutability by default. Spring Boot 3.2.x / Java 17+ supports records for serialization.

Example
public record PersonResponse(
    Long id,
    String firstName,
    String lastName,
    String pesel,
    LocalDate birthDate,
    String email,
    String phone,
    String address
) {}

Note: This would require updating PersonService.toResponse() to use the record constructor instead of setters.

Comment thread .circleci/config.yml
Comment on lines +10 to +18
steps:
- checkout
- run:
name: Build with Maven
command: mvn clean package -DskipTests
- save_cache:
key: v1-dependencies-{{ checksum "pom.xml" }}
paths:
- ~/.m2
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

build job never restores the Maven cache, so first builds always download all dependencies.

The build job saves the cache (Line 15) but never restores it. On subsequent runs, it will re-download all dependencies from scratch. Add a restore_cache step before the build command.

Proposed fix
     steps:
       - checkout
+      - restore_cache:
+          key: v1-dependencies-{{ checksum "pom.xml" }}
       - run:
           name: Build with Maven
           command: mvn clean package -DskipTests
       - save_cache:
           key: v1-dependencies-{{ checksum "pom.xml" }}
           paths:
             - ~/.m2
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
steps:
- checkout
- run:
name: Build with Maven
command: mvn clean package -DskipTests
- save_cache:
key: v1-dependencies-{{ checksum "pom.xml" }}
paths:
- ~/.m2
steps:
- checkout
- restore_cache:
key: v1-dependencies-{{ checksum "pom.xml" }}
- run:
name: Build with Maven
command: mvn clean package -DskipTests
- save_cache:
key: v1-dependencies-{{ checksum "pom.xml" }}
paths:
- ~/.m2
🤖 Prompt for AI Agents
In @.circleci/config.yml around lines 10 - 18, The CI job saves the Maven cache
but never restores it, causing full dependency downloads on each run; add a
restore_cache step before the Maven build using the same cache key
(v1-dependencies-{{ checksum "pom.xml" }}) and paths (~/.m2) so the saved cache
from save_cache is reused; place the restore_cache step immediately before the
run step named "Build with Maven" in the steps sequence.

Comment thread docker-compose.yml
Comment on lines +34 to +35
JWT_ISSUER_URI: https://auth.example.com
JWT_JWK_SET_URI: https://auth.example.com/.well-known/jwks.json
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Placeholder JWT URIs (auth.example.com) will cause runtime failures.

The Spring Boot OAuth2 resource server auto-configuration will attempt to fetch the JWK set from these URIs at startup. With unreachable placeholder URLs, the application will fail to start (or reject all requests). Either document this clearly, provide a way to disable security locally, or point to a real/local identity provider.

🤖 Prompt for AI Agents
In `@docker-compose.yml` around lines 34 - 35, The docker-compose JWT placeholders
will break startup; update JWT_ISSUER_URI and JWT_JWK_SET_URI in
docker-compose.yml to point to a reachable dev IdP (e.g., your local OIDC
provider like http://localhost:9000 and its /.well-known/jwks.json) or add a
clear comment plus a toggle env (e.g., DISABLE_SECURITY=true) that your app
checks to skip JWT validation for local runs; ensure you modify the
JWT_ISSUER_URI and JWT_JWK_SET_URI environment entries referenced in the compose
file accordingly so the resource-server can fetch the JWK set at startup.

Comment thread Dockerfile
Comment on lines +8 to +12
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Container runs as root — add a non-root user.

Trivy correctly flags this. Running the JRE stage as root increases the blast radius if the container is compromised. Add a non-root user for the runtime stage.

🛡️ Proposed fix
 FROM eclipse-temurin:17-jre-alpine
 WORKDIR /app
 COPY --from=build /app/target/*.jar app.jar
+RUN addgroup -S appgroup && adduser -S appuser -G appgroup
+USER appuser
 EXPOSE 8080
 ENTRYPOINT ["java", "-jar", "app.jar"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
RUN addgroup -S appgroup && adduser -S appuser -G appgroup && chown -R appuser:appgroup /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
🤖 Prompt for AI Agents
In `@Dockerfile` around lines 8 - 12, The Dockerfile runtime stage runs the JVM as
root (FROM eclipse-temurin:17-jre-alpine + ENTRYPOINT ["java", "-jar",
"app.jar"]), so add a non-root user and switch to it: create a dedicated
user/group (non-root uid e.g. 1000 or a named user like appuser), chown the
WORKDIR (/app) and the copied artifact (app.jar) to that user, and add a USER
instruction before ENTRYPOINT to drop privileges at container runtime; ensure
the user has a valid home and no password and that file ownership is set after
COPY so the JVM can read the jar.

Comment thread pom.xml
Comment on lines +7 to +12
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/>
</parent>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Spring Boot latest releases 3.2.x 3.3.x 3.4.x 2024 2025

💡 Result:

As of Feb 16, 2026, the latest open-source Spring Boot patch releases in the 3.2.x / 3.3.x / 3.4.x lines are:

  • 3.2.x → 3.2.12 (Nov 21, 2024)end of OSS support for 3.2.x [1]

    • 2024 releases: 3.2.11 (Oct 24, 2024), 3.2.12 (Nov 21, 2024) [4]
  • 3.3.x → 3.3.13 (Jun 19, 2025)end of OSS support for 3.3.x [2]

    • 2024 releases: 3.3.0 (May 23), 3.3.1 (Jun 20), 3.3.2 (Jul 18), 3.3.3 (Aug 22), 3.3.4 (Sep 19), 3.3.5 (Oct 24), 3.3.6 (Nov 21), 3.3.7 (Dec 19) [4]
    • 2025 releases: 3.3.8 (Jan 23), 3.3.9 (Feb 20), 3.3.10 (Mar 20), 3.3.11 (Apr 24), 3.3.12 (May 22), 3.3.13 (Jun 19) [4]
  • 3.4.x → 3.4.13 (Dec 18, 2025)end of OSS support for 3.4.x [3]

    • 2024 releases: 3.4.0 (Nov 21), 3.4.1 (Dec 19) [4]
    • 2025 releases: 3.4.2 (Jan 23), 3.4.3 (Feb 20), 3.4.4 (Mar 21), 3.4.5 (Apr 24), 3.4.6 (May 22), 3.4.7 (Jun 19), 3.4.8 (Jul 24), 3.4.9 (Aug 21), 3.4.10 (Sep 18), 3.4.11 (Oct 23), 3.4.12 (Nov 20), 3.4.13 (Dec 18) [4]

Sources
[1] Spring blog: Spring Boot 3.2.12 available now (Nov 21, 2024) https://spring.io/blog/2024/11/21/spring-boot-3-2-12-available-now/
[2] Spring blog: Spring Boot 3.3.13 available now (Jun 19, 2025) https://spring.io/blog/2025/06/19/spring-boot-3-3-13-available-now
[3] Spring blog: Spring Boot 3.4.13 available now (Dec 18, 2025) https://spring.io/blog/2025/12/18/spring-boot-3-4-13-available-now
[4] Maven Central listing (via MVNRepository): org.springframework.boot:spring-boot versions https://mvnrepository.com/artifact/org.springframework.boot/spring-boot/versions


🌐 Web query:

Spring Boot 3.2.2 release date January 2024 security patches

💡 Result:

  • Spring Boot 3.2.2 release date: January 19, 2024 (released to Maven Central). [1]
  • January 2024 security patch in 3.2.2: Spring Boot 3.2.2 upgrades Spring Framework to 6.1.3, which includes the fix for CVE-2024-22233 (Spring Framework server-side HTTP DoS). [2][3]
    • The Spring security advisory notes the affected Spring Framework versions (6.1.2 / 6.0.15) and recommends upgrading to 6.1.3 / 6.0.16, respectively—Boot 3.2.2 is the Boot line that picks up the 6.1.3 fix. [3]

Sources: [1] Spring Boot 3.2.2 release announcement, [2] Spring blog post for CVE-2024-22233 noting Boot 3.2.2 includes the fixed Spring Framework, [3] Spring security advisory for CVE-2024-22233.


🌐 Web query:

Spring Boot security vulnerabilities 3.2.2 CVE

💡 Result:

Spring Boot 3.2.2 (Jan 2024 line) is associated with these notable security CVEs:

  • CVE-2024-22233 (Spring Framework Web DoS)
    Boot 3.2.2 is not affected (it upgrades Spring Framework to 6.1.3, which contains the fix). [1][2]

  • CVE-2024-38807 (Spring Boot Loader signature forgery)
    Boot 3.2.2 is in the affected line; Spring fixed this in Spring Boot 3.2.9 (and 3.3.3). [3]

  • CVE-2024-38816 (Spring Framework path traversal in functional web frameworks)
    Boot 3.2.2 uses Spring Framework 6.1.3, which is within the affected range 6.1.0–6.1.12; fixed in 6.1.13. [4][5]

  • CVE-2025-22235 (Actuator EndpointRequest.to() wrong matcher → /null/** bypass)
    Boot 3.2.2 is affected (range 3.2.0–3.2.13.2). Fixed in Spring Boot 3.2.14 (Enterprise Support), or in OSS lines 3.3.11 / 3.4.5. [6][7]

Practical remediation: if you must stay on the 3.2 line, the security fix for CVE-2025-22235 requires 3.2.14 (Enterprise Support); otherwise upgrade to an OSS-supported line such as 3.3.11+ or 3.4.5+. [6][7]

References:
[1] https://spring.io/security/cve-2024-22233
[2] https://spring.io/blog/2024/01/11/spring-framework-6-1-3-and-6-0-16-available-now
[3] https://spring.io/blog/2024/08/23/spring-boot-releases-fix-for-cve-2024-38807/
[4] https://spring.io/blog/2024/09/12/spring-framework-releases-fixes-for-cve-2024-38816/
[5] https://asec.ahnlab.com/en/83247/
[6] https://spring.io/security/cve-2025-22235/
[7] https://spring.io/blog/2025/04/24/spring-boot-CVE-2025-22235/


Spring Boot 3.2.2 has multiple known security vulnerabilities.

Spring Boot 3.2.2 (January 2024) is affected by:

  • CVE-2024-38807 (Loader signature forgery) — fixed in 3.2.9+
  • CVE-2024-38816 (Path traversal in functional web frameworks) — fixed in Spring Framework 6.1.13
  • CVE-2025-22235 (Actuator EndpointRequest bypass) — fixed in 3.3.11+, 3.4.5+

Upgrade to 3.3.11+ or 3.4.5+ to pick up all security fixes. The 3.2.x line (latest: 3.2.12) is no longer receiving open-source support as of November 2024.

🤖 Prompt for AI Agents
In `@pom.xml` around lines 7 - 12, The project currently uses Spring Boot parent
version 3.2.2 which has known security vulnerabilities; update the <parent>
version element (the <version> under the <parent> block referencing
org.springframework.boot:spring-boot-starter-parent) to a secure release
(recommended minimum 3.3.11 or 3.4.5+) so the build picks up fixes (and ensure
any direct Spring Framework dependencies are aligned to 6.1.13+ if present);
after changing the parent <version>, run a build and tests to resolve any
dependency or API breakages and update the pom dependencyManagement entries if
needed to keep versions consistent.

Comment thread pom.xml
Comment on lines +63 to +79
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for any import or usage of io.jsonwebtoken in the codebase
rg -rn 'io\.jsonwebtoken' --type=java

Repository: piomin/claude-ai-spring-boot

Length of output: 54


🏁 Script executed:

#!/bin/bash
# Check for any references to oauth2ResourceServer or jwt in config files
rg -rn 'oauth2ResourceServer|JwtDecoder|JwtAuthenticationConverter' --type=java

Repository: piomin/claude-ai-spring-boot

Length of output: 187


🏁 Script executed:

#!/bin/bash
# Double-check for any other jjwt references (e.g., in comments, profiles, or other config)
rg -rn 'jjwt|jsonwebtoken' --type=xml,java,properties

Repository: piomin/claude-ai-spring-boot

Length of output: 115


🏁 Script executed:

#!/bin/bash
# Search for any jjwt or jsonwebtoken references across all files
rg -rn 'jjwt|jsonwebtoken' .

Repository: piomin/claude-ai-spring-boot

Length of output: 373


Remove unused jjwt dependencies.

The jjwt-api, jjwt-impl, and jjwt-jackson dependencies (lines 63–79) are not used anywhere in the codebase. Your security configuration relies solely on Spring Security's oauth2ResourceServer().jwt(), which internally uses Nimbus JOSE for JWT validation. Unused dependencies increase the attack surface and maintenance burden; remove them.

🤖 Prompt for AI Agents
In `@pom.xml` around lines 63 - 79, Remove the unused JJWT dependencies by
deleting the <dependency> entries for artifactId jjwt-api, jjwt-impl, and
jjwt-jackson (version 0.12.3) from the POM; these are not referenced by your
security config which uses Spring Security’s oauth2ResourceServer().jwt()
(Nimbus) so removing jjwt-api, jjwt-impl, and jjwt-jackson reduces unused
surface area—after removal, rebuild and run mvn dependency:tree to confirm they
are no longer present.

Comment on lines +1 to +72
apiVersion: apps/v1
kind: Deployment
metadata:
name: person-service
labels:
app: person-service
spec:
replicas: 1
selector:
matchLabels:
app: person-service
template:
metadata:
labels:
app: person-service
spec:
containers:
- name: person-service
image: person-service:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: POSTGRES_HOST
valueFrom:
configMapKeyRef:
name: person-config
key: postgres.host
- name: POSTGRES_PORT
valueFrom:
configMapKeyRef:
name: person-config
key: postgres.port
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
name: person-config
key: postgres.db
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: person-secret
key: postgres.user
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: person-secret
key: postgres.password
- name: JWT_ISSUER_URI
valueFrom:
configMapKeyRef:
name: person-config
key: jwt.issuer-uri
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for deployment manifests
find src/main/kubernetes/ -name "deployment.y*" 2>/dev/null | sort

Repository: piomin/claude-ai-spring-boot

Length of output: 142


🏁 Script executed:

#!/bin/bash
# If files exist, show their content and calculate diff
if [ -f "src/main/kubernetes/deployment.yaml" ] && [ -f "src/main/kubernetes/deployment.yml" ]; then
  echo "=== deployment.yaml ==="
  wc -l src/main/kubernetes/deployment.yaml
  echo ""
  echo "=== deployment.yml ==="
  wc -l src/main/kubernetes/deployment.yml
  echo ""
  echo "=== Diff ==="
  diff -u src/main/kubernetes/deployment.yml src/main/kubernetes/deployment.yaml || true
elif [ -f "src/main/kubernetes/deployment.yaml" ]; then
  echo "Only deployment.yaml exists"
  wc -l src/main/kubernetes/deployment.yaml
elif [ -f "src/main/kubernetes/deployment.yml" ]; then
  echo "Only deployment.yml exists"
  wc -l src/main/kubernetes/deployment.yml
else
  echo "Neither file found"
fi

Repository: piomin/claude-ai-spring-boot

Length of output: 580


Remove duplicate deployment manifest.

Both deployment.yaml and deployment.yml exist in src/main/kubernetes/ with nearly identical content. The only difference is line 20 in deployment.yaml which includes imagePullPolicy: IfNotPresent; deployment.yml omits this line. Having two nearly identical manifests creates confusion about which is the canonical deployment configuration and makes future maintenance error-prone. Keep one file and remove the other.

🧰 Tools
🪛 Checkov (3.2.334)

[medium] 1-72: Containers should not run with allowPrivilegeEscalation

(CKV_K8S_20)


[medium] 1-72: Minimize the admission of root containers

(CKV_K8S_23)

🪛 Trivy (0.69.1)

[error] 18-72: Root file system is not read-only

Container 'person-service' of Deployment 'person-service' should set 'securityContext.readOnlyRootFilesystem' to true

Rule: KSV-0014

Learn more

(IaC/Kubernetes)


[error] 18-72: Default security context configured

container person-service in default namespace is using the default security context

Rule: KSV-0118

Learn more

(IaC/Kubernetes)


[error] 16-72: Default security context configured

deployment person-service in default namespace is using the default security context, which allows root privileges

Rule: KSV-0118

Learn more

(IaC/Kubernetes)

🤖 Prompt for AI Agents
In `@src/main/kubernetes/deployment.yaml` around lines 1 - 72, There are two
nearly identical Kubernetes manifests (deployment.yaml and deployment.yml);
remove one to avoid duplication and keep a single canonical deployment file.
Choose the file you want to keep, ensure it contains the intended
imagePullPolicy line ("imagePullPolicy: IfNotPresent") and all env/config/secret
refs (POSTGRES_*, JWT_ISSUER_URI), and delete the other duplicate file so only
the canonical manifest remains. Update any CI/deployment references to point to
the retained filename if necessary.

Comment on lines +1 to +8
apiVersion: v1
kind: Secret
metadata:
name: person-secret
type: Opaque
stringData:
postgres.user: postgres
postgres.password: postgres
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Hardcoded credentials committed to version control.

Storing plaintext database credentials (postgres/postgres) in a tracked Kubernetes Secret manifest is a security risk. Even though stringData is base64-encoded at apply time, the source file remains readable in the repo history. For non-demo environments, use an external secrets manager (e.g., Sealed Secrets, HashiCorp Vault, or cloud-native secret stores) and avoid committing credential values.

Comment on lines +26 to +49
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true

logging:
level:
pl.piomin.services: INFO

management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true
show-details: always
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Duplicate management key — second block silently overrides the first.

YAML does not support duplicate top-level keys. The second management: block (Line 40) silently replaces the first (Line 26), so the parsed config only contains what's in lines 40-49. This is likely unintentional — you probably want a single merged block that includes show-details: always.

🔧 Proposed fix: merge into a single block
 management:
   endpoints:
     web:
       exposure:
         include: health,info
   endpoint:
     health:
       probes:
         enabled: true
-
-logging:
-  level:
-    pl.piomin.services: INFO
-
-management:
-  endpoints:
-    web:
-      exposure:
-        include: health,info
-  endpoint:
-    health:
-      probes:
-        enabled: true
       show-details: always
+
+logging:
+  level:
+    pl.piomin.services: INFO
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true
logging:
level:
pl.piomin.services: INFO
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true
show-details: always
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
probes:
enabled: true
show-details: always
logging:
level:
pl.piomin.services: INFO
🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 40-40: duplication of key "management" in mapping

(key-duplicates)

🤖 Prompt for AI Agents
In `@src/main/resources/application.yml` around lines 26 - 49, The YAML contains
duplicate top-level management blocks so the second one overrides the first;
consolidate into a single management block that merges the settings — ensure
management -> endpoints -> web -> exposure -> include contains "health,info",
management -> endpoint -> health -> probes -> enabled is true, and include
show-details: always under endpoint.health, then remove the duplicate block so
all keys are present together (look for the management,
endpoints.web.exposure.include, endpoint.health.probes.enabled and
endpoint.health.show-details entries).

@@ -0,0 +1,155 @@
package pl.piomin.services.person.service;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

fd 'PersonServiceTest.java' src/test/

Repository: piomin/claude-ai-spring-boot

Length of output: 134


🏁 Script executed:

head -n 5 src/test/java/pl/piomin/services/person/PersonServiceTest.java

Repository: piomin/claude-ai-spring-boot

Length of output: 242


Package declaration doesn't match file location — this will cause a compilation error.

The file is located at src/test/java/pl/piomin/services/person/PersonServiceTest.java (package pl.piomin.services.person), but declares package pl.piomin.services.person.service. Move the file to src/test/java/pl/piomin/services/person/service/PersonServiceTest.java or correct the package declaration to pl.piomin.services.person.

🤖 Prompt for AI Agents
In `@src/test/java/pl/piomin/services/person/PersonServiceTest.java` at line 1,
The package declaration in the PersonServiceTest class is incorrect for its file
location: update the package statement in the PersonServiceTest source so it
matches the directory structure (change package from
pl.piomin.services.person.service to pl.piomin.services.person) or move the file
into a matching folder (pl/piomin/services/person/service) so the class
PersonServiceTest compiles; adjust the package line in the PersonServiceTest
file accordingly to resolve the mismatch.

validRequest = new PersonRequest();
validRequest.setFirstName("John");
validRequest.setLastName("Doe");
validRequest.setPesel("1234567890");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test PESEL value is only 10 characters; the domain constraint requires exactly 11.

"1234567890" is 10 characters, but PersonRequest validates @Size(min = 11, max = 11). While validation annotations aren't enforced in unit tests, test data should be consistent with domain constraints to avoid confusion and to be reusable in integration tests.

Proposed fix
-        validRequest.setPesel("1234567890");
+        validRequest.setPesel("12345678901");

Apply the same fix to the person entity setup on Line 50 and the findByPesel mock/assertion on Lines 102–107.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
validRequest.setPesel("1234567890");
validRequest.setPesel("12345678901");
🤖 Prompt for AI Agents
In `@src/test/java/pl/piomin/services/person/PersonServiceTest.java` at line 40,
The test uses a 10-character PESEL ("1234567890") which violates the domain
constraint on PersonRequest (`@Size`(min = 11, max = 11)); update the test data to
use an 11-character PESEL (e.g. "12345678901") wherever PESEL is set: change
validRequest.setPesel(...) in PersonServiceTest, update the corresponding person
entity setup (the Person instance used in the test), and update the mocked
repository interaction/assertion that references findByPesel(...) so all three
places use the same valid 11-character value to keep test data consistent with
the domain constraint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant