securestore

package
v0.30.0 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package securestore provides a platform-agnostic seam for holding the private key behind a TLS client certificate. The calling code (the cert-auth flow in internal/auth) never branches on platform: it asks Open for a backend, then Generate/Import/Load a crypto.Signer plus an opaque handle it can persist alongside the certificate.

Two backends ship today:

  • "file" — a software key stored as a PKCS#8 PEM handle. Used for the plain "mtls" auth method and on any platform without hardware support. The key bytes live in the handle, so the caller writes them at 0600.
  • "tpm" — (Linux/Windows only) the key is sealed under the TPM's Storage Root Key. The handle is the marshalled go-tpm-tools SealedBytes proto and carries no usable key material off the originating chip.

macOS Secure Enclave support is a future backend: Open("tpm") returns ErrUnsupported there until the binary is code-signed with the required entitlements. The interface is designed so that lands without changing any caller.

The whole package is CGO-free; the TPM backend talks to /dev/tpmrm0 (Linux) or TBS (Windows) through pure-Go go-tpm/go-tpm-tools.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupported = errors.New("securestore: backend not supported on this platform")

ErrUnsupported is returned by Open when the requested backend is not available on the current platform/build (e.g. "tpm" on unsigned macOS, or a host with no TPM device). Callers surface this as a clear error and must never silently fall back to a weaker backend.

Functions

func HardwareAvailable

func HardwareAvailable() error

HardwareAvailable reports whether the platform hardware backend can be opened on this host (nil) or why it cannot (ErrUnsupported, wrapped). It is a cheap preflight used to fail a "+tpm" auth method fast and clearly when no TPM is present, rather than authenticating and then silently failing to persist the sealed token.

func ModeForMethod

func ModeForMethod(authMethod string) string

ModeForMethod maps a dotvault auth method to a securestore backend mode. "mtls+tpm" wants hardware; everything else (including plain "mtls") uses the file backend.

func SealData

func SealData(data []byte) ([]byte, error)

SealData seals data under the platform hardware backend (TPM on Linux/Windows), opening and closing the device around the operation. It returns ErrUnsupported on a host with no hardware backend — callers MUST treat that as a hard error and never fall back to storing data in plaintext. The sealed blob is machine-bound: only UnsealData on the originating chip can recover it.

func UnsealData

func UnsealData(handle []byte) ([]byte, error)

UnsealData reverses SealData, opening and closing the hardware backend around the operation. ErrUnsupported (no hardware) or an unseal error (wrong machine, cleared TPM) are both surfaced to the caller.

Types

type Capabilities

type Capabilities struct {
	// Name is the backend identifier ("file", "tpm", "secure-enclave").
	Name string
	// HardwareBound is true when the private key is bound to hardware and
	// cannot be loaded on another machine (TPM/Enclave), false when it is a
	// portable software key (file).
	HardwareBound bool
}

Capabilities describes a backend.

type DataSealer

type DataSealer interface {
	// SealData seals data and returns an opaque handle. The handle is
	// machine-bound: it can only be unsealed by UnsealData on the originating
	// chip.
	SealData(data []byte) ([]byte, error)
	// UnsealData reverses SealData.
	UnsealData(handle []byte) ([]byte, error)
}

DataSealer is an optional capability for hardware backends that can seal an arbitrary small blob (e.g. a Vault token) under the same hardware root of trust that protects a key. The "file" backend deliberately does NOT implement it: sealing data under a software key kept on the same disk gives no at-rest protection, so data sealing is a hardware-only (TPM) feature.

type KeyType

type KeyType string

KeyType selects the algorithm for a generated key.

const (
	// KeyEC is an ECDSA P-256 key. Default; the only type the macOS Secure
	// Enclave supports, so cross-platform configs should prefer it.
	KeyEC KeyType = "ec"
	// KeyRSA is an RSA 2048 key.
	KeyRSA KeyType = "rsa"
)

type Storage

type Storage interface {
	// Capabilities reports backend identity and whether it hardware-binds.
	Capabilities() Capabilities
	// Generate creates a new private key of the given type and returns a
	// crypto.Signer plus an opaque handle that Load can later use to
	// reconstruct the signer. sealToPCRs binds the key to the current PCR
	// (boot) state where the backend supports it; it is ignored by backends
	// that do not.
	Generate(kt KeyType, sealToPCRs bool) (crypto.Signer, []byte, error)
	// Import takes an existing software private key (the BYO path) and
	// returns a crypto.Signer plus a handle, sealing it into hardware where
	// supported.
	Import(key crypto.PrivateKey, sealToPCRs bool) (crypto.Signer, []byte, error)
	// Load reconstructs a crypto.Signer from a handle previously returned by
	// Generate or Import.
	Load(handle []byte) (crypto.Signer, error)
	// Close releases any resources (e.g. the TPM device handle).
	Close() error
}

Storage holds the private key behind a client certificate. Implementations are not required to be safe for concurrent use; the cert-auth flow loads a signer once and assembles a tls.Certificate from it.

func Open

func Open(mode string) (Storage, error)

Open returns a backend for the given mode: "file" or "tpm". "tpm" maps to the platform hardware backend (TPM on Linux/Windows) and returns ErrUnsupported where no hardware backend is built.

Jump to

Keyboard shortcuts

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