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 ¶
- type AppRoleAuth
- type Client
- func (c *Client) Address() string
- func (c *Client) Close()
- func (c *Client) CreateKey(ctx context.Context, keyName, keyType string) error
- func (c *Client) Decrypt(ctx context.Context, keyName, ciphertext, derivedContext string) (string, error)
- func (c *Client) Encrypt(ctx context.Context, keyName, plaintext, derivedContext string) (string, error)
- func (c *Client) Mount() string
- func (c *Client) ReadKey(ctx context.Context, keyName string) ([]byte, error)
- func (c *Client) RotateKey(ctx context.Context, keyName string) error
- func (c *Client) Sign(ctx context.Context, keyName, digest, hashAlg string, keyVersion int) (string, error)
- type ClientConfig
- type Encryptor
- func (e *Encryptor) Client() *Client
- func (e *Encryptor) Close() error
- func (e *Encryptor) Decrypt(ctx context.Context, ciphertext []byte, ownerContext string) ([]byte, error)
- func (e *Encryptor) DriverName() string
- func (e *Encryptor) Encrypt(ctx context.Context, plaintext []byte, ownerContext string) ([]byte, error)
- type Store
- func (s *Store) ListActive(ctx context.Context) ([]*output.SigningKey, error)
- func (s *Store) LoadCurrent(ctx context.Context) (*output.SigningKey, error)
- func (s *Store) LoadPrevious(ctx context.Context) (*output.SigningKey, error)
- func (s *Store) Save(ctx context.Context, _ *output.SigningKey) error
- type VaultError
- type VaultSigner
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AppRoleAuth ¶
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) 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.
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 ¶
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) 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 ¶
DriverName returns "vault_transit_encrypt".
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 ¶
ListActive returns all active signing keys (current + previous if exists).
func (*Store) LoadCurrent ¶
LoadCurrent returns the current (latest version) signing key. Returns nil, nil if the key doesn't exist in Vault.
func (*Store) LoadPrevious ¶
LoadPrevious returns the previous signing key version for JWKS during rotation. Returns nil, nil if no previous version exists.
func (*Store) Save ¶
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 ¶
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.