Context Propagation
Request/trace correlation across async boundaries.
Context propagation ensures that all enforcement calls, traces, and spans are correctly correlated within a single request or user session.
Why Context Matters
Without proper context, you lose:
- Trace continuity: Spans from the same request appear disconnected.
- Audit correlation: Cannot link enforcement decisions back to the originating request.
- User attribution: Cannot filter logs by
user_idororg_id.
Context Fields
| Field | Description | Example |
|---|---|---|
requestId |
Unique ID for the current request | req_abc123 |
traceId |
ID for the distributed trace | trace_xyz789 |
orgId |
Organization/tenant identifier | org_acme |
userId |
End-user identifier | user_42 |
sessionId |
Browser/client session | sess_abc |
tags |
Arbitrary key-value metadata | { env: "prod" } |
TypeScript (AsyncLocalStorage)
The SDK uses Node.js AsyncLocalStorage to propagate context across async boundaries.
njira.runWithContext(
{
requestId: "req_123",
traceId: "trace_abc",
orgId: "org_1",
userId: "u_9",
tags: { environment: "production" }
},
async () => {
// All calls inside this function use the same context
await njira.enforcePre({ input: "hello" });
njira.trace.event("custom", { ok: true });
// Nested async calls also inherit context
await processSubTask();
}
);
Python (contextvars)
The Python SDK uses contextvars for async-safe context propagation.
ctx = {
"request_id": "req_123",
"trace_id": "trace_abc",
"org_id": "org_1",
"user_id": "u_9",
"tags": {"environment": "production"}
}
async def handler():
# Context is available via njira.get_context()
await njira.enforce_pre(input_data="hello")
return njira.get_context()
await njira.run_with_context(ctx, handler)
Middleware Integration
For web applications, use the provided middleware wrappers. They automatically:
- Generate a unique
requestIdif not present. - Extract
traceIdfrom incomingx-njira-trace-idheader. - Set context for the request lifecycle.
- Attach
x-njira-trace-idto the response. - Flush traces after the request completes.
Express
import { njiraMiddleware } from "@njiraai/sdk/express";
app.use(njiraMiddleware(njira));
FastAPI
from njiraai.fastapi import NjiraMiddleware
app.add_middleware(NjiraMiddleware, njira=njira)
Next.js
// middleware.ts
export { njiraMiddleware as middleware } from "@njiraai/sdk/next";
Debugging Context Issues
If traces appear disconnected or context is missing:
- Check middleware order: Njira middleware should run early.
- Verify async boundaries: Ensure
runWithContextwraps all async work. - Log context: Use
njira.getContext()to inspect current values. - Check for context loss: Some libraries (e.g.,
pgcallbacks) may lose context.