CI run https://github.com/api7/aisix/actions/runs/30912950213 (PR #886, commit b07ccda) failed sls-content-capture-masked-e2e.test.ts > full-capture exporter receives the masked stream text, never the raw PII:
AssertionError: expected '\n<binary>...' not to contain 'alice@example.com'
Evidence this is not the PR's doing and not (only) a test-decode flake:
- The PR's diff (
main...b07ccda) touches the quota gate, policy loader, and error envelope — nothing on the guardrail/mask/capture/exporter path; the identical test passed on the same PR's previous commit ae14c0a ~40 min earlier, the last 15 main CI runs are green, and 4 consecutive local runs of the spec pass.
- The interesting part is what failed:
fullText is the lz4-block-decompressed PutLogs payload (sls-mock.ts decompresses with the x-log-bodyrawsize size before asserting). lz4 decompression can only reproduce byte runs present in the source literals, so an intact alice@example.com in the decompressed text means that one captured payload actually carried the raw, pre-mask email on the wire. The replacement-char noise around it is just protobuf field bytes rendered as UTF-8 — present in green runs too.
So under CI load this looks like a timing window where a streaming capture chunk is exported before the mask pass rewrites it — the exact class #932 x AISIX-Cloud#947 addressed, surviving in some scheduling interleaving that a loaded 2-vCPU runner hits and a dev machine doesn't. I couldn't reproduce locally (including repeated runs), so I'm filing the evidence instead of guessing at a fix.
Worth ruling out first: whether the mock's hand-rolled lz4DecompressBlock can mis-decode a multi-request capture (each request decompressed independently — a wrong rawSize on one request would corrupt that segment, though it still couldn't fabricate the email bytes out of nothing).
Happy to dig further if someone can hand me a second failing run's raw payload; PR #886 is unblocked via re-run in the meantime.
CI run https://github.com/api7/aisix/actions/runs/30912950213 (PR #886, commit b07ccda) failed
sls-content-capture-masked-e2e.test.ts > full-capture exporter receives the masked stream text, never the raw PII:Evidence this is not the PR's doing and not (only) a test-decode flake:
main...b07ccda) touches the quota gate, policy loader, and error envelope — nothing on the guardrail/mask/capture/exporter path; the identical test passed on the same PR's previous commitae14c0a~40 min earlier, the last 15mainCI runs are green, and 4 consecutive local runs of the spec pass.fullTextis the lz4-block-decompressed PutLogs payload (sls-mock.tsdecompresses with thex-log-bodyrawsizesize before asserting). lz4 decompression can only reproduce byte runs present in the source literals, so an intactalice@example.comin the decompressed text means that one captured payload actually carried the raw, pre-mask email on the wire. The replacement-char noise around it is just protobuf field bytes rendered as UTF-8 — present in green runs too.So under CI load this looks like a timing window where a streaming capture chunk is exported before the mask pass rewrites it — the exact class #932 x AISIX-Cloud#947 addressed, surviving in some scheduling interleaving that a loaded 2-vCPU runner hits and a dev machine doesn't. I couldn't reproduce locally (including repeated runs), so I'm filing the evidence instead of guessing at a fix.
Worth ruling out first: whether the mock's hand-rolled
lz4DecompressBlockcan mis-decode a multi-request capture (each request decompressed independently — a wrongrawSizeon one request would corrupt that segment, though it still couldn't fabricate the email bytes out of nothing).Happy to dig further if someone can hand me a second failing run's raw payload; PR #886 is unblocked via re-run in the meantime.