protect

package
v0.1.0 Latest Latest
Warning

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

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

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

View Source
const (
	ContractID    framework.ContractID = "human.protector"
	ContractMajor uint16               = 1
)
View Source
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
)
View Source
const (
	StoredValueVersion  uint16 = 1
	MaxStoredValueBytes int64  = MaxStoredEnvelopeBytes + (1 << 20)
)

Variables

View Source
var (
	ErrInvalidBinding      = errors.New("invalid protection binding")
	ErrInvalidEnvelope     = errors.New("invalid protection envelope")
	ErrAuthentication      = errors.New("protected payload authentication failed")
	ErrKeyUnavailable      = errors.New("protection key is unavailable")
	ErrProviderUnavailable = errors.New("protection provider is temporarily unavailable")
)
View Source
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.

View Source
var ErrInvalidStoredValue = errors.New("invalid stored protected value")

Functions

func MarshalEnvelope

func MarshalEnvelope(envelope Envelope) ([]byte, error)

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 ValidateBinding(binding Binding) error

func ValidateDescription

func ValidateDescription(description Description) error

func ValidateEnvelope

func ValidateEnvelope(envelope Envelope) error

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.

func (Binding) AAD

func (binding Binding) AAD() ([]byte, error)

AAD returns the stable JSON encoding that conformance adapters use as associated data. It first validates the complete binding.

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

func CloneEnvelope(envelope Envelope) Envelope

CloneEnvelope returns a deep copy safe to retain across adapter boundaries.

func UnmarshalEnvelope

func UnmarshalEnvelope(encoded []byte) (Envelope, error)

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

func UnmarshalEnvelopeLimited(encoded []byte, maxBytes int64) (Envelope, error)

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

type Resource = framework.Resource[Protector]

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

type Rewrapper interface {
	Rewrap(context.Context, Binding, Envelope) (Envelope, error)
}

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"
)

Directories

Path Synopsis
Package aead provides Human's local, in-memory AES-256-GCM Protector.
Package aead provides Human's local, in-memory AES-256-GCM Protector.

Jump to

Keyboard shortcuts

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