Documentation
¶
Overview ¶
Package config loads locksql profiles from the project and user config files, applies defaults, refuses anything that looks like a secret, and computes the security-relevant policy of a profile.
Index ¶
- Constants
- func ApprovedKey(root, profile string) string
- func DefaultDetectors() []string
- func DefaultPort(engine string) int
- func FindProjectRoot(cwd string) (string, bool)
- func Fingerprint(p Policy) string
- func IsLoopback(host string) bool
- func ParseProfiles(data []byte, name, baseDir string) (map[string]Profile, error)
- func ProjectHash(root string) string
- func ProjectKey(cwd string) string
- func SSHString(s *SSHProfile) string
- func SaveApproved(stateDir, key string, p Policy) error
- func StateDir() (string, error)
- func TLSRank(mode string) int
- func TLSVerifiesChain(mode, ca string) bool
- func UserConfigPath() (string, error)
- type Change
- type Config
- type Limits
- type Policy
- type Profile
- type SSHProfile
- type Tier
Constants ¶
const ( EngineMariaDB = "mariadb" EngineMySQL = "mysql" EnginePostgres = "postgres" EngineSQLite = "sqlite" )
Supported engines.
const ( MinIdleTimeout = time.Minute MaxMaxSession = 24 * time.Hour )
Bounds of the session limits: MinIdleTimeout <= idle_timeout <= max_session <= MaxMaxSession.
const ( TLSDisable = kconfig.TLSDisable TLSPrefer = kconfig.TLSPrefer TLSRequire = kconfig.TLSRequire TLSVerifyCA = kconfig.TLSVerifyCA TLSVerifyFull = kconfig.TLSVerifyFull )
TLS modes of a network profile, as libpq's sslmode, in increasing strength.
const ( CredentialsAsk = kconfig.CredentialsAsk CredentialsKeychain = kconfig.CredentialsKeychain CredentialsVault = kconfig.CredentialsVault )
Credentials modes. CredentialsVault reads the user and password from HashiCorp Vault with the vault CLI at every connection (Profile.VaultPath).
const ( SSHAuthKey = kconfig.SSHAuthKey SSHAuthAgent = kconfig.SSHAuthAgent SSHAuthPassword = kconfig.SSHAuthPassword )
SSH authentication methods.
const DefaultMaskMode = "redact"
DefaultMaskMode is the mode of a mask rule that sets none.
const DefaultSSHPort = kconfig.DefaultSSHPort
DefaultSSHPort is the port of an ssh table that leaves port unset.
Variables ¶
This section is empty.
Functions ¶
func ApprovedKey ¶
ApprovedKey names the approved-policy file of a profile: <ProjectHash(root)>-<profile>, or user-<profile> for a profile that comes from the user config only (root == "").
func DefaultDetectors ¶
func DefaultDetectors() []string
DefaultDetectors is the detector set used when a profile does not set detectors. National id detectors are opt-in.
func DefaultPort ¶ added in v0.5.0
DefaultPort is the port of engine when a profile leaves port unset, 0 for an engine without one (sqlite).
func FindProjectRoot ¶
FindProjectRoot walks up from cwd to the first directory holding .locksql/config.toml.
func Fingerprint ¶
Fingerprint returns the hex sha256 of the policy's canonical JSON. List order does not change the fingerprint. Only an out-of-range Tier can fail to encode; lockkit then fingerprints its raw form so that it still differs from every valid policy.
func IsLoopback ¶ added in v0.4.0
IsLoopback reports "localhost" or a loopback IP literal.
func ParseProfiles ¶ added in v0.1.2
ParseProfiles decodes and validates config data. name labels errors. Relative sqlite paths are resolved against baseDir. Errors never quote config values that could be secrets.
func ProjectHash ¶
ProjectHash returns the first 8 hex digits of sha256 of the absolute, cleaned project root.
func ProjectKey ¶
ProjectKey names the project of cwd in socket paths: ProjectHash of the project root, or "user" when cwd is outside any project (profiles from the user config only). The console and its clients must agree on it.
func SSHString ¶ added in v0.4.0
func SSHString(s *SSHProfile) string
SSHString shows a bastion in a policy change.
func SaveApproved ¶
SaveApproved atomically writes the policy to <stateDir>/locksql/approved/<key>.json with mode 0600.
func StateDir ¶
StateDir returns the user state directory (without the locksql suffix): $XDG_STATE_HOME or ~/.local/state on Linux and other Unix systems, and os.UserConfigDir() on macOS.
func TLSVerifiesChain ¶ added in v0.4.0
TLSVerifiesChain reports a tls mode that verifies the server's certificate chain: verify-ca and verify-full, and require with tls_ca.
func UserConfigPath ¶ added in v0.1.2
UserConfigPath returns <user config dir>/locksql/config.toml.
Types ¶
type Change ¶
Change is one difference between two policies.
func Diff ¶
Diff lists the changes from approved to current and marks each loosening (spec section 4): a higher tier, production true→false, a larger limit (0 means unlimited), a longer idle_timeout or max_session, a removed PII rule or detector, an added allow rule, any change of engine, host, port, path, database or user, and a credentials mode other than ask, a weaker tls mode, any change of tls_ca, tls_cert, tls_key or tls_server_name and any change of the ssh table.
type Config ¶
type Config struct {
// ProjectRoot is the directory holding .locksql/config.toml, or "" when
// no project config was found.
ProjectRoot string
Profiles map[string]Profile
}
Config is the merged set of profiles visible from a working directory.
type Limits ¶
type Limits struct {
StatementTimeout time.Duration `toml:"statement_timeout" json:"statement_timeout"`
ExplainRowsWarn int64 `toml:"explain_rows_warn" json:"explain_rows_warn"`
ExplainRowsRefuse int64 `toml:"explain_rows_refuse" json:"explain_rows_refuse"`
MaxRows int `toml:"max_rows" json:"max_rows"`
MaxCellChars int `toml:"max_cell_chars" json:"max_cell_chars"`
MaxOutputBytes int `toml:"max_output_bytes" json:"max_output_bytes"`
// ExplainCostRefuse refuses a plan whose total cost, in the engine's
// own units, is above it; 0 disables the check. Engines without a cost
// (SQLite) are not checked.
ExplainCostRefuse float64 `toml:"explain_cost_refuse" json:"explain_cost_refuse,omitempty"`
// KAnonymity is the smallest number of rows a PII filter, a grouping
// on a PII column or an aggregate of one may cover without a warning
// on the approval screen.
KAnonymity int `toml:"k_anonymity" json:"k_anonymity,omitempty"`
// ReferenceProbe is how many distinct cells of one result the agent may
// filter on, one statement each, before the console warns of equality
// probing; raising it is a loosening.
ReferenceProbe int `toml:"reference_probe" json:"reference_probe,omitempty"`
// IdleTimeout ends the console session after that long without
// activity, MaxSession after that long in all; raising either is a
// loosening. Bounds: 1m <= IdleTimeout <= MaxSession <= 24h.
IdleTimeout time.Duration `toml:"idle_timeout" json:"idle_timeout,omitempty"`
MaxSession time.Duration `toml:"max_session" json:"max_session,omitempty"`
}
Limits bound the cost and size of one statement.
func DefaultLimits ¶
DefaultLimits returns the limits applied to unset (zero) limit fields.
type Policy ¶
type Policy struct {
Profile Profile `json:"profile"`
PIIMask []string `json:"pii_mask"` // sorted column patterns
PIIAllow []string `json:"pii_allow"` // sorted column patterns
// PIIModes maps a mask pattern to its mode when it is not the default
// (redact): partial or email.
PIIModes map[string]string `json:"pii_modes,omitempty"`
}
Policy is the security-relevant view of one profile plus its PII rules. The console compares the current policy with the last approved one and asks the human before applying any loosening.
func LoadApproved ¶
LoadApproved reads <stateDir>/locksql/approved/<key>.json. When no policy was approved yet, the error wraps fs.ErrNotExist.
type Profile ¶
type Profile struct {
Name string `json:"name"`
Engine string `json:"engine"`
Host string `json:"host"`
Path string `json:"path"`
User string `json:"user"`
Database string `json:"database"`
Credentials string `json:"credentials"`
// TLS is the transport mode (TLSDisable ... TLSVerifyFull) and TLSCA an
// optional PEM bundle that replaces the system roots.
TLS string `json:"tls,omitempty"`
TLSCA string `json:"tls_ca,omitempty"`
// TLSCert and TLSKey are the PEM files of a client certificate and its
// private key, presented when the server asks for one. TLSServerName
// replaces host as the name verify-full checks in the certificate.
TLSCert string `json:"tls_cert,omitempty"`
TLSKey string `json:"tls_key,omitempty"`
TLSServerName string `json:"tls_server_name,omitempty"`
// SSH, when set, is the bastion the profile is reached through.
SSH *SSHProfile `json:"ssh,omitempty"`
Port int `json:"port"`
Tier Tier `json:"tier"`
Production bool `json:"production"`
Detectors []string `json:"detectors"`
Limits Limits `json:"limits"`
// CredentialsTTL makes the console ask for the secret again (and
// reconnect) once the connection is that old; 0 keeps it for the
// session. It suits short-lived secrets from a vault.
CredentialsTTL time.Duration `json:"credentials_ttl,omitempty"`
// VaultPath is the Vault path read for the login when Credentials is
// "vault", such as "database/creds/app-readonly".
VaultPath string `json:"vault_path,omitempty"`
}
Profile is one named database target with its policy. It never holds a secret.
type SSHProfile ¶ added in v0.4.0
type SSHProfile = kconfig.SSHProfile
SSHProfile is the bastion a network profile is reached through.
type Tier ¶
type Tier int
Tier is the highest statement class a profile may run. The order is TierRead < TierWrite < TierDDL < TierAdmin.
func (Tier) MarshalText ¶
MarshalText encodes the tier by name.
func (*Tier) UnmarshalText ¶
UnmarshalText decodes a tier name.