ibexharness
DocsBlogReleasesRoadmap
GitHub
ibexharness

Documentation

Architecture Decision RecordsADR-0002: Repository foundation bootstrapADR-0003: Branch protection and merge policyADR-0004: Protobuf and code generation policyADR-0005: Postgres migration strategyADR-0006: Auth protobuf contract (`ibex.auth.v1`)ADR-0007: Auth token validation implementationADR-0008: Security scanning and CI quality gatesADR-0009: Permission bitmap layoutADR-0010: Cryptography policyADR-0011: Proxy auth gRPC client and middlewareADR-0012: Proxy request normalization (OpenAI chat)ADR-0013: Proxy input validation and stable error envelopeADR-0014: Core domain migration sequencingADR-0015: Proxy rate limit skeleton (Phase 1)ADR-0016: Proxy agent identity verification (Phase 1)ADR-0017: Request ID and trace context strategy (Phase 1)ADR-0018: Graceful shutdown contract (Phase 1)ADR-0019: OpenTelemetry provider configuration (Phase 1)ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`ADR-0021: Prometheus Metric Catalog (Phase 1)ADR-0022: Health check contract (Phase 1)ADR-0023: Docs site architecture (Phase 1.5)
ADRs›ADR-0017: Request ID and trace context strategy (Phase 1)
ADRs

ADR-0017: Request ID and trace context strategy (Phase 1)

Architecture decision record 0017.

ADR-0017: Request ID and trace context strategy (Phase 1)

  • Status: Accepted
  • Date: 2026-06-07
  • Authors: IBEX Harness team

Context

M1.2.3 introduced RequestContextMiddleware, response headers (X-Request-ID, X-Trace-ID, X-Response-Time), and an error envelope with a request_id field. Generated IDs used UUID v4 and inbound header values were accepted without validation (garbage strings could propagate).

ARCHITECTURE.md requires request_id in every structured log line so auth gRPC calls, rate limit checks, and handlers can be correlated. M1.3.1 adds OTel distributed tracing; request ID must be established first as the internal correlation token.

Decision

1) UUID v7 for generated request IDs

New request IDs use UUID v7 (RFC 9562) via github.com/google/uuid v1.6.0+:

  • First 48 bits encode millisecond timestamp — IDs are time-ordered in logs
  • Falls back to UUID v4 if v7 generation fails

Inbound X-Request-ID (or IBEX_REQUEST_ID_HEADER) is honoured when it parses as a valid UUID (v4 or v7). Invalid values are discarded and a fresh v7 ID is generated.

2) Shared package packages/reqid

Request ID generation, validation, and context propagation live in packages/reqid:

  • New() — generate v7 (v4 fallback)
  • ResolveInbound(raw) — honour valid UUID or generate
  • WithRequestID / FromContext / MustFromContext
  • Constants: Header (X-Request-ID), GRPCMetadataKey (x-request-id)

Proxy internal/http thin-wraps context helpers; it does not maintain a separate context key.

3) HTTP middleware (no duplicate middleware)

M1.2.3 RequestContextMiddleware in services/proxy/internal/http/middleware.go is refactored, not replaced:

  • Request ID: reqid.ResolveInbound + reqid.WithRequestID
  • Trace ID: unchanged (UUID v4 synthetic until M1.3.1 OTel)
  • ResponseHeadersMiddleware unchanged — sets configurable request ID header on every response

Outer chain order unchanged:

metrics → requestContext → responseHeaders → logging → mux

Protected route order unchanged per ADR-0016.

4) gRPC propagation to auth

Proxy auth gRPC client connection uses a unary client interceptor that appends x-request-id from Go context to outgoing metadata on every call (ValidateToken, ValidateAgent).

Bearer token metadata remains in individual verifiers; the interceptor only adds request ID.

Auth service may log the metadata key in M1.3.3 (shared logger); no auth-side changes in this ADR.

5) Relationship to OTel trace ID

TokenPurposePhase 1 source
Request IDInternal log correlation; error envelope; response headerpackages/reqid / middleware
Trace ID (X-Trace-ID)Placeholder until OTelSynthetic UUID v4 in middleware
OTel trace IDDistributed tracing spanM1.3.1 — W3C traceparent

They coexist. Request ID appears in all log lines; OTel trace ID replaces synthetic trace ID when the tracer is active (M1.3.1).

6) Error envelope

All proxy JSON error responses populate error.request_id from reqid.FromContext (via RequestIDFromContext wrapper). Value matches the X-Request-ID response header.

Consequences

Positive

  • Time-ordered request IDs improve log search and debugging
  • Untrusted inbound IDs cannot inject arbitrary strings
  • Single shared package for future services (auth HTTP, dashboard API)
  • Auth gRPC calls correlate with proxy logs via metadata

Negative

  • Existing deployments relying on non-UUID inbound request IDs will receive fresh generated IDs instead

References

  • Milestone 1.2.6
  • ADR-0013 (amended §7)
  • ADR-0016
  • Milestone 1.3.1

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0016: Proxy agent identity verification (Phase 1)NextADR-0018: Graceful shutdown contract (Phase 1)

On this page

  • Context
  • Decision
  • 1) UUID v7 for generated request IDs
  • 2) Shared package packages/reqid
  • 3) HTTP middleware (no duplicate middleware)
  • 4) gRPC propagation to auth
  • 5) Relationship to OTel trace ID
  • 6) Error envelope
  • Consequences
  • Positive
  • Negative
  • References
0%