Stop shipping the sops binary in your .NET images
Description and use
Nops enables .NET applications to decrypt SOPS files in memory, removing the need to ship the SOPS binary and preventing secret leakage in logs or image layers.
Problem
A .NET service needs to consume secrets encrypted with SOPS, but SOPS is a Go CLI tool, so the service cannot decrypt secrets in-process without adding a binary or exposing plaintext.
Outcome
Using Nops eliminates the need to ship the SOPS binary or expose plaintext secrets, allowing secure in-memory decryption in .NET applications and seamless integration with Kubernetes and GitOps workflows.
Workflow
- 1. Store secrets in a SOPS-encrypted file.
- 2. Add the Nops provider to the .NET application: builder.Configuration.AddSops("secrets.sops.yaml").
- 3. At startup, Nops reads the encrypted file, verifies the MAC, unwraps the data key, decrypts values in memory, and exposes them through IConfiguration.
- 4. The application accesses secrets via IOptions
<T>or IConfiguration as usual. - 5. (Optional) Deploy the encrypted file as a ConfigMap and the decryption key as a Secret or via cloud KMS.
- 6. The pod watches the file for changes and reloads configuration without restart.
Evidence
SOPS is a good way to keep secrets in git. It encrypts the values in a YAML, JSON, dotenv, INI or binary file while leaving the keys readable, so a pull request that changes a secret still shows a meaningful diff, and the file itself is safe to commit.
The application, or an init container, invokes sops -d at startup and reads the result from standard output or a temporary file. This keeps the plaintext out of the build pipeline, but it adds a Go binary and its dependencies to what should be a .NET image.
Nops reads the same files the sops CLI writes and supports the same key types, so adopting it does not change how your team edits secrets, only how the application consumes them.
- Record date: 2026-10-25T13:26:23.721Z