Multi tenant kafka header organization context
Skill kjuhwa/skills-hub/skills/backend/multi-tenant-kafka-header-organization-context
Self-correcting knowledge corpus for Claude Code — 9 stable shape clusters, bias-correction pipeline baked into contribution flow. 47 papers, 45 techniques, 1.1k skills.
npx -y skills add kjuhwa/skills-hub --skill multi-tenant-kafka-header-organization-contextAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Propagate tenant/organization id from Kafka headers through async handler threads via a ThreadLocal context holder
SKILL.md
1.9 KB, as published. Nobody here has run it
Multi-tenant Kafka header → context propagation
Keep tenant id out of message payloads when possible; carry it in a Kafka header so routing can happen without deserializing the body. On the consumer side, extract once and push into a TenantContextHolder ThreadLocal before dispatching to async handlers.
Shape
- Producer sets header
organizationId(ortenantId) on every record. - Consumer reads header, wraps payload + header into an event wrapper (e.g.
CollectionEvent(organizationId, payload)). - Before handing to an executor/BlockingQueue consumer, set
TenantContextHolder.set(orgId); always clear infinally. - Handler threads must inherit the context — use
DelegatingSecurityContextExecutor-style wrapping or set inside the runnable, NOT by relying on InheritableThreadLocal across a long-lived pool.
Steps
- Define
TenantContextHolderwithset/get/clearover a plainThreadLocal<String>. - In the Kafka listener: read
organizationIdfrom headers; reject records missing it. - Wrap payload in an event object that carries
organizationIdexplicitly (don't depend on ThreadLocal across queue boundaries). - On the consuming thread (handler), first line:
TenantContextHolder.set(event.orgId);try { handle(event); } finally { TenantContextHolder.clear(); }. - Any downstream code reaching into tenant-scoped stores reads from the holder.
- Guardrail: queue-based hand-offs cross threads — never rely on ThreadLocal surviving the hand-off; always re-set on the other side.