db

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: AGPL-3.0 Imports: 30 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AgentTypeFilesystem = config.AgentTypeFilesystem
	AgentTypeDatabase   = config.AgentTypeDatabase
	AgentTypeKubernetes = config.AgentTypeKubernetes
	JobTypeFilesystem   = config.AgentTypeFilesystem
	JobTypeDatabase     = config.AgentTypeDatabase
	JobTypeKubernetes   = config.AgentTypeKubernetes
	// JobTypePVE backs up a Proxmox VE host's configuration; it runs on the
	// filesystem agent installed on the node
	JobTypePVE = "pve"
	// JobTypeDocker backs up a Docker host (definitions, compose files, volumes); it
	// runs on the filesystem agent installed on the host
	JobTypeDocker = "docker"
	// JobTypeM365 backs up a Microsoft 365 tenant through Graph; it runs on any
	// filesystem agent with outbound HTTPS (no host capability involved)
	JobTypeM365 = "m365"
)

Agent / job types: each agent binary handles one kind of job

View Source
const (
	PxarFormatV1 = "v1" // single stream + catalog; browsable everywhere
	PxarFormatV2 = "v2" // split metadata/payload streams; PBS 3.2+
)

pxar archive formats a target accepts

View Source
const (
	EncryptionNone    = "none"
	EncryptionEncrypt = "encrypt"
)

Encryption modes of a target

View Source
const (
	BindingUser  = "user"
	BindingGroup = "group"
	// BindingClaim matches a value of a configured ID token claim; the subject is
	// "<claim>=<value>" (e.g. roles=Backup.Admin)
	BindingClaim = "claim"
)

Binding kinds

View Source
const (
	OpIn        = "in"     // key=v, key==v, key in (v1, v2)
	OpNotIn     = "notin"  // key!=v, key notin (v1, v2): also matches when key is absent
	OpExists    = "exists" // key
	OpNotExists = "!"      // !key
)

Selector operators

View Source
const MaxLabels = 20

MaxLabels caps the entries on one object or selector

View Source
const StaleAfter = 90 * 24 * time.Hour

StaleAfter is how long a binding's subject may go unseen at sign-in before the Access page flags it

Variables

View Source
var (
	ErrNotFound = errors.New("record not found")
	// ErrInUse: the row is referenced by others and cannot be deleted
	ErrInUse = errors.New("record is in use")
)
View Source
var ErrLastAdmin = errors.New("this is the last binding that grants rbac:manage on everything")

ErrLastAdmin refuses removing the last binding that can manage access

View Source
var ErrTenantInUse = errors.New("tenant is referenced by backup jobs")

ErrTenantInUse is returned when a tenant still has jobs

View Source
var Unscoped = Scope{All: true}

Unscoped reaches every row. Only for internal callers (workflows, agent endpoints, the PBS tunnel); admin requests take their scope from the principal.

Functions

func CleanDBEngines added in v0.11.3

func CleanDBEngines(in []string) []string

CleanDBEngines keeps the known engine names, canonical and without duplicates

func JobAllowedOnAgent added in v0.9.5

func JobAllowedOnAgent(jobType, agentType string) bool

JobAllowedOnAgent reports whether an agent of agentType may run a job of jobType. Job types normally match the agent type; the exceptions are database jobs on a kubernetes agent (dumped from a pod inside the cluster) or on a filesystem agent (the combined agent, when it reports database client tools), Proxmox VE / Docker host jobs, which run on the filesystem agent installed on the host, and Microsoft 365 jobs, which any filesystem agent runs.

func NormalizeAgentType added in v0.6.0

func NormalizeAgentType(t string) (string, bool)

NormalizeAgentType maps "" to filesystem and reports unknown values

func NormalizeJobType added in v0.9.5

func NormalizeJobType(t string) (string, bool)

NormalizeJobType maps "" to filesystem and accepts the job-only types pve, docker and m365

func SetScheduleLocation added in v0.7.2

func SetScheduleLocation(loc *time.Location)

SetScheduleLocation installs the timezone used for next-run display

func ValidateBackupPaths added in v0.6.0

func ValidateBackupPaths(paths []string) ([]string, error)

ValidateBackupPaths normalises a job's backup paths and rejects combinations that cannot form one archive: every path must be absolute, exact duplicates are dropped and no path may lie inside another (its data would be archived twice). Paths sharing a basename are fine; the agent names them after their full path in the archive. The rules are those of a Unix agent regardless of the host the server runs on, so the slash-only path package is used rather than path/filepath.

func ValidateBackupPathsFor added in v0.9.5

func ValidateBackupPathsFor(agentOS string, paths []string) ([]string, error)

ValidateBackupPathsFor validates paths with the rules of the agent's operating system ("windows" or anything else): the server runs on Linux but stores jobs for Windows agents, whose paths use drive letters and backslashes.

func ValidateCron added in v0.6.2

func ValidateCron(expr string) error

ValidateCron rejects schedule expressions the scheduler cannot run; empty = manual

func ValidateExcludePatterns added in v0.6.0

func ValidateExcludePatterns(patterns []string) error

ValidateExcludePatterns checks exclude patterns against the pxar pattern syntax (proxmox-backup-client --exclude); invalid patterns would otherwise fail the backup only at run time on the agent.

func ValidateLabels added in v1.0.0

func ValidateLabels(l Labels) error

ValidateLabels applies the Kubernetes label syntax: key is [prefix/]name with a DNS subdomain prefix (at most 253 characters) and a name of at most 63 characters; the value is empty or a name. At most MaxLabels entries.

func ValidateLocalBackupPaths added in v0.9.6

func ValidateLocalBackupPaths(paths []string) ([]string, error)

ValidateLocalBackupPaths validates paths with the rules of the operating system the caller runs on; the agent uses it for the paths it is about to read.

Types

type APIKey

type APIKey struct {
	ID         uuid.UUID  `json:"id"`
	Name       string     `json:"name"`
	KeyHash    string     `json:"-"`
	CreatedBy  string     `json:"created_by"`
	CreatedAt  time.Time  `json:"created_at"`
	LastUsedAt *time.Time `json:"last_used_at"`
	ExpiresAt  *time.Time `json:"expires_at"`
	RevokedAt  *time.Time `json:"revoked_at"`
	// Role and Selector are the key's single access binding
	Role     string   `json:"role"`
	Selector Selector `json:"selector"`
}

APIKey is an admin credential for fallbck-ctl and scripts. The raw key is never stored.

type AdminSession added in v1.0.0

type AdminSession struct {
	ID         uuid.UUID  `json:"id"`
	Subject    string     `json:"subject"`
	Email      string     `json:"email"`
	Name       string     `json:"name"`
	SourceIP   string     `json:"source_ip"`
	UserAgent  string     `json:"user_agent"`
	CreatedAt  time.Time  `json:"created_at"`
	LastSeenAt time.Time  `json:"last_seen_at"`
	ExpiresAt  time.Time  `json:"expires_at"`
	RevokedAt  *time.Time `json:"revoked_at,omitempty"`
	RevokedBy  string     `json:"revoked_by,omitempty"`
}

AdminSession is one signed-in browser session

type Agent

type Agent struct {
	ID        uuid.UUID `json:"id" db:"id"`
	Hostname  string    `json:"hostname" db:"hostname"`
	IPAddress string    `json:"ip_address" db:"ip_address"`
	OS        string    `json:"os" db:"os"`
	Arch      string    `json:"arch" db:"arch"`
	Version   string    `json:"version" db:"version"`
	AgentType string    `json:"agent_type" db:"agent_type"`
	TaskQueue string    `json:"task_queue" db:"task_queue"`
	// DebugLogging raises the agent's log level to debug (applied via heartbeats)
	DebugLogging bool `json:"debug_logging" db:"debug_logging"`
	// AutoUpdate lets the agent update itself to the server's version (per-agent opt-in)
	AutoUpdate bool `json:"auto_update" db:"auto_update"`
	// SelfUpdate is reported by the agent when it can replace its own binary (Linux
	// package or manual install; not containers, not Windows)
	SelfUpdate bool `json:"self_update" db:"self_update"`
	// UpdateRequestedAt is set by "Update now" in the web UI; cleared when the agent
	// reports the server's version or an update error
	UpdateRequestedAt *time.Time `json:"update_requested_at,omitempty" db:"update_requested_at"`
	// UpdateError is the agent's last self-update failure (empty: none)
	UpdateError string `json:"update_error,omitempty" db:"update_error"`
	// PVEHost is reported by the agent when it runs on a Proxmox VE node
	PVEHost bool `json:"pve_host" db:"pve_host"`
	// DockerHost is reported by the agent when a Docker daemon answers on its host
	DockerHost bool `json:"docker_host" db:"docker_host"`
	// DBTools is reported by a filesystem agent that found database client tools
	// (pg_dump, mysqldump/mariadb-dump, mongodump) and can therefore run database jobs
	DBTools bool `json:"db_tools" db:"db_tools"`
	// DBEngines are the database engines the agent reported (see CanRunDBEngine)
	DBEngines []string `json:"db_engines" db:"db_engines"`
	// Inventory is the compact summary the agent attaches to a heartbeat every few
	// minutes (inventory.Summary); InventoryDetail the on-demand full inventory
	Inventory         json.RawMessage `json:"inventory,omitempty" db:"inventory"`
	InventoryAt       *time.Time      `json:"inventory_at,omitempty" db:"inventory_at"`
	InventoryDetail   json.RawMessage `json:"inventory_detail,omitempty" db:"inventory_detail"`
	InventoryDetailAt *time.Time      `json:"inventory_detail_at,omitempty" db:"inventory_detail_at"`
	Status            AgentStatus     `json:"status" db:"status"`
	// Labels place the agent in access scopes; copied from the enrollment token
	Labels     Labels     `json:"labels"`
	LastSeenAt *time.Time `json:"last_seen_at" db:"last_seen_at"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at" db:"updated_at"`
}

Agent represents a registered backup agent host

func (*Agent) CanRunDBEngine added in v0.11.3

func (a *Agent) CanRunDBEngine(engine string) bool

CanRunDBEngine reports whether this agent can back up the engine. Filesystem agents go by the engines they report; one that only sent the older db_tools flag predates the mssql engine and is assumed to have the client tools of the other three. Kubernetes agents dump from a pod and the retired database agent predates mssql, so both handle everything except SQL Server.

func (*Agent) CanRunJob added in v0.10.1

func (a *Agent) CanRunJob(jobType string) bool

CanRunJob reports whether this agent may run a job of jobType, including the capability flags a filesystem agent reports (Proxmox VE node, Docker daemon, database client tools)

type AgentAuthState

type AgentAuthState struct {
	ID           uuid.UUID
	TaskQueue    string
	TokenVersion int
	Revoked      bool
}

AgentAuthState is the subset of agent state needed to validate an agent bearer token

type AgentCapabilities added in v0.10.1

type AgentCapabilities struct {
	PVEHost    bool
	DockerHost bool
	DBTools    bool
	DBEngines  []string
	// Version is the running binary's version (empty keeps the stored one)
	Version string
	// SelfUpdate / UpdateError: see Agent
	SelfUpdate  bool
	UpdateError string
	// Inventory is the summary attached to this heartbeat (nil: none this time)
	Inventory json.RawMessage
}

AgentCapabilities are the host facts a filesystem agent reports with every heartbeat

type AgentStatus

type AgentStatus string

AgentStatus represents the lifecycle state of an agent

const (
	AgentStatusOnline  AgentStatus = "online"
	AgentStatusOffline AgentStatus = "offline"
	AgentStatusBusy    AgentStatus = "busy"
	AgentStatusError   AgentStatus = "error"
)

type AuditEntry added in v1.0.0

type AuditEntry struct {
	ID           int64           `json:"id"`
	At           time.Time       `json:"at"`
	ActorKind    string          `json:"actor_kind"`
	Actor        string          `json:"actor"`
	Action       string          `json:"action"`
	ResourceKind string          `json:"resource_kind"`
	ResourceID   string          `json:"resource_id"`
	ResourceName string          `json:"resource_name"`
	Labels       Labels          `json:"labels"`
	SourceIP     string          `json:"source_ip"`
	Details      json.RawMessage `json:"details,omitempty"`
}

AuditEntry is one row of the append-only audit log

type AuditFilter added in v1.0.0

type AuditFilter struct {
	Actor        string
	Action       string // prefix match: "job" matches job.create, job.delete...
	ResourceKind string
	From, To     *time.Time
	Limit        int
}

AuditFilter narrows ListAudit; empty fields match everything

type BackupJob

type BackupJob struct {
	ID           uuid.UUID `json:"id" db:"id"`
	Name         string    `json:"name" db:"name"`
	AgentID      uuid.UUID `json:"agent_id" db:"agent_id"`
	TargetID     uuid.UUID `json:"target_id" db:"target_id"`
	ScheduleCron string    `json:"schedule_cron" db:"schedule_cron"`
	BackupPaths  []string  `json:"backup_paths" db:"backup_paths"`
	ExcludePaths []string  `json:"exclude_paths" db:"exclude_paths"`
	Enabled      bool      `json:"enabled" db:"enabled"`
	// DirectPBS makes the agent talk to PBS itself (credentials handed out per run)
	// instead of through the server-side tunnel. Server-side setting only.
	DirectPBS bool `json:"direct_pbs" db:"direct_pbs"`
	// OneFileSystem keeps a filesystem job on the filesystem of each backup path:
	// other mounts below it are left out (filesystem jobs only)
	OneFileSystem bool `json:"one_file_system" db:"one_file_system"`
	// BackupID is the PBS backup group of filesystem, Docker, Proxmox VE and
	// kubernetes jobs (database and Microsoft 365 jobs carry theirs in their config).
	// Empty means the agent ID, see EffectiveBackupID.
	BackupID string `json:"backup_id" db:"backup_id"`
	// JobType is filesystem (BackupPaths) or database (DBConfig)
	JobType string `json:"job_type" db:"job_type"`
	// DBConfig is the database job specification; the password is stored but never
	// returned by the API (see Sanitize)
	DBConfig *dbbackup.Spec `json:"db_config,omitempty" db:"db_config"`
	// K8sConfig is the kubernetes job specification
	K8sConfig *k8sbackup.Spec `json:"k8s_config,omitempty" db:"k8s_config"`
	// PVEConfig is the Proxmox VE host job specification
	PVEConfig *pvebackup.Spec `json:"pve_config,omitempty" db:"pve_config"`
	// DockerConfig is the Docker host job specification
	DockerConfig *dockerbackup.Spec `json:"docker_config,omitempty" db:"docker_config"`
	// M365Config is the Microsoft 365 job specification (its TenantID is also the
	// m365_tenant_id column, so a tenant cannot be deleted while jobs use it)
	M365Config *m365.Spec `json:"m365_config,omitempty" db:"m365_config"`
	CreatedAt  time.Time  `json:"created_at" db:"created_at"`
	UpdatedAt  time.Time  `json:"updated_at" db:"updated_at"`
	// Labels place the job and all of its runs in access scopes. On update, an
	// absent field (nil) keeps the stored labels; {} clears them.
	Labels Labels `json:"labels"`

	// Joined fields for display
	AgentName  string `json:"agent_name,omitempty"`
	TargetName string `json:"target_name,omitempty"`
	// LastRun is the job's newest run (filled by the Jobs page; nil = never ran)
	LastRun *JobLastRun `json:"last_run,omitempty" db:"-"`
}

func (*BackupJob) EffectiveBackupID added in v0.14.12

func (j *BackupJob) EffectiveBackupID() string

BackupJob defines what, when, and where an agent backs up EffectiveBackupID is the PBS backup group a filesystem, Docker, Proxmox VE or kubernetes job writes to: the stored backup_id, else the agent ID (with -docker / -pve for those types). Server-derived on purpose: an agent must not be able to pick another host's group by reporting its hostname.

func (*BackupJob) IsDatabase added in v0.6.0

func (j *BackupJob) IsDatabase() bool

IsDatabase reports whether the job is a database backup

func (*BackupJob) IsDocker added in v0.9.11

func (j *BackupJob) IsDocker() bool

IsDocker reports whether the job is a Docker host backup

func (*BackupJob) IsKubernetes added in v0.7.2

func (j *BackupJob) IsKubernetes() bool

IsKubernetes reports whether the job is a kubernetes backup

func (*BackupJob) IsM365 added in v0.14.0

func (j *BackupJob) IsM365() bool

IsM365 reports whether the job is a Microsoft 365 backup

func (*BackupJob) IsPVE added in v0.9.5

func (j *BackupJob) IsPVE() bool

IsPVE reports whether the job is a Proxmox VE host backup

func (*BackupJob) NextRunString added in v0.6.2

func (j *BackupJob) NextRunString() string

NextRunString reports when the schedule fires next, in the schedule timezone with its abbreviation; empty when the job is manual, disabled, or the expression does not parse.

func (*BackupJob) Sanitize added in v0.6.0

func (j *BackupJob) Sanitize() *BackupJob

Sanitize redacts the stored database password (HasPassword tells whether one exists)

func (*BackupJob) Summary added in v0.6.0

func (j *BackupJob) Summary() string

Summary describes what the job backs up (paths, database target or cluster scope)

type BackupRun

type BackupRun struct {
	ID            uuid.UUID  `json:"id" db:"id"`
	JobID         uuid.UUID  `json:"job_id" db:"job_id"`
	AgentID       uuid.UUID  `json:"agent_id" db:"agent_id"`
	TargetID      uuid.UUID  `json:"target_id" db:"target_id"`
	WorkflowID    string     `json:"workflow_id" db:"workflow_id"`
	RunID         string     `json:"run_id" db:"run_id"`
	Status        RunStatus  `json:"status" db:"status"`
	StartTime     *time.Time `json:"start_time" db:"start_time"`
	EndTime       *time.Time `json:"end_time" db:"end_time"`
	BytesScanned  int64      `json:"bytes_scanned" db:"bytes_scanned"`
	BytesUploaded int64      `json:"bytes_uploaded" db:"bytes_uploaded"`
	DedupRatio    float64    `json:"dedup_ratio" db:"dedup_ratio"`
	ChunkCount    int        `json:"chunk_count" db:"chunk_count"`
	ErrorMessage  string     `json:"error_message" db:"error_message"`
	PBSSnapshotID string     `json:"pbs_snapshot_id" db:"pbs_snapshot_id"`
	// LogTail is the agent's recent log output captured when the run failed
	LogTail string `json:"log_tail,omitempty" db:"log_tail"`
	// KeyFingerprint names the encryption key the snapshot was written with ("" = plaintext)
	KeyFingerprint string `json:"key_fingerprint,omitempty" db:"key_fingerprint"`
	// Details is a type-specific JSON blob (archives / databases / PVCs) for the run
	// detail page; carries a top-level "type" discriminator. Empty for older runs.
	Details json.RawMessage `json:"details,omitempty" db:"details"`
	// Progress is the live state of a running backup (phase + per-item statuses),
	// updated mid-run and polled by the detail page.
	Progress  json.RawMessage `json:"progress,omitempty" db:"progress"`
	CreatedAt time.Time       `json:"created_at" db:"created_at"`

	// Joined fields
	JobName   string `json:"job_name,omitempty"`
	AgentName string `json:"agent_name,omitempty"`
}

BackupRun records a single execution of a backup job

func (*BackupRun) DurationString added in v0.6.0

func (r *BackupRun) DurationString() string

DurationString renders how long the run took (or has been running); "-" before start

type BackupTarget

type BackupTarget struct {
	ID         uuid.UUID `json:"id" db:"id"`
	Name       string    `json:"name" db:"name"`
	TargetType string    `json:"target_type" db:"target_type"` // "pbs"
	Endpoint   string    `json:"endpoint" db:"endpoint"`
	Datastore  string    `json:"datastore" db:"datastore"`
	Namespace  string    `json:"namespace" db:"namespace"`
	// AuthToken is the PBS API token in clear in memory; the repository seals it with
	// the server master key on write and opens it on read (column auth_token_encrypted)
	AuthToken   string    `json:"-" db:"auth_token_encrypted"`
	Fingerprint string    `json:"fingerprint" db:"fingerprint"`
	TLSVerify   bool      `json:"tls_verify" db:"tls_verify"`
	PxarFormat  string    `json:"pxar_format" db:"pxar_format"`
	CreatedAt   time.Time `json:"created_at" db:"created_at"`
	UpdatedAt   time.Time `json:"updated_at" db:"updated_at"`

	// Client-side encryption: EncryptionNone or EncryptionEncrypt. The key comes from
	// the target's key ring (KeyRingID); targets on one ring share the active key and
	// so deduplicate against each other on PBS. EncryptionKeyID, KeyFingerprint,
	// KeyCreatedAt and MasterPublicKey are the ring's active key and RSA public key,
	// joined on read.
	EncryptionMode  string     `json:"encryption_mode" db:"encryption_mode"`
	KeyRingID       *uuid.UUID `json:"key_ring_id,omitempty" db:"key_ring_id"`
	KeyRingName     string     `json:"key_ring_name,omitempty" db:"-"`
	EncryptionKeyID *uuid.UUID `json:"encryption_key_id,omitempty" db:"-"`
	MasterPublicKey string     `json:"master_public_key,omitempty" db:"-"`
	KeyFingerprint  string     `json:"key_fingerprint,omitempty" db:"-"`
	KeyCreatedAt    *time.Time `json:"key_created_at,omitempty" db:"-"`

	// HasToken reports whether an API token is stored (the token itself is never returned)
	HasToken bool   `json:"has_token" db:"-"`
	Labels   Labels `json:"labels"`
	// TokenCheck is the last check of the API token's privileges on PBS (nil: not
	// checked yet); anything but ok shows as a warning on the target
	TokenCheck *pbs.TokenCheck `json:"token_check"`
}

BackupTarget represents a remote backup repository such as Proxmox Backup Server

func (*BackupTarget) Encrypted added in v0.13.0

func (t *BackupTarget) Encrypted() bool

Encrypted reports whether runs to this target encrypt client-side

func (*BackupTarget) Sanitize added in v0.6.0

func (t *BackupTarget) Sanitize() *BackupTarget

Sanitize fills derived, API-safe fields

type DB

type DB struct {
	Pool *pgxpool.Pool
	// Sealer protects stored secrets (target API tokens, encryption keys) at rest.
	// nil (tests) stores them in clear.
	Sealer *secrets.Sealer
}

DB wraps the pgx connection pool and exposes repository operations

func New

func New(ctx context.Context, cfg config.DatabaseConfig) (*DB, error)

New creates a new database connection pool and applies migrations if enabled

func (*DB) BindTokenAgent added in v0.11.0

func (d *DB) BindTokenAgent(ctx context.Context, tokenID, agentID uuid.UUID) error

BindTokenAgent records the agent that enrolled with the token

func (*DB) BindingsFor added in v1.0.0

func (d *DB) BindingsFor(ctx context.Context, email string, groups, claims []string) ([]*RoleBinding, error)

BindingsFor returns the bindings of a user (email, case-insensitive; "" matches none), of the groups it belongs to and of its claim values ("<claim>=<value>"), with their roles' permissions

func (*DB) BootstrapAdmin added in v1.0.0

func (d *DB) BootstrapAdmin(ctx context.Context, email, role string) (bool, error)

BootstrapAdmin binds the built-in admin role globally to email when no binding exists yet (the first sign-in on a fresh instance). Reports whether it did.

func (*DB) BumpAgentTokenVersion

func (d *DB) BumpAgentTokenVersion(ctx context.Context, id uuid.UUID) (int, error)

BumpAgentTokenVersion invalidates every previously issued token for the agent and returns the new version that must be embedded in freshly issued tokens.

func (*DB) ClearAgentUpdateRequest added in v0.14.3

func (d *DB) ClearAgentUpdateRequest(ctx context.Context, id uuid.UUID) error

ClearAgentUpdateRequest drops a pending request (the agent reached the version)

func (*DB) CloneTarget added in v0.11.0

func (d *DB) CloneTarget(ctx context.Context, sourceID uuid.UUID, name, namespace, pxarFormat string) (*BackupTarget, error)

CloneTarget creates a new target from an existing one: same PBS endpoint, datastore, API token (the sealed column is copied as is), fingerprint, TLS setting, encryption mode, key ring and labels, and (unless overridden) pxar format, with a new name and namespace. Sharing the ring is the point of a clone: another namespace of the same datastore deduplicates against the source only with the same key.

func (*DB) Close

func (d *DB) Close()

Close closes the underlying pool

func (*DB) CountRunsWithKey added in v0.13.0

func (d *DB) CountRunsWithKey(ctx context.Context, fingerprint string) (int, error)

CountRunsWithKey counts runs whose snapshot was written with the key

func (*DB) CreateAPIKey

func (d *DB) CreateAPIKey(ctx context.Context, key *APIKey) error

func (*DB) CreateAdminSession added in v1.0.0

func (d *DB) CreateAdminSession(ctx context.Context, s *AdminSession) error

CreateAdminSession records a new session, and drops rows that expired over a week ago (they only matter while someone might still present the cookie)

func (*DB) CreateAgent

func (d *DB) CreateAgent(ctx context.Context, agent *Agent) error

func (*DB) CreateBinding added in v1.0.0

func (d *DB) CreateBinding(ctx context.Context, b *RoleBinding) error

func (*DB) CreateEnrollmentToken

func (d *DB) CreateEnrollmentToken(ctx context.Context, token *EnrollmentToken) error

func (*DB) CreateJob

func (d *DB) CreateJob(ctx context.Context, job *BackupJob) error

func (*DB) CreateKeyRing added in v0.14.12

func (d *DB) CreateKeyRing(ctx context.Context, r *KeyRing) error

CreateKeyRing stores an empty ring (the caller activates a key next)

func (*DB) CreateRole added in v1.0.0

func (d *DB) CreateRole(ctx context.Context, r *Role) error

CreateRole stores a custom role

func (*DB) CreateRun

func (d *DB) CreateRun(ctx context.Context, run *BackupRun) error

func (*DB) CreateTarget

func (d *DB) CreateTarget(ctx context.Context, target *BackupTarget) error

func (*DB) CreateTargetKey added in v0.13.0

func (d *DB) CreateTargetKey(ctx context.Context, k *TargetKey) error

CreateTargetKey stores a key (sealed) on a ring

func (*DB) CreateTenant added in v0.14.0

func (d *DB) CreateTenant(ctx context.Context, t *m365.Tenant) error

CreateTenant stores a tenant; the secret and private key are sealed

func (*DB) DeleteAgent

func (d *DB) DeleteAgent(ctx context.Context, id uuid.UUID) error

func (*DB) DeleteBinding added in v1.0.0

func (d *DB) DeleteBinding(ctx context.Context, id uuid.UUID) error

DeleteBinding removes a binding, refusing (ErrLastAdmin) to remove the last one that grants rbac:manage with an empty selector, which would lock everyone out

func (*DB) DeleteEnrollmentToken added in v0.6.0

func (d *DB) DeleteEnrollmentToken(ctx context.Context, id uuid.UUID) error

DeleteEnrollmentToken invalidates a token immediately (enrollment looks tokens up by hash, so a deleted row can never be consumed again)

func (*DB) DeleteJob

func (d *DB) DeleteJob(ctx context.Context, id uuid.UUID) error

func (*DB) DeleteKeyRing added in v0.14.12

func (d *DB) DeleteKeyRing(ctx context.Context, id uuid.UUID) error

DeleteKeyRing removes a ring and its keys; refused (ErrInUse) while a target uses it

func (*DB) DeleteRole added in v1.0.0

func (d *DB) DeleteRole(ctx context.Context, name string) error

DeleteRole removes a custom role nothing is bound to (ErrInUse otherwise)

func (*DB) DeleteTarget

func (d *DB) DeleteTarget(ctx context.Context, id uuid.UUID) error

func (*DB) DeleteTenant added in v0.14.0

func (d *DB) DeleteTenant(ctx context.Context, id uuid.UUID) error

DeleteTenant removes a tenant that no job references (ErrTenantInUse otherwise)

func (*DB) EnsureUnlimitedEnrollmentToken added in v0.14.3

func (d *DB) EnsureUnlimitedEnrollmentToken(ctx context.Context, tokenHash, name string) error

EnsureUnlimitedEnrollmentToken creates a never-expiring, unlimited-use token with the given hash unless it already exists (server --insecure-unlimited-dev-token)

func (*DB) GetAPIKeyByHash

func (d *DB) GetAPIKeyByHash(ctx context.Context, hash string) (*APIKey, error)

func (*DB) GetAgentAuthState

func (d *DB) GetAgentAuthState(ctx context.Context, id uuid.UUID) (*AgentAuthState, error)

GetAgentAuthState returns the token version and revocation state of an agent. Returns ErrNotFound if the agent does not exist (e.g. it was deleted).

func (*DB) GetAgentByID

func (d *DB) GetAgentByID(ctx context.Context, id uuid.UUID, scope Scope) (*Agent, error)

GetAgentByID loads an agent within scope (ErrNotFound outside it)

func (*DB) GetBinding added in v1.0.0

func (d *DB) GetBinding(ctx context.Context, id uuid.UUID) (*RoleBinding, error)

func (*DB) GetEnrollmentToken added in v0.11.0

func (d *DB) GetEnrollmentToken(ctx context.Context, id uuid.UUID, scope Scope) (*EnrollmentToken, error)

GetEnrollmentToken loads one token within scope (with the hostname of the agent that used it)

func (*DB) GetJobByID

func (d *DB) GetJobByID(ctx context.Context, id uuid.UUID, scope Scope) (*BackupJob, error)

GetJobByID loads a job within scope (ErrNotFound outside it)

func (*DB) GetKeyRing added in v0.14.12

func (d *DB) GetKeyRing(ctx context.Context, id uuid.UUID, scope Scope) (*KeyRing, error)

GetKeyRing loads a ring within scope (ErrNotFound outside it)

func (*DB) GetRole added in v1.0.0

func (d *DB) GetRole(ctx context.Context, name string) (*Role, error)

func (*DB) GetRunByID added in v0.3.1

func (d *DB) GetRunByID(ctx context.Context, id uuid.UUID, scope Scope) (*BackupRun, error)

GetRunByID returns a single run whose job is within scope

func (*DB) GetRunByWorkflowID added in v0.3.1

func (d *DB) GetRunByWorkflowID(ctx context.Context, workflowID string) (*BackupRun, error)

GetRunByWorkflowID returns the run record created for a Temporal workflow execution

func (*DB) GetTargetByID

func (d *DB) GetTargetByID(ctx context.Context, id uuid.UUID, scope Scope) (*BackupTarget, error)

GetTargetByID loads a target within scope (ErrNotFound outside it)

func (*DB) GetTargetKey added in v0.13.0

func (d *DB) GetTargetKey(ctx context.Context, id uuid.UUID) (*TargetKey, error)

GetTargetKey loads one key with its material

func (*DB) GetTenantByID added in v0.14.0

func (d *DB) GetTenantByID(ctx context.Context, id uuid.UUID, scope Scope) (*m365.Tenant, error)

GetTenantByID returns the tenant within scope with its credentials opened

func (*DB) HasSealedSecrets added in v0.14.12

func (d *DB) HasSealedSecrets(ctx context.Context) (bool, error)

HasSealedSecrets reports whether any stored secret is already sealed, i.e. a master key existed before. A freshly generated key then means the key file was lost.

func (*DB) LatestRunByJob added in v0.11.2

func (d *DB) LatestRunByJob(ctx context.Context) (map[uuid.UUID]*JobLastRun, error)

LatestRunByJob returns the newest run of every job that has one

func (*DB) ListAPIKeys

func (d *DB) ListAPIKeys(ctx context.Context) ([]*APIKey, error)

func (*DB) ListActiveAdminSessions added in v1.0.0

func (d *DB) ListActiveAdminSessions(ctx context.Context) ([]*AdminSession, error)

ListActiveAdminSessions returns the sessions still valid, most recently active first

func (*DB) ListAgents

func (d *DB) ListAgents(ctx context.Context, scope Scope) ([]*Agent, error)

ListAgents lists the agents within scope

func (*DB) ListAudit added in v1.0.0

func (d *DB) ListAudit(ctx context.Context, f AuditFilter, scope Scope) ([]*AuditEntry, error)

ListAudit returns the newest entries within scope (on the labels the object had at the time) matching the filter

func (*DB) ListBindings added in v1.0.0

func (d *DB) ListBindings(ctx context.Context) ([]*RoleBinding, error)

func (*DB) ListEnrollmentTokens

func (d *DB) ListEnrollmentTokens(ctx context.Context, scope Scope) ([]*EnrollmentToken, error)

ListEnrollmentTokens lists the tokens within scope

func (*DB) ListJobs

func (d *DB) ListJobs(ctx context.Context, scope Scope) ([]*BackupJob, error)

ListJobs lists the jobs within scope

func (*DB) ListKeyRings added in v0.14.12

func (d *DB) ListKeyRings(ctx context.Context, scope Scope) ([]*KeyRing, error)

ListKeyRings lists the rings within scope

func (*DB) ListRingKeys added in v0.14.12

func (d *DB) ListRingKeys(ctx context.Context, ringID uuid.UUID) ([]*TargetKey, error)

ListRingKeys lists a ring's keys (newest first) without their material

func (*DB) ListRoles added in v1.0.0

func (d *DB) ListRoles(ctx context.Context) ([]*Role, error)

func (*DB) ListRuns

func (d *DB) ListRuns(ctx context.Context, limit int, scope Scope) ([]*BackupRun, error)

ListRuns lists the newest runs whose job is within scope. Runs have no labels of their own: a run is visible exactly when its job is.

func (*DB) ListRunsByAgent added in v0.12.0

func (d *DB) ListRunsByAgent(ctx context.Context, agentID uuid.UUID, limit int, scope Scope) ([]*BackupRun, error)

ListRunsByAgent is ListRuns restricted to one agent (the agent status page)

func (*DB) ListSeenSubjects added in v1.0.0

func (d *DB) ListSeenSubjects(ctx context.Context) ([]*SeenSubject, error)

ListSeenSubjects returns what sign-ins have shown, newest first

func (*DB) ListTargets

func (d *DB) ListTargets(ctx context.Context, scope Scope) ([]*BackupTarget, error)

ListTargets lists the targets within scope

func (*DB) ListTenants added in v0.14.0

func (d *DB) ListTenants(ctx context.Context, scope Scope) ([]*m365.Tenant, error)

ListTenants returns the tenants within scope ordered by name

func (*DB) MarkRunStarted added in v0.3.1

func (d *DB) MarkRunStarted(ctx context.Context, id uuid.UUID, temporalRunID string, startedAt time.Time) error

MarkRunStarted moves a pending run to running once the workflow has prepared the session

func (*DB) MergeAgents added in v0.10.1

func (d *DB) MergeAgents(ctx context.Context, from, into uuid.UUID) (int64, int64, error)

MergeAgents moves every job and run of the agent from onto the agent into and deletes from, in one transaction. Deleting an agent cascades to its jobs and runs, so the move must come first. It returns the number of jobs and runs moved.

func (*DB) Migrate

func (d *DB) Migrate(ctx context.Context) error

Migrate applies all pending schema migrations to PostgreSQL. Each migration runs in its own transaction and is recorded in schema_migrations so it is applied exactly once.

func (*DB) PruneAudit added in v1.0.0

func (d *DB) PruneAudit(ctx context.Context, before time.Time, export func([]*AuditEntry) error) (int, error)

PruneAudit deletes entries older than before in batches. Each batch is handed to export first (nil: no export) and deleted only when export succeeded, in the same transaction, so a row is never gone without having reached the sink. It returns how many rows were deleted; when another server holds the prune lock it does nothing.

func (*DB) RecordSignIn added in v1.0.0

func (d *DB) RecordSignIn(ctx context.Context, email string, groups, claims []string) error

RecordSignIn remembers what a successful sign-in showed: the verified email ("" skips it), every group and every claim value

func (*DB) RequestAgentUpdate added in v0.14.3

func (d *DB) RequestAgentUpdate(ctx context.Context, id uuid.UUID) error

RequestAgentUpdate asks the agent to update on its next heartbeat (the web UI's "Update now"); a previous error is cleared so the retry starts clean

func (*DB) RetireTargetKey added in v0.13.0

func (d *DB) RetireTargetKey(ctx context.Context, id uuid.UUID) error

RetireTargetKey marks a key as no longer used for new snapshots

func (*DB) RevokeAPIKey

func (d *DB) RevokeAPIKey(ctx context.Context, id uuid.UUID) error

func (*DB) RevokeAdminSession added in v1.0.0

func (d *DB) RevokeAdminSession(ctx context.Context, id uuid.UUID, by string) (*AdminSession, error)

RevokeAdminSession ends one valid session (ErrNotFound when none)

func (*DB) RevokeAgent

func (d *DB) RevokeAgent(ctx context.Context, id uuid.UUID) error

RevokeAgent marks the agent as revoked; its tokens stop validating immediately

func (*DB) RevokeUserAdminSessions added in v1.0.0

func (d *DB) RevokeUserAdminSessions(ctx context.Context, email, by string) (int, error)

RevokeUserAdminSessions ends every valid session of an email (case-insensitive) and returns how many

func (*DB) ScopedBindingsOfRole added in v1.0.0

func (d *DB) ScopedBindingsOfRole(ctx context.Context, role string) (int, error)

ScopedBindingsOfRole counts bindings and live API keys of a role with a non-empty selector (a role that gains a global-only permission must have none)

func (*DB) SealLegacySecrets added in v0.13.0

func (d *DB) SealLegacySecrets(ctx context.Context) (int, error)

SealLegacySecrets rewrites secrets stored in clear before the master key existed. It returns how many rows were sealed. Safe to run at every start.

func (*DB) SetAgentAutoUpdate added in v0.14.3

func (d *DB) SetAgentAutoUpdate(ctx context.Context, id uuid.UUID, enabled bool) error

SetAgentAutoUpdate flips the per-agent auto-update opt-in

func (*DB) SetAgentDebugLogging added in v0.6.2

func (d *DB) SetAgentDebugLogging(ctx context.Context, id uuid.UUID, enabled bool) error

SetAgentDebugLogging flips the per-agent debug toggle (delivered on the next heartbeat)

func (*DB) SetAgentInventoryDetail added in v0.12.0

func (d *DB) SetAgentInventoryDetail(ctx context.Context, id uuid.UUID, detail []byte) error

SetAgentInventoryDetail stores the on-demand full inventory

func (*DB) SetAgentLabels added in v1.0.0

func (d *DB) SetAgentLabels(ctx context.Context, id uuid.UUID, labels Labels) error

SetAgentLabels replaces an agent's labels

func (*DB) SetRingActiveKey added in v0.14.12

func (d *DB) SetRingActiveKey(ctx context.Context, ringID uuid.UUID, keyID *uuid.UUID) error

SetRingActiveKey points the ring at a key (nil: no active key)

func (*DB) SetRunItems added in v0.9.0

func (d *DB) SetRunItems(ctx context.Context, runID uuid.UUID, updatedAt string, items map[string][]byte) error

SetRunItems merges per-item statuses into an active run's progress. Each item is written at progress.items.<key> so concurrent per-item updates never clobber.

func (*DB) SetRunPhase added in v0.9.0

func (d *DB) SetRunPhase(ctx context.Context, runID uuid.UUID, phase, updatedAt string) error

SetRunPhase records the current phase of an active run (jsonb_set: no read-modify-write)

func (*DB) SetRunStatus added in v0.3.1

func (d *DB) SetRunStatus(ctx context.Context, id uuid.UUID, status RunStatus, message string, endTime *time.Time) error

SetRunStatus updates the status (and optionally end time / message) of a run

func (*DB) SetTargetEncryption added in v0.13.0

func (d *DB) SetTargetEncryption(ctx context.Context, targetID uuid.UUID, mode string, ringID *uuid.UUID) error

SetTargetEncryption switches a target's mode and key ring in one statement; mode none keeps the ring attached so re-enabling reuses it (and old snapshots keep their keys)

func (*DB) SetTargetTokenCheck added in v1.0.0

func (d *DB) SetTargetTokenCheck(ctx context.Context, id uuid.UUID, check *pbs.TokenCheck) (string, error)

SetTargetTokenCheck stores a token check result and returns the previous status ("" when the target was never checked)

func (*DB) SyncBuiltinRoles added in v1.0.0

func (d *DB) SyncBuiltinRoles(ctx context.Context, roles map[string][]string, descriptions map[string]string) error

SyncBuiltinRoles writes the built-in roles' permissions (called at every start, so a new permission reaches the built-ins without a migration)

func (*DB) TouchAPIKey

func (d *DB) TouchAPIKey(ctx context.Context, id uuid.UUID) error

TouchAPIKey records the last use of a key (best-effort, called on successful auth)

func (*DB) TouchAdminSession added in v1.0.0

func (d *DB) TouchAdminSession(ctx context.Context, id string) (bool, error)

TouchAdminSession reports whether the session is still valid (exists, not revoked, not expired) and records the activity

func (*DB) UpdateAgentHeartbeat

func (d *DB) UpdateAgentHeartbeat(ctx context.Context, id uuid.UUID, status AgentStatus, caps AgentCapabilities) (HeartbeatState, error)

UpdateAgentHeartbeat records the heartbeat (status, capabilities, version) and returns what the response needs. An update error from the agent consumes a pending "update now" request so a failed manual update is not retried every heartbeat.

func (*DB) UpdateJob added in v0.6.0

func (d *DB) UpdateJob(ctx context.Context, job *BackupJob) error

UpdateJob replaces the editable fields of a job

func (*DB) UpdateKeyRing added in v0.14.12

func (d *DB) UpdateKeyRing(ctx context.Context, r *KeyRing) error

UpdateKeyRing writes a ring's name, master public key and labels

func (*DB) UpdateRole added in v1.0.0

func (d *DB) UpdateRole(ctx context.Context, r *Role) error

UpdateRole replaces a custom role's description and permissions (built-ins: ErrNotFound)

func (*DB) UpdateRun

func (d *DB) UpdateRun(ctx context.Context, run *BackupRun) error

func (*DB) UpdateTarget added in v0.9.0

func (d *DB) UpdateTarget(ctx context.Context, target *BackupTarget) error

UpdateTarget replaces a target's editable fields (name, endpoint, datastore, namespace, token, fingerprint, TLS, format); the encryption mode and key ring change only through SetTargetEncryption. The caller supplies the final values, including AuthToken (kept unchanged by loading the existing row first when the operator leaves the token field blank).

func (*DB) UpdateTenant added in v0.14.0

func (d *DB) UpdateTenant(ctx context.Context, t *m365.Tenant) error

UpdateTenant replaces every editable field (the caller keeps the stored credential when the request carries none)

func (*DB) UpsertAgent

func (d *DB) UpsertAgent(ctx context.Context, agent *Agent) error

func (*DB) ValidateAndConsumeToken

func (d *DB) ValidateAndConsumeToken(ctx context.Context, tokenHash string) (*EnrollmentToken, error)

func (*DB) WriteAudit added in v1.0.0

func (d *DB) WriteAudit(ctx context.Context, e *AuditEntry) error

type EnrollmentToken

type EnrollmentToken struct {
	ID        uuid.UUID `json:"id" db:"id"`
	TokenHash string    `json:"-" db:"token_hash"`
	Name      string    `json:"name" db:"name"`
	MaxUses   int       `json:"max_uses" db:"max_uses"`
	UsesCount int       `json:"uses_count" db:"uses_count"`
	ExpiresAt time.Time `json:"expires_at" db:"expires_at"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`
	// AgentID is the agent that last enrolled with this token (onboarding waits for it)
	AgentID *uuid.UUID `json:"agent_id,omitempty" db:"agent_id"`
	// AgentHostname is joined for display; empty when no agent used the token
	AgentHostname string `json:"agent_hostname,omitempty" db:"-"`
	// Labels are copied onto every agent that enrolls with the token
	Labels Labels `json:"labels"`
}

EnrollmentToken represents a one-time or multi-use token for agent onboarding

func (*EnrollmentToken) Status added in v0.6.0

func (t *EnrollmentToken) Status() string

Status describes whether the token can still be used

type HeartbeatState added in v0.14.3

type HeartbeatState struct {
	DebugLogging    bool
	AutoUpdate      bool
	UpdateRequested bool
	OS, Arch        string
}

HeartbeatState is what the heartbeat response needs from the agent row

type JobLastRun added in v0.11.2

type JobLastRun struct {
	RunID  uuid.UUID `json:"run_id"`
	Status RunStatus `json:"status"`
	At     time.Time `json:"at"`
}

JobLastRun is the newest run of a job, for list views

type KeyRing added in v0.14.12

type KeyRing struct {
	ID              uuid.UUID  `json:"id"`
	Name            string     `json:"name"`
	ActiveKeyID     *uuid.UUID `json:"active_key_id,omitempty"`
	MasterPublicKey string     `json:"master_public_key,omitempty"`
	CreatedAt       time.Time  `json:"created_at"`
	UpdatedAt       time.Time  `json:"updated_at"`
	CreatedBy       string     `json:"created_by,omitempty"`
	// KeyFingerprint / KeyCreatedAt describe the active key, Targets names the targets
	// attached to the ring (joined on read)
	KeyFingerprint string     `json:"key_fingerprint,omitempty"`
	KeyCreatedAt   *time.Time `json:"key_created_at,omitempty"`
	Targets        []string   `json:"targets"`
	Labels         Labels     `json:"labels"`
}

KeyRing is a set of encryption keys shared by the targets attached to it. Targets on one ring encrypt with the same active key and therefore deduplicate against each other on PBS (one datastore, many namespaces); targets on different rings never do. Rotation retires the active key for every target on the ring at once. The optional RSA master public key wraps the active key into every snapshot for recovery.

type Labels added in v1.0.0

type Labels map[string]string

Labels are key=value pairs on agents, targets, jobs, tenants, key rings and enrollment tokens. Access bindings select objects by them.

func (Labels) Contains added in v1.0.0

func (l Labels) Contains(sel Labels) bool

Contains reports whether every entry of sel is present in l (equality, AND)

func (Labels) Equal added in v1.0.0

func (l Labels) Equal(o Labels) bool

Equal reports whether both hold the same entries (nil equals empty)

func (Labels) JSON added in v1.0.0

func (l Labels) JSON() string

JSON is the jsonb text of the labels; pgx sends a string parameter to a jsonb column as raw JSON

func (Labels) OrEmpty added in v1.0.0

func (l Labels) OrEmpty() Labels

OrEmpty returns a non-nil map (the columns are NOT NULL)

func (Labels) String added in v1.0.0

func (l Labels) String() string

String renders key=value pairs sorted by key, comma separated

type Migration

type Migration struct {
	Version int
	Name    string
	SQL     string
}

Migration is a single embedded SQL migration file

func LoadMigrations

func LoadMigrations() ([]Migration, error)

LoadMigrations returns the embedded migrations ordered by version. Files are named NNN_description.sql; the numeric prefix is the version.

type Requirement added in v1.0.0

type Requirement struct {
	Key    string   `json:"key"`
	Op     string   `json:"op"`
	Values []string `json:"values,omitempty"`
}

Requirement is one clause of a selector

func (Requirement) Matches added in v1.0.0

func (r Requirement) Matches(l Labels) bool

Matches reports whether labels satisfy the requirement

func (Requirement) String added in v1.0.0

func (r Requirement) String() string

type Role added in v1.0.0

type Role struct {
	Name        string    `json:"name"`
	Builtin     bool      `json:"builtin"`
	Description string    `json:"description"`
	Permissions []string  `json:"permissions"`
	Bindings    int       `json:"bindings"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

Role is a named set of permissions. Built-in roles are defined in code and rewritten at every start; they cannot be edited, only cloned.

type RoleBinding added in v1.0.0

type RoleBinding struct {
	ID        uuid.UUID `json:"id"`
	Kind      string    `json:"kind"`
	Subject   string    `json:"subject"`
	Role      string    `json:"role"`
	Selector  Selector  `json:"selector"`
	CreatedBy string    `json:"created_by"`
	CreatedAt time.Time `json:"created_at"`
	// Permissions of the role (joined)
	Permissions []string `json:"permissions,omitempty"`
	// LastSeen is the subject's last appearance at a sign-in (nil: never seen); Stale
	// flags one not seen for StaleAfter
	LastSeen *time.Time `json:"last_seen"`
	Stale    bool       `json:"stale"`
}

RoleBinding grants a role to a user (verified OIDC email), a group (groups claim value) or a claim value on the objects its selector matches (empty: everything)

type RunStatus

type RunStatus string

RunStatus represents the state of a backup run

const (
	RunStatusPending   RunStatus = "pending"
	RunStatusRunning   RunStatus = "running"
	RunStatusCompleted RunStatus = "completed"
	RunStatusFailed    RunStatus = "failed"
	// RunStatusCancelling: cancellation requested, waiting for the agent to stop
	RunStatusCancelling RunStatus = "cancelling"
	RunStatusCancelled  RunStatus = "cancelled"
)

func (RunStatus) IsActive added in v0.3.1

func (s RunStatus) IsActive() bool

IsActive reports whether a run can still be cancelled

type Scope added in v1.0.0

type Scope struct {
	All       bool
	Selectors []Selector
}

Scope is the set of objects one permission reaches for a principal: everything (All), nothing (zero value), or the objects matched by any of the selectors. It is the only input to both forms of the access decision: Matches for an object in hand and SQL for queries, so the two cannot drift apart.

func (Scope) Empty added in v1.0.0

func (s Scope) Empty() bool

Empty reports whether the scope reaches nothing

func (Scope) Matches added in v1.0.0

func (s Scope) Matches(l Labels) bool

Matches reports whether an object with these labels is in scope

func (Scope) SQL added in v1.0.0

func (s Scope) SQL(col string, args []any) (string, []any)

SQL renders the scope as a WHERE fragment on a jsonb labels column, appending its parameters to args: TRUE, FALSE, or (selector OR selector ...)

type SeenSubject added in v1.0.0

type SeenSubject struct {
	Kind     string    `json:"kind"`
	Value    string    `json:"value"`
	LastSeen time.Time `json:"last_seen"`
}

SeenSubject is an email, group or claim value a sign-in has shown

type Selector added in v1.0.0

type Selector []Requirement

Selector picks objects by their labels, Kubernetes style. Every requirement must hold (AND); an empty selector matches everything. Written and stored as a string:

team=web, env in (prod, stage), env!=dev, tier notin (frontend), managed, !legacy

func MustSelector added in v1.0.0

func MustSelector(text string) Selector

MustSelector parses a selector known to be valid (tests, constants); it panics otherwise

func ParseSelector added in v1.0.0

func ParseSelector(text string) (Selector, error)

ParseSelector reads the string form. Keys and values follow the label syntax (ValidateLabels); at most MaxLabels requirements.

func SelectorFromLabels added in v1.0.0

func SelectorFromLabels(l Labels) Selector

SelectorFromLabels is the equality selector for a label set (key=value for each)

func (Selector) Equal added in v1.0.0

func (s Selector) Equal(o Selector) bool

Equal compares canonical forms

func (Selector) MarshalJSON added in v1.0.0

func (s Selector) MarshalJSON() ([]byte, error)

MarshalJSON writes the canonical string

func (Selector) Matches added in v1.0.0

func (s Selector) Matches(l Labels) bool

Matches reports whether labels satisfy every requirement

func (Selector) Narrows added in v1.0.0

func (s Selector) Narrows(wider Selector) bool

Narrows reports whether everything s matches is also matched by wider: every requirement of wider is implied by some requirement of s. Sufficient, not necessary: an unusual combination that would be narrower can be refused, never the other way round.

func (*Selector) Scan added in v1.0.0

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

Scan reads the stored canonical string

func (Selector) String added in v1.0.0

func (s Selector) String() string

String is the canonical form: requirements sorted, values sorted and unique. Two selectors with the same meaning in the same clauses print the same, which is what the database's uniqueness and empty checks compare.

func (*Selector) UnmarshalJSON added in v1.0.0

func (s *Selector) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts the string form, or an object of key: value pairs (the equality-only form API clients used before set-based selectors)

type TargetKey added in v0.13.0

type TargetKey struct {
	ID          uuid.UUID  `json:"id"`
	RingID      uuid.UUID  `json:"ring_id"`
	Key         [32]byte   `json:"-"`
	Fingerprint string     `json:"fingerprint"`
	CreatedAt   time.Time  `json:"created_at"`
	RetiredAt   *time.Time `json:"retired_at,omitempty"`
	CreatedBy   string     `json:"created_by,omitempty"`
}

TargetKey is one encryption key of a key ring. Key is in clear in memory only; the repository seals it with the server master key (column key_sealed). A retired key is kept because the snapshots written with it still need it.

Jump to

Keyboard shortcuts

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