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" and "passthrough", and the type names "bool", "int32", "int64", "uint32", "uint64", "float32", "float64", "string" and "bytes". 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 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
}
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.
type Output ¶
type Output string
Output is one output of a sealed field, by its wire key.
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.
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.
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
}
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 | json), query (or null), query_sql_domain (or null), producible and reason (or null).