Skip to content

[encryption]: Add skipEncodings to avoid double-encrypting payloads - #201

Merged
pseudomuto merged 1 commit into
mainfrom
skip-encodings
Oct 7, 2026
Merged

pseudomuto merged 1 commit into
mainfrom
skip-encodings

Conversation

@pseudomuto

Copy link
Copy Markdown
Collaborator

The proxy seals every outbound payload when encryption is enabled, even if a Worker's own codec already encrypted it or an earlier proxy in the chain already sealed it. A chained hop was worse...on the response, it tried to open the first hop's payloads, failed with an unknown key, and failed the whole call.

encryption.skipEncodings lists encodings to treat as already encrypted. Payloads under a listed encoding are forwarded unchanged. Matching is exact on the encoding metadata, so sample codecs that also use binary/encrypted, for example, are skipped too. Listing binary/encrypted additionally makes Decode return payloads sealed under a KEK this proxy doesn't hold instead of failing. That entry is opt-in, so a standalone proxy that lost a KEK still fails loudly. With it set, you can observe it via vault_ops_total{result="unknown_key"}.

Listing an encoding trusts every Worker that sets it, since the proxy cannot tell ciphertext from plaintext labelled that way. Blank entries are rejected so a payload with no encoding can never match, and the dataplane warns when a list is set with no keys configured.

Skips are counted in a new metric (payloads_skipped_total) by operation, encoding, and namespace. The encoding label only ever holds a configured entry. vault_ops_total reports an unknown KEK as unknown_key rather than error.

@pseudomuto
pseudomuto requested a review from a team as a code owner October 6, 2026 15:45
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread dev/config.yaml
encryption:
enabled: true
cacheSize: 200
# Encodings already encrypted before they reach the proxy, forwarded unsealed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:
Maybe note in the commend that this is a header?
It looks like a header, but might as well be very explicit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're actually fields (Payload.Metadata["encoding"]) set by PayloadCodecs.

Comment on lines +161 to +165
// With no keys there is no encryption codec, so the list has nothing to skip.
if len(cfg.Encryption.SkipEncodings) > 0 && o.vault == nil {
o.logger.Warn("encryption.skipEncodings is set but no encryption keys are configured, so it has no effect")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im fine with this but there is an argument for just failing invalid/non-effect configs

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. So far, I've been failing cases where behaviour would be invalid (e.g., enabling encryption without a default key policy) and warning about things that are ineffectual or don't break an invariant (e.g., apiTranslations defined with no Cloud upstream).

I absolutely don't feel super strongly about this, so if you'd prefer an error case here, say the word.

The proxy seals every outbound payload when encryption is enabled, even
one a Worker's own codec already encrypted, or one an earlier proxy in
a chain already sealed. A chained hop was worse...on the response it
tried to open the first hop's payloads, failed with unknown key, and
failed the whole call.

`encryption.skipEncodings` lists encodings to treat as already
encrypted. Payloads under a listed encoding are forwarded unchanged.
Matching is exact on the _encoding_ metadata, so sample codecs that also
use binary/encrypted, for example, are skipped too. Listing
`binary/encrypted` additionally makes `Decode` return payloads sealed
under a KEK this proxy doesn't hold instead of failing. That entry is
opt-in so a standalone proxy that lost a KEK still fails loudly. With it
set, you can observe it via `vault_ops_total{result="unknown_key"}`.

Listing an encoding trusts every Worker that sets it, since the proxy
cannot tell ciphertext from plaintext labeled that way. Blank entries
are rejected so a payload with no encoding can never match, and the
dataplane warns when a list is set with no keys configured.

Skips are counted in a new metric (`payloads_skipped_total`) by operation, encoding,
and namespace. The encoding label only ever holds a configured entry.
`vault_ops_total` reports an unknown KEK as _unknown_key_ rather than
error.
@pseudomuto
pseudomuto merged commit ed5e590 into main Oct 7, 2026
6 checks passed
@pseudomuto
pseudomuto deleted the skip-encodings branch October 7, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants