- Java 97.2%
- Lua 2.4%
- Dockerfile 0.4%
identity-service's opaque-ticket mint keys family-service.GetFamilyForUser + user-service.GetUserProfile on the user's UUID. JwtAuthenticationFilter now binds the principal from the access token's userId (UUID) claim, not sub (email) — fixing the INVALID_ARGUMENT the mint returned when the email sub reached the UUID-keyed fan-out. Fails CLOSED (HTTP 401, never a downstream 500/INVALID_ARGUMENT) when userId is missing, blank, the wrong JSON type, or non-UUID; normalises valid UUIDs to canonical lowercase. sub (email) retained in claims for audit. Six JwtAuthenticationFilterTest cases cover every rejection branch. Pairs with user-service #24 (additive userId claim). Verified e2e: mint -> HTTP 200. |
||
|---|---|---|
| src | ||
| .dockerignore | ||
| .gitignore | ||
| Dockerfile | ||
| LICENSE | ||
| pom.xml | ||
| README.md | ||
im2be-identity-service
L0 Tranche-0 #6 — Centrifugo opaque-ticket minter + connect_proxy.Validate gRPC server.
Implements the flow defined in ADR-0002: user-service issues an RS256/JWKS user JWT → client calls identity-service POST /token/centrifugo with that Bearer token → identity-service mints a 192-bit-entropy opaque ticket, stores it in Redis (TTL=5min), returns base64url to the client → client presents ticket to Centrifugo → Centrifugo invokes connect_proxy.Validate(ticket) via gRPC through the Envoy/SPIFFE sidecar → identity-service consumes the ticket (single-use semantics) and returns user context.
Status
This repo currently holds the PR-OPAQUE-1 scaffold (Spring Boot project, gRPC stub, HTTP controller stub, Envoy sidecar overlay). The HTTP endpoint returns 501 NOT_IMPLEMENTED and the gRPC RPC returns UNIMPLEMENTED — actual ticket mint + validate logic lands in PR-OPAQUE-2 and PR-OPAQUE-3.
| PR | Scope |
|---|---|
| PR-OPAQUE-1 (this PR) | Spring Boot scaffold, OTel, gRPC stub, Redis client, Dockerfile, flux overlay |
| PR-OPAQUE-2 | Ticket mint logic (/token/centrifugo 200 OK) + Redis storage |
| PR-OPAQUE-3 | ConnectProxyService.Validate real implementation |
| PR-OPAQUE-5 | realtime-service / Centrifugo gRPC client wiring |
| PR-OPAQUE-6 | E2E qa-rig flow |
| PR-OPAQUE-7 | Fallback ticket pool consumption |
Tech stack
- Java 17, Spring Boot 3.3.13, Maven
- gRPC (net.devh:grpc-spring-boot-starter 3.1.0.RELEASE; grpc-java 1.65.1)
- Redis (Lettuce; via spring-boot-starter-data-redis)
- JWT verification (jjwt 0.11.5) — verifier-half of L0 #5 RS256/JWKS chain
- OpenTelemetry (instrumentation BOM 2.13.3, OTLP gRPC exporter) — W2 PR-OTEL baseline
- Protobuf (3.25.5) — proto contracts from meta-repo
protobuf/realtime/v1/connect.proto
Build
mvn clean install # full build + tests
mvn -P unit-tests clean test # unit tests only
mvn -P integration-tests verify # integration tests
mvn -DskipTests=true clean package # JAR only
Build must exit with zero warnings (rule 62 — clean compilation).
Run locally
SPRING_PROFILES_ACTIVE=dev \
JWT_ISSUER_JWKS_URL=http://localhost:8081/.well-known/jwks.json \
IDENTITY_REDIS_HOST=localhost \
mvn spring-boot:run
HTTP server on :8080, gRPC on :50051, actuator probes on :8080/actuator/health/{liveness,readiness}.
Deployment
Manifests live in the meta-repo at flux-applications/apps/identity-service/. The L0 Tranche-0 SPIFFE substrate (Pattern B per ADR-0003) provisions:
- One identity-service container (Spring Boot, port 8080 HTTP + 50051 gRPC)
- One Envoy sidecar that terminates inbound mTLS for the gRPC port and originates outbound mTLS to user-service's JWKS endpoint
- SPIRE workload registration entry SPIFFE ID:
spiffe://aim2be.svc.cluster.local/ns/<ns>/sa/identity-service
License
Apache-2.0 (see LICENSE).