sealed

package
v1.16.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package sealed encrypts personal data in database columns: phone numbers, addresses, tokens of other services. A sealed.String is an ordinary string in Go and AES-256-GCM ciphertext in the database, so a copy of the database, a backup or a stray SELECT shows nothing.

sealed.SetKeys(s.FieldKey)                    // at start, from settings
db.ExecContext(ctx, `UPDATE users SET phone = ? WHERE id = ?`, sealed.String(phone), id)
var phone sealed.String
db.QueryRowContext(ctx, `SELECT phone FROM users WHERE id = ?`, id).Scan(&phone)

Keys rotate: SetKeys takes the key to encrypt with and older ones that still decrypt; each value records which key sealed it. Encrypted values can't be searched; Blind gives a keyed hash to store beside one, for finding rows by an exact value.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoKeys is returned when values are sealed or opened before
	// SetKeys.
	ErrNoKeys = errors.New("sealed: no keys; call sealed.SetKeys when the app starts")
	// ErrUnknownKey is a value sealed with a key that isn't among the
	// keys, such as one dropped too early in a rotation.
	ErrUnknownKey = errors.New("sealed: the value was sealed with a key that isn't set")
	// ErrNotSealed is a value in the database that isn't encrypted; see
	// AllowPlain.
	ErrNotSealed = errors.New("sealed: the column holds a value that isn't sealed")
)

Functions

func AllowPlain

func AllowPlain(allow bool)

AllowPlain lets columns that aren't encrypted yet be read: a value without the sealed format is returned as it is, and sealed when it's written again. Use it while encrypting a column that has data.

func Blind

func Blind(value string) (string, error)

Blind is a keyed hash of value, to store in a column beside a sealed one and find rows by an exact value: WHERE email_hash = ?. It's the same for the same value, so it shows which rows share one, and nothing else. Rotating keys changes it: write the hashes again with the new key.

func Current

func Current(sealedValue string) bool

Current reports whether a stored value is sealed with the current key, to find the rows a rotation hasn't rewritten yet.

func Open

func Open(sealedValue string) ([]byte, error)

Open decrypts a value Seal made, with whichever key sealed it.

func Seal

func Seal(plain []byte) (string, error)

Seal encrypts plain with the current key.

func SetKeys

func SetKeys(primary settings.Secret, old ...settings.Secret) error

SetKeys sets the key that seals values, and older keys that still open them, each at least 32 characters. Rotate by passing a new key first and the old one after it; once every row has been written again, drop it.

Types

type Bytes

type Bytes []byte

Bytes is a binary column stored sealed.

func (Bytes) LogValue

func (b Bytes) LogValue() slog.Value

LogValue implements slog.LogValuer: personal data stays out of logs.

func (*Bytes) Scan

func (b *Bytes) Scan(src any) error

Scan implements sql.Scanner: the column, opened. NULL is nil.

func (Bytes) Value

func (b Bytes) Value() (driver.Value, error)

Value implements driver.Valuer: the bytes, sealed.

type String

type String string

String is a string column stored sealed.

func (String) LogValue

func (s String) LogValue() slog.Value

LogValue implements slog.LogValuer: personal data stays out of logs.

func (*String) Scan

func (s *String) Scan(src any) error

Scan implements sql.Scanner: the column, opened. NULL is "".

func (String) Value

func (s String) Value() (driver.Value, error)

Value implements driver.Valuer: the string, sealed.

Jump to

Keyboard shortcuts

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