Use Threadline.Integrations.Sigra when your Phoenix host already uses Sigra for request authentication and impersonation.
Install
Add Sigra to your host application's mix.exs as an optional dependency:
{:sigra, "~> 0.2", optional: true}This dependency is for hosts; never for the library.
Plug callback wire-up
Wire Threadline.Plug directly with both callbacks in the router pipeline
after your host has established request auth and any proxy-aware IP rewriting:
pipeline :api do
plug :accepts, ["json"]
plug Threadline.Plug,
actor_fn: &Threadline.Integrations.Sigra.actor_ref_from_conn/1,
context_overrides_fn: &Threadline.Integrations.Sigra.audit_context_overrides_from_conn/1
endactor_fn decides who acted. context_overrides_fn can add only additive
request metadata when the baseline conn extraction has no value.
Threadline.Plug always derives request_id from x-request-id first and
correlation_id from x-correlation-id first. The Sigra callback is therefore
supplemental: it fills missing values and never replaces an explicit header or
already-derived actor identity. If the callback returns unknown keys or any
non-map value, Threadline.Plug raises ArgumentError immediately.
Hosts still own transport normalization. If your deployment needs proxy-aware IP
handling, rewrite conn.remote_ip upstream before Threadline.Plug runs.
Behaviors locked by SPEC
- Impersonation maps to
:admin. Whencurrent_scope.impersonating_fromis non-nil,actor_ref_from_conn/1returns an admin actor and keeps the impersonated user encoded in correlation metadata. - API token maps to
:service_account. Whencurrent_scope.auth_methodis:api_tokenor:jwt,actor_ref_from_conn/1returns a service account actor usingcurrent_scope.id. - Active organization adds a suffix. When Sigra exposes an active organization, the adapter appends
:org:<id>to the derived correlation id. - Anonymous / Sigra-absent returns
nil. If the request has no supported Sigra actor shape,actor_ref_from_conn/1returns rawnil. x-correlation-idheader always wins. When the header is present,audit_context_overrides_from_conn/1returns%{}soThreadline.Plugpreserves the request value instead of replacing it.x-request-idand any existing actor identity also stay authoritative.context_overrides_fnis additive request metadata only; it is not a second actor path.- Plug-only adapter; no telemetry subscription in v1.
correlation_id formats
- Impersonation:
sigra-imp:<session_id>:user:<imp_user_id> - Plain session:
sigra-session:<session_id> - API token:
sigra-token:<token_id> - Anonymous / Sigra absent: no override /
%{}
Soft-dep contract
Code.ensure_loaded?(Sigra.Session) is the single soft-dependency gate.
When that check is false:
actor_ref_from_conn/1returnsnilaudit_context_overrides_from_conn/1returns%{}