Local development
Run the same tenant flows on your workstation.
The local environment uses PostgreSQL, Eureka service discovery, tenant hostnames, and an optional trusted HTTPS certificate. Use HTTPS when testing browser redirects, tenant isolation, or passkeys.
Profile convention
eureka- Local database settings, local ports, Eureka registration, and load-balanced service WebClients.
local-https- HTTPS overlay for local certificates and direct authorization-server token and issuer URLs.
non-eureka- Direct service URLs for environments such as Kubernetes. Do not combine it with the local Eureka profile.
kubernetes- Kubernetes environment values, normally paired with
non-eurekain deployed workloads.
# Local HTTP
SPRING_PROFILES_ACTIVE=eureka ./gradlew bootRun
# Local HTTPS
SPRING_PROFILES_ACTIVE=eureka,local-https ./gradlew bootRunService ports and databases
8761None8082role8083authentication8084user8085None8086account28087attempt8088organization9001authorization + tenant databases9093authzmanager8080NoneAuthorization also connects to freeauth, business1auth, and business2auth for tenant-specific authorization data.
Start services in dependency order
- Start PostgreSQL and confirm every required local database is available.
- Start discovery-service and verify the Eureka registry on port 8761.
- Start role, authentication, user, account, attempt, organization, and email services.
- Confirm the services are registered in Eureka before starting authorization.
- Start authorization after its dependencies so tenant and organization seeding can complete.
- Start authzmanager and api-gateway, then test the tenant HTTPS URLs.
Eureka uses test:test locally. Verify registrations athttp://localhost:8761/eureka/apps before diagnosing WebClient failures.
Configure tenant hostnames
Add these entries to /etc/hosts:
127.0.0.1 platform.openissuer.test
127.0.0.1 free.openissuer.test business1.openissuer.test business2.openissuer.test
127.0.0.1 platform.admin.openissuer.test free.admin.openissuer.test
127.0.0.1 business1.admin.openissuer.test business2.admin.openissuer.testCreate the local HTTPS certificate
Install and trust the local certificate authority once:
brew install mkcert nss
mkcert -install
mkdir -p ~/openissuer-local-certsCreate the certificate used by the local-https profile:
mkcert \
-cert-file ~/openissuer-local-certs/openissuer.test.pem \
-key-file ~/openissuer-local-certs/openissuer.test-key.pem \
platform.openissuer.test free.openissuer.test \
business1.openissuer.test business2.openissuer.test \
platform.admin.openissuer.test free.admin.openissuer.test \
business1.admin.openissuer.test business2.admin.openissuer.test \
authorization-server localhost 127.0.0.1Fully quit and reopen the browser after installing the local CA. Passkeys require a trusted secure context, so tenant passkey testing must use HTTPS.
Run the browser-facing services
# authorization repository
SPRING_PROFILES_ACTIVE=eureka,local-https ./gradlew bootRun
# authzmanager repository
SPRING_PROFILES_ACTIVE=eureka,local-https ./gradlew bootRun
# api-gateway repository
SPRING_PROFILES_ACTIVE=eureka,local-https ./gradlew bootRunCommon local URLs:
https://free.openissuer.test:9001
https://business1.openissuer.test:9001
https://free.admin.openissuer.test:9093
https://business1.admin.openissuer.test:9093Database and Flyway behavior
Each service applies its Flyway migrations when it starts. Never edit an already-applied migration in a persistent environment. Add a new migration for an incremental schema change.
Run tests and diagnose startup failures
./gradlew test
# Faster compile and test-source verification
./gradlew testClasses- Unresolved server port
- Activate
eurekaso the local port variables are loaded. - Eureka returns 401
- Confirm the local registry credentials are
test:testand the registry is running. - Service name cannot resolve
- Confirm both services use
eurekaand the target appears in the registry. - TLS required on this port
- Use
local-httpsconsistently for services calling the HTTPS authorization server. - Port already in use
- Stop the existing process or verify that another copy of the service is not already running.