This Spring Boot sample demonstrates an Order API with OAuth 2.0 operation scopes, HTTP Basic authentication, API-key authentication, and mutual TLS (mTLS).
The OpenAPI contract is checked in at spec/order-api-with-auth_v2.yaml.
specmatic.yaml uses this filesystem contract directly. The OAuth fixtures live alongside it in spec/order-api-with-auth_v2_examples, which lets Specmatic load them as external examples.
POST /ordersandPATCH /orders/{id}requireorder:create.POST /productsandPATCH /products/{id}requireproduct:create.GEToperations use HTTP Basic authentication.DELETEoperations use theX-API-Keyheader.GET /healthis public at the HTTP authorization layer.
Keycloak retains users and admins roles only to decide scope eligibility. The API authorizes JWT SCOPE_order:create and SCOPE_product:create authorities; it does not consume Keycloak realm roles.
| Principal | Granted scope | Allowed writes |
|---|---|---|
user1 |
order:create |
Orders |
service_account |
product:create |
Products |
A valid token without the required operation scope returns 403 Forbidden.
The API serves HTTPS on port 8443 and requires a client certificate. Demo-only certificate material is checked in under certs for local and Docker contract testing. It is excluded from the application image and mounted at runtime for Docker Compose.
Even though /health is HTTP-public, it still requires mTLS because TLS completes before Spring receives the request.
The repository-local OpenAPI 3.0 contract configuration does not declare a custom mTLS extension. Specmatic receives the client JKS through systemUnderTest.service.runOptions.openapi.cert.
This starts the application in the test profile, uses the in-process mock token server, and runs Specmatic against https://localhost:8443 with the demo client JKS.
./gradlew test --tests com.store.ContractTestThe mock token server preserves the fixture flow: the fixture requests a scope, captures ACCESS_TOKEN, and the test security filter authorizes that captured token.
This runs the production security profile, real Keycloak, and Specmatic Enterprise in containers against the checked-in contract and examples.
./gradlew test --tests com.store.ContractTestUsingTestContainerTestIt also verifies that a request without a client certificate fails during the TLS handshake and that a valid client certificate reaches /health.
The Dockerfile copies a prebuilt application JAR, so build it before starting Compose:
./gradlew bootJar
docker compose -f docker-compose-test.yaml up --build --abort-on-container-exit --exit-code-from specmatic-testCompose starts Keycloak, the Order API, and Specmatic Enterprise. It mounts the checked-in contract/examples and certs, then uses the client JKS plus an HTTPS mTLS health check before running the contract suite.
Reports are written to:
build/reports/specmatic/test/html/index.htmlbuild/reports/specmatic/test/ctrf/ctrf-report.json
Clean up with:
docker compose -f docker-compose-test.yaml down --remove-orphans/health is excluded from generated Specmatic scenarios with PATH!=/health; it remains covered by focused application and TLS tests.
Start Keycloak:
docker compose upStart the API with the production profile:
./gradlew bootRun --args='--spring.profiles.active=prod'Request an order token from Keycloak:
curl -fsS -X POST http://localhost:8083/realms/specmatic/protocol/openid-connect/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_id=order-api' \
--data-urlencode 'username=user1' \
--data-urlencode 'password=password' \
--data-urlencode 'scope=order:create'Request a product token with service_account using scope=product:create. Supply the demo client certificate, private key, and CA when calling the API:
curl --cacert certs/ca.crt \
--cert certs/specmatic-client.crt \
--key certs/specmatic-client.key \
https://localhost:8443/healthThe certificate fixtures and their password are public demo material. Do not reuse them outside this sample.