Skip to content

Keeps the location token out of the query log - #149

Merged
johnnyt merged 1 commit into
mainfrom
sr-d2j1-keep-token-out-of-query-log
Oct 2, 2026
Merged

johnnyt merged 1 commit into
mainfrom
sr-d2j1-keep-token-out-of-query-log

Conversation

@johnnyt

@johnnyt johnnyt commented Oct 2, 2026

Copy link
Copy Markdown
Member

What

At the :debug level Ecto's query log prints every bound parameter, and
three of this package's statements bind the BasicHTTP location token, so a
host running at :debug had the token printed by this package's own
statements. Ruled by the operator, 2026-10-01: those statements run with
Ecto's log: false option and nothing else changes.

  • StatifierRouter.BasicHTTP.Front, private resolve/2: the lookup built
    by address_by_token/2 now runs as config.repo.one(query, log: false).
  • StatifierRouter.Delivery, private locate/3: the location insert at
    create now runs as config.repo.insert!(row, log: false).
  • StatifierRouter.BasicHTTP.rotate_location/2: the upsert gains
    log: false beside its on_conflict and conflict_target options.

How: the option goes on the repo call itself, not through the Config
helpers (Config.put_meta/2 and Config.queryable/2 only place the row and
the query in the configured table and prefix). No other statement binds the
token; BasicHTTP.location/2 binds only the execution id and is untouched.
No table, option, answer or transaction changes.

The test

test/statifier_router/basic_http_query_log_test.exs, "the debug query
log": it raises the logger to :debug (restored in on_exit; the module
is async: false because the level is global), drives a create, a front
POST, a rotation and a POST at the new location inside capture_log/2, and
finds neither token in any log entry that names one of this package's
tables. The assertion is scoped to those entries because the capture also
holds statifier_persistence's execution insert and update, whose
position_blob carries the location inside _ioprocessors (cut short by
Ecto's inspect limit, so unreadable there, not absent); those statements
are that package's. A positive control asserts this package's address
statements did print at :debug.

Sabotage, one mutation at a time, each restored byte-equal before the next:
dropping log: false from the lookup, from the create's insert and from the
upsert each turned the test red on that statement's own log line.

The record

A dated Note at the foot of docs/adr/0002-addressing.md (zero removed
lines): the three statements; the token is part of the execution's
persisted state (written into _ioprocessors once at session start, and
into position_blob by statifier_persistence on every create and step, in
the clear unless the host passes an encrypting :blob_type); this package
keeps it out of its own query log only, since ecto_sql 3.14.0's
Ecto.Adapters.SQL emits the query telemetry event with the parameters
before it reads log; after a rotation the persisted _ioprocessors still
names the old token, as the location Amendment's "What rotation does not
reach" bullet already says; the mitigation is rotation and never :debug
in production. Every claim was checked against the dependency sources
locked in mix.lock (statifier 2.10.0, statifier_persistence 0.18.0,
ecto_sql 3.14.0) and this branch.

Changelog

changelog.d/sr-d2j1.md, under Security.

Gate

Full mix quality green on the branch head before the push.

Provenance

The branch was cut before the outbound-send Amendment merged to ADR-0002;
this Note was re-appended after that Amendment at the foot of the file
(additive, keep-both), and the full gate ran on the rebased head. The test
file is new rather than a case in basic_http_test.exs, because that
module is async: true and this test changes the global logger level.

Review tier: a cold review, dispatched separately.

At :debug, Ecto's query log prints every bound parameter, and three
statements bind the BasicHTTP location token: the front's lookup, the
location insert at create and the rotation's upsert. Each now passes
log: false on the repo call itself; no other statement changes.

A dated Note on ADR-0002 records that the token is part of the
execution's persisted state, that this package keeps it out of its
own query log only (the query telemetry event still carries the
parameters), and the mitigation: rotation, and never :debug in
production.

Refs: sr-d2j1
@johnnyt
johnnyt force-pushed the sr-d2j1-keep-token-out-of-query-log branch from ca2f85e to 9ae971e Compare October 2, 2026 09:51
@johnnyt
johnnyt merged commit bbe6c16 into main Oct 2, 2026
1 check passed
@johnnyt
johnnyt deleted the sr-d2j1-keep-token-out-of-query-log branch October 2, 2026 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant