But I Use SOPS | SecretSpec<br>Skip to content
But I Use SOPS
Jul 23, 2026<br>Domen Kožar
Whenever I show someone SecretSpec, I often hear the same response:
But I use SOPS.
SOPS is good. It encrypts files so they can<br>live in Git without exposing their plaintext values.
But SecretSpec solves a different problem: how applications declare, find, and<br>consume secrets.
How does your application use the secret?<br>Section titled “How does your application use the secret?”
Once you have encrypted secrets.yaml, how does your Python service consume<br>it? What about your Go worker or Node.js app?
You still need to decrypt the file, inject its values, select the right file for<br>each environment, validate required keys, and repeat that integration for every<br>language.
And if you release the project as open source, that choice does not stay yours.<br>With SOPS baked into the setup, everyone who runs or contributes to the project<br>must adopt SOPS and its key management, whatever secrets tooling they already<br>use.
SecretSpec starts at the other end. The project<br>declares what the application needs without storing<br>any values:
secretspec.toml[project]
name = "payments"
revision = "1.0"
[profiles.default]
DATABASE_URL = { description = "Postgres connection string" }
STRIPE_API_KEY = { description = "Stripe secret key" }
The same secret can come from a developer’s<br>system keyring or CI<br>environment variables, while a more sensitive production<br>environment resolves it from Vault. Applications use the<br>same declaration through eight SDKs for Rust,<br>Python, Go,<br>Ruby, Node.js/TypeScript,<br>Haskell, PHP, and C# without<br>knowing the provider.
Encrypted files also make the key workflow a project-wide requirement. Adding a<br>teammate means adding their key to .sops.yaml and re-encrypting every file;<br>removing one means rekeying and rotating the affected secrets, since their key<br>already saw the plaintext. SecretSpec leaves identity and access to the<br>provider: onboarding to Vault or a cloud secrets manager is granting a role,<br>and offboarding is revoking it.
SOPS may be enough today. As your team grows more sensitive to how secrets are<br>handled, you may want Vault’s access policies and centralized audit trail. If<br>applications know about SOPS, each one needs migrating. If they know only<br>SecretSpec, you change the provider configuration; SDK<br>calls and secret names stay the same.
The same resolver provides profiles,<br>required-secret checks,<br>per-secret provider routing and fallback,<br>provider-native references,<br>temporary files, and<br>metadata-only audit logs. You build the integration once,<br>not once per provider and language.
Different layers, different jobs<br>Section titled “Different layers, different jobs”
SOPS protects a file. SecretSpec gives applications a provider-independent<br>interface. The selected provider remains responsible for storage, encryption,<br>identity, access control, and availability.
I wrote a fuller SecretSpec comparison showing exactly where<br>SecretSpec ends, where providers begin, and which responsibilities belong to<br>each layer.
Where SecretSpec goes next<br>Section titled “Where SecretSpec goes next”
Because applications talk to an interface instead of a file, the interface can<br>grow without touching them. Three open proposals point where it is heading:
Project security requirements<br>would let a project declare the guarantees a provider must meet, such as<br>encryption at rest or an audit trail, and reject providers that fall short.
Lease-aware refresh would<br>let running applications follow key rotation and short-lived credentials<br>instead of restarting for a new value.
A native SOPS provider would<br>bring SOPS itself behind the same SDK interface, making your encrypted files<br>one more place secrets can come from.
Once that provider lands, perhaps “But I use SOPS” just needs two more words:
But I use SOPS with SecretSpec.
If encrypted files fit your workflow, keep using SOPS. Just recognize the<br>boundary: encryption at rest is not an application secrets interface.<br>Secrets Don’t Belong in Config