codegen: honor [debug_redact = true] in generated Debug impls#162
Conversation
Fields annotated with the standard debug_redact option print [REDACTED] instead of their value in owned-message, oneof, view, and view-oneof Debug output. Types without the annotation produce byte-identical code. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
@iainmcgin would appreciate a review when you have a chance — this adds support for the standard |
Fields whose descriptor carries [debug_redact = true] now print [REDACTED] in place of their value when a DynamicMessage is Debug-formatted, matching the redaction performed by generated Debug impls. Covered by an e2e test with a hand-built descriptor and noted in the guide.
A keyword-named field (e.g. `type`) now prints the label `type` instead of `r#type`, matching #[derive(Debug)] and the view Debug impl. Includes the regenerated bootstrap descriptor types and a codegen test.
Assert the redacted bytes/repeated fields stay out of the view Debug output and exercise the no-lifetime view-oneof Debug impl at runtime. Add changelog entries for the DynamicMessage redaction and the Debug label fix.
|
[claude code] Thanks for this contribution — the design is exactly right: the derive swap is keyed on the presence of an annotated field, so unannotated protos generate byte-identical code (verified locally — I've pushed three follow-up commits directly to this branch (taking advantage of "Allow edits by maintainers") rather than going through a review round-trip: 4832138 — 3d8f6d1 — owned-message Debug labels drop the 24ed306 — two view-side test additions. Assertions that the redacted Things we considered and deliberately left as-is:
With the follow-ups on the branch, |
…debug-impls # Conflicts: # CHANGELOG.md
Motivation
debug_redactis protobuf's standard way to mark fields whose values must not appear in debug output — C++/Java honor it inDebugString, and Go hasprotoc-gen-go-redact. buffa currently prints annotated fields like any other: the generated owned-messageDebugimpl lists every field's value, and oneof enums / view structs / view-oneof enums#[derive(Debug)]. That makes atracing::debug!(?req)on a generated request type a credential/PII leak for any consumer that wants to rely on the annotation. We'd like to start annotating sensitive fields (API keys, access/refresh tokens) in our protos and have buffa-generated Rust redact them automatically, matching what our Go codegen already does.What this does
message.rs): the generatedDebugimpl prints the literal marker[REDACTED](via::core::format_args!, so it renders unquoted) in place of an annotated field's value.oneof.rs,view.rs): when a contained field/variant is annotated, theDebugderive is swapped for a generated impl that redacts those fields/variants; everything else prints as before.FooOwnedViewwrappers pick this up transitively viaOwnedView'sDebug.Debugformatting only: binary, JSON, and text-format serialization are untouched.docs/guide.md(new "debug_redactandDebugoutput" subsection), thetype_attributePitfalls rustdoc in buffa-build, and a CHANGELOG entry under Unreleased.Conscious choices, happy to adjust:
[REDACTED](matches protobuf's own debug-output convention); no config knob in this first cut — one can be added additively later.Debugoutput (matching the owned-message impl);__buffa_unknown_fieldsis deliberately excluded since unknown fields can carry redacted data from a newer schema version. Noted in the CHANGELOG.Testing
buffa-codegen/src/tests/debug_redact.rs: 4 codegen-output tests (message / oneof / view+view-oneof redaction, plus an unannotated-proto test asserting the derives and absence of the marker).buffa-test/protos/debug_redact.proto+buffa-test/src/tests/debug_redact.rs: 6 runtime tests assertingformat!("{:?}")never contains the annotated values for owned message, oneof variant, repeated field, all-redacted scalar oneof, and decoded views — and that unannotated fields/variants still print.buffa-codegen(415) andbuffa-testsuites pass;task gen-wkt-typesproduces no diff (no vendored proto uses the option); clippy clean on the touched crates.🤖 Generated with Claude Code