Help us shape the future of Go! Take the 2026 Go Developer Survey

record

package
v0.1.0-rc.3 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package record is the data form of a declaration as the engine reads it: the plan object the guest's se_encrypt_record, se_decrypt_record and se_plan_check parse, and the per-field outputs they return. It is shared by the encrypt package, which runs plans, by encrypt/gensupport, which lowers a generated declaration into one, and by stashgen, which asks the engine to check one.

The spellings here are wire format, fixed by stack-encrypt's dynamic::record: the output keys "c", "eq", "match", "ore", "ope", "ore_block" and "passthrough", and the type names "bool", "int8", "int16", "int32", "int64", "int128", "uint8", "uint16", "uint32", "uint64", "uint128", "float32", "float64", "decimal", "date", "timestamp", "string", "bytes" and "json". A field's context is its label — the plan's context segments and the field's identity — nested to the left under each part the caller extends it by.

Passthrough fields do not appear in a Plan. The Go SDK keeps them on the host: the FFI codec cannot carry every Go type a program stores beside a ciphertext (a time.Time, a driver.Valuer), and nothing the engine does to a passthrough value could be observed. The one exception is a context field: a string field whose value is the context every other field is sealed under (the engine's context_field). It crosses the binding as a passthrough of type string, because the engine reads it to seal and to open, and the stored record carries it in the clear.

Index

Constants

View Source
const EQLKey = "eql"

EQLKey is the stored key a target field's EQL value rides under: not an output a plan asks for (the field names a Target instead), but the key of its one node in a sealed record, fixed by stack-encrypt's dynamic::record::EQL_KEY.

Variables

This section is empty.

Functions

func CheckPart

func CheckPart(part any) error

CheckPart refuses a context extension part that is not a string, a byte slice or an integer the codec carries.

func CheckSegment

func CheckSegment(s string) error

CheckSegment is the one rule for a plain label segment, the same as stack-encrypt's Label::check_segment: non-empty, no control or invisible format character, none of '/', '(' and ')', and not beginning like another descriptor form ("b64:", a digit or '-'). The shared fixture packages/stack-encrypt/tests/fixtures/label_segments.json holds the two implementations together.

func ParseContext

func ParseContext(s string) ([]string, error)

ParseContext splits a `context=` value on '/' and checks each segment is plain: what a label is, so the ZeroKMS descriptor renders it verbatim.

Types

type ElementArray

type ElementArray struct {
	Path    string
	Members []string
}

ElementArray is an array of a document whose elements have ordered members: the path through the array's elements ($.contacts[*]), and each ordered path beneath it as a member of one element (relationship, address.city). The element predicate (element_match) tests these members of one element together.

type Fidelity

type Fidelity string

Fidelity says how far the server's answer to an operator can be trusted: Exact, or Probabilistic, whose rows a caller verifies after decrypt.

const (
	// Exact is an answer the server gives whole: nothing to verify.
	Exact Fidelity = "exact"
	// Probabilistic is an answer that can hold false positives and no false
	// negatives: each decrypted row is verified, and the fetch is sized for
	// the false positives.
	Probabilistic Fidelity = "probabilistic"
)

The fidelities an operator has.

type Field

type Field struct {
	// Name is the field's name in the declaration: the key of its value in a
	// source and of its outputs in a result.
	Name string
	// Identity is the last segment of the field's label, under the plan's
	// context. It is the name unless a policy pinned another.
	Identity string
	// Kind is the declared type, or Untyped.
	Kind Kind
	// Outputs are the field's outputs: Ciphertext and/or terms, at least one
	// — unless the field names a Target, which has none of its own.
	Outputs []Output
	// Target is the EQL type the field seals into (encrypt_into), such as
	// TextEq, or "". A field has outputs or a target, never both: the EQL
	// type's own plan decides what is sealed and which terms sit beside it,
	// and the engine returns the finished value under EQLKey.
	Target string
	// Null is how the field stores a value that is not there: NotNull for a
	// field every row has, SealedNull or SQLNull for one declared over a
	// pointer.
	Null Null
	// TargetOptions are the options the field gives its Target: those of
	// the index the target carries. A target that stores a JSON document
	// (JsonSearch) takes the JSON index's; nil runs a target under its
	// defaults, and no other target takes any.
	TargetOptions *TargetOptions
}

Field is one sealed field of a plan.

func (Field) HasCiphertext

func (f Field) HasCiphertext() bool

HasCiphertext reports whether the field's stored node is opened on decrypt: a ciphertext output, or an EQL value.

func (Field) IsTarget

func (f Field) IsTarget() bool

IsTarget reports whether the field names an EQL type.

type Kind

type Kind string

Kind is a plan field's declared type: the data form of the Rust chain's `::<F>`. It decides which terms the field derives, not how it seals: a field lowered from data seals in vitaminc's self-describing tagged leaf encoding whatever its kind. A Rust record derives the same terms, and opens the leaf only when its field is a Value; a Rust record over a bare u32 or String writes a different leaf, which neither side can open.

const (
	Untyped   Kind = ""
	Bool      Kind = "bool"
	Int8      Kind = "int8"
	Int16     Kind = "int16"
	Int32     Kind = "int32"
	Int64     Kind = "int64"
	Int128    Kind = "int128"
	Uint8     Kind = "uint8"
	Uint16    Kind = "uint16"
	Uint32    Kind = "uint32"
	Uint64    Kind = "uint64"
	Uint128   Kind = "uint128"
	Float32   Kind = "float32"
	Float64   Kind = "float64"
	Decimal   Kind = "decimal"
	Date      Kind = "date"
	Timestamp Kind = "timestamp"
	String    Kind = "string"
	Bytes     Kind = "bytes"
	// JSON is a JSON document, which crosses the binding as its UTF-8 JSON
	// text in a bytes value and opens back to its text. The engine parses
	// the text by one set of rules (numbers, repeated members, Unicode);
	// a field of this kind names a target that stores a document.
	JSON Kind = "json"
)

The kinds. The names are vitaminc's ValueKind names, frozen.

func (Kind) Known

func (k Kind) Known() bool

Known reports whether k is a kind that the engine names; Untyped is one.

type Null

type Null string

Null is how a field stores a value that is not there: the plan's "null". The spellings are wire format, stack-encrypt's dynamic::NullMode.

const (
	// NotNull is a field every row has. A typed field refuses a nil.
	NotNull Null = ""
	// SealedNull seals a nil like a value, as a typed null as long as one of
	// the field's kind, so the stored record does not show which rows are
	// absent; it opens as nil. Beside an equality index it stores the term
	// every nil shares. The engine takes it on a field whose only index is
	// equality, of a kind of fixed width.
	SealedNull Null = "sealed"
	// SQLNull stores nothing for a nil: the field is left out of the record,
	// a source may leave it out, and a stored record without it opens it as
	// nil. Its columns hold SQL NULL, which shows that the value is absent.
	SQLNull Null = "sql"
)

type Operator

type Operator struct {
	// Name is the operator's name, as a query names it: eq, lt, lte, gt,
	// gte, between or matches; for a field that stores a JSON document,
	// contains, contained_by, eq_at, lt_at, lte_at, gt_at, gte_at,
	// between_at, selector, subtree, children, child_count, element_match
	// or match.
	Name string
	// Fidelity is how far the server's answer can be trusted.
	Fidelity Fidelity
	// Pair says the operator takes two values, low then high, as between
	// does, where every other takes one.
	Pair bool
	// Index is the index that answers it: the field's, or its EQL type's.
	Index Output
	// Input is the shape of the operator's input, as the engine names it:
	// value (one value of the field's kind), pair (two, low then high),
	// json, path_json, path_pair, path, path_bound, path_predicates or
	// predicate (objects of named inputs, for a document's operators).
	Input string
}

Operator is one operator the engine answers for a field: for an EQL type, as se_targets lists it, and for any field of a plan, as se_operators lists it.

type Output

type Output string

Output is one output of a sealed field, by its wire key.

const (
	Ciphertext Output = "c"
	Equality   Output = "eq"
	Match      Output = "match"
	Ore        Output = "ore"
	Ope        Output = "ope"
	OreBlock   Output = "ore_block"
	// JSONIndex is the JSON index, which a target that stores a JSON
	// document carries and answers a document's operators through. No
	// field asks for it as an output.
	JSONIndex   Output = "json"
	Passthrough Output = "passthrough"
)

The outputs. Passthrough is not one a Plan's Fields ask for (see the package doc); it is the context field's, which Wire writes itself.

func (Output) IsTerm

func (o Output) IsTerm() bool

IsTerm reports whether the output is an index term.

type Outputs

type Outputs struct {
	// Ciphertext is the frozen leaf bytes, or nil for an index-only field
	// or a target field.
	Ciphertext []byte
	// Terms are the index terms by output, each its frozen bytes.
	Terms map[Output][]byte
	// EQL is the EQL value's JSON bytes for a field that names a Target.
	EQL []byte
	// Context is the context field's value as the record stores it, in the
	// clear, and nothing for any other field.
	Context string
}

Outputs is what the engine produced for one sealed field, or what it stored for the context field.

type Plan

type Plan struct {
	// Context is the label every field's label extends: at least one plain
	// segment. The guest requires a field's label to have two or more
	// segments, which the identity supplies. Empty when ContextField is set.
	Context []string
	// ContextField is the name of the record's field whose value is the
	// context, when the declaration takes its context from a field rather
	// than from Context: the engine's context_field. The field is a string,
	// crosses the binding as a passthrough, and is not in Fields. Each
	// field's label is then its identity alone, under that value.
	ContextField string
	// Extension is the caller's parts, nested to the left of every field's
	// label, in order: a tenant, a region.
	Extension []any
	// Fields are the sealed fields, in declared order.
	Fields []Field
}

Plan is a declaration as the engine reads it: one context, any extension, and the sealed fields.

func (*Plan) Descriptor

func (p *Plan) Descriptor(f Field) string

Descriptor renders a field's label as ZeroKMS logs it, for messages. Under a context field the context is the record's, so the descriptor names the field in its place: "<tenant>/age".

func (*Plan) Field

func (p *Plan) Field(name string) *Field

Field returns the field named, or nil.

func (*Plan) FieldContext

func (p *Plan) FieldContext(f Field) any

FieldContext is one field's context as the guest reads it: the label as a flat list of its segments, then each extension part nested to the left — [[["users", "age"], 7], "eu"] — exactly the shape se_term takes for a probe of that field. Under a context field the label is the identity alone: [["age"], 7].

func (*Plan) Validate

func (p *Plan) Validate() error

Validate checks what the host can check before the engine sees the plan: a context, plain segments, at least one field, names and identities once, outputs once and at least one, known kinds, a kind on every indexed field, and extension parts the codec carries. The engine's own rules — which index a kind admits, what the builder refuses — are the engine's, asked through se_plan_check.

func (*Plan) Wire

func (p *Plan) Wire() vcvalue.Object

Wire renders the plan as the guest parses it: per field, its context (the label, extended), its outputs or its target, and its type; with a context field, the plan-level "context_field" key and that field's own entry, a passthrough of type string. Validate first.

type Sealed

type Sealed = map[string]Outputs

Sealed is one record as stored: each sealed field's outputs by name, and the context field's under its name when the plan has one. A SQLNull field that was nil has no entry.

type Source

type Source = map[string]any

Source is one record's plaintext for the engine: each sealed field's value by name, and the context field's string when the plan has one. Passthrough and omitted fields are not in it, nor need a SQLNull field that is nil be.

type Target

type Target struct {
	// Name is the Go type name, and the value of encrypt_into: TextEq.
	Name string
	// Family and Suffix are the two halves of the name: Text, Eq.
	Family string
	Suffix string
	// Plaintext is the kind the type seals, or Untyped when the entry says
	// null.
	Plaintext Kind
	// SQLDomain is the Postgres domain of the stored value.
	SQLDomain string
	// Indexes are the terms the type carries.
	Indexes []Output
	// Query is the Go type name of the query value, or "" for none.
	Query string
	// QuerySQLDomain is the Postgres domain of the query value, or "".
	QuerySQLDomain string
	// Producible says whether this build of the engine produces the type;
	// Reason says why not when it does not.
	Producible bool
	Reason     string
	// Operators are the operators the engine answers for a field that names
	// the type, in the engine's order; none for a type it does not produce.
	Operators []Operator
}

Target is one EQL type as se_targets lists it. The entry's keys are wire format, written by eql-bindings' serialiser and read by [ParseTargets]: name, family, suffix, plaintext (a ValueKind name, or null), sql_domain, indexes (eq | match | ore | ope | ore_block | json), query (or null), query_sql_domain (or null), producible, reason (or null), and operators, which the engine adds: the operators it answers for the type, each an object of operator, fidelity (exact | probabilistic), arity (one | pair) and index.

type TargetOptions

type TargetOptions struct {
	// SealedRoot says whether the document's root is sealed: its entry
	// holds the whole document, and no token enumerates its top-level
	// members. nil is the default, sealed.
	SealedRoot *bool
	// Ordered are the JSONPath paths ($.age, $.visits[*].at) whose number
	// and string leaves carry an ordering term, so they answer the
	// orderings. None by default.
	Ordered []string
}

TargetOptions are a target's options, as a plan gives them: the JSON index's, the only index that takes any. A field left nil takes the index's default. The engine checks them when the plan is built.

func (*TargetOptions) ElementArrays

func (o *TargetOptions) ElementArrays() []ElementArray

ElementArrays groups the ordered paths by the array each one's last wildcard names: $.contacts[*].relationship and $.contacts[*].address.city give the array $.contacts[*] with the members relationship and address.city. A path with no wildcard, one that ends at its wildcard, or one whose member crosses another array has no element member. Only paths a stash tag spells are read ($, then .key, [n] and [*] steps): a path with a quoted key has none. Arrays and members are in the order the paths are given.

Jump to

Keyboard shortcuts

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