hcvault

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: AGPL-3.0 Imports: 26 Imported by: 0

Documentation

Overview

Package hcvault implements key storage and data encryption using HashiCorp Vault Transit. Signing keys never leave Vault — signing and encryption are delegated over the Vault HTTP API.

A single Client is shared between the KeyStore (JWT signing) and DataEncryptor (data encryption) when both target the same Vault server and Transit mount.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppRoleAuth

type AppRoleAuth struct {
	RoleID   string
	SecretID string
	Mount    string // default "approle"
}

AppRoleAuth holds AppRole authentication details.

type Client

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

Client is a minimal Vault HTTP client that supports token and AppRole auth. It handles background token renewal when using AppRole.

func NewClient

func NewClient(ctx context.Context, cfg ClientConfig, obs *observability.Provider) (*Client, error)

NewClient creates a Vault Transit client. If AppRole is configured, it performs an initial login and starts a background renewal goroutine. Call Close() to stop renewal.

func (*Client) Address

func (c *Client) Address() string

Address returns the Vault server address.

func (*Client) Close

func (c *Client) Close()

Close stops the background token renewal goroutine.

func (*Client) CreateKey

func (c *Client) CreateKey(ctx context.Context, keyName, keyType string) error

CreateKey creates a new Transit key.

func (*Client) Decrypt

func (c *Client) Decrypt(ctx context.Context, keyName, ciphertext, derivedContext string) (string, error)

Decrypt calls the Vault Transit decrypt endpoint. Returns the base64-encoded plaintext.

func (*Client) Encrypt

func (c *Client) Encrypt(ctx context.Context, keyName, plaintext, derivedContext string) (string, error)

Encrypt calls the Vault Transit encrypt endpoint. plaintext and context are base64-encoded by the caller.

func (*Client) Mount

func (c *Client) Mount() string

Mount returns the Transit mount path.

func (*Client) ReadKey

func (c *Client) ReadKey(ctx context.Context, keyName string) ([]byte, error)

ReadKey reads the public key material from a Transit key.

func (*Client) RotateKey

func (c *Client) RotateKey(ctx context.Context, keyName string) error

RotateKey rotates a Transit key to a new version.

func (*Client) Sign

func (c *Client) Sign(ctx context.Context, keyName, digest, hashAlg string, keyVersion int) (string, error)

Sign calls the Vault Transit sign endpoint. digest is base64-encoded, prehashed indicates the input is already hashed.

type ClientConfig

type ClientConfig struct {
	Address string
	Token   string // static token (mutually exclusive with AppRole)
	Mount   string // transit secret engine mount, default "transit"
	AppRole *AppRoleAuth
	Timeout time.Duration // HTTP client timeout, default 10s
}

ClientConfig configures the Vault client.

type Encryptor

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

Encryptor implements DataEncryptor via the Vault Transit API. It delegates HTTP communication to a shared Client.

func NewEncryptor

func NewEncryptor(client *Client, keyName string, obs *observability.Provider) *Encryptor

NewEncryptor creates a Vault Transit encrypt adapter using a shared Client.

func (*Encryptor) Client

func (e *Encryptor) Client() *Client

Client returns the underlying Vault client. Used by the signing factory to share a client when both signing and encryption target the same Vault server.

func (*Encryptor) Close

func (e *Encryptor) Close() error

Close stops the underlying Vault client's background renewal goroutine.

func (*Encryptor) Decrypt

func (e *Encryptor) Decrypt(ctx context.Context, ciphertext []byte, ownerContext string) ([]byte, error)

Decrypt decrypts ciphertext via the Vault Transit decrypt API.

func (*Encryptor) DriverName

func (e *Encryptor) DriverName() string

DriverName returns "vault_transit_encrypt".

func (*Encryptor) Encrypt

func (e *Encryptor) Encrypt(ctx context.Context, plaintext []byte, ownerContext string) ([]byte, error)

Encrypt encrypts plaintext via the Vault Transit encrypt API.

type Store

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

Store implements output.KeyStore using Vault Transit. It maps one Transit key name to current/previous versions.

Vault Transit keys are versioned internally. We track:

  • current version = latest version
  • previous version = latest - 1 (for JWKS during rotation)

The KeyID format is "<keyName>-v<version>" for JWKS kid matching.

func NewStore

func NewStore(client *Client, keyName, algorithm string, obs *observability.Provider) *Store

NewStore creates a Vault Transit key store.

func (*Store) ListActive

func (s *Store) ListActive(ctx context.Context) ([]*output.SigningKey, error)

ListActive returns all active signing keys (current + previous if exists).

func (*Store) LoadCurrent

func (s *Store) LoadCurrent(ctx context.Context) (*output.SigningKey, error)

LoadCurrent returns the current (latest version) signing key. Returns nil, nil if the key doesn't exist in Vault.

func (*Store) LoadPrevious

func (s *Store) LoadPrevious(ctx context.Context) (*output.SigningKey, error)

LoadPrevious returns the previous signing key version for JWKS during rotation. Returns nil, nil if no previous version exists.

func (*Store) Save

func (s *Store) Save(ctx context.Context, _ *output.SigningKey) error

Save creates or rotates the Transit key.

On first call: creates the key in Vault Transit. On subsequent calls: rotates the key to a new version.

The incoming key parameter is ignored for the private key material — Vault generates and holds the private key internally. We use the algorithm from the store's config.

type VaultError

type VaultError struct {
	StatusCode int
	Body       string
	Path       string
}

VaultError represents a non-2xx response from Vault.

func (*VaultError) Error

func (e *VaultError) Error() string

type VaultSigner

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

VaultSigner implements crypto.Signer by delegating signing to Vault Transit. The private key never leaves Vault.

func NewVaultSigner

func NewVaultSigner(client *Client, keyName string, keyVersion int, pub crypto.PublicKey, algorithm string) *VaultSigner

NewVaultSigner creates a VaultSigner from parsed public key material.

func (*VaultSigner) Public

func (s *VaultSigner) Public() crypto.PublicKey

Public returns the public key associated with this signer.

func (*VaultSigner) Sign

func (s *VaultSigner) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

Sign signs digest with the Vault Transit key.

CRITICAL: The digest parameter is already hashed by go-jose before calling Sign. We set prehashed=true in the Vault API call to prevent double-hashing.

For ECDSA keys, Vault returns raw R||S format, but go-jose expects ASN.1 DER encoding. This method handles the conversion.

Jump to

Keyboard shortcuts

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