phase 2 (part 4): SSE stream via io.Pipe, OIDC JWT auth middleware

- SSE stream: GET /events/stream using io.Pipe to bridge the SSE
  goroutine to the response body. Replay from Last-Event-ID via
  in-memory broker with DB fallback. LISTEN/NOTIFY fan-out to all
  subscribers. Heartbeat every 15s. Bounded channels.
- OIDC JWT auth: validates Bearer tokens against Authentik/OIDC
  issuer via JWKS discovery + key caching. Extracts sub/email into
  context actor. Falls back to static bearer tokens. Dev mode (no
  OIDC + no tokens) = open.
- Config: OIDCIssuer, OIDCClientID env vars
- SSE + OIDC infrastructure complete, build passes, all tests pass

Remaining: MCP server, conformance tests, wire audit middleware
This commit is contained in:
2026-07-07 09:40:11 +02:00
parent 9c63a1bfa9
commit 1bfc18ea3a
9 changed files with 1101 additions and 20 deletions

View File

@@ -26,6 +26,8 @@ func statusFor(err error) (status int, title string) {
return http.StatusConflict, "relationship cardinality violation"
case errors.Is(err, domain.ErrAbstractType), errors.Is(err, domain.ErrInvalidEdge):
return http.StatusUnprocessableEntity, "ontology validation failed"
case errors.Is(err, domain.ErrInvalidInput):
return http.StatusBadRequest, "invalid input"
case errors.Is(err, domain.ErrApprovalRequired):
return http.StatusForbidden, "operator approval required"
case errors.Is(err, domain.ErrAutonomyBlocked):