getsops / getsops/sops

decrypt API lacks context.Context support: slow KMS round-trips cannot be cancelled mid-call

Open
#2,179 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/keyservice enhancement
Dominant language
Go
Stars
23.1k
Forks
1.1k
Avg merge
1d 11h
Merged PRs (30d)
9

Description

Summary

decrypt.Data(data []byte, format string) ([]byte, error) (and the related decrypt.File) doesn't accept a context.Context. Consumers that bind sops into a request path or a boot sequence can't interrupt a stuck KMS round-trip — the call blocks until the underlying provider's own internal timeout fires (often 30s+).

Reproduction

ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()

// We can check ctx before calling…
if err := ctx.Err(); err != nil {
    return err
}

// …but once we're in here, the ctx is irrelevant.
plaintext, err := decrypt.Data(ciphertext, "yaml")
// If the KMS provider is hung, this blocks for ~30s regardless
// of the 100ms deadline we set above.

Affects every key service that calls out to a remote provider: AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault. The underlying provider SDKs (aws-sdk-go-v2, cloud.google.com/go/kms, etc.) accept contexts; sops just doesn't thread one through.

Real-world impact

We hit this in chameleon, a layered-config library that wraps sops/decrypt for encrypted layer files. A hung GCP KMS round during application boot blocks initialization indefinitely instead of failing fast. Our workaround is checking ctx.Err() before invoking sops; once we're in the call, we're stuck. Documented as a known limitation on our side: chameleon README ("Sops API has no ctx.Context hook").

Proposed API

Add ctx-aware variants alongside the existing functions (backward compatible):

// New, in package decrypt:
func DataWithContext(ctx context.Context, data []byte, format string) ([]byte, error)
func FileWithContext(ctx context.Context, path, format string) ([]byte, error)

The existing context-less functions can delegate to the ctx variants with context.Background(). Internally, the ctx threads to each key-service call (aws-sdk's WithContext request options, GCP's existing ctx-first methods, etc.).

For sops v4 / next major: replace the existing signatures.

Alternatives considered

  • Goroutine + select-on-channel — works but leaks goroutines on cancel (no way to interrupt the blocked provider call). Worse than no fix.
  • runtime.Goexit from a watchdog goroutine — actively destructive: leaks resources held by the provider SDK (connections, mutexes).
  • Documented "don't call from latency-sensitive paths" — true but unhelpful for boot-time use.

Scope estimate

Mechanical: every kms.Decrypt(...) / kv.Decrypt(...) call site inside the key-service implementations under keyservice/ accepts a context already; threading from a new DataWithContext entry point through is a one-pass change. Tests need a fake key service that respects a cancel signal.

Happy to put up a PR if there's appetite — would appreciate a maintainer comment first on the API shape (separate WithContext functions vs. breaking change).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with decrypt.Data and decrypt.File, then trace the kms.Decrypt and kv.Decrypt call sites under keyservice/. Verify how the existing key-service context parameters can be threaded through the proposed context-aware entry points, and add tests using a fake key service that respects cancellation; done means a cancelled context interrupts the decrypt path while existing functions remain compatible.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, azure, gcp, go
Domain
backend-api-design, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.