fix(log): scrub PII + secret-adjacent data from auth + stripe log lines #280
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/bunyip!280
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-265-log-hygiene"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
BUNYIP-265: tighten the log surface so PII and Stripe customer data stop ending up in long-retained log files. The 2026-06-30 audit named the load-bearing call sites.
bunyip-api/src/handlers/auth.rs:260,405,466,848,887: fivetracing::error!sites emittedemail = %emailon email-send failure. The email failure mode is the actionable signal; the address is PII + an enumeration channel ("does this address have an account?" answered by checking the logs). Drop the email field; correlation already comes from the request_id middleware. Same fix at the "Initial admin user created via setup"tracing::info!(now logsuser_idonly).bunyip-api/src/handlers/auth.rs:928-936(auth_redirect): the debug log emittedtarget_url = %target_url, which on this code path carries OIDCstate/code/return_toquery parameters. Parse the URL once and log only the path; the query string never reaches log files.crates/bunyip-domain/src/services/stripe.rs:948,1001: twotracing::error!sites emitted the FULL Stripe response body on failure. Stripe error envelopes commonly carry customer email, subscription id, last-4 PAN digits - none of which should sit in log files. Newstripe_error_envelopehelper parses the documented{"error":{"code":"...","type":"..."}}shape and the loggers emit only those two operationally-actionable fields.EMAIL_LOG_TOKENSis already fail-closed in production (crates/bunyip-domain/src/config.rs:124-let log_tokens = !is_production && ...), so the audit's separate concern about magic-link / reset URL leakage is already addressed and untouched here.#BUNYIP-265
BUNYIP-265: tighten the log surface so PII and Stripe customer data stop ending up in long-retained log files. The 2026-06-30 audit named the load-bearing call sites. - `bunyip-api/src/handlers/auth.rs:260,405,466,848,887`: five `tracing::error!` sites emitted `email = %email` on email-send failure. The email failure mode is the actionable signal; the address is PII + an enumeration channel ("does this address have an account?" answered by checking the logs). Drop the email field; correlation already comes from the request_id middleware. Same fix at the "Initial admin user created via setup" `tracing::info!` (now logs `user_id` only). - `bunyip-api/src/handlers/auth.rs:928-936` (`auth_redirect`): the debug log emitted `target_url = %target_url`, which on this code path carries OIDC `state` / `code` / `return_to` query parameters. Parse the URL once and log only the path; the query string never reaches log files. - `crates/bunyip-domain/src/services/stripe.rs:948,1001`: two `tracing::error!` sites emitted the FULL Stripe response body on failure. Stripe error envelopes commonly carry customer email, subscription id, last-4 PAN digits - none of which should sit in log files. New `stripe_error_envelope` helper parses the documented `{"error":{"code":"...","type":"..."}}` shape and the loggers emit only those two operationally-actionable fields. `EMAIL_LOG_TOKENS` is already fail-closed in production (`crates/bunyip-domain/src/config.rs:124` - `let log_tokens = !is_production && ...`), so the audit's separate concern about magic-link / reset URL leakage is already addressed and untouched here. #BUNYIP-265