Repository navigation
feat(go,terraform): mask sensitive body values in HTTP logs - #72
Conversation
There was a problem hiding this comment.
1 issue found across 20 files
Confidence score: 4/5
- In
sensitive_values_test.go, the failure-path assertion would miss diagnostic leaks of the nested or merged secrets. Check all three values inresp.Diagnosticstoo.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="zSDKs/terraform-provider-testing/internal/provider/sensitive_values_test.go">
<violation number="1" location="zSDKs/terraform-provider-testing/internal/provider/sensitive_values_test.go:335">
P2: The failure-path assertion checks all three values in logs but only `computed-response-secret` in diagnostics, so diagnostic leaks of the nested or merged secret pass. Check all three values in `resp.Diagnostics` too.</violation>
</file>
Shadow auto-approve: would not auto-approve because issues were found.
Click Fix with cubic on a comment, or reply @cubic-dev-ai fix this, and cubic writes the fix.
Fix all with cubic | Re-trigger cubic
fa1d50d to
9827741
Compare
Generator Snapshot Testing
Snapshot results: https://github.com/speakeasy-api/openapi-generation-snapshots/issues/110#issuecomment-6068136117 Snapshot results are summarized above. Additional run context is linked for maintainers with access. |
9827741 to
9a34bce
Compare
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 4 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval blocked by 1 unresolved issue from previous reviews.
Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 3 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval skipped because cubic reviewed only this push, not the earlier force-push. Comment @cubic review to review the whole pull request.
View guided diff | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval skipped because cubic reviewed only this push, not the earlier force-push. Comment @cubic review to review the whole pull request.
View guided diff | Turn on auto-fix | Re-trigger cubic
Values marked x-speakeasy-param-sensitive or format: password in request and response bodies could appear in HTTP debug logs and error messages. Value-based redaction only covers values known before the request, so a newly returned secret was logged before it could be recognised. Generate a per-operation schema graph of sensitive request and response body locations into a new public redact package. Operations with sensitive values tag their request context with the operation ID, so transports and custom HTTP clients can mask bodies by schema path. APIError messages and the Terraform provider's logging transport and diagnostics mask bodies with it. Methods of operations without sensitive values are unchanged.
Move the schema walk from the Go templates into Operation methods (SensitiveRequestBodyGraph, SensitiveResponseBodyGraph, HasSensitiveBodies) so that any target can render the same language-agnostic graph. The Go templates now only render it.
b072157 to
0938bf5
Compare
The redact package now takes the body's Content-Type and masks application/x-www-form-urlencoded fields and multipart parts by name, including JSON-encoded fields, keeping the body valid. The sensitive body graph is now built from TypeDef.Children, with TypeDef.Walk skipping schemas that hold nothing sensitive.
There was a problem hiding this comment.
All reported issues were addressed across 14 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
…arts A JSON value whose shape cannot hold the sensitive values of its schema is masked as a whole. Only multipart/form-data bodies are masked part by part, since other multipart subtypes have no part names, and masked parts drop their Content-Transfer-Encoding.
There was a problem hiding this comment.
All reported issues were addressed across 9 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
The sensitive body graph pruned union members that hold nothing sensitive, so a value matching such a member looked like it did not match its schema and was masked as a whole. Union nodes now record that a plain member exists, and the redactor leaves values of an unexpected shape readable when one does.
There was a problem hiding this comment.
0 issues found across 13 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval blocked by 1 unresolved issue from previous reviews.
View guided diff | Turn on auto-fix | Re-trigger cubic
Union nodes now record the shapes (object, array, scalar) of members that hold nothing sensitive, instead of a single flag. A value that matches no sensitive member stays readable only when a plain member of the same shape exists. Form fields and multipart parts are parsed as JSON before the repeated array item rule applies, so a valid plain object beside a sensitive array stays readable. Text that is not JSON stays readable only when it is not a sensitive array item and a plain scalar member exists; malformed JSON is otherwise masked as before.
There was a problem hiding this comment.
All reported issues were addressed across 12 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
Plain union members are now recorded by JSON type (object, array, string, number, boolean), with enums following their underlying type. A form field or multipart part that is not valid JSON stays readable only beside a plain string member, of the field or of its items when sent as repeated fields; a plain integer or boolean member no longer lets malformed JSON through. Text starting like a JSON object or array is never accepted as a plain string. JSON scalars must match a plain member of their own type. Nested plain unions are followed once each, so recursive unions terminate. Masked multipart parts also drop Content-Length and Content-Encoding, which no longer describe the masked payload.
There was a problem hiding this comment.
All reported issues were addressed across 13 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
…ve-response-logs-plain
|
[P1] Preserve literal field names ending in Both redactForm and redactMultipart unconditionally strip type: object
properties:
payload[]:
type: string
x-speakeasy-param-sensitive: true
name:
type: stringThe SDK serializer preserves This leaks a schema-marked value with valid input; the generic property name also avoids the CLI's name-based redaction rules. Please resolve literal schema wire names before applying array-suffix aliases, distinguishing a literal suffix from one appended by the legacy multipart array serializer. Add form and multipart regression cases for a marked scalar named |
Form fields and multipart parts were looked up with any trailing [] removed, so a property whose wire name ends in brackets missed its sensitivity marker and was logged as sent. The exact name is now looked up first; the suffix is only removed when no schema declares the bracketed name, as for arrays sent as repeated fields.
There was a problem hiding this comment.
All reported issues were addressed across 9 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
Whether a form field or multipart part name ending in [] named a literal property or an array sent as repeated fields was decided across all schemas at once, and only from properties that survived pruning of the sensitive graph. A literal name in one response schema could hide a sensitive array of another, and a plain bracketed property beside a sensitive one was masked. The graph now lists every declared property of the object nodes it keeps, and each schema and union variant resolves the exact name, then the name without the suffix, then its additional properties.
There was a problem hiding this comment.
0 issues found across 12 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval skipped because cubic reviewed only this push, not the earlier force-push. Comment @cubic review to review the whole pull request.
View guided diff | Turn on auto-fix | Re-trigger cubic
…n redacting - JSON with a repeated object key is masked as a whole: decoding keeps only the last value, so the bytes returned unchanged could still hold an earlier sensitive one. - Multipart parts of a field with sensitive values are masked as a whole when transfer or content encoded, since their bytes are not the value. - Every repeated item of a sensitive array is masked, including `null`. - A form body whose keys start like JSON is masked as a whole.
There was a problem hiding this comment.
All reported issues were addressed across 8 files (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
View guided diff | Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 8 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval skipped because cubic reviewed only this push, not the earlier force-push. Comment @cubic review to review the whole pull request.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
A form field or multipart part that is not a JSON object or array may be one item of an array sent as repeated fields, so it is now matched against the item schemas too: integer and boolean items of a union with a sensitive object stay readable, as string items already did. Cases for property names ending in brackets move to dedicated operations tested only by the Go SDK, since other targets do not generate them yet. The declared-fields test preallocates its slice.
There was a problem hiding this comment.
0 issues found across 10 files (changes from recent commits).
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would not auto-approve. Auto-approval skipped because cubic reviewed only this push, not the earlier force-push. Comment @cubic review to review the whole pull request.
View guided diff | Turn on auto-fix | Re-trigger cubic
Why
Terraform's HTTP debug logging writes raw request and response bodies before responses are decoded, so values marked sensitive (
x-speakeasy-param-sensitiveorformat: password) that the API returns for the first time are not yet known to value-based redaction. API error strings can also contain response bodies.What changed
Operation.SensitiveRequestBodyGraph(),SensitiveResponseBodyGraph()andHasSensitiveBodies()(internal/ast/sensitive_body.go) compute a language-agnostic graph of where sensitive values sit in an operation's bodies, by property name. The graph is built alongTypeDef.Children, andTypeDef.Walkskips bodies with nothing sensitive. They handle objects, error types, arrays, maps andadditionalProperties, unions, recursive schemas, and SSE/JSONL streams (masked as a whole). They are declared intypeDefs.d.ts, so any target can render them.redactpackage holds the rendered graphs and exposesRequestBody(ctx, contentType, body)/ResponseBody(ctx, contentType, body). Methods of operations with sensitive bodies stamp the operation ID on the request context at request construction (utils.WithOperation), so a transport can find it from the request orres.Request. The transport and serialization are unchanged. Operations without sensitive bodies generate byte-identical code.APIError.Error()masks the body when the SDK has any sensitive bodies; theBodyfield stays raw.debugResponsemask request and response bodies throughredact. The existing known-value redaction is kept.JSON bodies are masked value by value.
application/x-www-form-urlencodedfields and multipart parts are matched by name: a sensitive field, or a field repeated for an array of sensitive values, is masked, and a JSON-encoded field or part is masked within. The masked body stays a valid form or multipart body with the same boundary. Other media types, and bodies that cannot be parsed, are masked as a whole for operations that have sensitive values. Unchanged bodies are returned byte-identical. Split request bodies (one schema per content type) are separate methods with their own operation IDs, so each is masked with its own schema.Testing
internal/astunit tests for the graph: nested, array items, map values beside a declared plain property,format: passwordwith a renamed property, union variants, recursion, error types, streams, and a plain property sharing a sensitive one's name.sensitive-body-redaction.yamlwith Go runtime tests (redact_additional_test.go) for JSON, form, multipart and split request bodies sent through the SDK, the context stamp, andAPIError.Error(). The form and multipart tests fail when their masking is disabled.TARGET=primary make test-gopasses.debugResponsehide computed sensitive values while decoded values stay raw. The full./scripts/build-review-terraform.shacceptance suite passes.go test ./pkg/generate/...(the Python snapshot tests fail onmaintoo, on a mypy_DURATION_ADAPTERannotation error), andmake check-template-{go,terraform,cli}.Known limitations
json.Marshalthemselves inError().redact.ResponseBody.