L0 Tranche-0 #6 — Opaque-ticket validator service for Centrifugo connect_proxy (ADR-0002). Spring Boot 3.3 + gRPC + Redis.
  • Java 97.2%
  • Lua 2.4%
  • Dockerfile 0.4%
Find a file
hibryda c3f4083a08 fix(mint): read userId UUID claim instead of sub (email) for the gRPC fan-out (#8)
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.
2026-06-02 08:22:53 +02:00
src fix(mint): read userId UUID claim instead of sub (email) for the gRPC fan-out (#8) 2026-06-02 08:22:53 +02:00
.dockerignore fix(docker): PR #1 R2 MINOR — drop !target/*.jar from .dockerignore 2026-05-24 01:46:38 +02:00
.gitignore feat(identity-service): bootstrap Spring Boot 3.3 + Maven + base deps 2026-05-24 00:56:39 +02:00
Dockerfile chore(dockerfile): PR #1 R1 MINOR — declare ARG DSKIP_TESTS + SKIP_CHECKSTYLE 2026-05-24 01:34:20 +02:00
LICENSE Initial commit 2026-05-24 00:48:23 +02:00
pom.xml fix(observability): ADR-0015 follow-up — null-span + bridge test + recordEventOnly (#332) (#7) 2026-05-31 02:31:22 +02:00
README.md feat(identity-service): bootstrap Spring Boot 3.3 + Maven + base deps 2026-05-24 00:56:39 +02:00

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).