Documentation
¶
Overview ¶
Package protect defines the provider-neutral payload protection port used by Human runtimes. Authentication and API-token hashing are separate concerns.
Index ¶
- Constants
- Variables
- func MarshalEnvelope(envelope Envelope) ([]byte, error)
- func MarshalStoredValue(value StoredValue) ([]byte, error)
- func Requirements() framework.Requirements
- func ValidateBinding(binding Binding) error
- func ValidateDescription(description Description) error
- func ValidateEnvelope(envelope Envelope) error
- func ValidateStoredValue(value StoredValue) error
- type Binding
- type Description
- type Envelope
- type Protector
- type Resource
- type Rewrapper
- type StoredValue
- func CloneStoredValue(value StoredValue) StoredValue
- func NewPlainStoredValue(plaintext []byte) StoredValue
- func NewSealedStoredValue(plaintextNil bool, envelope Envelope) (StoredValue, error)
- func UnmarshalStoredValue(encoded []byte) (StoredValue, error)
- func UnmarshalStoredValueLimited(encoded []byte, maxBytes int64) (StoredValue, error)
- type StoredValueMode
Constants ¶
const ( ContractID framework.ContractID = "human.protector" ContractMajor uint16 = 1 )
const ( // StoredEnvelopeVersion is the strict, provider-neutral persistence framing // version emitted by MarshalEnvelope. StoredEnvelopeVersion uint16 = 1 // MaxStoredEnvelopeBytes bounds the base64-expanded JSON representation of a // maximum-size Envelope plus its metadata. Providers normally impose a much // smaller Description.MaxEnvelopeBytes before this framing is reached. MaxStoredEnvelopeBytes int64 = 172 << 20 )
const ( StoredValueVersion uint16 = 1 MaxStoredValueBytes int64 = MaxStoredEnvelopeBytes + (1 << 20) )
Variables ¶
var ( ErrInvalidBinding = errors.New("invalid protection binding") ErrInvalidEnvelope = errors.New("invalid protection envelope") ErrAuthentication = errors.New("protected payload authentication failed") )
var ErrInvalidStoredEnvelope = errors.New("invalid stored protection envelope")
ErrInvalidStoredEnvelope reports malformed, unsupported, ambiguous, or oversized persistence framing. It is distinct from ErrAuthentication: no cryptographic interpretation has happened yet.
var ErrInvalidStoredValue = errors.New("invalid stored protected value")
Functions ¶
func MarshalEnvelope ¶
MarshalEnvelope emits deterministic, versioned persistence bytes. The explicit nil flags preserve nil versus non-nil empty byte slices exactly.
Human cores call Seal and MarshalEnvelope before entering a Store.Update callback, then store only the returned opaque bytes inside the callback. They copy those bytes from Store.View and call UnmarshalEnvelope and Open only after the callback returns. This keeps remote KMS/provider I/O outside Store transactions while leaving custom Store implementations encryption-agnostic.
func MarshalStoredValue ¶
func MarshalStoredValue(value StoredValue) ([]byte, error)
MarshalStoredValue encodes a deterministic, versioned persistence frame. Call it after Seal and before entering Store.Update; the Store callback only needs to persist the returned opaque bytes.
func Requirements ¶
func Requirements() framework.Requirements
Requirements returns the immutable base contract required by Human cores.
func ValidateBinding ¶
func ValidateDescription ¶
func ValidateDescription(description Description) error
func ValidateEnvelope ¶
func ValidateStoredValue ¶
func ValidateStoredValue(value StoredValue) error
ValidateStoredValue checks the logical mode/shape without performing any cryptographic operation.
Types ¶
type Binding ¶
type Binding struct {
Component string `json:"component"`
Purpose string `json:"purpose"`
Authority string `json:"authority"`
Namespace string `json:"namespace"`
RecordType string `json:"record_type"`
RecordID string `json:"record_id"`
Field string `json:"field"`
Schema uint32 `json:"schema"`
}
Binding is canonical associated data supplied by the Human core. A Protector must cryptographically bind every field to the ciphertext. Moving an Envelope between authorities, records, fields, schemas, or purposes must make Open fail authentication.
type Description ¶
type Description struct {
Contract framework.Contract
Provider string
Format string
MaxPlaintextBytes int64
MaxEnvelopeBytes int64
}
Description is frozen at runtime construction. MaxPlaintextBytes and MaxEnvelopeBytes are hard admission limits, not hints.
type Envelope ¶
type Envelope struct {
Provider string `json:"provider"`
Format string `json:"format"`
KeyID string `json:"key_id"`
KeyVersion string `json:"key_version"`
Nonce []byte `json:"nonce,omitempty"`
Data []byte `json:"data"`
}
Envelope is self-describing encrypted payload state. Provider and Format identify the adapter/wire format; KeyID and KeyVersion select old keys after rotation. Nonce and Data are opaque bytes and must be defensively copied by both callers and implementations.
func CloneEnvelope ¶
CloneEnvelope returns a deep copy safe to retain across adapter boundaries.
func UnmarshalEnvelope ¶
UnmarshalEnvelope strictly decodes MarshalEnvelope output. Unknown or duplicate fields, unsupported versions, trailing values, inconsistent nil/empty markers, and oversized inputs are rejected fail-closed.
func UnmarshalEnvelopeLimited ¶
UnmarshalEnvelopeLimited applies a caller-selected admission limit no larger than MaxStoredEnvelopeBytes. It is useful when a runtime's negotiated Description is substantially smaller than the framework hard limit.
type Protector ¶
type Protector interface {
Describe(context.Context) (Description, error)
Seal(context.Context, Binding, []byte) (Envelope, error)
Open(context.Context, Binding, Envelope) ([]byte, error)
}
Protector seals and opens payloads. Implementations must be safe for concurrent Describe, Seal, and Open calls using independent contexts. They must not retain input or return buffers. KMS/network work belongs outside Store transaction callbacks.
type Resource ¶
Resource makes Protector ownership explicit at composition boundaries. Borrowed Protectors remain caller-owned; owned Protectors (for example a KMS client or an in-memory keyring) are released by the receiving Human runtime. A borrowed Protector must remain valid and concurrency-safe until that runtime reaches Done. A runtime must acquire the value once during construction and must never call Seal, Open, Describe, or Rewrap from inside a Store View/Update callback: providers may perform network or hardware-KMS I/O.
type Rewrapper ¶
Rewrapper optionally rotates an Envelope without changing its plaintext identity. It follows Protector's concurrency and byte-ownership rules. The returned envelope must still open under the exact same Binding.
type StoredValue ¶
type StoredValue struct {
Mode StoredValueMode
Nil bool
Plain []byte
Envelope *Envelope
}
StoredValue is the logical, version-independent representation of one opaque persistence field. Mode is always explicit: runtimes never guess protection from a magic byte prefix. Nil preserves nil versus non-nil empty plaintext. Plain and Envelope are caller-owned and must be defensively copied when retained across an adapter boundary.
func CloneStoredValue ¶
func CloneStoredValue(value StoredValue) StoredValue
CloneStoredValue returns a deep copy safe to retain across Store and Protector boundaries.
func NewPlainStoredValue ¶
func NewPlainStoredValue(plaintext []byte) StoredValue
NewPlainStoredValue copies plaintext into an explicitly unprotected value. It exists so deployments can turn protection on without making old plain records ambiguous or unreadable.
func NewSealedStoredValue ¶
func NewSealedStoredValue(plaintextNil bool, envelope Envelope) (StoredValue, error)
NewSealedStoredValue copies a validated Envelope and records whether the authenticated plaintext was nil. Opened plaintext must match that marker.
func UnmarshalStoredValue ¶
func UnmarshalStoredValue(encoded []byte) (StoredValue, error)
UnmarshalStoredValue strictly decodes MarshalStoredValue output. It performs no Open operation; callers leave Store.View with these copied bytes, decode them, and only then call Protector.Open.
func UnmarshalStoredValueLimited ¶
func UnmarshalStoredValueLimited(encoded []byte, maxBytes int64) (StoredValue, error)
UnmarshalStoredValueLimited applies a caller-selected admission limit no larger than MaxStoredValueBytes.
type StoredValueMode ¶
type StoredValueMode string
const ( StoredValuePlain StoredValueMode = "plain" StoredValueSealed StoredValueMode = "sealed" )