When using Obscura's assign-mode redaction in Phoenix, placing a sanitized copy of request params in conn.assigns is not enough — Phoenix's default telemetry logger still reads conn.params and can log raw PII. The solution is Obscura.Phoenix.Logger, an opt-in telemetry handler that reads only the redacted assign and fails closed in all error paths. Installation requires three explicit steps: disabling Phoenix's default logger, adding the Obscura plug after Plug.Parsers and before the router, and supervising the telemetry handler. The handler also logs route templates instead of raw paths, validates HTTP methods, clears inherited Logger metadata, and enforces work budgets (max 64 keys, 64 KiB scalar values, 1,024 traversed values) to prevent DoS via adversarial request shapes. The post includes a deployment checklist and clearly scopes what the integration does not protect.

10m read timeFrom hfiguera.github.io
Post cover image
Table of contents
The Result in One MinuteThe Gap Between a Safe Copy and a Safe LogWhy I Did Not Replace conn.paramsThe BoundaryWhy the Logger Is Opt-InInstalling It in a Phoenix ApplicationThe Route Template MattersA Redacted Assign Still Needs Defensive HandlingSynchronous Logging Needs Work BudgetsMethods, Metadata, and Failures Are Boundaries TooWhat This Integration Does Not ProtectA Deployment ChecklistThe Larger Lesson

Questions this post answers

How do I prevent Phoenix from logging raw request parameters like emails and passwords in its default telemetry logger?

Disable Phoenix's default logger with `config :phoenix, :logger, false`, create a redacted assign after Plug.Parsers using a plug like Obscura.Phoenix.Plug in :assign_redacted mode, then supervise a custom telemetry handler that reads only that assign. This ensures the controller still receives original params while the log record contains only the sanitized copy. The handler must fail closed — never falling back to conn.params — when the assign is missing or malformed. Phoenix developers shipping PII-handling endpoints track patterns like this on daily.dev.

What are the work budget limits in Obscura.Phoenix.Logger to prevent DoS via large request bodies?

The handler rejects parameter graphs exceeding any of these limits: 64 parameter keys, 4 KiB cumulative key text, 64 KiB cumulative scalar value text, 1,024 traversed values, 128 terms requiring PII analysis, and 64 decimal digits in a single number. Exceeding any budget produces a single `Parameters: "[FILTERED]"` log line with no partial output and no fallback to raw parameters. Teams hardening Phoenix logging against adversarial inputs find the latest Elixir security patterns on daily.dev.

Why does Obscura.Phoenix.Logger log route templates instead of raw request paths in Phoenix?

Raw URL paths can contain PII directly — for example `/users/jane@example.com/documents/4111111111111111`. The handler logs the matched Phoenix route template (e.g. `/users/:email/documents/:card_id`) instead, which preserves enough information to group and search logs without copying path parameters into every record. A route with sensitive literal text in the template itself is considered a bad route and should be fixed at the source. Developers designing privacy-safe API routing share approaches like this on daily.dev.

61 Impressions