Skip to content

[Feature Request]: Add GroupByEncryptedKey transform #36214

Closed

Description

@damccorm

What would you like to happen?

Add a transform which allows users to use a secret manager to ensure that any GBK data is encrypted before being sent to a runner. This allows users to avoid unencrypted data at rest.

Exact support is still runner dependent (the runner needs to guarantee it won't otherwise materialize Pcollections), but this gives the ability to offer this capability.

Subparts:

Future work: Support a more universal pipeline option which runners can opt into/out of for this concept, like #36214 (comment)

Issue Priority

Priority: 2 (default / most feature requests should be filed as P2)

Issue Components

  • Component: Python SDK
  • Component: Java SDK
  • Component: Go SDK
  • Component: Typescript SDK
  • Component: IO connector
  • Component: Beam YAML
  • Component: Beam examples
  • Component: Beam playground
  • Component: Beam katas
  • Component: Website
  • Component: Infrastructure
  • Component: Spark Runner
  • Component: Flink Runner
  • Component: Samza Runner
  • Component: Twister2 Runner
  • Component: Hazelcast Jet Runner
  • Component: Google Cloud Dataflow Runner

Activity

  1. self-assigned this
    on Sep 19, 2025
  2. hjtran commented on Sep 22, 2025

    @hjtran
    Contributor

    Just passing by and saw this ticket. Out of curiosity, how are runners supposed to guarantee encryption at rest? Can't a runner arbitrarily decide when to materialize pcollections to disk? In which case, would the runner need to be able to encrypt at any point of the pipeline?

  3. damccorm commented on Sep 22, 2025

    @damccorm
    ContributorAuthor

    Good question - I updated the description a bit. Basically, the goal here is to allow runners to add this capability; in order to do so, they'd need to guarantee that they're not going to materialize any PCollections in an undesirable way outside of the context of a GBK.

    But using the transform with an arbitrary runner isn't necessarily enough by itself.

  4. hjtran commented on Sep 22, 2025

    @hjtran
    Contributor

    Would it be feasible to implement this capability generically for all transforms using a wrapper secret coder? It'd be a type of BytesCoder that allows specifying a secret. Then runners could use this secret coder and wrap any final bytes coder they'd be using to read/write for the SKD harness and GBK without requiring users to adjust their pipelines to accommodate encryption-at-rest

  5. damccorm commented on Sep 22, 2025

    @damccorm
    ContributorAuthor

    That would definitely be an option. I'll note that it is probably less efficient though, since you need to apply it to any encoding/decoding, as opposed to just:

    1. Applying it at the GBK boundary
    2. Enforcing that you only persist GBK'd data (this is how most runners work/checkpoint already AFAIK).

    An alternative would be to eventually offer both and let the runner choose the mode that works for them.

  6. hjtran commented on Sep 22, 2025

    @hjtran
    Contributor
    1. Enforcing that you only persist GBK'd data (this is how most runners work/checkpoint already AFAIK).

    The Schrodinger SeamRunner doesn't work this way. Many of the SeamRunner stage boundaries are just from GBKs but there are many stage boundaries that arise from incompatible environments as well. Not sure how other runners handle stage boundaries - do they just pipe together data streams directly between workers?

    An alternative would be to eventually offer both and let the runner choose the mode that works for them.

    If we had an API that specifies how secrets are determined as a PipelineOption, then only the only-GBK-persisting runners could replace GBKs with GBEKs and other runners could use the secret in all places where they persist pcollections.

    I think a main concern here for me is the addition of a new transform that blurs the SDK/runner boundary. When onboarding new developers onto Beam, the biggest hurdle I face is introducing Reshuffle since it breaks the promise of "As a pipeline author, you don't have to worry about the how of execution" and GBEK may be another transform like `Reshuffle.

  7. damccorm commented on Sep 22, 2025

    @damccorm
    ContributorAuthor

    Not sure how other runners handle stage boundaries - do they just pipe together data streams directly between workers?

    Generally this reduces to a reshuffle or similar which eventually uses GBK under the hood. But definitely not part of the Beam API.

    If we had an API that specifies how secrets are determined as a PipelineOption, then only the only-GBK-persisting runners could replace GBKs with GBEKs and other runners could use the secret in all places where they persist pcollections.

    Yeah, this is more or less what I'm suggesting here; this issue is more of an implementation detail (though potentially you could only encrypt some of your pipeline at the GBK step if you want to use it directly I guess).

    Note that even with this transform and the GBK guarantees, it is still impossible for users to get encryption at rest guarantees since they would need to replace GBK in reshuffles (and other transforms) somehow, and they won't be able to do that. So a pipeline option will be necessary regardless.

  8. hjtran commented on Sep 22, 2025

    @hjtran
    Contributor

    Ah gotcha. This all makes sense to me then. Thanks for taking the time to explain!

  9. damccorm commented on Oct 15, 2025

    @damccorm
    ContributorAuthor

    At this point, all outstanding items are complete, so closing here. We can follow up on #36214 (comment) separately

  10. added this to the 2.69.0 Release milestone on Oct 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions