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 ¶
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 ¶
CheckPart refuses a context extension part that is not a string, a byte slice or an integer the codec carries.
func CheckSegment ¶
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 ¶
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 ¶
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 ¶
HasCiphertext reports whether the field's stored node is opened on decrypt: a ciphertext output, or an EQL value.
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.
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.
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 ¶
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) FieldContext ¶
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 ¶
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.
type Sealed ¶
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 ¶
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.