signr

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 17, 2025 License: MIT Imports: 2 Imported by: 0

README

signr

A backend agnostic go libarary for key management, rotation, creation, signgin and veryfying signatures with integrations into different backends.

signr provides:

  • A KeyManager abstraction for organizing keys into named groups.
  • Pluggable backends (currently an in-memory backend) for storing and generating keys.
  • A simple SigningKey interface for signing and verifying data.

Installation

go get github.com/The127/signr

If you want to use the in-memory backend:

go get github.com/The127/signr/backends/memory

Quick Start

The example below shows how to:

  • Create a key manager with the in-memory backend.
  • Lazily generate an EdDSA key in a named group.
  • Sign and verify a message.
package main

import (
    "fmt"
    "time"

	"github.com/The127/signr"
	"github.com/The127/signr/backends/memory"
)

// Clock implements the memory backend's Clock interface using time.Now.
type Clock struct{}

func (c Clock) Now() time.Time {
    return time.Now()
}

func main() {
    // Initialize a KeyManager with the in-memory backend.
    km, err := signr.New(signr.Config{
        Backend: memory.Config{
            Clock: Clock{},
        },
    })
    if err != nil {
        panic(fmt.Errorf("failed to create key manager: %w", err))
    }

    // Get the "signing-key" group and an EdDSA key from it.
    // If no EdDSA key exists yet, it will be generated automatically.
    key, err := km.GetGroup("signing-key").GetKey("EdDSA")
    if err != nil {
        panic(fmt.Errorf("failed to get key: %w", err))
    }
    
    // Sign some data.
    msg := []byte("hello")
    sig, err := key.Sign(msg)
    if err != nil {
        panic(fmt.Errorf("failed to sign: %w", err))
    }
    
    // Print the signature as hex.
    fmt.Printf("signature: %x\n", sig)
    
    // Verify the signature.
    if err := key.Verify(msg, sig); err != nil {
        panic(fmt.Errorf("failed to verify: %w", err))
    }
    
    fmt.Println("ok")
}

Example output (actual signature will differ):

signature: 5d610e0ec5f902695a2582887845b3f49b7c447f484da63ea0842daf999fa8f8b6a104ce98d5de323070f9be771ac893097e2fe95058f15e5a61846ff81aea0e
ok

Concepts

Key Manager

The key manager is the main entry point:

  • Organizes keys into groups (e.g. "signing-key", "refresh-tokens", etc.).
  • Provides a high-level API to get keys by group and algorithm.

Typical usage:

km, err := signr.New(signr.Config{/* backend config */})
group := km.GetGroup("signing-key")
key, err := group.GetKey("EdDSA")
Key Groups

A key group is a logical bucket of keys that belong together (for example, all keys used to sign access tokens). You address keys within a group by JWA algorithm name (e.g. "EdDSA", "RS256"). The backend decides how keys are generated, stored, and rotated.

Signing Keys

A SigningKey can:

  • Sign data: Sign(data []byte) ([]byte, error)
  • Verify signatures: Verify(data, signature []byte) error
  • Expose metadata: algorithm name and key ID.

This is what you get back from GetKey.

Backends

Backends are responsible for storing and generating keys. They implement the concrete interactions with the underlying key storage system.

signr ships with the following backends:

In-Memory Backend

The in-memory backend:

  • Stores all key groups and keys in process memory.
  • Lazily generates keys when GetKey is called and no active key exists for the requested algorithm.
  • Uses an injected Clock to timestamp key creation (handy for testing or custom time sources).

Use it when:

  • You want a simple setup for demos, tests, or local development.
  • You don’t need keys to persist across process restarts.

Running the Example

There is a simple example program under example/ which is similar to the quick-start snippet.

From the module root:

cd example
go run .

You should see a hex-encoded signature followed by:

ok

License

This project is licensed under the MIT license.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend interface {

	// GetGroup retrieves a BackendGroup by its name with the specified options, creating it if AutoCreate is true in options.
	GetGroup(name string, opts GroupOptions) (BackendGroup, error)
}

Backend defines an interface for managing and retrieving signing key groups. It provides methods for accessing or creating grouped keys used in cryptographic operations.

type BackendConfig

type BackendConfig interface {

	// Create initializes and returns a new Backend instance or an error if the creation fails.
	Create() (Backend, error)
}

BackendConfig defines an interface for creating a cryptographic backend that manages signing key groups.

type BackendGroup

type BackendGroup interface {

	// GetKey retrieves the active signing key for the specified JWA algorithm or generates a new one if none exists.
	GetKey(jwa string) (SigningKey, error)
}

BackendGroup provides an interface for managing and retrieving cryptographic signing keys grouped by algorithm names. It includes methods to retrieve or generate the appropriate signing key for a given algorithm.

type Config

type Config struct {

	// Backend specifies the configuration for initializing and managing a cryptographic backend.
	Backend BackendConfig
}

Config holds the configuration settings for initializing a cryptographic backend.

type GroupOption

type GroupOption func(*GroupOptions)

GroupOption defines a function type used to configure GroupOptions for customizing group behaviors.

type GroupOptions

type GroupOptions struct {
}

GroupOptions provides configuration options for managing groups, such as enabling automatic creation of missing groups.

type KeyGroup

type KeyGroup interface {

	// GetKey retrieves the signing key corresponding to the specified JSON Web Algorithm (JWA).
	GetKey(jwa string) (SigningKey, error)
}

KeyGroup defines an interface for retrieving signing keys based on a specified JSON Web Algorithm (JWA).

type KeyManager

type KeyManager interface {

	// GetGroup retrieves a KeyGroup by its name, with optional configurations applied through variadic GroupOption parameters.
	GetGroup(name string, opts ...GroupOption) KeyGroup
}

KeyManager defines an interface for managing cryptographic key groups used in signing and verification operations. GetGroup provides access to a KeyGroup by name, allowing optional configurations through GroupOptions parameters.

func New

func New(cfg Config) (KeyManager, error)

New initializes and returns a KeyManager instance configured with the provided backend, or an error if creation fails.

type SigningKey

type SigningKey interface {

	// Sign generates a digital signature for the provided data using the private key associated with the SigningKey.
	Sign(data []byte) ([]byte, error)

	// Verify checks if the provided signature is valid for the given data using the public key.
	Verify(data, signature []byte) error

	// PublicKey retrieves the public key associated with the SigningKey for verification or distribution purposes.
	PublicKey() (crypto.PublicKey, error)

	// Algorithm returns the name of the cryptographic algorithm associated with the key, e.g., "RS256".
	Algorithm() string

	// KeyID returns a unique identifier for this signing key, used to differentiate it from other keys.
	KeyID() string
}

SigningKey represents an interface for cryptographic signing operations and metadata retrieval.

Directories

Path Synopsis
backends
utils
jwt

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL