sql

package
v0.5.8 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package sql is the SQL protocol-family facet. It owns the SQL CEL environment (verb / tables / functions / statement, exposed as fields on the `sql` variable), the matcher that walks a parsed SQL statement, the Meta type wire-frame frontends (postgres, clickhouse) populate on match.Request.Meta, and the per-family report fields the dashboard shows for a SQL query.

SQL endpoints derive Meta themselves from the wire frame (the postgres / clickhouse runtimes parse the Query message and stash a *Meta on the request before dispatch), so PrepareRequest is a no-op. The matcher type-asserts req.Meta to *Meta and fails the match cleanly when the assertion fails — e.g. when an https- family request accidentally reaches a sql rule.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Facet

type Facet struct{}

Facet is the SQL facet Runtime. Singleton.

func (Facet) CELContrib

func (Facet) CELContrib() facet.CELContrib

CELContrib declares the SQL facet's CEL contribution: the `sql` variable backed by Fields and the path lists CompileCondition needs.

lowercasedPaths: sql.verb's activation value is lowercased so rules written as `sql.verb == "SELECT"` match a select statement.

truncatablePaths: every SQL field, because the wire frontends (postgres pgClientToServer, clickhouse_native chHandleQuery) feed the matcher one piece of text — the raw statement — and every CEL field (verb, tables, functions, statement) is derived from the same parsed bytes. When the frontend caps the frame, all four are simultaneously untrustworthy — they become CEL unknowns, so any condition whose outcome depends on one fails closed on a truncated request.

Note credential and database are intentionally absent: they resolve off-wire (StartupMessage user / database, Hello username / database, HTTPS query+header), never from frame bytes, so predicates on either still evaluate correctly on a truncated request. The dispatcher applies r.Credential before the matcher runs (config/runtime/dispatch.go), and the database value flows through req.Database / meta.Database which the wire frontend populates before any SQL bytes are read. unparseablePaths declares the SQL fields a wire frontend's parser derives from the Query bytes — verb, tables, functions. When the parser refuses the input, the frontend leaves these zero and sets req.Unparseable=true; the matcher then marks these paths as CEL unknowns and any rule whose outcome depends on one is denied.

sql.statement is intentionally absent: the frontend populates it with the raw bytes regardless of parse success, so a rule keyed on `sql.statement` / `sql.statement.matches(...)` can still evaluate honestly on an unparseable request.

func (Facet) EndpointFamilies

func (Facet) EndpointFamilies() []string

EndpointFamilies enumerates endpoint families a sql rule may attach to.

func (Facet) HITLQueryLabel

func (Facet) HITLQueryLabel() string

HITLQueryLabel is the dashboard / Slack label for a SQL query.

func (Facet) HostIsResource

func (Facet) HostIsResource() bool

HostIsResource reports that a SQL request's Host is typically a virtual IP, not a label the operator would recognise.

func (Facet) Name

func (Facet) Name() string

Name reports the family identifier this facet handles.

func (Facet) NewMatcher

func (f Facet) NewMatcher(condition string) (match.Matcher, error)

NewMatcher compiles a CEL condition into a Matcher. Delegates to the package-level composer (the sql family composes only its own sql facet today — postgres / clickhouse_native wire protocols are binary, not HTTPS, so there is no http facet to add).

func (Facet) PrepareRequest

func (Facet) PrepareRequest(*match.Request)

PrepareRequest is a no-op: SQL endpoint runtimes set req.Meta directly from the wire frame.

func (Facet) Report

func (Facet) Report(req *match.Request) map[string]any

Report extracts the SQL report fields from a request. When Meta isn't a *Meta (e.g. a request that never ran through a SQL frontend) the result is empty rather than panicking.

func (Facet) ReportFields

func (Facet) ReportFields() []facet.ReportFieldSpec

ReportFields declares the per-family columns the SQL facet emits.

func (Facet) Transport

func (Facet) Transport() string

Transport returns "" because the SQL family doesn't share the HTTPS-MITM dispatch path. Each SQL endpoint plugin (postgres, clickhouse_native, ...) owns its own wire-protocol handler and gets dispatched on the protocol's well-known port instead of through SNI peek on 443.

type Fields

type Fields struct {
	Verb      string   `cel:"verb"`
	Tables    []string `cel:"tables"`
	Functions []string `cel:"functions"`
	Statement string   `cel:"statement"`
	Database  string   `cel:"database"`
}

Fields is the CEL-facing view of a SQL statement. Exposed as the `sql` variable in rule conditions (`sql.verb`, `sql.tables`, `sql.functions`, `sql.statement`, `sql.database`). The plural `functions` matches the multi-valued shape (a statement can reference multiple functions) and parallels `tables`.

type Meta

type Meta struct {
	Verb      string   // select | insert | update | delete | merge | ...
	Tables    []string // unqualified table names referenced
	Functions []string // unqualified function names called
	Statement string   // the raw text — exposed for `statement` /
	// `statement_regex` matchers
	Database string // session-scoped database name; postgres

}

Meta carries the per-request SQL fields the matcher reads. The postgres and clickhouse endpoint runtimes build one of these from the parsed wire frame and assign it to match.Request.Meta.

Jump to

Keyboard shortcuts

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