If your Team, Organization or Company is serious about where to keep credentials used by services (or to interact with them), they are likely in Kubernetes Secrets, Hashicorp Vault, one of the various cloud-based Secrets Managers, 1Password, etc. Then, when running locally, they might be in your Environment Variables, in a .env, in a file or just in plaintext in a script (naughty!).
This might lead to services and tools written to deal with those different “secret provision scenarios”. Or tricky/brittle local setups.
Introducing Spelunk

Ready to dig-up your secrets 😜
Spelunk is a Golang library for extracting secrets from various sources (Kubernetes, Vault, env vars, files) using a unified URI-based string: Secret Coordinates. For example:
| |
Spelunk simplifies the access to secrets by requiring only the coordinates for “digging it up”. I deal for cloud-native environments, and suitable for command-line tools, as well as deployed services.
Use cases?
- Cloud-Native CLI Tools & Applications: simplifies secret management for CLI tools via “Secret Coordinates” instead of hardcoding secrets or managing integrations
- Adaptable Secret Fetching: if your Security Team decides to move from a secret storage to another, all there is to do is changing coordinates (i.e.
k8s://→vault://) - Secret Modification/Formatting: Using Modifiers, users can extract exactly what they need from a secret (e.g. via JSONPath)
- Idiomatic Parsing: It integrates with CLI configuration libraries (like flag, Kong, urfave/cli, Viper, …) to treat secrets just like any other parsed argument (code examples)
Let’s see some code!
You have a Kubernetes Secret:
| |
Spelunk can dig it up for you:
| |
And it can dig-up secrets out of?
Currently Spelunk supports fetching secrets from these sources:
- Environment Variables
- File
- Plaintext
- Base64
- Kubernetes Secrets (plugin)
- HashiCorp Vault (plugin)
“Modifiers” you said?
Modifiers are optional behaviour applied to a secret after it has been dug-up by Spelunk. It can be seen as a function in the mathematical sense:
$$ Modifier(Val,Input) = ModifiedVal $$Each modifier is applied in the same order provided to the secret value found at the coordinates:
| |
Currently we have a JSONPath extractor (?jp=<JSONPath>) and Base64 encoder (?b64). And, like for secret sources, more modifiers are in the works.
Only what you need
Spelunk follows a “only import what you need” principle. Aside from the most simple SecretSources and SecretModifiers, all others are provided as plug-in that you import in your project when needed:
| |
Alternatives?
When the need for something like Spelunk rose, I looked for what options were out there. The closest thing I found was Go CDK Secrets. But, to my surprise, it does not support Kubernetes!
So, I decided to roll my own.
Next steps
Right now the latest release of Spelunk is v1.1.0, that introduced support for HashiCorp Vault. In the works I got:
- Support for GCP Secrets Manager, AWS Secrets Manager and Azure Key Vault
- Support for more extractors (like XPath)
- Support for more encoders (like SHA-2/3)
- Build a
spelunkbinary, so to embed it in shell scripts