Getting Started
Install
go get github.com/floatpane/go-secretbox
Requires Go 1.26+.
Encrypt one blob
The fastest way in. Seal returns bytes you can write anywhere; Unseal
needs only the password.
package main
import (
"fmt"
"log"
"github.com/floatpane/go-secretbox"
)
func main() {
blob, err := secretbox.Seal([]byte("attack at dawn"), "correct horse battery staple")
if err != nil {
log.Fatal(err)
}
plain, err := secretbox.Unseal(blob, "correct horse battery staple")
if err != nil {
log.Fatal(err) // secretbox.ErrDecrypt on wrong password or tampering
}
fmt.Println(string(plain)) // attack at dawn
}
Or run a password-protected vault
v := secretbox.NewVault("/home/me/.config/app/secure.meta")
if !v.Initialized() {
if err := v.Init(masterPassword); err != nil { // first run
log.Fatal(err)
}
} else if err := v.Unlock(masterPassword); err != nil { // later runs
log.Fatal(err) // secretbox.ErrWrongPassword
}
defer v.Lock()
v.WriteFile("/home/me/.config/app/config.json", cfg, 0o600)
data, _ := v.ReadFile("/home/me/.config/app/config.json")
Errors
All errors are sentinels — compare with errors.Is:
| Error | Meaning |
|---|---|
ErrDecrypt | Wrong key, truncated input, or tampering. Deliberately indistinct. |
ErrWrongPassword | Unlock failed the sentinel check. |
ErrLocked | A Vault operation needs the session key but the vault is locked. |
ErrNotInitialized | Unlock found no metadata file. |
ErrUnsupported | Metadata names a KDF/cipher this build can't construct. |
Next steps
- One-Shot: Seal & Unseal — the self-describing blob format.
- The Vault — secure mode, the session key, transparent file I/O.
- Key Rotation — changing the password and migrating files safely.
- Threat Model — what this protects, and what it does not.