keystore

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package keystore is the single source of signing material for Legant. It loads active signing keys from the database — decrypting their private keys with an envelope key derived from configuration — caches them in memory, and supports rotation. This replaces the previous behaviour of generating an ephemeral key on every boot, which made every issued token die on restart and caused replicas to sign divergently.

Private keys are stored AES-256-GCM-encrypted with the key id bound as additional authenticated data, so a ciphertext cannot be swapped between rows and tampering is detected on decrypt. They are never written to disk or logs in plaintext.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Key

type Key struct {
	ID        string
	Private   *rsa.PrivateKey
	Public    *rsa.PublicKey
	CreatedAt time.Time
	ExpiresAt *time.Time
}

Key is a signing key loaded into memory.

type KeyInfo

type KeyInfo struct {
	ID        string
	Active    bool
	CreatedAt time.Time
	ExpiresAt *time.Time
}

KeyInfo is a non-secret description of a stored key, for `legant keys list`.

type Keystore

type Keystore struct {
	// contains filtered or unexported fields
}

Keystore caches the active signing keys and mediates rotation.

func Open

func Open(ctx context.Context, pool *pgxpool.Pool, encKey []byte, overlap time.Duration) (*Keystore, error)

Open loads all active signing keys. If none exist, it bootstraps one so the server can always start with a usable key. encKey is the envelope key used to decrypt private keys at rest; overlap is how long a rotated-out key stays published before it can be pruned.

func (*Keystore) ActiveKID

func (k *Keystore) ActiveKID() string

ActiveKID returns the kid of the current signing key, or "" if none.

func (*Keystore) ActiveSigner

func (k *Keystore) ActiveSigner() *rsa.PrivateKey

ActiveSigner returns the current signing private key. It reflects rotation performed within this process, so it is safe to use directly as a Fosite keyGetter source.

func (*Keystore) List

func (k *Keystore) List(ctx context.Context) ([]KeyInfo, error)

List returns metadata for all signing keys, newest first.

func (*Keystore) Prune

func (k *Keystore) Prune(ctx context.Context) (int64, error)

Prune deactivates keys whose retirement time has passed, removing them from the JWKS. It never deactivates the active key. Returns the number pruned.

func (*Keystore) Reencrypt

func (k *Keystore) Reencrypt(ctx context.Context, newEncKey []byte) error

Reencrypt re-wraps every signing key's private key under newEncKey, in a single transaction. Use when rotating the key-encryption secret. On success the keystore switches to newEncKey for subsequent operations.

func (*Keystore) Reload

func (k *Keystore) Reload(ctx context.Context) error

Reload re-reads the active signing keys from the database, picking up keys added or retired by another process (e.g. `legant keys rotate` followed by a reload signal). Safe for concurrent use.

func (*Keystore) Rotate

func (k *Keystore) Rotate(ctx context.Context) (string, error)

Rotate generates a new active signing key and schedules the previously-active key for retirement after the overlap window. The old key stays published in the JWKS until pruned, so tokens it already signed keep verifying.

func (*Keystore) VerifierKeys

func (k *Keystore) VerifierKeys() map[string]*rsa.PublicKey

VerifierKeys returns every currently-trusted public key indexed by kid, for JWKS publication and delegation-token verification.

Jump to

Keyboard shortcuts

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