docs(spec): eliminate secret leakage in logs, spans, and error responses - #31
Draft
antstanley wants to merge 1 commit into
Draft
Conversation
antstanley
force-pushed
the
spec/eliminate-secret-leakage-logs-spans
branch
2 times, most recently
from
August 5, 2026 08:22
8031bc4 to
39283a4
Compare
antstanley
changed the base branch from
main
to
spec/runtime-parity-across-interfaces
August 5, 2026 08:22
antstanley
marked this pull request as draft
August 5, 2026 08:25
This was referenced Aug 5, 2026
antstanley
force-pushed
the
spec/eliminate-secret-leakage-logs-spans
branch
from
August 5, 2026 09:00
39283a4 to
c398ab3
Compare
antstanley
force-pushed
the
spec/eliminate-secret-leakage-logs-spans
branch
from
August 5, 2026 11:29
c398ab3 to
7814df6
Compare
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
antstanley
force-pushed
the
spec/eliminate-secret-leakage-logs-spans
branch
from
August 5, 2026 12:01
7814df6 to
a308cc3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Stacked PR 13 of 16 — part of stack #35, which targets
main.Base: #27 (
spec/runtime-parity-across-interfaces) · Followed by: #30This PR's diff shows only its own change. Merge the stack bottom-up; do not merge this before its base.
Why it sits at position 13: Introduces
Secret<T>and theread_boundedhelper that #33 relies on for the JWKS success path; cross-references #24 for the fixed-classification auditreason.Scope of this PR
This PR currently carries the change spec. It will also carry the implementation plan and the build work for that spec — plan and code land as later commits on this same branch, so the spec, its plan, and its implementation review and merge as one unit.
Review order within the PR: spec first, then plan, then implementation.
Change spec proposing that secrets and internal detail stop reaching logs, spans, and error responses.
Problem. Seven confirmed findings with one root cause: credential-bearing values are ordinary
Strings, so keeping them out of telemetry is a matter of reviewer discipline rather than something the compiler enforces. Three provider sites interpolate an upstream non-2xx body — which can carry provider tokens and client secrets — intoProviderError.detail; the LMDB and Valkey adapters put a refresh-token hash and session data into#[instrument]spans; the/tokenerror path distinguishes failure causes to the caller; andX-Request-Idis client-chosen, unbounded, and propagated into every downstream span.Proposed delta.
Secret<T>incrates/core— a newtype implementing neitherDebugnorDisplay, so a credential reaching a tracing macro, aformat!, or#[instrument]'s default argument capture becomes a compile error rather than a review miss. The spec enumerates the nine values it wraps, fromSession.refresh_token_hashthrough the three configured secrets to every upstream response body read at a provider boundary.#[serde(transparent)], so no schema change.shared::upstream::error_detail, fed by a 64 KiB-boundedread_bounded, replaces the three sites that interpolate an upstream body, redacting after percent-decoding.client_description()for the caller, with the fullDisplaylogged under the request span for every error class rather than onlyserver_error, closing the/tokenvalidation oracle.[A-Za-z0-9_-], minting a fresh UUIDv4 silently on rejection rather than failing the request.#[instrument]redactions are specified to ship immediately, ahead of the type — one-line changes with no design dependency.What reading the code changed.
Debugprecedent is six sites, not two. BeyondWebhookConfig.secretandInternalApiConfig.shared_secret, the code hand-implements redactingDebugforOidcProviderConfig,TokenResponse,ProviderTokens, andAppleProvider. Six correct applications and one miss —Sessionplainly derivesDebug— is precisely the discipline-lapse pattern that argues for a type instead of a convention, so the Motivation is written to that fact.OidcProviderhas noDebugimpl at all, derived or manual. Itsclient_secret: Option<String>is protected by the absence ofDebug, not by a redacting one — no finding mentions this, and adding#[derive(Debug)]later would silently open a leak. Covered by wrapping the field.LocalKeyManageris not an eighth leak. It derivesDebugand holds aned25519_dalek::SigningKey, whose ownDebugusesfinish_non_exhaustive()to omit the secret. Recorded as an Assumption — an upstream discipline this repo depends on but does not control — rather than a finding.Cross-reference note.
2026-08-05-audit_and_throttle_authentication_failures.md(#24) specifies the fixed-classification auditreasonfor the same root cause seen from the audit side; it is cross-referenced, not restated. That file is not onmainyet, so the link resolves once #24 merges.Drafted with the
spec-creatorplugin from a deep security scan of the repository at53cbdec9. Spec only — no source changes.