Zero dependency Go package for generating & validating API keys
Keymaker is a zero-dependency Golang
package that makes it easy to generate API keys in your application.
This package was inspired by an excellent YouTube video done by Josh Twist (CEO & Co-founder at zuplo) titled API Key Authentication Best Practices
go get github.com/williepotgieter/keymaker
The package generates API keys in the following standardized format:
<LABEL>_<SECRET>_<CHECKSUM>
Labelling API keys is a convenient way to make keys easily identifiable between differen environments or purpose. Labels can be any string.
skp
=> shareable key productionpks
=> publishable key staging
Secrets are random strings made up of characters a-z
, A-Z
and 0-9
. They are automatically generated by the package using Golang's built-in rand/crypto
package and a Fisher-Yates shuffling algorithm. The length of the secret can be adjusted as required, but can be maximum 256 charaters.
15nd14iju19qV3s63379a5iJz1jGunI
=> 32 charactersKl1kD9mj7ZU742K399Sr03Uo5Acb21Gu8I3Y2c13e23Eko4B7ew1zZy10207Pm02
=> 64 characters
The checksum is the computed CRC-32 checksum of the generated key, using Golang's built-in hash/crc32
package.
995215320
=> 32 character secret1215000562
=> 64 character secret
skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320
pks_Kl1kD9mj7ZU742K399Sr03Uo5Acb21Gu8I3Y2c13e23Eko4B7ew1zZy10207Pm02_1215000562
API Keys are generated by the NewApiKey
function. The following code will generate an API key with a label of skp
and a secret with a length of 32 characters.
key, err := keymaker.NewApiKey("skp", 32)
The code above will return a ApiKey
struct or an error wrapped in ErrGenerateNewApiKey
if there was an error during creation.
type ApiKey struct {
Label string
Secret string
Checksum uint32
}
Once an API key has been created it can be converted into a string using the String()
function
key, _ := keymaker.NewApiKey("skp", 32)
// Output:
// ApiKey{
// Label: "skp",
// Secret: "15nd14iju19qV3s63379a5iJz1jGunI",
// Checksum: 995215320,
// }
apiKeyStr := key.String()
// Output: skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320
Valid API key strings in the format <LABEL>_<SECRET>_<CHECKSUM>
can be parsed into ApiKey
structs using the ParseApiKey
function.
apiKey, err := ParseApiKey("skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320")
// Output:
// ApiKey{
// Label: "skp",
// Secret: "15nd14iju19qV3s63379a5iJz1jGunI",
// Checksum: 995215320,
// }
Use the ValidateApiKey
function to check wheter a string value API key is valid. This function can be integrated with http request handling middleware to quickly (and inexpensively) filter out any invalid API keys early on.
validA, err := ValidateApiKey("skp_15nd14iju19qV3s63379a5iJz1jGunI_995215320")
// Output: valid = true, err = nil
validB, err := ValidateApiKey("skp_15nd14iju19qV3s63379a5iJz1jGunI_123456789")
// Output: valid = false, err = nil
If any keymaker
functions generate an error, they will always be wrapped in one of the following errors:
var (
ErrInvalidApiKey = errors.New("invalid api key")
ErrGenerateNewApiKey = errors.New("error while generating new api key")
ErrParseApiKey = errors.New("error while parsing api key")
ErrValidateApiKey = errors.New("error while validating api key")
)
Twist, J. (2022). API Key Authentication Best Practices. Zuplo. Available at: https://www.youtube.com/watch?v=ooyOmiczY1g [Accessed 28 Nov. 2023].