database

package
v0.0.0-...-1232c89 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 47 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ProbeOutcomeStatusSuccess = "success"
	ProbeOutcomeStatusFailure = "failure"
)

Outcome enum stored in connection_probe_outcomes.outcome.

View Source
const (
	// LabelKeyNameMaxLength is the maximum length for the name portion of a label key
	LabelKeyNameMaxLength = 63

	// LabelKeyPrefixMaxLength is the maximum length for the optional prefix portion of a label key
	LabelKeyPrefixMaxLength = 253

	// LabelValueMaxLength is the maximum length for a label value
	LabelValueMaxLength = 63

	// ApxyLabelValueMaxLength is the maximum length for a label value stored
	// under an apxy/-prefixed key. System-managed labels such as
	// apxy/<rt>/-/ns can hold a namespace path that may exceed the standard
	// LabelValueMaxLength. User-supplied values are still capped at
	// LabelValueMaxLength via ValidateLabelValue.
	ApxyLabelValueMaxLength = 253

	// ApxyReservedPrefix is the reserved label-key prefix for system-managed
	// labels (implicit identifier labels and parent carry-forward labels).
	// User-supplied label keys may not begin with this prefix.
	ApxyReservedPrefix = "apxy/"

	// ApxyImplicitSegment is the segment used inside apxy/ keys to mark an
	// implicit identifier label, e.g. apxy/<rt>/-/id.
	ApxyImplicitSegment = "-"
)

Kubernetes-style label restrictions

View Source
const ActorTable = "actors"
View Source
const (
	// AnnotationsTotalMaxSize is the maximum total size of all annotations (keys + values) in bytes.
	AnnotationsTotalMaxSize = 256 * 1024 // 256KB
)
View Source
const ConnectionCredentialsTable = "connection_credentials"
View Source
const ConnectionProbeOutcomesTable = "connection_probe_outcomes"
View Source
const ConnectionsTable = "connections"
View Source
const ConnectorVersionsTable = "connector_versions"
View Source
const DataEncryptionKeysTable = "data_encryption_keys"
View Source
const EncryptionKeyVersionsTable = "encryption_key_versions"
View Source
const EncryptionKeysTable = "encryption_keys"
View Source
const MigrateMutexKeyName = "db-migrate-lock"

MigrateMutexKeyName is the key that can be used when locking to perform a migration in redis.

View Source
const NamespaceLabelToken = "ns"

NamespaceLabelToken is the <rt> token used in apxy/ keys that reference a namespace. Namespaces are path-keyed (not apid-keyed) so the token is hard-coded rather than derived from an apid prefix.

View Source
const NamespacesTable = "namespaces"
View Source
const OAuth2AccessTokenExpiryBuffer = 30 * time.Second
View Source
const OAuth2TokensTable = "oauth2_tokens"
View Source
const RateLimitsTable = "rate_limits"
View Source
const UsedNoncesTable = "used_nonces"

Variables

View Source
var ErrDuplicate = errors.New("duplicate record")

ErrDuplicate is returned when a database operation that is expected to be unique fails because a duplicate record already exists.

View Source
var ErrNamespaceDoesNotExist = errors.New("namespace does not exist")

ErrNamespaceDoesNotExist is returned when a namespace does not exist for a resource that is attempting to be created in the specified namespace.

View Source
var ErrNotFound = errors.New("record not found")

ErrNotFound is returned when a database operation that is expected to find a record does not find the record.

View Source
var ErrProtected = errors.New("resource is protected")

ErrProtected is returned when an operation is attempted on a protected resource that cannot be modified in the requested way.

View Source
var ErrViolation = errors.New("database constraint violation")

ErrViolation is returned when a constraint in the database is violated (e.g. multiple rows with the same ID) after an operation that should have been unique.

View Source
var GlobalEncryptionKeyID = apid.ID("ek_global")

GlobalEncryptionKeyID is the ID of the global encryption key created by migration. It is the root of the encryption key hierarchy and must not be deleted.

Functions

func ApidPrefixToLabelToken

func ApidPrefixToLabelToken(p apid.Prefix) string

ApidPrefixToLabelToken returns the label-key token associated with an apid prefix. It strips the trailing underscore so e.g. "cxr_" becomes "cxr" and "cxn_" becomes "cxn". Used to build apxy/ keys whose <rt> segment matches the resource's id prefix.

func BuildLabelSelectorFromMap

func BuildLabelSelectorFromMap(labels map[string]string) string

BuildLabelSelectorFromMap creates a label selector string from key-value pairs. Keys are sorted for deterministic output. Example: {"type": "salesforce", "env": "prod"} -> "env=prod,type=salesforce"

func IsValidActorOrderByField

func IsValidActorOrderByField[T string | ActorOrderByField](field T) bool

IsValidActorOrderByField checks if the given value is a valid ActorOrderByField.

func IsValidConnectionHealthState

func IsValidConnectionHealthState[T string | ConnectionHealthState](state T) bool

func IsValidConnectionOrderByField

func IsValidConnectionOrderByField[T string | ConnectionOrderByField](field T) bool

func IsValidConnectionState

func IsValidConnectionState[T string | ConnectionState](state T) bool

func IsValidConnectorOrderByField

func IsValidConnectorOrderByField[T string | ConnectorOrderByField](field T) bool

func IsValidConnectorVersionOrderByField

func IsValidConnectorVersionOrderByField[T string | ConnectorVersionOrderByField](field T) bool

func IsValidConnectorVersionState

func IsValidConnectorVersionState[T string | ConnectorVersionState](state T) bool

func IsValidEncryptionKeyOrderByField

func IsValidEncryptionKeyOrderByField[T string | EncryptionKeyOrderByField](field T) bool

func IsValidEncryptionKeyState

func IsValidEncryptionKeyState[T string | EncryptionKeyState](state T) bool

func IsValidNamespaceOrderByField

func IsValidNamespaceOrderByField[T string | NamespaceOrderByField](field T) bool

func IsValidNamespaceState

func IsValidNamespaceState[T string | NamespaceState](state T) bool

func IsValidRateLimitOrderByField

func IsValidRateLimitOrderByField[T string | RateLimitOrderByField](field T) bool

func RegisterEncryptedField

func RegisterEncryptedField(reg EncryptedFieldRegistration)

RegisterEncryptedField adds an encrypted field registration to the global registry. Panics if the registration is invalid. Must be called during init().

func ValidateAnnotationKey

func ValidateAnnotationKey(key string) error

ValidateAnnotationKey validates a single annotation key. Annotation keys follow the same format as label keys.

func ValidateAnnotationValue

func ValidateAnnotationValue(_ string) error

ValidateAnnotationValue validates a single annotation value. Annotation values have no format restriction — any string is allowed. Individual value size is not restricted; only the total annotations size is checked.

func ValidateAnnotations

func ValidateAnnotations(annotations map[string]string) error

ValidateAnnotations validates all annotations in a map.

func ValidateApxyLabelValue

func ValidateApxyLabelValue(value string) error

ValidateApxyLabelValue validates a label value stored under an apxy/-prefixed key. It allows up to ApxyLabelValueMaxLength characters so namespace paths (e.g. root.foo.bar.baz...) can fit. Character rules are otherwise the same as ValidateLabelValue.

func ValidateLabelKey

func ValidateLabelKey(key string) error

ValidateLabelKey validates a single label key.

Two grammars are accepted:

  1. Standard Kubernetes-style key: [prefix/]name - prefix (optional): valid DNS subdomain, max 253 characters - name (required): 1-63 characters, must start/end with alphanumeric, may contain '-', '_', '.'

  2. Reserved apxy/ multi-segment key: apxy/<seg>(/<seg>)*/<name> - each <seg> is a DNS-label-like token or the literal "-" sentinel - <name> follows the standard name rule above - total prefix portion (everything before the final '/') still capped at LabelKeyPrefixMaxLength characters

This function accepts apxy/ keys; user-input call sites should use ValidateUserLabelKey to additionally reject the reserved namespace.

func ValidateLabelValue

func ValidateLabelValue(value string) error

ValidateLabelValue validates a single label value according to Kubernetes restrictions. - 0-63 characters (can be empty) - if non-empty: must start and end with alphanumeric, may contain alphanumeric, '-', '_', '.'

func ValidateLabels

func ValidateLabels(labels map[string]string) error

ValidateLabels validates all labels in a map. apxy/-prefixed keys are accepted (use ValidateUserLabels at user-input boundaries instead) and values stored under apxy/ keys are validated against the longer ApxyLabelValueMaxLength cap.

func ValidateUserLabelDeletionKeys

func ValidateUserLabelDeletionKeys(keys []string) error

ValidateUserLabelDeletionKeys validates a list of keys passed to a user-facing label-deletion endpoint. Keys must be well-formed and must not reference the reserved apxy/ namespace.

func ValidateUserLabelKey

func ValidateUserLabelKey(key string) error

ValidateUserLabelKey validates a label key supplied directly by an end user. In addition to the rules of ValidateLabelKey, it rejects any key in the reserved apxy/ namespace — those keys are managed by the system and may not be set, modified, or deleted through user-input endpoints.

func ValidateUserLabels

func ValidateUserLabels(labels map[string]string) error

ValidateUserLabels validates a labels map supplied by a user. It applies the same key/value rules as ValidateLabels but rejects any key in the reserved apxy/ namespace.

Types

type Actor

type Actor struct {
	Id           apid.ID
	Namespace    string
	ExternalId   string
	Permissions  Permissions
	Labels       Labels
	Annotations  Annotations
	EncryptedKey *encfield.EncryptedField
	CreatedAt    time.Time
	UpdatedAt    time.Time
	EncryptedAt  *time.Time
	DeletedAt    *time.Time
}

Actor is some entity taking action within the system.

func (*Actor) CanSelfSign

func (a *Actor) CanSelfSign() bool

CanSelfSign returns true if this actor has an encrypted key and can self-sign requests

func (*Actor) GetAnnotations

func (a *Actor) GetAnnotations() map[string]string

func (*Actor) GetEncryptedKey

func (a *Actor) GetEncryptedKey() *encfield.EncryptedField

func (*Actor) GetExternalId

func (a *Actor) GetExternalId() string

func (*Actor) GetId

func (a *Actor) GetId() apid.ID

func (*Actor) GetLabels

func (a *Actor) GetLabels() map[string]string

func (*Actor) GetNamespace

func (a *Actor) GetNamespace() string

func (*Actor) GetPermissions

func (a *Actor) GetPermissions() []aschema.Permission

type ActorOrderByField

type ActorOrderByField string
const (
	ActorOrderByCreatedAt  ActorOrderByField = "created_at"
	ActorOrderByUpdatedAt  ActorOrderByField = "updated_at"
	ActorOrderByNamespace  ActorOrderByField = "namespace"
	ActorOrderByExternalId ActorOrderByField = "external_id"
	ActorOrderByDeletedAt  ActorOrderByField = "deleted_at"
)

type Annotations

type Annotations map[string]string

Annotations is a map of key-value pairs similar to Kubernetes annotations. Keys follow the same format as label keys ([prefix/]name). Values have no format restriction — any string is allowed. Total size of all annotations (keys + values) must not exceed 256KB.

func (Annotations) Copy

func (a Annotations) Copy() Annotations

Copy returns a deep copy of the annotations.

func (Annotations) Get

func (a Annotations) Get(key string) (string, bool)

Get returns the value for an annotation key, and whether the key exists.

func (Annotations) Has

func (a Annotations) Has(key string) bool

Has returns true if the annotation key exists.

func (*Annotations) Scan

func (a *Annotations) Scan(value interface{}) error

Scan implements the sql.Scanner interface for Annotations

func (Annotations) Validate

func (a Annotations) Validate() error

Validate validates all annotations.

func (Annotations) Value

func (a Annotations) Value() (driver.Value, error)

Value implements the driver.Valuer interface for Annotations

type ApiKeyCredential

type ApiKeyCredential struct {
	Id                   apid.ID
	ConnectionId         apid.ID                  // FK to Connection; not enforced by DB
	EncryptedCredentials encfield.EncryptedField  // Opaque encrypted credential blob
	PlacementSnapshot    *cschema.ApiKeyPlacement // API-key placement config at submission time
	CreatedByActorId     *apid.ID                 // Actor who submitted (or rotated to) this credential
	LastValidatedAt      *time.Time               // Most recent successful probe against this credential
	CreatedAt            time.Time
	EncryptedAt          *time.Time
	DeletedAt            *time.Time
}

ApiKeyCredential is one row in the connection_credentials table — an encrypted credential blob submitted by a user for a connection. API-key connections store api key material here; OAuth2 client_credentials connections store client id / secret material here. The encrypted_credentials column stores a single opaque encrypted blob; the substructure inside is decided by the encrypt/decrypt layer that owns the plaintext shape — the database is agnostic to it.

Rotation produces a new row and soft-deletes the prior, so the history of credentials is preserved. At most one row per connection has deleted_at IS NULL at any given moment.

func (*ApiKeyCredential) Validate

func (c *ApiKeyCredential) Validate() error

type ApiKeyCredentialPlaintext

type ApiKeyCredentialPlaintext struct {
	ApiKey   string `json:"api_key"`
	Username string `json:"username,omitempty"`
}

ApiKeyCredentialPlaintext is the canonical plaintext shape stored, encrypted, inside ApiKeyCredential.EncryptedCredentials. Defined here so callers that encrypt (the connection-initiate submit handler) and callers that decrypt (the api-key proxy) share one contract. The database itself never inspects the plaintext — it only stores the encrypted blob.

type Connection

type Connection struct {
	Id                     apid.ID
	Namespace              string
	State                  ConnectionState
	HealthState            ConnectionHealthState
	ConnectorId            apid.ID
	ConnectorVersion       uint64
	Labels                 Labels
	Annotations            Annotations
	EncryptedConfiguration *encfield.EncryptedField
	EncryptedAt            *time.Time
	SetupStep              *cschema.SetupStep
	SetupError             *string
	CreatedAt              time.Time
	UpdatedAt              time.Time
	DeletedAt              *time.Time
}

func (*Connection) GetAnnotations

func (c *Connection) GetAnnotations() map[string]string

func (*Connection) GetConnectorId

func (c *Connection) GetConnectorId() apid.ID

func (*Connection) GetConnectorVersion

func (c *Connection) GetConnectorVersion() uint64

func (*Connection) GetId

func (c *Connection) GetId() apid.ID

func (*Connection) GetLabels

func (c *Connection) GetLabels() map[string]string

func (*Connection) GetNamespace

func (c *Connection) GetNamespace() string

func (*Connection) Validate

func (c *Connection) Validate() error

type ConnectionHealthState

type ConnectionHealthState string

ConnectionHealthState is the operational health signal for a connection, distinct from its lifecycle state. A connection can be Configured and unhealthy simultaneously — for example, an OAuth2 connection whose refresh token has been revoked stays in ConnectionStateConfigured but flips to unhealthy until the user re-authenticates. Probe-driven and refresh-driven signals both write to this field; UI surfaces it to drive the unified reauth action.

const (
	ConnectionHealthStateHealthy   ConnectionHealthState = "healthy"
	ConnectionHealthStateUnhealthy ConnectionHealthState = "unhealthy"
)

type ConnectionOrderByField

type ConnectionOrderByField string
const (
	ConnectionOrderById        ConnectionOrderByField = "id"
	ConnectionOrderByNamespace ConnectionOrderByField = "namespace"
	ConnectionOrderByState     ConnectionOrderByField = "state"
	ConnectionOrderByCreatedAt ConnectionOrderByField = "created_at"
	ConnectionOrderByUpdatedAt ConnectionOrderByField = "updated_at"
)

type ConnectionProbeOutcome

type ConnectionProbeOutcome struct {
	Id           apid.ID
	ConnectionId apid.ID
	ProbeId      string
	Outcome      string
	ErrorMessage *string
	OccurredAt   time.Time
	CreatedAt    time.Time
}

ConnectionProbeOutcome is one append-only event in the probe-outcome log. Each probe invocation produces a row; the runtime walks the most recent rows for a (connection_id, probe_id) pair to compute consecutive-success or -failure counts that drive the connection's health_state transitions.

Storage is event-shaped rather than counter-shaped so that:

  • writes never race on a shared counter row;
  • the log naturally carries probe history for operators (when did the last failure happen? what error did it report?);
  • threshold semantics can change without a schema migration.

A daily cleanup task (DeleteOldProbeOutcomes) caps growth — see internal/core/task_probe_outcome_cleanup.go.

type ConnectionState

type ConnectionState string
const (
	// ConnectionStateSetup is the initial state — a connection in setup
	// has been persisted and has one or more setup steps in progress.
	ConnectionStateSetup ConnectionState = "setup"
	// ConnectionStateConfigured means setup is complete. The connection
	// may or may not be currently usable; whether the credentials still
	// work is the orthogonal ConnectionHealthState axis (e.g. an OAuth2
	// connection with a revoked refresh token stays Configured but flips
	// unhealthy until reauth).
	ConnectionStateConfigured    ConnectionState = "configured"
	ConnectionStateDisabled      ConnectionState = "disabled"
	ConnectionStateDisconnecting ConnectionState = "disconnecting"
	ConnectionStateDisconnected  ConnectionState = "disconnected"
)

type Connector

type Connector struct {
	ConnectorVersion
	TotalVersions int64
	States        ConnectorVersionStates
}

Connector object is returned from queries for connectors, with one record per id. It aggregates some information across all versions for a connector.

type ConnectorOrderByField

type ConnectorOrderByField string
const (
	ConnectorOrderById        ConnectorOrderByField = "id"
	ConnectorOrderByVersion   ConnectorOrderByField = "version"
	ConnectorOrderByNamespace ConnectorOrderByField = "namespace"
	ConnectorOrderByState     ConnectorOrderByField = "state"
	ConnectorOrderByCreatedAt ConnectorOrderByField = "created_at"
	ConnectorOrderByUpdatedAt ConnectorOrderByField = "updated_at"
	ConnectorOrderByType      ConnectorOrderByField = "type"
)

type ConnectorVersion

type ConnectorVersion struct {
	Id                  apid.ID
	Version             uint64
	Namespace           string
	State               ConnectorVersionState
	Hash                string
	EncryptedDefinition encfield.EncryptedField
	Labels              Labels
	Annotations         Annotations
	CreatedAt           time.Time
	UpdatedAt           time.Time
	EncryptedAt         *time.Time
	DeletedAt           *time.Time
}

func (*ConnectorVersion) GetId

func (cv *ConnectorVersion) GetId() apid.ID

func (*ConnectorVersion) GetNamespace

func (cv *ConnectorVersion) GetNamespace() string

func (*ConnectorVersion) GetVersion

func (cv *ConnectorVersion) GetVersion() uint64

func (*ConnectorVersion) Validate

func (cv *ConnectorVersion) Validate() error

type ConnectorVersionId

type ConnectorVersionId struct {
	Id      apid.ID
	Version uint64
}

type ConnectorVersionOrderByField

type ConnectorVersionOrderByField string
const (
	ConnectorVersionOrderById        ConnectorVersionOrderByField = "id"
	ConnectorVersionOrderByVersion   ConnectorVersionOrderByField = "version"
	ConnectorVersionOrderByState     ConnectorVersionOrderByField = "state"
	ConnectorVersionOrderByCreatedAt ConnectorVersionOrderByField = "created_at"
	ConnectorVersionOrderByUpdatedAt ConnectorVersionOrderByField = "updated_at"
)

type ConnectorVersionState

type ConnectorVersionState string
const (
	// ConnectorVersionStateDraft means the connector definition is being worked on and new users should not connect to
	// this version and existing users should not be upgraded to this version
	ConnectorVersionStateDraft ConnectorVersionState = "draft"

	// ConnectorVersionStatePrimary means that the version has been published and this should be the version used for
	// new connections. Existing connections of this connector will be upgraded to this version if possible, or
	// transitioned to a state where action is required to complete the upgrade.
	ConnectorVersionStatePrimary ConnectorVersionState = "primary"

	// ConnectorVersionStateActive means that a newer version of the connector has been published, but connections
	// still exist on this version that have not been upgraded.
	ConnectorVersionStateActive ConnectorVersionState = "active"

	// ConnectorVersionStateArchived means that this is an old version of the connect that does not have any active
	// connections running on the version.
	ConnectorVersionStateArchived ConnectorVersionState = "archived"
)

func (*ConnectorVersionState) Scan

func (s *ConnectorVersionState) Scan(value interface{}) error

Scan implements the sql.Scanner interface for ConnectorVersionState

func (ConnectorVersionState) Value

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

Value implements the driver.Valuer interface for ConnectorVersionState

type ConnectorVersionStates

type ConnectorVersionStates []ConnectorVersionState

ConnectorVersionStates is a custom type for a slice of ConnectorVersionState

func (*ConnectorVersionStates) Scan

func (s *ConnectorVersionStates) Scan(value interface{}) error

Scan implements the sql.Scanner interface for ConnectorVersionStates

func (ConnectorVersionStates) Value

Value implements the driver.Valuer interface for ConnectorVersionStates

type DB

type DB interface {
	SetCursorEncryptor(e pagination.CursorEncryptor)
	Migrate(ctx context.Context) error
	Ping(ctx context.Context) bool

	GetNamespace(ctx context.Context, path string) (*Namespace, error)
	CreateNamespace(ctx context.Context, ns *Namespace) error
	EnsureNamespaceByPath(ctx context.Context, path string) error
	DeleteNamespace(ctx context.Context, path string) error
	SetNamespaceState(ctx context.Context, path string, state NamespaceState) error
	SetNamespaceEncryptionKeyId(ctx context.Context, path string, ekId *apid.ID) (*Namespace, error)
	UpdateNamespaceLabels(ctx context.Context, path string, labels map[string]string) (*Namespace, error)
	PutNamespaceLabels(ctx context.Context, path string, labels map[string]string) (*Namespace, error)
	DeleteNamespaceLabels(ctx context.Context, path string, keys []string) (*Namespace, error)
	UpdateNamespaceAnnotations(ctx context.Context, path string, annotations map[string]string) (*Namespace, error)
	PutNamespaceAnnotations(ctx context.Context, path string, annotations map[string]string) (*Namespace, error)
	DeleteNamespaceAnnotations(ctx context.Context, path string, keys []string) (*Namespace, error)
	ListNamespacesBuilder() ListNamespacesBuilder
	ListNamespacesFromCursor(ctx context.Context, cursor string) (ListNamespacesExecutor, error)
	EnumerateNamespaceEncryptionTargets(
		ctx context.Context,
		callback func(targets []NamespaceEncryptionTarget, lastPage bool) (updates []NamespaceTargetEncryptionKeyVersionUpdate, keepGoing pagination.KeepGoing, err error),
	) error

	GetActor(ctx context.Context, id apid.ID) (*Actor, error)
	GetActorByExternalId(ctx context.Context, namespace, externalId string) (*Actor, error)
	CreateActor(ctx context.Context, actor *Actor) error
	UpsertActor(ctx context.Context, actor IActorData) (*Actor, error)
	DeleteActor(ctx context.Context, id apid.ID) error
	PutActorLabels(ctx context.Context, id apid.ID, labels map[string]string) (*Actor, error)
	DeleteActorLabels(ctx context.Context, id apid.ID, keys []string) (*Actor, error)
	UpdateActorAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*Actor, error)
	PutActorAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*Actor, error)
	DeleteActorAnnotations(ctx context.Context, id apid.ID, keys []string) (*Actor, error)
	ListActorsBuilder() ListActorsBuilder
	ListActorsFromCursor(ctx context.Context, cursor string) (ListActorsExecutor, error)

	GetConnectorVersion(ctx context.Context, id apid.ID, version uint64) (*ConnectorVersion, error)
	GetConnectorVersions(ctx context.Context, requested []ConnectorVersionId) (map[ConnectorVersionId]*ConnectorVersion, error)
	GetConnectorVersionForLabels(ctx context.Context, labelSelector string) (*ConnectorVersion, error)
	GetConnectorVersionForLabelsAndVersion(ctx context.Context, labelSelector string, version uint64) (*ConnectorVersion, error)
	GetConnectorVersionForState(ctx context.Context, id apid.ID, state ConnectorVersionState) (*ConnectorVersion, error)
	NewestConnectorVersionForId(ctx context.Context, id apid.ID) (*ConnectorVersion, error)
	NewestPublishedConnectorVersionForId(ctx context.Context, id apid.ID) (*ConnectorVersion, error)
	UpsertConnectorVersion(ctx context.Context, cv *ConnectorVersion) error
	SetConnectorVersionState(ctx context.Context, id apid.ID, version uint64, state ConnectorVersionState) error
	DeleteConnector(ctx context.Context, id apid.ID) error
	ListConnectorVersionsBuilder() ListConnectorVersionsBuilder
	ListConnectorVersionsFromCursor(ctx context.Context, cursor string) (ListConnectorVersionsExecutor, error)
	ListConnectorsBuilder() ListConnectorsBuilder
	ListConnectorsFromCursor(ctx context.Context, cursor string) (ListConnectorsExecutor, error)

	GetConnection(ctx context.Context, id apid.ID) (*Connection, error)
	CreateConnection(ctx context.Context, c *Connection) error
	DeleteConnection(ctx context.Context, id apid.ID) error
	SetConnectionState(ctx context.Context, id apid.ID, state ConnectionState) error
	SetConnectionHealthState(ctx context.Context, id apid.ID, state ConnectionHealthState) error
	SetConnectionSetupStep(ctx context.Context, id apid.ID, setupStep *cschema.SetupStep) error
	SetConnectionSetupError(ctx context.Context, id apid.ID, setupError *string) error
	SetConnectionEncryptedConfiguration(ctx context.Context, id apid.ID, encryptedConfig *encfield.EncryptedField) error
	UpdateConnectionLabels(ctx context.Context, id apid.ID, labels map[string]string) (*Connection, error)
	PutConnectionLabels(ctx context.Context, id apid.ID, labels map[string]string) (*Connection, error)
	DeleteConnectionLabels(ctx context.Context, id apid.ID, keys []string) (*Connection, error)
	UpdateConnectionAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*Connection, error)
	PutConnectionAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*Connection, error)
	DeleteConnectionAnnotations(ctx context.Context, id apid.ID, keys []string) (*Connection, error)
	ListConnectionsBuilder() ListConnectionsBuilder
	ListConnectionsFromCursor(ctx context.Context, cursor string) (ListConnectionsExecutor, error)

	/*
	 * OAuth2 tokens
	 */
	GetOAuth2Token(ctx context.Context, connectionId apid.ID) (*OAuth2Token, error)
	InsertOAuth2Token(
		ctx context.Context,
		connectionId apid.ID,
		refreshedFrom *apid.ID,
		encryptedRefreshToken encfield.EncryptedField,
		encryptedAccessToken encfield.EncryptedField,
		accessTokenExpiresAt *time.Time,
		scopes string,
		requestedScopes string,
		createdByActorId *apid.ID,
	) (*OAuth2Token, error)
	DeleteOAuth2Token(ctx context.Context, tokenId apid.ID) error
	DeleteAllOAuth2TokensForConnection(ctx context.Context, connectionId apid.ID) error

	// EnumerateOAuth2TokensExpiringWithin enumerates OAuth2 tokens that are expiring within a specified time interval
	// of now. This includes tokens that are already expired. Deleted tokens are not considered, nor are tokens tied
	// to a deleted connection.
	EnumerateOAuth2TokensExpiringWithin(
		ctx context.Context,
		duration time.Duration,
		callback func(tokens []*OAuth2TokenWithConnection, lastPage bool) (keepGoing pagination.KeepGoing, err error),
	) error

	/*
	 * API Key credentials
	 */
	GetActiveApiKeyCredential(ctx context.Context, connectionId apid.ID) (*ApiKeyCredential, error)
	InsertApiKeyCredential(
		ctx context.Context,
		connectionId apid.ID,
		encryptedCredentials encfield.EncryptedField,
		placement *cschema.ApiKeyPlacement,
		createdByActorId *apid.ID,
	) (*ApiKeyCredential, error)
	UpdateApiKeyCredentialLastValidated(ctx context.Context, credentialId apid.ID, at time.Time) error
	DeleteAllApiKeyCredentialsForConnection(ctx context.Context, connectionId apid.ID) error

	/*
	 * Connection probe outcomes — append-only event log that drives the
	 * probe-driven health-check signal. The runtime walks the most-recent
	 * rows for each (connection_id, probe_id) to compute consecutive-success
	 * or -failure counts. A daily cleanup task caps growth (see
	 * internal/core/task_probe_outcome_cleanup.go).
	 */
	InsertProbeOutcome(ctx context.Context, connectionId apid.ID, probeId string, outcome string, errorMessage string) (*ConnectionProbeOutcome, error)
	GetRecentProbeOutcomes(ctx context.Context, connectionId apid.ID, probeId string, limit int) ([]*ConnectionProbeOutcome, error)
	DeleteOldProbeOutcomes(ctx context.Context, connectionId apid.ID, probeId string, keepMinimum int, olderThan time.Time) (int64, error)
	DistinctProbeIdsForConnection(ctx context.Context, connectionId apid.ID) ([]string, error)
	CountProbeOutcomes(ctx context.Context, connectionId apid.ID, probeId string) (int, error)

	GetEncryptionKey(ctx context.Context, id apid.ID) (*EncryptionKey, error)
	CreateEncryptionKey(ctx context.Context, ek *EncryptionKey) error
	UpdateEncryptionKey(ctx context.Context, id apid.ID, updates map[string]interface{}) (*EncryptionKey, error)
	DeleteEncryptionKey(ctx context.Context, id apid.ID) error
	SetEncryptionKeyState(ctx context.Context, id apid.ID, state EncryptionKeyState) error
	UpdateEncryptionKeyLabels(ctx context.Context, id apid.ID, labels map[string]string) (*EncryptionKey, error)
	PutEncryptionKeyLabels(ctx context.Context, id apid.ID, labels map[string]string) (*EncryptionKey, error)
	DeleteEncryptionKeyLabels(ctx context.Context, id apid.ID, keys []string) (*EncryptionKey, error)
	UpdateEncryptionKeyAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*EncryptionKey, error)
	PutEncryptionKeyAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*EncryptionKey, error)
	DeleteEncryptionKeyAnnotations(ctx context.Context, id apid.ID, keys []string) (*EncryptionKey, error)
	ListEncryptionKeysBuilder() ListEncryptionKeysBuilder
	ListEncryptionKeysFromCursor(ctx context.Context, cursor string) (ListEncryptionKeysExecutor, error)

	// EnumerateEncryptionKeysInDependencyOrder loads all non-deleted encryption keys and walks them
	// in breadth-first order starting from the root key (the one with nil EncryptedKeyData).
	// The callback receives one depth-level of keys at a time, with depth 0 being the root.
	// Returns a slice of orphaned keys whose parent encryption key version could not be resolved.
	EnumerateEncryptionKeysInDependencyOrder(
		ctx context.Context,
		callback func(keys []*EncryptionKey, depth int) (keepGoing pagination.KeepGoing, err error),
	) ([]*EncryptionKey, error)

	CreateEncryptionKeyVersion(ctx context.Context, ekv *EncryptionKeyVersion) error
	GetEncryptionKeyVersion(ctx context.Context, id apid.ID) (*EncryptionKeyVersion, error)
	GetCurrentEncryptionKeyVersionForEncryptionKey(ctx context.Context, encryptionKeyId apid.ID) (*EncryptionKeyVersion, error)
	ListEncryptionKeyVersionsForEncryptionKey(ctx context.Context, encryptionKeyId apid.ID) ([]*EncryptionKeyVersion, error)
	GetMaxOrderedVersionForEncryptionKey(ctx context.Context, encryptionKeyId apid.ID) (int64, error)
	ClearCurrentFlagForEncryptionKey(ctx context.Context, encryptionKeyId apid.ID) error
	GetCurrentEncryptionKeyVersionForNamespace(ctx context.Context, namespacePath string) (*EncryptionKeyVersion, error)
	ListEncryptionKeyVersionsForNamespace(ctx context.Context, namespacePath string) ([]*EncryptionKeyVersion, error)
	GetMaxOrderedVersionForNamespace(ctx context.Context, namespacePath string) (int64, error)
	ClearCurrentFlagForNamespace(ctx context.Context, namespacePath string) error
	DeleteEncryptionKeyVersion(ctx context.Context, id apid.ID) error
	DeleteEncryptionKeyVersionsForEncryptionKey(ctx context.Context, encryptionKeyId apid.ID) error
	SetEncryptionKeyVersionCurrentFlag(ctx context.Context, id apid.ID, isCurrent bool) error

	// EnumerateEncryptionKeyVersionsForKey enumerates all non-deleted encryption key versions for a
	// specified key in batches.
	EnumerateEncryptionKeyVersionsForKey(
		ctx context.Context,
		ekId apid.ID,
		callback func(ekvs []*EncryptionKeyVersion, lastPage bool) (keepGoing pagination.KeepGoing, err error),
	) error

	CreateDataEncryptionKey(ctx context.Context, dek *DataEncryptionKey) error
	GetDataEncryptionKey(ctx context.Context, id apid.ID) (*DataEncryptionKey, error)
	ListDataEncryptionKeysForEncryptionKey(ctx context.Context, encryptionKeyId apid.ID) ([]*DataEncryptionKey, error)

	GetRateLimit(ctx context.Context, id apid.ID) (*RateLimit, error)
	CreateRateLimit(ctx context.Context, rl *RateLimit) error
	UpdateRateLimitDefinition(ctx context.Context, id apid.ID, def rlschema.RateLimit) (*RateLimit, error)
	DeleteRateLimit(ctx context.Context, id apid.ID) error
	UpdateRateLimitLabels(ctx context.Context, id apid.ID, labels map[string]string) (*RateLimit, error)
	PutRateLimitLabels(ctx context.Context, id apid.ID, labels map[string]string) (*RateLimit, error)
	DeleteRateLimitLabels(ctx context.Context, id apid.ID, keys []string) (*RateLimit, error)
	UpdateRateLimitAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*RateLimit, error)
	PutRateLimitAnnotations(ctx context.Context, id apid.ID, annotations map[string]string) (*RateLimit, error)
	DeleteRateLimitAnnotations(ctx context.Context, id apid.ID, keys []string) (*RateLimit, error)
	ListRateLimitsBuilder() ListRateLimitsBuilder
	ListRateLimitsFromCursor(ctx context.Context, cursor string) (ListRateLimitsExecutor, error)

	// EnumerateFieldsRequiringReEncryption walks all registered encrypted fields across all tables,
	// finding rows whose encrypted field EKV ID does not match the namespace's target EKV ID.
	EnumerateFieldsRequiringReEncryption(
		ctx context.Context,
		callback func(targets []ReEncryptionTarget, lastPage bool) (keepGoing pagination.KeepGoing, err error),
	) error

	// BatchUpdateReEncryptedFields updates encrypted field values after re-encryption,
	// setting the new value and updating encrypted_at.
	BatchUpdateReEncryptedFields(ctx context.Context, updates []ReEncryptedFieldUpdate) error

	// PurgeSoftDeletedRecords hard-deletes all soft-deleted records where deleted_at is before olderThan.
	// Returns the total number of records deleted across all tables.
	PurgeSoftDeletedRecords(ctx context.Context, olderThan time.Time) (int64, error)

	// RefreshNamespaceLabelsCarryForward re-derives the materialized apxy/
	// portion of every resource that inherits from nsPath, then walks each
	// direct child namespace, recomputes its labels, and recurses. Each
	// row's update runs in its own short transaction. Intended to be
	// invoked from a background asynq task — a label change on a deeply
	// nested namespace can fan out to many descendants.
	RefreshNamespaceLabelsCarryForward(ctx context.Context, nsPath string) error

	// RefreshConnectionsForConnectorVersion re-derives the materialized
	// apxy/ portion of every connection pointing at the given (id,
	// version). Each connection's update runs in its own short
	// transaction. Intended to be invoked from a background asynq task
	// after a connector version's user labels change (only meaningful for
	// draft versions; primary and active are immutable).
	RefreshConnectionsForConnectorVersion(ctx context.Context, id apid.ID, version uint64) error

	// ReconcileCarryForwardLabels walks every labelled resource in batches
	// of `batchSize` and re-derives the materialized apxy/ portion of
	// each row. The optional `limiter` is consulted before each row is
	// processed, providing a per-row records/sec rate limit; nil means
	// unlimited. Drift is rare under normal operation, but this method
	// is the safety net for any propagation task that misfired or any
	// data path that bypassed the carry-forward triggers. Intended to be
	// invoked from a daily asynq cron task. Returns the total number of
	// rows whose labels were corrected.
	ReconcileCarryForwardLabels(ctx context.Context, batchSize int32, limiter *rate.Limiter) (corrected int64, err error)

	HasNonceBeenUsed(ctx context.Context, nonce apid.ID) (hasBeenUsed bool, err error)
	CheckNonceValidAndMarkUsed(ctx context.Context, nonce apid.ID, retainRecordUntil time.Time) (wasValid bool, err error)
	DeleteExpiredNonces(ctx context.Context) (err error)
}

func MustApplyBlankTestDbConfig

func MustApplyBlankTestDbConfig(t testing.TB, cfg config.C) (config.C, DB)

MustApplyBlankTestDbConfig applies a test database configuration to the specified config root. The database is guaranteed to be blank and migrated. This method uses a temp file so that the database will be eventually cleaned up after the process exits. Note that the configuration in the root will be modified for the database and populated for the GlobalAESKey if it is not already populated.

To support debugging tests by inspecting the SQLite database, if the SQLITE_TEST_DATABASE_PATH env var is set this method will use the database at that path. It will delete the existing file at that path to recreate unless the SQLITE_TEST_DATABASE_PATH_CLEAR env var is set to false.

To run tests against Postgres, set AUTH_PROXY_TEST_DATABASE_PROVIDER=postgres and configure the connection with POSTGRES_TEST_HOST, POSTGRES_TEST_PORT, POSTGRES_TEST_USER, POSTGRES_TEST_PASSWORD, POSTGRES_TEST_DATABASE, and POSTGRES_TEST_OPTIONS. You can also tune POSTGRES_TEST_MAX_PARALLEL and POSTGRES_TEST_MAX_CONNS to reduce connection pressure.

Parameters: - t: the test instance used for naming and cleanup - cfg: the config to apply the database config to. This may be nil, in which case a new config is created. This method will overwrite the existing config.

Returns: - the config with information populated for the database. If a config was passed in, the same value is returned with data populated. - a database instance configured with the specified root. This database can be used directly, or if the root used again, it will connect to the same database instance.

func MustApplyBlankTestDbConfigRaw

func MustApplyBlankTestDbConfigRaw(t testing.TB, cfg config.C) (config.C, DB, *sql.DB)

func NewService

func NewService(db *sql.DB, dbConfig config.DatabaseImpl, logger *slog.Logger) (DB, error)

NewService creates the AuthProxy database service using an already-open and fully configured database/sql handle. The caller owns the SQL handle and is responsible for closing it.

type DataEncryptionKey

type DataEncryptionKey struct {
	Id              apid.ID
	EncryptionKeyId apid.ID
	Provider        string
	ProviderID      string
	ProviderVersion string
	ProtectedData   *sconfig.KeyVersionProtectedData
	IsCurrent       bool
	CreatedAt       time.Time
	UpdatedAt       time.Time
	DeletedAt       *time.Time
}

func (*DataEncryptionKey) Validate

func (d *DataEncryptionKey) Validate() error

type DeletedHandling

type DeletedHandling bool
const (
	// DeletedHandlingExclude will exclude deleted records from the result set
	DeletedHandlingExclude DeletedHandling = false

	// DeletedHandlingInclude will include deleted records in the result set
	DeletedHandlingInclude DeletedHandling = true
)

type EncryptedFieldRegistration

type EncryptedFieldRegistration struct {
	Table          string
	PrimaryKeyCols []string // e.g. ["id"] or ["id", "version"]
	EncryptedCols  []string // e.g. ["encrypted_access_token", "encrypted_refresh_token"]

	// Direct namespace resolution (most tables)
	NamespaceCol string // e.g. "namespace" — column on this table

	// Indirect namespace resolution via JOIN (e.g. oauth2_tokens → connections)
	JoinTable        string // e.g. "connections"
	JoinLocalCol     string // e.g. "connection_id" — FK column on this table
	JoinRemoteCol    string // e.g. "id" — PK column on join table
	JoinNamespaceCol string // e.g. "namespace" — namespace column on join table
}

EncryptedFieldRegistration declares which columns on a table contain encrypted fields and how the table resolves to a namespace.

func GetEncryptedFieldRegistrations

func GetEncryptedFieldRegistrations() []EncryptedFieldRegistration

GetEncryptedFieldRegistrations returns a copy of all registered encrypted field registrations.

type EncryptionKey

type EncryptionKey struct {
	Id               apid.ID
	Namespace        string
	EncryptedKeyData *encfield.EncryptedField
	State            EncryptionKeyState
	Labels           Labels
	Annotations      Annotations
	CreatedAt        time.Time
	UpdatedAt        time.Time
	EncryptedAt      *time.Time
	DeletedAt        *time.Time
}

EncryptionKey represents a user-managed encryption key configuration.

func (*EncryptionKey) GetNamespace

func (ek *EncryptionKey) GetNamespace() string

func (*EncryptionKey) Validate

func (ek *EncryptionKey) Validate() error

type EncryptionKeyOrderByField

type EncryptionKeyOrderByField string
const (
	EncryptionKeyOrderByState     EncryptionKeyOrderByField = "state"
	EncryptionKeyOrderByCreatedAt EncryptionKeyOrderByField = "created_at"
	EncryptionKeyOrderByUpdatedAt EncryptionKeyOrderByField = "updated_at"
)

type EncryptionKeyState

type EncryptionKeyState string
const (
	EncryptionKeyStateActive   EncryptionKeyState = "active"
	EncryptionKeyStateDisabled EncryptionKeyState = "disabled"
)

type EncryptionKeyVersion

type EncryptionKeyVersion struct {
	Id              apid.ID
	EncryptionKeyId apid.ID
	Provider        string
	ProviderID      string
	ProviderVersion string
	OrderedVersion  int64
	IsCurrent       bool
	CreatedAt       time.Time
	UpdatedAt       time.Time
	DeletedAt       *time.Time
}

func (*EncryptionKeyVersion) Validate

func (ekv *EncryptionKeyVersion) Validate() error

type IActorData

type IActorData interface {
	GetId() apid.ID
	GetExternalId() string
	GetPermissions() []aschema.Permission
	GetNamespace() string
	GetLabels() map[string]string
	// GetAnnotations returns the annotations to apply on upsert. A nil return means
	// annotations should be left unchanged on existing actors (PATCH semantics);
	// a non-nil map (including empty) is treated as a full replacement.
	GetAnnotations() map[string]string
}

type IActorDataExtended

type IActorDataExtended interface {
	IActorData
	GetEncryptedKey() *encfield.EncryptedField
}

IActorDataExtended extends IActorData with additional fields for labels and encrypted key. This interface is used when creating or updating actors with extended data such as labels for tracking the source of admin syncs, or encrypted keys for admin authentication.

type LabelOperator

type LabelOperator string
const (
	LabelOperatorEqual     LabelOperator = "="
	LabelOperatorNotEqual  LabelOperator = "!="
	LabelOperatorExists    LabelOperator = "exists"
	LabelOperatorNotExists LabelOperator = "!exists"
)

type LabelRequirement

type LabelRequirement struct {
	Key      string
	Operator LabelOperator
	Value    string
}

type LabelSelector

type LabelSelector []LabelRequirement

func ParseLabelSelector

func ParseLabelSelector(selector string) (LabelSelector, error)

ParseLabelSelector parses a Kubernetes-style label selector string. Supported syntax: - key=value, key==value - key!=value - key (exists) - !key (does not exist)

func (LabelSelector) ApplyToSqlBuilderWithProvider

func (s LabelSelector) ApplyToSqlBuilderWithProvider(q sq.SelectBuilder, labelsColumn string, provider config.DatabaseProvider) sq.SelectBuilder

func (LabelSelector) Matches

func (s LabelSelector) Matches(labels map[string]string) bool

Matches reports whether the supplied label map satisfies every requirement in the selector. An empty / nil selector matches any input — same convention the SQL-side uses (no requirements means no filter).

This is the in-memory counterpart to ApplyToSqlBuilderWithProvider used by the rate-limit evaluator (and any future runtime path that needs to match label selectors against per-request snapshots).

func (LabelSelector) String

func (s LabelSelector) String() string

type Labels

type Labels map[string]string

Labels is a map of key-value pairs following Kubernetes label restrictions. Keys follow the format [prefix/]name where: - prefix (optional): valid DNS subdomain, max 253 characters - name (required): 1-63 characters, alphanumeric start/end, may contain '-', '_', '.' Values: 0-63 characters, if non-empty must start/end with alphanumeric

func ApplyParentCarryForward

func ApplyParentCarryForward(userLabels Labels, parents ...ParentCarryForward) Labels

ApplyParentCarryForward composes a child resource's labels from the parents listed and the user-supplied labels. For each parent it calls BuildCarriedLabels(parent.Rt, parent.Labels) and merges the result; the user's own labels are merged last among non-self entries (they cannot collide with apxy/ keys because user input cannot reference the apxy/ namespace). Parents are applied in order, so a later parent's apxy/ pass-through overrides an earlier parent's — list parents from most distant to most direct so the most direct ancestor wins on conflicts (deeper-overrides-shallower).

Callers should follow with InjectSelfImplicitLabels (or InjectNamespaceSelfImplicitLabels for path-keyed namespaces) so the child's own self-implicit labels override any same-keyed pass-through from a parent.

func BuildCarriedLabels

func BuildCarriedLabels(parentRt string, parentLabels Labels) Labels

BuildCarriedLabels takes a parent's labels and returns the carry-forward labels for a child of the parent.

  • User labels on the parent (any key NOT starting with apxy/) are re-keyed under apxy/<parentRt>/<key>.
  • apxy/-prefixed labels on the parent are forwarded as-is so that ancestors further up the chain remain visible. The child is expected to merge its own self-implicit labels on top of this map (deeper overrides shallower).

parentRt is the resource-type token of the parent (e.g. "cxr", "cxn", "ns") — typically obtained via ApidPrefixToLabelToken.

func BuildImplicitIdentifierLabels

func BuildImplicitIdentifierLabels(id apid.ID, namespacePath string) Labels

BuildImplicitIdentifierLabels returns the two implicit identifier labels for an apid-keyed resource: apxy/<rt>/-/id and apxy/<rt>/-/ns, where <rt> is derived from the resource's id prefix. The id and namespacePath are stored as label values verbatim — callers must ensure they have already been validated by their respective rules.

func BuildImplicitIdentifierLabelsForToken

func BuildImplicitIdentifierLabelsForToken(rt, id, namespacePath string) Labels

BuildImplicitIdentifierLabelsForToken builds the apxy/<rt>/-/id and apxy/<rt>/-/ns implicit identifier labels for any resource type, keyed by the supplied <rt> token and identifier string. This is the underlying builder used by both apid-keyed and path-keyed resources.

func BuildNamespaceImplicitIdentifierLabels

func BuildNamespaceImplicitIdentifierLabels(path string) Labels

BuildNamespaceImplicitIdentifierLabels builds the self-implicit identifier labels for a namespace. Both the -/id and -/ns labels carry the namespace's own path (a namespace is its own namespace).

func InjectNamespaceSelfImplicitLabels

func InjectNamespaceSelfImplicitLabels(path string, existing Labels) Labels

InjectNamespaceSelfImplicitLabels returns a copy of existing with a namespace's own apxy/ns/-/id and apxy/ns/-/ns labels added. Mirrors InjectSelfImplicitLabels but for path-keyed namespace resources.

func InjectSelfImplicitLabels

func InjectSelfImplicitLabels(id apid.ID, namespacePath string, existing Labels) Labels

InjectSelfImplicitLabels returns a copy of existing with the resource's own apxy/<rt>/-/id and apxy/<rt>/-/ns labels added. The self-implicit labels override any same-keyed entries already in existing (deeper-overrides- shallower across the carry-forward chain). Callers pass this to the create path so the row is persisted with the implicit identifier labels in place.

func MergeApxyAndUserLabels

func MergeApxyAndUserLabels(user, apxy Labels) Labels

MergeApxyAndUserLabels returns a single map containing both the user and apxy portions. Because the two inputs are partitioned by key prefix, no collisions are possible.

func MergeUpsertLabels

func MergeUpsertLabels(callerLabels, existingLabels Labels) Labels

MergeUpsertLabels composes the labels to persist on an upsert by combining caller-supplied labels with the row's existing apxy/ labels.

User-portion labels come from the caller — fully replacing what was stored (write-API endpoints that PATCH user labels go through a different helper). apxy/-prefixed labels merge: stored values are preserved by default, and any apxy/-prefixed entries the caller passes in override the stored values for those specific keys. This lets system code update its own provenance markers (e.g. apxy/cxr/source) on an upsert without requiring a separate label-mutation call, while still preserving apxy/ labels owned by other subsystems (e.g. carry-forward materializations).

func SplitUserAndApxyLabels

func SplitUserAndApxyLabels(labels Labels) (user, apxy Labels)

SplitUserAndApxyLabels partitions a labels map into the user-provided portion (no apxy/ prefix) and the system-managed portion (apxy/ prefix). The two returned maps are disjoint and together reconstitute the input. Either map may be nil if its half is empty.

func (Labels) Copy

func (l Labels) Copy() Labels

Copy returns a deep copy of the labels.

func (Labels) Get

func (l Labels) Get(key string) (string, bool)

Get returns the value for a label key, and whether the key exists.

func (Labels) Has

func (l Labels) Has(key string) bool

Has returns true if the label key exists.

func (*Labels) Scan

func (l *Labels) Scan(value interface{}) error

Scan implements the sql.Scanner interface for Labels

func (Labels) Validate

func (l Labels) Validate() error

Validate validates all labels (system mode — apxy/ keys allowed, with the longer ApxyLabelValueMaxLength value cap for those keys).

func (Labels) Value

func (l Labels) Value() (driver.Value, error)

Value implements the driver.Valuer interface for Labels

type ListActorsBuilder

type ListActorsBuilder interface {
	ListActorsExecutor
	ForExternalId(externalId string) ListActorsBuilder
	ForNamespaceMatcher(matcher string) ListActorsBuilder
	ForNamespaceMatchers(matchers []string) ListActorsBuilder
	Limit(int32) ListActorsBuilder
	OrderBy(ActorOrderByField, pagination.OrderBy) ListActorsBuilder
	IncludeDeleted() ListActorsBuilder
	ForLabelSelector(selector string) ListActorsBuilder
}

type ListActorsExecutor

type ListActorsExecutor interface {
	FetchPage(context.Context) pagination.PageResult[*Actor]
	Enumerate(context.Context, pagination.EnumerateCallback[*Actor]) error
}

type ListConnectionsBuilder

type ListConnectionsBuilder interface {
	ListConnectionsExecutor
	Limit(int32) ListConnectionsBuilder
	ForState(ConnectionState) ListConnectionsBuilder
	ForStates([]ConnectionState) ListConnectionsBuilder
	ForConnectorId(id apid.ID) ListConnectionsBuilder
	ForNamespaceMatcher(matcher string) ListConnectionsBuilder
	ForNamespaceMatchers(matchers []string) ListConnectionsBuilder
	OrderBy(ConnectionOrderByField, pagination.OrderBy) ListConnectionsBuilder
	IncludeDeleted() ListConnectionsBuilder
	WithDeletedHandling(DeletedHandling) ListConnectionsBuilder
	ForLabelSelector(selector string) ListConnectionsBuilder
	WithSetupStepNotNull() ListConnectionsBuilder
	UpdatedBefore(t time.Time) ListConnectionsBuilder
}

type ListConnectionsExecutor

type ListConnectionsExecutor interface {
	FetchPage(context.Context) pagination.PageResult[Connection]
	Enumerate(context.Context, pagination.EnumerateCallback[Connection]) error
}

type ListConnectorsExecutor

type ListConnectorsExecutor interface {
	FetchPage(context.Context) pagination.PageResult[Connector]
	Enumerate(context.Context, pagination.EnumerateCallback[Connector]) error
}

type ListEncryptionKeysExecutor

type ListEncryptionKeysExecutor interface {
	FetchPage(context.Context) pagination.PageResult[EncryptionKey]
	Enumerate(context.Context, pagination.EnumerateCallback[EncryptionKey]) error
}

type ListNamespacesBuilder

type ListNamespacesBuilder interface {
	ListNamespacesExecutor
	Limit(int32) ListNamespacesBuilder
	ForPathPrefix(path string) ListNamespacesBuilder
	ForDepth(depth uint64) ListNamespacesBuilder
	ForChildrenOf(path string) ListNamespacesBuilder
	ForNamespaceMatcher(matcher string) ListNamespacesBuilder
	ForNamespaceMatchers(matchers []string) ListNamespacesBuilder
	ForState(NamespaceState) ListNamespacesBuilder
	OrderBy(NamespaceOrderByField, pagination.OrderBy) ListNamespacesBuilder
	IncludeDeleted() ListNamespacesBuilder
	ForLabelSelector(selector string) ListNamespacesBuilder
}

type ListNamespacesExecutor

type ListNamespacesExecutor interface {
	FetchPage(context.Context) pagination.PageResult[Namespace]
	Enumerate(context.Context, pagination.EnumerateCallback[Namespace]) error
}

type ListRateLimitsBuilder

type ListRateLimitsBuilder interface {
	ListRateLimitsExecutor
	Limit(int32) ListRateLimitsBuilder
	ForNamespaceMatcher(matcher string) ListRateLimitsBuilder
	ForNamespaceMatchers(matchers []string) ListRateLimitsBuilder
	OrderBy(RateLimitOrderByField, pagination.OrderBy) ListRateLimitsBuilder
	IncludeDeleted() ListRateLimitsBuilder
	ForLabelSelector(selector string) ListRateLimitsBuilder
}

type ListRateLimitsExecutor

type ListRateLimitsExecutor interface {
	FetchPage(context.Context) pagination.PageResult[RateLimit]
	Enumerate(context.Context, pagination.EnumerateCallback[RateLimit]) error
}

type Namespace

type Namespace struct {
	Path string

	State           NamespaceState
	EncryptionKeyId *apid.ID
	Labels          Labels
	Annotations     Annotations
	CreatedAt       time.Time
	UpdatedAt       time.Time
	DeletedAt       *time.Time
	// contains filtered or unexported fields
}

Namespace is the grouping of resources within AuthProxy.

func (*Namespace) GetNamespace

func (ns *Namespace) GetNamespace() string

func (*Namespace) Validate

func (ns *Namespace) Validate() error

type NamespaceEncryptionTarget

type NamespaceEncryptionTarget struct {
	Path                         string
	Depth                        uint64
	EncryptionKeyId              *apid.ID
	TargetEncryptionKeyVersionId *apid.ID
}

NamespaceEncryptionTarget holds the fields needed by the background job that computes and caches the target encryption key version for each namespace.

type NamespaceOrderByField

type NamespaceOrderByField string
const (
	NamespaceOrderByPath      NamespaceOrderByField = "path"
	NamespaceOrderByState     NamespaceOrderByField = "state"
	NamespaceOrderByCreatedAt NamespaceOrderByField = "created_at"
	NamespaceOrderByUpdatedAt NamespaceOrderByField = "updated_at"
)

type NamespaceState

type NamespaceState string
const (
	NamespaceStateActive     NamespaceState = "active"
	NamespaceStateDestroying NamespaceState = "destroying"
	NamespaceStateDestroyed  NamespaceState = "destroyed"
)

type NamespaceTargetEncryptionKeyVersionUpdate

type NamespaceTargetEncryptionKeyVersionUpdate struct {
	Path                         string
	TargetEncryptionKeyVersionId apid.ID
}

NamespaceTargetEncryptionKeyVersionUpdate carries an update to set the target encryption key version for a specific namespace.

type OAuth2ClientCredentialsPlaintext

type OAuth2ClientCredentialsPlaintext struct {
	ClientId     string `json:"client_id"`
	ClientSecret string `json:"client_secret,omitempty"`
}

type OAuth2Token

type OAuth2Token struct {
	Id                    apid.ID
	ConnectionId          apid.ID // Foreign key to Connection; not enforced by database
	RefreshedFromId       *apid.ID
	EncryptedRefreshToken encfield.EncryptedField
	EncryptedAccessToken  encfield.EncryptedField
	AccessTokenExpiresAt  *time.Time
	Scopes                string
	RequestedScopes       string
	CreatedByActorId      *apid.ID // Actor who initiated this token (carried forward on refresh)
	CreatedAt             time.Time
	EncryptedAt           *time.Time
	DeletedAt             *time.Time
}

func (*OAuth2Token) IsAccessTokenExpired

func (t *OAuth2Token) IsAccessTokenExpired(ctx context.Context) bool

func (*OAuth2Token) Validate

func (t *OAuth2Token) Validate() error

type OAuth2TokenWithConnection

type OAuth2TokenWithConnection struct {
	Token      OAuth2Token
	Connection Connection
}

type ParentCarryForward

type ParentCarryForward struct {
	Rt     string
	Labels Labels
}

ParentCarryForward bundles a parent's resource-type token with the parent's stored labels for use with ApplyParentCarryForward.

type Permissions

type Permissions []aschema.Permission

Permissions is a custom type for a slice of permissions. The values are serlized to json.

func (*Permissions) Scan

func (p *Permissions) Scan(value interface{}) error

Scan implements the sql.Scanner interface for Permissions

func (Permissions) Value

func (p Permissions) Value() (driver.Value, error)

Value implements the driver.Valuer interface for Permissions

type RateLimit

type RateLimit struct {
	Id          apid.ID
	Namespace   string
	Definition  rlschema.RateLimit
	Labels      Labels
	Annotations Annotations
	CreatedAt   time.Time
	UpdatedAt   time.Time
	DeletedAt   *time.Time
}

RateLimit is the database envelope for a rate-limit resource. Definition holds the JSON-serialised configuration (mode, selector, bucket, algorithm).

func (*RateLimit) GetNamespace

func (rl *RateLimit) GetNamespace() string

func (*RateLimit) Validate

func (rl *RateLimit) Validate() error

type RateLimitOrderByField

type RateLimitOrderByField string
const (
	RateLimitOrderByCreatedAt RateLimitOrderByField = "created_at"
	RateLimitOrderByUpdatedAt RateLimitOrderByField = "updated_at"
	RateLimitOrderByNamespace RateLimitOrderByField = "namespace"
)

type ReEncryptedFieldUpdate

type ReEncryptedFieldUpdate struct {
	Table            string
	PrimaryKeyCols   []string
	PrimaryKeyValues []any
	FieldColumn      string
	NewValue         encfield.EncryptedField
}

ReEncryptedFieldUpdate carries the data to update a single encrypted field after re-encryption.

type ReEncryptionTarget

type ReEncryptionTarget struct {
	Table                        string
	PrimaryKeyCols               []string                // column names in PK order (from registration)
	PrimaryKeyValues             []any                   // values in PK column order
	FieldColumn                  string                  // which encrypted column
	EncryptedFieldValue          encfield.EncryptedField // current value (contains EKV ID)
	TargetEncryptionKeyVersionId apid.ID                 // what it should be
}

ReEncryptionTarget represents one encrypted field on one row that needs re-encryption.

type UpsertConnectorVersionResult

type UpsertConnectorVersionResult struct {
	ConnectorVersion *ConnectorVersion
	State            ConnectorVersionState
	Version          uint64
}

type UsedNonce

type UsedNonce struct {
	Id          apid.ID
	RetainUntil time.Time
	CreatedAt   time.Time
}

UsedNonce represents a onetime use value (UUID) that has already been used in the system and cannot be used again. When used outside the system, nonces should also use some sort of expiry mechanism such that when they are used there is a known time that they must be retained until so that the list of used nonces doesn't grow infinitely.

Directories

Path Synopsis
Package mock is a generated GoMock package.
Package mock is a generated GoMock package.

Jump to

Keyboard shortcuts

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