Skip to content

negrel/secrecy

Repository files navigation

🤫 secrecy - A simple secret-keeping library for Go.

PkgGoDev Go Report Card Go version

secrecy is a simple library which provides wrapper type for secret management in Go. It is inspired from the excellent secrecy Rust crate.

It provides a Secret[T] type for wrapping another value in a secret cell which attempts to limit exposure (only available via the special ExposeSecret() function).

Each secret has a finalizer attached that recusively zeroize secret memory when garbage collected. You must not share memory contained within a secret and share the secret itself.

This helps to ensure secrets aren't accidentally copied, logged, or otherwise exposed (as much as possible), and also ensures secrets are securely wiped from memory when garbage collected.

Getting started

Here is a simple example for storing an API key.

package main

import (
	"github.com/negrel/secrecy"
)

func main() {
	// Load secret on startup.
	secretApi := secrecy.NewSecretString(retrieveApiKey())

	// Then use it like this.
	apiCall(secretApi)
}

func apiCall(secret secrecy.SecretString) {
	apiKey := secret.ExposeSecret()
	// Use your API key but don't store it.
}

func retrieveSecret() []byte {
	// Securely retrieve your api key.
}

If you accidentally leak your secret using fmt.Println, json.Marshal or another method, the output will contains <!SECRET_LEAKED!> marker string. You can customize this value by setting the package variable secrecy.SecretLeakedMarker. This way, you can easily check for secret leaks in your logs using tool such as grep.

Disable zeroize

Sometime, you must pass your secret to a library global variable such as stripe global Key variable.

To do so, you must disable memory zeroize as it will corrupt the exposed string when the secret will be garbage collected.

package main

import (
	"github.com/negrel/secrecy"
	"github.com/stripe/stripe-go/v80"
)

func main() {
	// Load secret on startup.
	stripeSecret := secrecy.NewSecretString(retrieveApiKey())
	stripeSecret.DisableZeroize()

	stripe.Key = stripeSecret.ExposeSecret()
}

func retrieveStripeSecret() []byte {
	// Securely retrieve your api key.
}

Contributing

If you want to contribute to secrecy to add a feature or improve the code contact me at [email protected], open an issue or make a pull request.

🌠 Show your support

Please give a ⭐ if this project helped you!

buy me a coffee

📜 License

MIT © Alexandre Negrel