Documentation
¶
Overview ¶
The acknowledged audit-delivery checkpoint (#1513): the durable per-destination cursor the leader-only webhook delivery loop (internal/audit/sinks) reads the already-masked audit trail from, and the status its metrics report. Methods live on PG, not Store: like the federation cursor (store_devices.go) they serve one background loop, so a test double that implements Store need never grow them.
Governance profiles and their subject assignments (migration 0052).
This file is DUMB on purpose: it round-trips rows and owns exactly one piece of logic, ResolveGovernanceProfile's ORDER BY, so precedence is a property of the single indexed read, not a caller that could forget it. Every write is validated at the API boundary (internal/api/governance.go).
Governance changes (migration 0126): a governance write held for a second human. The store owns the parts that must be one transaction: proposing (expire a lapsed change at the same target, then insert) and deciding (lock the change row, require it pending and unexpired, run the target's apply, move the state, commit). It knows nothing about any target: the apply a caller hands DecideGovernanceChange is that target's own code, run on the decision transaction.
Member drives: a person's own drive, a user_drives row whose owner_subject names them. Ownership is the authority, so there are no grant rows. owner_subject is written once, on INSERT; no statement here updates it.
Package store provides typed CRUD over the Wardyn schema using pgx/v5. Callers supply contexts with deadlines. InsertAuditEvent stays a free function taking the pool explicitly since it predates a Store value in the audit.Recorder wiring.
Naming: Create* inserts and returns the hydrated row; Get* fetches by primary key (ErrNotFound when absent); List* returns a slice, empty never nil; Update*/Decide* are point mutations with explicit optimistic guards.
The Azure DevOps personal access tokens Wardyn creates for `minted_pat` runs (migration 0102, #1428): the record that makes a token revocable after a crash. A row holds no secret; the token value lives in daemon memory only.
The console's reads of ado_run_pats (#1428): every token a run held, and the newest token created for a person on a row. Like the table, neither carries a secret.
The Azure DevOps sign-in end counter (migration 0129): per person, how many times their sign-in was disconnected or erased and whether one is running now, so a run token created on any replica across one of those ends revokes itself. The row holds no secret.
Per-user API tokens. Kept out of store.go on purpose (lint size boundary), mirroring store_sshkeys.go's split.
SECURITY: the raw token never reaches SQL — every method here hashes it with hashToken before touching the table, so token_sha256 is the only form that exists at rest.
The reads the attention projection and GET /me/attention need beyond what GET /runs already scoped: every PENDING approval on a batch of runs, in one query, so paging runs costs one extra round trip regardless of how many are held; and the two scoped PENDING counts /me/attention answers, counted in the database rather than by listing every row.
The attach lease (migration 0129): the one writer slot of a run's shared terminal, in Postgres so every replica agrees who holds it. The database's clock decides when a lease lapses.
Console branding (migration 0091_branding). One row or none; the request is validated at the API boundary (internal/api/branding.go).
Capability grants and the per-kind enforcement switch (migration 0042). Kept out of store.go on purpose, mirroring store_sshkeys.go's split.
Custom components (migration 0136_components) and the snapshot of the ones a run launched with (migration 0137_run_components). Round-trips rows; a definition is validated at the API boundary. See ComponentStore (iface.go).
Registered portals and the delegated tokens they are handed. Like store_apitokens.go and store_devices.go, every method hashes the RAW credential with hashToken before it reaches SQL.
Hybrid enrolment and audit federation (migration 0066): the organisation-side device inventory (devices, device_enrolment_tokens) and the laptop side's durable forwarder cursor (org_federation). Kept out of store.go (already at a lint size boundary), mirroring store_apitokens.go/store_sshkeys.go's split.
SECURITY: hashToken (store_ephemeral.go) is reused for both credential tables — the raw device bearer and raw enrolment token never reach a row, only hex(sha256(raw)).
Short-lived control-plane handoff row (migration 0026): single-use WS attach tickets, durable and shared across every control plane — an in-process map can't survive a restart or be seen by a second control plane. Consume-once is a single DELETE ... RETURNING, atomic under concurrency and across processes.
The sign-in gate and the owner guard: how a suspended identity is refused at issuance and how a credential minted during a suspension is refused at its insert (migration 0113, 0127).
Launch presets (migration 0087_launch_presets). Round-trips rows; the request body is validated at the API boundary (internal/api/presets.go).
The store half of leaver deprovisioning: the SCIM projection on an identity row, the suspension and reactivation transactions, and the durable step ledger (migration 0127).
The identity row every successful sign-in leaves (migration 0113).
Per-person preferences (migration 0080_user_view_type).
A held push's complete path list (migration 0085_push_content_paths).
Remote-hosted runners (migration 0173): the server's own Docker host or Kubernetes cluster, one row per configured substrate name, with a display name and the "Available to people's pools" policy. Every write takes the row FOR UPDATE and raises its revision; a person's add into their own user pool reads it FOR SHARE at the revision whose policy was checked (AddRemoteRunnerToUserPool).
Console-managed role mappings (migration 0051): the store half of internal/auth/oidc's RoleMappingSource. Kept out of store.go on purpose, mirroring store_capabilities.go's split.
The run lease (long-holds design rev 4; migration 0073): the reads and the conditional writes the lease sweep needs. Kept out of store.go for the same size reason as store_watcher.go.
Lost-run surface (long-holds design rev 4, RL-9; migration 0083): token stamp, lapsed-token read, and lost claim. Split out of store.go for size, like store_run_lease.go.
The live exec tail (migration 0129): the masked bytes a run's dispatching replica has printed so far, readable from any replica. One final row per run is run_outputs' (0122); these chunks are what stands in for it until that row is written, and what a recovery falls back to when the substrate cannot be re-read.
The persisted run output (migration 0119): one masked final row per run, the pending row that records a capture is owed, and the erasure tombstones that keep an erased run's output erased. Kept out of store.go for the same size reason as store_watcher.go.
Pause and resume (long-holds design rev 4, §3, RL-7; migration 0097): the presence clock, the reads the pause sweep needs and its conditional writes. Kept out of store.go for the same size reason as store_run_lease.go.
A run's sealed proxy config (#1176, migration 0093): what a revive rebuilds the run's proxy from, so the proxy container never holds it at rest.
Tightened limits reach live runs (long-holds design rev 4, §2.2, RL-8; migration 0095): the read and the conditional write the re-clamp sweep needs. Kept out of store.go for the same size reason as store_run_lease.go.
Revive and restart with current limits (long-holds design rev 4, RL-10 and RL-11; migration 0084): the claim a revive makes before it replaces a run's proxy, and the read the admin version-window listing makes.
Run templates (migration 0165_run_templates): the catalogue row, its immutable revisions, the group-management grants and the group labels. A document is validated at the API boundary and stored as the door returned it. See TemplateStore (iface.go).
The runner pool catalogue (migrations 0152, 0168, 0173): pools, their members, the use policy of an organization pool and the organisation's default. Every write that changes a pool, its members or its use policy holds the pool row and raises its revision by one in the same transaction, so a run admitted against a revision can tell that the pool moved. Whether a caller may use a pool is the API's rule, never this file's.
Registered runners and the credential delivery policy (migration 0139); pending actions are in store_runner_actions.go. Registration tokens and the routes that mint and consume them are a later lane's; this file is the rows the stream, the claim and the pending-action queue read and write.
Landing-page GET /runs scoping: RunFilter, the filtered list read, and hidden-row counts. Attention projection lives elsewhere; this file only scopes, windows and orders the bare AgentRun rows.
Sandbox ref -> substrate routing rows (migration 0021): the Postgres RefStore, letting a control-plane restart rehydrate lifecycle routing in multi-substrate deployments.
SSH gateway key registry. Kept out of store.go on purpose (lint size boundary), mirroring store_sandbox_ref.go's split.
Per-user run-detail cockpit widget-layout persistence (migration 0037). Kept out of store.go/iface.go on purpose — see RunLayoutStore's doc below.
User types (migration 0071_user_types). Round-trips rows; every write is validated at the API boundary (internal/api/user_types.go).
The run-watcher lease (migration 0027): two writes that make "who is responsible for finishing this run" a fact in Postgres, not a goroutine in one process. Kept out of store.go (lint size); shares run columns with store.go's CreateRun/GetRun and pagination.go's ListRunsPage.
The workspaces table (tier 3 of the three-tier split): JSONB parameter helpers, the wsCols column list, scanWorkspace, and the CRUD and scoped-writer methods PG exposes over a workspace row. store_sources.go is the read/hydrate half of the pair (tiers 1-2 plus s.hydrated).
User drives and their subject grants (migration 0054), split out of store.go like governance.go. Kept DUMB: round-trips rows, owns only ResolveUserDrive's ORDER BY (precedence must live in the one indexed read, not a caller). Writes are validated at the API boundary (types.ValidateUserDrive, types.ValidateUserDriveGrant).
Index ¶
- Constants
- Variables
- func AddRunnerPoolExecutorQ(ctx context.Context, q Querier, id uuid.UUID, executor string) (m types.RunnerPoolMember, added bool, rev int64, err error)
- func CapAuditTarget(target string) string
- func CreateServiceIdentityQ(ctx context.Context, tx Querier, si types.ServiceIdentity) (types.ServiceIdentity, error)
- func DeleteCapabilityGrantQ(ctx context.Context, q Querier, id uuid.UUID) error
- func DeleteGovernanceAssignmentQ(ctx context.Context, q Querier, id uuid.UUID) error
- func DeleteGovernanceProfileQ(ctx context.Context, q Querier, id uuid.UUID) error
- func DeleteRoleMappingQ(ctx context.Context, q Querier, id uuid.UUID) error
- func DeleteRunnerPoolUsePolicyQ(ctx context.Context, q Querier, id uuid.UUID) error
- func ExecRevocationCut(ctx context.Context, q batcher, sql string, args ...any) error
- func FederatedActor(deviceID uuid.UUID, claimed string) string
- func FederatedDeviceID(ev types.AuditEvent) *uuid.UUID
- func FederatedRowProblem(r types.FederatedAuditEvent) string
- func GetCapabilityEnforcementQ(ctx context.Context, q Querier) (map[string]bool, error)
- func GetCapabilityGrantByKeyQ(ctx context.Context, q Querier, subjectType, subject, capability, value string, ...) (types.CapabilityGrant, error)
- func GetCapabilityGrantQ(ctx context.Context, q Querier, id uuid.UUID, forUpdate bool) (types.CapabilityGrant, error)
- func GetCredentialDeliveryPolicyQ(ctx context.Context, q Querier) (types.CredentialDeliveryPolicyDoc, error)
- func GetGovernanceAssignmentByKeyQ(ctx context.Context, q Querier, subjectType, subject string, forUpdate bool) (types.GovernanceAssignment, error)
- func GetGovernanceAssignmentQ(ctx context.Context, q Querier, id uuid.UUID, forUpdate bool) (types.GovernanceAssignment, error)
- func GetGovernanceProfileQ(ctx context.Context, q Querier, id uuid.UUID, forUpdate bool) (types.GovernanceProfile, error)
- func GetLiveAPITokenQ(ctx context.Context, q Querier, id uuid.UUID) (types.APIToken, error)
- func GetRemoteRunnerQ(ctx context.Context, q Querier, id string, forUpdate bool) (types.RemoteRunner, error)
- func GetRunnerPoolUsePolicyQ(ctx context.Context, q Querier, id uuid.UUID) (types.RunnerPoolUsePolicy, error)
- func GetServiceIdentityForUpdateQ(ctx context.Context, tx Querier, name string) (types.ServiceIdentity, error)
- func GetSiteConfigQ(ctx context.Context, q Querier) (types.SiteConfig, error)
- func GetUserTypeQ(ctx context.Context, q Querier, id string, forUpdate bool) (types.UserType, error)
- func IdentityBlockedQ(ctx context.Context, q Querier, principal string, epoch int64) (bool, error)
- func InsertAuditEvent(ctx context.Context, pool *pgxpool.Pool, ev *types.AuditEvent) error
- func InsertAuditEventTx(ctx context.Context, tx pgx.Tx, ev *types.AuditEvent) error
- func LiftComponentRestrictionQ(ctx context.Context, q Querier, id uuid.UUID, _ string) error
- func ListCapabilityGrantsQ(ctx context.Context, q Querier) ([]types.CapabilityGrant, error)
- func ListCapabilityRestrictionsQ(ctx context.Context, q Querier) (map[string]map[string]bool, error)
- func ListGovernanceProfilesQ(ctx context.Context, q Querier) ([]types.GovernanceProfile, error)
- func ListRoleMappingsQ(ctx context.Context, q Querier) ([]types.RoleMapping, error)
- func ListUserTypesQ(ctx context.Context, q Querier) ([]types.UserType, error)
- func LockGovernanceAssignmentKey(ctx context.Context, q Querier, subjectType, subject string) error
- func LockGovernanceGraph(ctx context.Context, q Querier) error
- func LockGovernanceTarget(ctx context.Context, q Querier, kind string, parts ...string) error
- func LockLivePoolQ(ctx context.Context, q Querier, id uuid.UUID) error
- func LockRevocationOrder(ctx context.Context, tx Querier) error
- func LockSiteConfig(ctx context.Context, q Querier) error
- func PutCapabilityEnforcementQ(ctx context.Context, q Querier, enabled map[string]bool) (map[string]bool, error)
- func PutCredentialDeliveryPolicyQ(ctx context.Context, q Querier, policy json.RawMessage, by string, ...) (types.CredentialDeliveryPolicyDoc, error)
- func PutRunnerPoolUsePolicyQ(ctx context.Context, q Querier, id uuid.UUID, revision *int64, ...) (types.RunnerPoolUsePolicy, error)
- func PutSiteConfigQ(ctx context.Context, q Querier, cfg types.SiteConfig) (types.SiteConfig, error)
- func ReadRevocationSeq(ctx context.Context, q batcher) (int64, error)
- func RemoveRunnerPoolExecutorQ(ctx context.Context, q Querier, id uuid.UUID, executor string) (bool, int64, error)
- func RunnerPoolExecutorIDsQ(ctx context.Context, q Querier, id uuid.UUID) ([]string, error)
- func SetCapabilityRestrictionQ(ctx context.Context, q Querier, capability, value string, restricted bool, ...) error
- func SetRemoteRunnerPeopleQ(ctx context.Context, q Querier, id string, revision *int64, ...) (types.RemoteRunner, error)
- func TemplateLimit(owner types.TemplateOwner) int
- func UpdateUserTypeQ(ctx context.Context, q Querier, t types.UserType) (types.UserType, error)
- func UpsertCapabilityGrantQ(ctx context.Context, q Querier, g types.CapabilityGrant) (types.CapabilityGrant, error)
- func UpsertGovernanceAssignmentQ(ctx context.Context, q Querier, a types.GovernanceAssignment) (types.GovernanceAssignment, error)
- func UpsertRoleMappingQ(ctx context.Context, q Querier, m types.RoleMapping) (types.RoleMapping, error)
- func WithIdentityGuard(ctx context.Context, g IdentityGuard) context.Context
- func WriteGovernanceProfileQ(ctx context.Context, q Querier, id uuid.UUID, build GovernanceProfileBuild) (types.GovernanceProfile, error)
- type ADOSignInEndState
- type ADOSignInEndStore
- type APITokensByIdentityLister
- type APITokensByPrincipalPager
- type AWSSSOSpentTokenStore
- type ActiveRunsAtPathReader
- type ActiveRunsByCreatorReader
- type ApprovalNotifyReader
- type ApprovalsByRunCreatorPager
- type ApprovalsByRunPager
- type ApprovalsForRunsPager
- type AttachLease
- type AttachLeaseStore
- type AttachTicket
- type AuditChainStatus
- type AuditChainVerifier
- type AuditDeliveryStatus
- type AuditFilter
- type AuditPartitionExporter
- type AuditPartitionRow
- type AuditRetention
- type AuditRetentionDrop
- type AuditRetentionPartition
- type AuditRetentionPolicy
- type AuditRetentionPolicyChange
- type AuditRetentionRefused
- type AuditRetentionStatus
- type AuditSplitRange
- type AuditSplitRefused
- type AuditSplitResult
- type BrandingStore
- type CapabilityGrantsForPager
- type ComponentRestrictionLifter
- type ComponentStore
- type DecidedAlwaysEgressPager
- type DelegateReader
- type DelegateStore
- type DeprovisionFailure
- type DeprovisionJob
- type DeviceIngestResult
- type DeviceStore
- type DueIdentity
- type EndedKept
- type ErrGovernanceChangeNotPending
- type ErrGovernanceChangePending
- type ErrProfileHasChildren
- type ExpiredGovernanceChange
- type GovernanceDecideFunc
- type GovernanceDecision
- type GovernanceProfileBuild
- type GrantsByRunPager
- type IdentityGuard
- type IdentityUnbinder
- type IdentityUpdate
- type InvitationClaim
- type InvitationClaimed
- type InvitationStore
- type JobKey
- type LaunchIntentRecord
- type LaunchIntentStore
- type LeaverStore
- type LoginIdentity
- type LoginLocker
- type MemRunPATs
- func (m *MemRunPATs) InsertRunPAT(_ context.Context, p RunPAT) error
- func (m *MemRunPATs) LastRunPAT(_ context.Context, owner, providerRowID string) (RunPAT, bool, error)
- func (m *MemRunPATs) ListRunPATs(_ context.Context, runID uuid.UUID) ([]RunPAT, error)
- func (m *MemRunPATs) ListUnrevokedRunPATs(_ context.Context, f RunPATFilter) ([]RunPAT, error)
- func (m *MemRunPATs) MarkRunPATRevoked(_ context.Context, runID, authorizationID uuid.UUID, reason, lastError string) (bool, error)
- func (m *MemRunPATs) NoteRunPATRevokeFailed(_ context.Context, runID, authorizationID uuid.UUID, lastError string) error
- type MemberDriveStore
- type PG
- func (s PG) ADOSignInEnds(ctx context.Context, owner string) (ADOSignInEndState, error)
- func (s PG) AWSSSOTokenSpent(ctx context.Context, fingerprint string) (bool, error)
- func (s PG) AbortMemberDriveDelete(ctx context.Context, id uuid.UUID, started time.Time) error
- func (s PG) AcceptRunnerExit(ctx context.Context, runnerID, runID uuid.UUID, exit runnerwire.AgentExit, ...) (bool, error)
- func (s PG) AcquireAttachLease(ctx context.Context, l AttachLease, from uuid.UUID, ttl time.Duration) (bool, error)
- func (s PG) ActiveRunsAtWorkspacePath(ctx context.Context, workspacePath string) ([]types.AgentRun, error)
- func (s PG) ActiveRunsByCreator(ctx context.Context, createdBy, task, agent string) ([]types.AgentRun, error)
- func (s PG) AddOwnRunnerToPool(ctx context.Context, id, runnerID uuid.UUID, owner, orgURLSHA256 string) (types.RunnerPoolMember, bool, int64, error)
- func (s PG) AddRemoteRunnerToUserPool(ctx context.Context, id uuid.UUID, remoteRunner, owner string, ...) (types.RunnerPoolMember, bool, int64, error)
- func (s PG) AddRunnerPoolExecutor(ctx context.Context, id uuid.UUID, executor string) (types.RunnerPoolMember, bool, int64, error)
- func (s PG) AddSSHKey(ctx context.Context, k types.SSHPublicKey) (types.SSHPublicKey, error)
- func (s PG) AddScimGroupMembers(ctx context.Context, id uuid.UUID, identities []uuid.UUID, now time.Time) error
- func (s PG) AddUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, error)
- func (s PG) AddWorkspaceEgressDecision(ctx context.Context, id uuid.UUID, host string, allow bool, ...) (types.Workspace, error)
- func (s PG) AppendRunOutputChunk(ctx context.Context, runID uuid.UUID, replica string, b []byte, keep int) (bool, error)
- func (s PG) ApplyIdentityUpdate(ctx context.Context, id uuid.UUID, u IdentityUpdate, now time.Time) (PrincipalIdentity, error)
- func (s PG) ApprovalEscalations(ctx context.Context, ids []uuid.UUID, now time.Time) (map[uuid.UUID]types.ApprovalEscalation, error)
- func (s PG) ApprovalNotifyChannelStats(ctx context.Context, now time.Time) ([]types.ApprovalNotifyChannelStat, error)
- func (s PG) AuditDeliveryStatuses(ctx context.Context) ([]AuditDeliveryStatus, error)
- func (s PG) AuditHeadSeq(ctx context.Context) (int64, error)
- func (s PG) AuditKeyDestroyedAt(ctx context.Context, owner string) (time.Time, bool, error)
- func (s PG) AuditPartitionsAhead(ctx context.Context) (int, error)
- func (s PG) AuditPrincipalOf(ctx context.Context, id string) (string, bool, error)
- func (s PG) AuditRetentionStatus(ctx context.Context) (AuditRetentionStatus, error)
- func (s PG) AuditSubjectFor(ctx context.Context, principal string) (string, bool, error)
- func (s PG) AutodropAuditPartition(ctx context.Context) (AuditRetentionDrop, bool, error)
- func (s PG) BeginADOSignInEnd(ctx context.Context, owner, reason string) error
- func (s PG) BeginMemberDriveDelete(ctx context.Context, owner string, id uuid.UUID) (types.UserDrive, time.Time, error)
- func (s PG) BeginMemberDriveDeleteAdmin(ctx context.Context, id uuid.UUID) (types.UserDrive, time.Time, error)
- func (s PG) BeginRunnerExecution(ctx context.Context, runnerID, runID, previous, generation uuid.UUID, ...) (RunnerExecution, error)
- func (s PG) BeginRunnerInventory(ctx context.Context, runnerID uuid.UUID, sessionID string) error
- func (s PG) BindRunnerExecution(ctx context.Context, runnerID, runID, generation uuid.UUID, execID string) error
- func (s PG) BlankRunTasks(ctx context.Context, createdBy string) (int, error)
- func (s PG) BootstrapRunnerPools(ctx context.Context, executors []string, name string) (*types.RunnerPool, *types.RunnerPoolDefaults, error)
- func (s PG) ClaimInvitation(ctx context.Context, c InvitationClaim) (InvitationClaimed, error)
- func (s PG) ClaimRecordingRunOutput(ctx context.Context, runID uuid.UUID, retention, staleAfter time.Duration) (RecordingOutputClaim, bool, error)
- func (s PG) ClaimRunner(ctx context.Context, id uuid.UUID, owner, fingerprint string, now time.Time) (types.Runner, error)
- func (s PG) ClaimSourceActiveRun(ctx context.Context, id, runID uuid.UUID) error
- func (s PG) ClaimStaleRunWatchers(ctx context.Context, owner string, staleAfter time.Duration) ([]types.AgentRun, error)
- func (s PG) ClaimWorkspaceActiveRun(ctx context.Context, id, runID uuid.UUID, expected *uuid.UUID) (types.Workspace, bool, error)
- func (s PG) ClearPauseSettle(ctx context.Context, id uuid.UUID, due time.Time) error
- func (s PG) ClearRunContainmentError(ctx context.Context, id uuid.UUID) (bool, error)
- func (s PG) ClearRunPaused(ctx context.Context, id uuid.UUID) (bool, error)
- func (s PG) ClearSourceActiveRun(ctx context.Context, id, runID uuid.UUID) error
- func (s PG) ClearWorkspaceActiveRun(ctx context.Context, id, runID uuid.UUID) (bool, error)
- func (s PG) ConsumeAttachTicket(ctx context.Context, token string, now time.Time) (AttachTicket, bool, error)
- func (s PG) ConsumeEnrolmentToken(ctx context.Context, token string, now time.Time) (types.DeviceEnrolmentToken, bool, error)
- func (s PG) ConsumeRunnerRegistrationToken(ctx context.Context, raw, orgHash string, now time.Time) (types.RunnerRegistrationToken, bool, error)
- func (s PG) CountActiveRunsBy(ctx context.Context, createdBy string) (int, error)
- func (s PG) CountApprovalsForRun(ctx context.Context, runID uuid.UUID) (int, error)
- func (s PG) CountComponents(ctx context.Context, owner string) (int, error)
- func (s PG) CountHiddenRuns(ctx context.Context, f RunFilter) (olderHidden, killedHidden int, err error)
- func (s PG) CountNonTerminalRuns(ctx context.Context, except uuid.UUID) (int, error)
- func (s PG) CountPendingApprovals(ctx context.Context) (int, error)
- func (s PG) CountPendingApprovalsByRunCreator(ctx context.Context, createdBy string) (int, error)
- func (s PG) CountPushPathLists(ctx context.Context, runID uuid.UUID) (int, error)
- func (s PG) CountQueuedRunsByOwner(ctx context.Context, poolID uuid.UUID, owner string) (int, error)
- func (s PG) CountRunnerPoolSlotHolders(ctx context.Context, poolID uuid.UUID) (int, error)
- func (s PG) CreateAPIToken(ctx context.Context, t types.APIToken, raw string) (types.APIToken, error)
- func (s PG) CreateApproval(ctx context.Context, a types.ApprovalRequest) (types.ApprovalRequest, error)
- func (s PG) CreateComponent(ctx context.Context, c types.Component) (types.Component, error)
- func (s PG) CreateDelegate(ctx context.Context, d types.Delegate, raw string) (types.Delegate, error)
- func (s PG) CreateDevice(ctx context.Context, d types.Device, raw string) (types.Device, error)
- func (s PG) CreateGrant(ctx context.Context, g types.CredentialGrant) (types.CredentialGrant, error)
- func (s PG) CreateInvitation(ctx context.Context, inv types.Invitation, maxPending int, now time.Time) (types.Invitation, error)
- func (s PG) CreateMemberDrive(ctx context.Context, d types.UserDrive, limit int) (types.UserDrive, error)
- func (s PG) CreatePerson(ctx context.Context, p types.Person) (types.Person, bool, error)
- func (s PG) CreatePolicy(ctx context.Context, p types.RunPolicy) (types.RunPolicy, error)
- func (s PG) CreateQueuedRun(ctx context.Context, r types.AgentRun, e RunQueueEntry, maxPerOwner int) (types.AgentRun, error)
- func (s PG) CreateRestrictedComponent(ctx context.Context, c types.Component, capability, by string) (types.Component, error)
- func (s PG) CreateRun(ctx context.Context, r types.AgentRun) (types.AgentRun, error)
- func (s PG) CreateRunUnderCap(ctx context.Context, r types.AgentRun, limit int) (types.AgentRun, error)
- func (s PG) CreateRunner(ctx context.Context, r types.Runner) (types.Runner, error)
- func (s PG) CreateRunnerPool(ctx context.Context, p types.RunnerPool, by string) (types.RunnerPool, error)
- func (s PG) CreateScimGroup(ctx context.Context, externalID, displayName string, now time.Time) (ScimGroup, error)
- func (s PG) CreateScimIdentity(ctx context.Context, issuer, tenantID, objectID string, u IdentityUpdate, ...) (PrincipalIdentity, bool, error)
- func (s PG) CreateServiceIdentity(ctx context.Context, si types.ServiceIdentity) (types.ServiceIdentity, error)
- func (s PG) CreateServiceToken(ctx context.Context, name, sponsor string, maxLive int, t types.APIToken, ...) (types.APIToken, error)
- func (s PG) CreateTemplate(ctx context.Context, t types.RunTemplate, grant *TemplateGrantCheck) (types.RunTemplate, error)
- func (s PG) CreateUserType(ctx context.Context, t types.UserType) (types.UserType, error)
- func (s PG) CreateWorkspace(ctx context.Context, ws types.Workspace) (types.Workspace, error)
- func (s PG) DecideApproval(ctx context.Context, id uuid.UUID, decision types.ApprovalDecision) (types.ApprovalRequest, error)
- func (s PG) DecideGovernanceChange(ctx context.Context, id uuid.UUID, d GovernanceDecision, ...) (types.GovernanceChange, error)
- func (s PG) DeleteBaseImage(ctx context.Context, id uuid.UUID, detach bool) error
- func (s PG) DeleteBranding(ctx context.Context) (bool, error)
- func (s PG) DeleteCapabilityGrant(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteComponent(ctx context.Context, id uuid.UUID, owner string) (types.Component, error)
- func (s PG) DeleteComponentsByOwner(ctx context.Context, owner string) (int, error)
- func (s PG) DeleteGovernanceAssignment(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteGovernanceProfile(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteLaunchIntentsCreatedBy(ctx context.Context, createdBy string) (int, error)
- func (s PG) DeleteLaunchPreset(ctx context.Context, name string) (types.LaunchPreset, error)
- func (s PG) DeletePolicy(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteRef(ctx context.Context, ref string) error
- func (s PG) DeleteRestrictedComponent(ctx context.Context, id uuid.UUID, capability, by string) (types.Component, int, bool, error)
- func (s PG) DeleteRoleMapping(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteRunOutputsOlderThan(ctx context.Context, age time.Duration) (int, error)
- func (s PG) DeleteRunProxyConfig(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteRunnerPool(ctx context.Context, id uuid.UUID) (RunnerPoolDeletion, error)
- func (s PG) DeleteRunnerPoolUsePolicy(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteRunnerPoolsByOwner(ctx context.Context, owner string) ([]RunnerPoolDeletion, error)
- func (s PG) DeleteSSHKey(ctx context.Context, fingerprint, principal string) error
- func (s PG) DeleteSSHKeys(ctx context.Context, principal string) (int, error)
- func (s PG) DeleteScimGroup(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteSource(ctx context.Context, id uuid.UUID, detach bool) error
- func (s PG) DeleteTemplate(ctx context.Context, id uuid.UUID, grant *TemplateGrantCheck) (types.RunTemplate, error)
- func (s PG) DeleteTemplateGroupAdmin(ctx context.Context, group, person string) (bool, error)
- func (s PG) DeleteUserDrive(ctx context.Context, id uuid.UUID) error
- func (s PG) DeleteUserDriveGrant(ctx context.Context, id uuid.UUID) (types.UserDriveGrant, error)
- func (s PG) DeleteUserSubjectRows(ctx context.Context, id uuid.UUID, principals, emails []string) (grants, assignments, kept int64, err error)
- func (s PG) DeleteUserType(ctx context.Context, id string) error
- func (s PG) DeleteWorkspace(ctx context.Context, id uuid.UUID) error
- func (s PG) DropAuditPartition(ctx context.Context, partition, digest, actor string, ...) (AuditRetentionDrop, error)
- func (s PG) DryRunGovernance(ctx context.Context, fn func(q Querier) error) error
- func (s PG) DuePauseSettles(ctx context.Context) ([]PauseSettle, error)
- func (s PG) EnsureAuditDeliveryCursor(ctx context.Context, dest string) error
- func (s PG) EnsureAuditPartitions(ctx context.Context, months int) (int, error)
- func (s PG) EnsureDeprovisionJobs(ctx context.Context, identityID uuid.UUID, kind string, keys []JobKey) error
- func (s PG) EnsureRemoteRunners(ctx context.Context, ids []string, proposals map[string]types.RunnerLimits) (made, proposed []types.RemoteRunner, err error)
- func (s PG) EraseGovernanceChangePersonalFields(ctx context.Context, principals, emails []string) (int, error)
- func (s PG) EraseInvitationsOf(ctx context.Context, person string) (deleted, cleared int, err error)
- func (s PG) EraseRecordingRunOutputs(ctx context.Context, runIDs []uuid.UUID) (int, error)
- func (s PG) EraseRunComponentsByOwner(ctx context.Context, owner string) (int, error)
- func (s PG) EraseRunComponentsOfRun(ctx context.Context, runID uuid.UUID, owner string) (int, error)
- func (s PG) EraseRunOutputs(ctx context.Context, runIDs []uuid.UUID) error
- func (s PG) EraseRunSetupsOf(ctx context.Context, person string) (RunSetupsErased, error)
- func (s PG) EraseServiceIdentityAttributionOf(ctx context.Context, person string) (cleared int, sponsored []string, err error)
- func (s PG) ExitQueuedRun(ctx context.Context, id uuid.UUID, to types.RunState, detail, hint string) (bool, error)
- func (s PG) ExpireUnclaimedRunners(ctx context.Context, createdBefore time.Time) (int, error)
- func (s PG) ExpiredQueueEntries(ctx context.Context, now time.Time, limit int) ([]RunQueueEntry, error)
- func (s PG) ExportAuditPartition(ctx context.Context, name string, header func(PartitionManifest) error, ...) error
- func (s PG) FailDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey, cause error) error
- func (s PG) FederationRevoked(ctx context.Context) (bool, error)
- func (s PG) FinishADOSignInEnd(ctx context.Context, owner string) error
- func (s PG) FinishDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey, ...) error
- func (s PG) FinishMemberDriveDelete(ctx context.Context, id uuid.UUID, started time.Time) error
- func (s PG) GetAPITokenByRaw(ctx context.Context, raw string) (types.APIToken, error)
- func (s PG) GetApproval(ctx context.Context, id uuid.UUID) (types.ApprovalRequest, error)
- func (s PG) GetAttachLease(ctx context.Context, runID uuid.UUID) (AttachLease, bool, error)
- func (s PG) GetAuditDeliveryCursor(ctx context.Context, dest string) (int64, string, error)
- func (s PG) GetBaseImage(ctx context.Context, id uuid.UUID) (types.BaseImageEntry, error)
- func (s PG) GetBaseImagesByIDs(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]types.BaseImageEntry, error)
- func (s PG) GetBranding(ctx context.Context) (types.Branding, error)
- func (s PG) GetCapabilityEnforcement(ctx context.Context) (map[string]bool, error)
- func (s PG) GetComponent(ctx context.Context, id uuid.UUID, owner string) (types.Component, error)
- func (s PG) GetCredentialDeliveryPolicy(ctx context.Context) (types.CredentialDeliveryPolicyDoc, error)
- func (s PG) GetDelegateByID(ctx context.Context, id uuid.UUID) (types.Delegate, error)
- func (s PG) GetDelegateByRaw(ctx context.Context, raw string) (types.Delegate, error)
- func (s PG) GetDelegatedTokenByID(ctx context.Context, id uuid.UUID, now time.Time) (types.DelegatedToken, error)
- func (s PG) GetDelegatedTokenByRaw(ctx context.Context, raw string, now time.Time) (types.DelegatedToken, error)
- func (s PG) GetDeviceByRaw(ctx context.Context, raw string) (types.Device, error)
- func (s PG) GetFederationCursor(ctx context.Context) (int64, string, error)
- func (s PG) GetGovernanceChange(ctx context.Context, id uuid.UUID) (types.GovernanceChange, error)
- func (s PG) GetGovernanceProfile(ctx context.Context, id uuid.UUID) (types.GovernanceProfile, error)
- func (s PG) GetGovernanceProfileChain(ctx context.Context, id uuid.UUID) ([]types.GovernanceProfile, error)
- func (s PG) GetIdentity(ctx context.Context, id uuid.UUID) (PrincipalIdentity, error)
- func (s PG) GetIdentityByObject(ctx context.Context, issuer, tenantID, objectID string) (PrincipalIdentity, error)
- func (s PG) GetInvitation(ctx context.Context, id uuid.UUID, target string) (types.Invitation, error)
- func (s PG) GetLaunchIntent(ctx context.Context, runID uuid.UUID, createdBy string) (LaunchIntentRecord, error)
- func (s PG) GetLaunchPreset(ctx context.Context, name string) (types.LaunchPreset, error)
- func (s PG) GetMemberDriveOf(ctx context.Context, owner string, id uuid.UUID) (types.UserDrive, error)
- func (s PG) GetPerson(ctx context.Context, principal string) (types.Person, error)
- func (s PG) GetPolicy(ctx context.Context, id uuid.UUID) (types.RunPolicy, error)
- func (s PG) GetPrincipalPref(ctx context.Context, principal, key string) (json.RawMessage, error)
- func (s PG) GetPushPathList(ctx context.Context, approvalID uuid.UUID) (types.PushPathList, error)
- func (s PG) GetRef(ctx context.Context, ref string) (string, bool, error)
- func (s PG) GetRemoteRunner(ctx context.Context, id string) (RemoteRunnerRow, error)
- func (s PG) GetRun(ctx context.Context, id uuid.UUID) (types.AgentRun, error)
- func (s PG) GetRunLayout(ctx context.Context, principal, preset string) (types.RunLayout, error)
- func (s PG) GetRunOutput(ctx context.Context, runID uuid.UUID) (RunOutput, bool, error)
- func (s PG) GetRunProxyConfig(ctx context.Context, id uuid.UUID) ([]byte, error)
- func (s PG) GetRunQueueEntry(ctx context.Context, id uuid.UUID) (RunQueueEntry, error)
- func (s PG) GetRunner(ctx context.Context, id uuid.UUID) (types.Runner, error)
- func (s PG) GetRunnerPool(ctx context.Context, id uuid.UUID) (types.RunnerPool, error)
- func (s PG) GetRunnerPoolOrgDefaults(ctx context.Context) (types.RunnerPoolDefaults, error)
- func (s PG) GetSSHKeyByFingerprint(ctx context.Context, fingerprint string) (types.SSHPublicKey, error)
- func (s PG) GetScimGroup(ctx context.Context, id uuid.UUID) (ScimGroup, error)
- func (s PG) GetServiceIdentity(ctx context.Context, name string) (types.ServiceIdentity, error)
- func (s PG) GetSiteConfig(ctx context.Context) (types.SiteConfig, error)
- func (s PG) GetSource(ctx context.Context, id uuid.UUID) (types.Source, error)
- func (s PG) GetSourcesByIDs(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]types.Source, error)
- func (s PG) GetTemplate(ctx context.Context, id uuid.UUID) (types.RunTemplate, error)
- func (s PG) GetTemplateRevision(ctx context.Context, id uuid.UUID, revision int) (types.RunTemplate, error)
- func (s PG) GetUserDrive(ctx context.Context, id uuid.UUID) (types.UserDrive, error)
- func (s PG) GetUserType(ctx context.Context, id string) (types.UserType, error)
- func (s PG) GetWorkspace(ctx context.Context, id uuid.UUID) (types.Workspace, error)
- func (s PG) GroupRemovalFailures(ctx context.Context, limit int) ([]DeprovisionFailure, error)
- func (s PG) GroupRemovalIdentities(ctx context.Context, groupID uuid.UUID) ([]uuid.UUID, error)
- func (s PG) HasGroupTierAssignments(ctx context.Context) (bool, error)
- func (s PG) HasGroupTierDriveGrants(ctx context.Context) (bool, error)
- func (s PG) HasRunAuditEvent(ctx context.Context, runID uuid.UUID, f AuditFilter) (bool, error)
- func (s PG) HeartbeatRunWatcher(ctx context.Context, id uuid.UUID, owner string) error
- func (s PG) HeldEmails(ctx context.Context, id uuid.UUID, principals, emails []string) ([]string, error)
- func (s PG) HoldsAttachLease(ctx context.Context, runID, holderID uuid.UUID) (bool, error)
- func (s PG) IdentitiesByAlias(ctx context.Context, issuer, valueLower string) ([]PrincipalIdentity, error)
- func (s PG) IdentitiesByPrincipal(ctx context.Context, principal string) ([]PrincipalIdentity, error)
- func (s PG) IdentityAliasValues(ctx context.Context, id uuid.UUID) ([]string, error)
- func (s PG) IdentityBlocked(ctx context.Context, principal string, epoch int64) (bool, error)
- func (s PG) IdentityRefused(ctx context.Context, issuer, tenantID, objectID, principal string) (bool, error)
- func (s PG) IngestDeviceAudit(ctx context.Context, deviceID uuid.UUID, peer string, ...) (DeviceIngestResult, error)
- func (s PG) IngestRunnerDecision(ctx context.Context, runnerID uuid.UUID, row runnerspool.Record, ...) (bool, error)
- func (s PG) InsertPendingRunOutput(ctx context.Context, runID uuid.UUID) error
- func (s PG) InsertRunPAT(ctx context.Context, p RunPAT) error
- func (s PG) IntakeRunnerStatePage(ctx context.Context, runnerID uuid.UUID, sessionID string, ...) (RunnerInventoryResult, error)
- func (s PG) IssueLoginIdentity(ctx context.Context, in LoginIdentity, now time.Time) (epoch int64, err error)
- func (s PG) KillRunAtLifetimeIf(ctx context.Context, id uuid.UUID, reason types.RunEndReason, detail string, ...) (bool, error)
- func (s PG) LastRunPAT(ctx context.Context, owner, providerRowID string) (RunPAT, bool, error)
- func (s PG) LatestAuditEventByAction(ctx context.Context, action string) (types.AuditEvent, error)
- func (s PG) LeaveRunQueue(ctx context.Context, id uuid.UUID, to types.RunState, admittedAt *time.Time) (bool, error)
- func (s PG) LiftComponentRestriction(ctx context.Context, id uuid.UUID, by string) error
- func (s PG) ListAPITokens(ctx context.Context) ([]types.APIToken, error)
- func (s PG) ListAPITokensByIdentity(ctx context.Context, name string) ([]types.APIToken, error)
- func (s PG) ListAPITokensByPrincipal(ctx context.Context, principal string) ([]types.APIToken, error)
- func (s PG) ListAPITokensByPrincipalPage(ctx context.Context, principal string, p Page) ([]types.APIToken, error)
- func (s PG) ListApprovals(ctx context.Context, stateFilter types.ApprovalState) ([]types.ApprovalRequest, error)
- func (s PG) ListApprovalsPage(ctx context.Context, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
- func (s PG) ListApprovalsPageByRun(ctx context.Context, runID uuid.UUID, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
- func (s PG) ListApprovalsPageByRunCreator(ctx context.Context, createdBy string, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
- func (s PG) ListAuditEventsAfterSeq(ctx context.Context, seq int64, limit int) ([]types.FederatedAuditEvent, error)
- func (s PG) ListBaseImages(ctx context.Context) ([]types.BaseImageEntry, error)
- func (s PG) ListCapabilityGrants(ctx context.Context) ([]types.CapabilityGrant, error)
- func (s PG) ListCapabilityGrantsFor(ctx context.Context, users, groups []string, userType string) ([]types.CapabilityGrant, error)
- func (s PG) ListCapabilityGrantsForPage(ctx context.Context, users, groups []string, userType string, p Page) ([]types.CapabilityGrant, error)
- func (s PG) ListCapabilityRestrictions(ctx context.Context) (map[string]map[string]bool, error)
- func (s PG) ListComponents(ctx context.Context, owner string) ([]types.Component, error)
- func (s PG) ListComponentsByIDs(ctx context.Context, owner string, ids []uuid.UUID) ([]types.Component, error)
- func (s PG) ListDeactivatedIdentities(ctx context.Context, limit int) ([]PrincipalIdentity, error)
- func (s PG) ListDecidedAlwaysEgressPage(ctx context.Context, state types.ApprovalState, afterRequestedAt time.Time, ...) ([]types.ApprovalRequest, error)
- func (s PG) ListDelegates(ctx context.Context) ([]types.Delegate, error)
- func (s PG) ListDeprovisionFailures(ctx context.Context, limit int) ([]DeprovisionFailure, error)
- func (s PG) ListDeprovisionJobs(ctx context.Context, identityID uuid.UUID, kind string) ([]DeprovisionJob, error)
- func (s PG) ListDevices(ctx context.Context) ([]types.Device, error)
- func (s PG) ListEnrolmentTokens(ctx context.Context, now time.Time) ([]types.DeviceEnrolmentToken, error)
- func (s PG) ListGovernanceAssignments(ctx context.Context) ([]types.GovernanceAssignment, error)
- func (s PG) ListGovernanceChanges(ctx context.Context, state string) ([]types.GovernanceChange, error)
- func (s PG) ListGovernanceProfiles(ctx context.Context) ([]types.GovernanceProfile, error)
- func (s PG) ListGrantsByRun(ctx context.Context, runID uuid.UUID) ([]types.CredentialGrant, error)
- func (s PG) ListGrantsByRunPage(ctx context.Context, runID uuid.UUID, p Page) ([]types.CredentialGrant, error)
- func (s PG) ListGroupDenyGrants(ctx context.Context, capability string) ([]types.CapabilityGrant, error)
- func (s PG) ListInvitations(ctx context.Context, target string, state types.InvitationState, now time.Time, ...) ([]types.Invitation, error)
- func (s PG) ListLapsedTokenRuns(ctx context.Context, life time.Duration) ([]types.AgentRun, error)
- func (s PG) ListLaunchIntents(ctx context.Context, createdBy string, limit int) ([]LaunchIntentRecord, error)
- func (s PG) ListLaunchPresets(ctx context.Context) ([]types.LaunchPreset, error)
- func (s PG) ListLeasedRuns(ctx context.Context) ([]types.AgentRun, error)
- func (s PG) ListLiveRunnerRuns(ctx context.Context, runnerID uuid.UUID) ([]types.AgentRun, error)
- func (s PG) ListMemberDrives(ctx context.Context, p Page) ([]types.UserDrive, int, error)
- func (s PG) ListMemberDrivesOf(ctx context.Context, owner string) ([]types.UserDrive, error)
- func (s PG) ListNonTerminalRunsBy(ctx context.Context, createdBy string) ([]types.AgentRun, error)
- func (s PG) ListPauseCandidates(ctx context.Context) ([]PauseCandidate, time.Time, error)
- func (s PG) ListPendingApprovalsForRuns(ctx context.Context, runIDs []uuid.UUID) ([]types.ApprovalRequest, error)
- func (s PG) ListPendingRecordingRunOutputs(ctx context.Context, staleAfter time.Duration, limit int) ([]uuid.UUID, error)
- func (s PG) ListPendingRunnerActions(ctx context.Context, runnerID uuid.UUID) ([]types.RunnerPendingAction, bool, error)
- func (s PG) ListPeople(ctx context.Context) ([]types.Person, error)
- func (s PG) ListPeopleDirectory(ctx context.Context, f PeopleDirectoryFilter) (PeopleDirectoryPage, error)
- func (s PG) ListPolicies(ctx context.Context) ([]types.RunPolicy, error)
- func (s PG) ListPoliciesPage(ctx context.Context, p Page) ([]types.RunPolicy, error)
- func (s PG) ListProfiledLiveRuns(ctx context.Context) ([]types.AgentRun, error)
- func (s PG) ListRemoteRunners(ctx context.Context) ([]RemoteRunnerRow, error)
- func (s PG) ListRoleMappings(ctx context.Context) ([]types.RoleMapping, error)
- func (s PG) ListRunComponents(ctx context.Context, runID uuid.UUID) ([]types.RunComponent, error)
- func (s PG) ListRunHarnesses(ctx context.Context, runID uuid.UUID) ([]types.RunHarness, error)
- func (s PG) ListRunPATs(ctx context.Context, runID uuid.UUID) ([]RunPAT, error)
- func (s PG) ListRunProxyReleases(ctx context.Context) ([]RunProxyRelease, error)
- func (s PG) ListRunnerExitWork(ctx context.Context, after uuid.UUID) ([]RunnerExitWork, error)
- func (s PG) ListRunnerLapsedRuns(ctx context.Context, runnerID, after uuid.UUID) ([]types.AgentRun, error)
- func (s PG) ListRunnerPoolCatalogue(ctx context.Context, owner string, all bool) ([]RunnerPoolCatalogueRow, error)
- func (s PG) ListRunnerPoolMembers(ctx context.Context, id uuid.UUID) ([]types.RunnerPoolMember, error)
- func (s PG) ListRunnerPoolRunners(ctx context.Context, poolID uuid.UUID) ([]types.Runner, error)
- func (s PG) ListRunners(ctx context.Context) ([]types.Runner, error)
- func (s PG) ListRunnersByOwner(ctx context.Context, owner string) ([]types.Runner, error)
- func (s PG) ListRunnersPage(ctx context.Context, filter types.RunnerFilter, now time.Time, p Page) ([]types.Runner, error)
- func (s PG) ListRuns(ctx context.Context) ([]types.AgentRun, error)
- func (s PG) ListRunsFiltered(ctx context.Context, f RunFilter, p Page) ([]types.AgentRun, error)
- func (s PG) ListRunsPage(ctx context.Context, p Page) ([]types.AgentRun, error)
- func (s PG) ListRunsPageByCreator(ctx context.Context, createdBy string, p Page) ([]types.AgentRun, error)
- func (s PG) ListRunsPageByCreatorOrSponsor(ctx context.Context, principal string, p Page) ([]types.AgentRun, error)
- func (s PG) ListSSHKeysByPrincipal(ctx context.Context, principal string) ([]types.SSHPublicKey, error)
- func (s PG) ListSSHKeysByPrincipalPage(ctx context.Context, principal string, p Page) ([]types.SSHPublicKey, error)
- func (s PG) ListServiceIdentities(ctx context.Context, sponsor string, p Page) ([]types.ServiceIdentity, error)
- func (s PG) ListSources(ctx context.Context) ([]types.Source, error)
- func (s PG) ListStalePendingRunOutputs(ctx context.Context, age time.Duration, limit int) ([]uuid.UUID, error)
- func (s PG) ListTemplateGroupAdmins(ctx context.Context) ([]types.TemplateGroupAdmin, error)
- func (s PG) ListTemplatesVisible(ctx context.Context, person string, groups []string) ([]types.RunTemplate, error)
- func (s PG) ListUnrevokedRunPATs(ctx context.Context, f RunPATFilter) ([]RunPAT, error)
- func (s PG) ListUnusedRunnerRegistrationTokensPage(ctx context.Context, now time.Time, owner string, p Page) ([]types.RunnerRegistrationToken, error)
- func (s PG) ListUserDriveGrants(ctx context.Context) ([]types.UserDriveGrant, error)
- func (s PG) ListUserDriveGrantsPage(ctx context.Context, p Page) ([]types.UserDriveGrant, error)
- func (s PG) ListUserDrives(ctx context.Context) ([]types.UserDriveListItem, error)
- func (s PG) ListUserTypes(ctx context.Context) ([]types.UserType, error)
- func (s PG) ListWorkspaces(ctx context.Context) ([]types.Workspace, error)
- func (s PG) ListWorkspacesPage(ctx context.Context, p Page) ([]types.Workspace, error)
- func (s PG) ListWorkspacesPageForOwner(ctx context.Context, owner string, p Page) ([]types.Workspace, error)
- func (s PG) LockLoginSupersede(ctx context.Context, actor string) (func(), error)
- func (s PG) Locker() db.Locker
- func (s PG) MarkAWSSSOTokenSpent(ctx context.Context, fingerprint, owner string, markedAt time.Time) error
- func (s PG) MarkFederationRevoked(ctx context.Context) error
- func (s PG) MarkIdentityPurged(ctx context.Context, id uuid.UUID, requireDue bool) (bool, error)
- func (s PG) MarkPersonSignedIn(ctx context.Context, principal string, now time.Time) error
- func (s PG) MarkRunAgentStopped(ctx context.Context, id uuid.UUID, lostAt time.Time) error
- func (s PG) MarkRunEnded(ctx context.Context, id uuid.UUID, now time.Time) (bool, error)
- func (s PG) MarkRunEndingSoon(ctx context.Context, id uuid.UUID, endsAt time.Time, thresholdSec int) (bool, error)
- func (s PG) MarkRunLost(ctx context.Context, id uuid.UUID, reason types.LostReason, now time.Time, ...) (bool, error)
- func (s PG) MarkRunOutputIncomplete(ctx context.Context, runID uuid.UUID) (bool, error)
- func (s PG) MarkRunPATRevoked(ctx context.Context, runID, authorizationID uuid.UUID, ...) (bool, error)
- func (s PG) MarkRunPaused(ctx context.Context, id uuid.UUID, reason types.PauseReason, ...) (bool, error)
- func (s PG) MarkRunRevived(ctx context.Context, id uuid.UUID, from types.LostReason, ended *EndedKept, ...) (bool, error)
- func (s PG) MarkRunnerRunLost(ctx context.Context, runnerID, runID uuid.UUID, expectedRef string, ...) (bool, error)
- func (s PG) MergeWorkspaceRequirements(ctx context.Context, id uuid.UUID, add map[string]types.WorkspaceRequirement) (types.Workspace, error)
- func (s PG) MintAttachTicket(ctx context.Context, token string, t AttachTicket, now, expiresAt time.Time) error
- func (s PG) MintDelegatedToken(ctx context.Context, t types.DelegatedToken, raw string, now time.Time) (types.DelegatedToken, error)
- func (s PG) MintEnrolmentToken(ctx context.Context, token string, t types.DeviceEnrolmentToken) (types.DeviceEnrolmentToken, error)
- func (s PG) MintRunnerRegistrationToken(ctx context.Context, raw string, token types.RunnerRegistrationToken) (types.RunnerRegistrationToken, error)
- func (s PG) MoveAPIToken(ctx context.Context, id uuid.UUID, serviceIdentity, by string, now time.Time) (types.TokenMove, error)
- func (s PG) NotePauseSettle(ctx context.Context, id uuid.UUID, after time.Duration) (time.Time, error)
- func (s PG) NoteRunPATRevokeFailed(ctx context.Context, runID, authorizationID uuid.UUID, lastError string) error
- func (s PG) PendingGroupRemovals(ctx context.Context, idleFor time.Duration, limit int) ([]PendingGroupRemoval, error)
- func (s PG) PendingLeavers(ctx context.Context, idleFor time.Duration, limit int) ([]PendingLeaver, error)
- func (s PG) Ping(ctx context.Context) error
- func (s PG) PoolSlotsUsed(ctx context.Context) (map[uuid.UUID]int, error)
- func (s PG) PrincipalAliases(ctx context.Context, principal string) ([]string, error)
- func (s PG) PrincipalEntraNames(ctx context.Context, principal string) ([]string, error)
- func (s PG) PrincipalForName(ctx context.Context, name string) (string, error)
- func (s PG) PrincipalsNamed(ctx context.Context, name string) ([]string, error)
- func (s PG) PrincipalsSharingObject(ctx context.Context, principal string) ([]string, error)
- func (s PG) PromoteRunQueue(ctx context.Context, pass PromotePass, admit QueueAdmit) ([]PromotedRun, []QueueHeld, error)
- func (s PG) ProposeGovernanceChange(ctx context.Context, ch types.GovernanceChange, ttl time.Duration) (types.GovernanceChange, []ExpiredGovernanceChange, error)
- func (s PG) PruneAWSSSOSpentTokens(ctx context.Context, cutoff time.Time) (int, error)
- func (s PG) PurgeAssertedRunnerSubjects(ctx context.Context) (int64, error)
- func (s PG) PurgeDueIdentities(ctx context.Context, limit int) ([]DueIdentity, error)
- func (s PG) PurgeTerminalRunProxyConfigs(ctx context.Context) (int64, error)
- func (s PG) PutBranding(ctx context.Context, b types.Branding, keepLogo bool) (types.Branding, error)
- func (s PG) PutCapabilityEnforcement(ctx context.Context, enabled map[string]bool) (map[string]bool, error)
- func (s PG) PutCredentialDeliveryPolicy(ctx context.Context, policy json.RawMessage, by string, now time.Time) (types.CredentialDeliveryPolicyDoc, error)
- func (s PG) PutLaunchPreset(ctx context.Context, p types.LaunchPreset) (types.LaunchPreset, PresetWrite, error)
- func (s PG) PutPrincipalPref(ctx context.Context, principal, key string, value json.RawMessage) error
- func (s PG) PutRef(ctx context.Context, ref, substrateName string) error
- func (s PG) PutRunComponents(ctx context.Context, runID uuid.UUID, comps []types.RunComponent) error
- func (s PG) PutRunHarnesses(ctx context.Context, runID uuid.UUID, hs []types.RunHarness) error
- func (s PG) PutRunLayout(ctx context.Context, principal, preset string, layout []types.RunLayoutWidget) (types.RunLayout, error)
- func (s PG) PutRunProxyConfig(ctx context.Context, id uuid.UUID, sealed []byte) error
- func (s PG) PutRunnerPoolOrgDefaults(ctx context.Context, d types.RunnerPoolDefaults, by string) error
- func (s PG) PutRunnerPoolUsePolicy(ctx context.Context, id uuid.UUID, revision *int64, ...) (types.RunnerPoolUsePolicy, error)
- func (s PG) PutSiteConfig(ctx context.Context, cfg types.SiteConfig) (types.SiteConfig, error)
- func (s PG) PutTemplateGroupAdmin(ctx context.Context, g types.TemplateGroupAdmin) (types.TemplateGroupAdmin, error)
- func (s PG) QueryAuditEvents(ctx context.Context, runID uuid.UUID, limit int) ([]types.AuditEvent, error)
- func (s PG) QueryAuditEventsFilteredPage(ctx context.Context, runID *uuid.UUID, f AuditFilter, p Page) ([]types.AuditEvent, error)
- func (s PG) QueryAuditEventsPage(ctx context.Context, runID uuid.UUID, p Page) ([]types.AuditEvent, error)
- func (s PG) QueryRecentAuditEvents(ctx context.Context, limit int) ([]types.AuditEvent, error)
- func (s PG) QueryRecentAuditEventsPage(ctx context.Context, p Page) ([]types.AuditEvent, error)
- func (s PG) QueueDepth(ctx context.Context) (map[uuid.UUID]int, error)
- func (s PG) QueueEntriesOfRevokedRunners(ctx context.Context, limit int) ([]RunQueueEntry, error)
- func (s PG) QueueOwnerEntries(ctx context.Context, owner string) ([]RunQueueEntry, error)
- func (s PG) QueuePoolIDs(ctx context.Context) ([]uuid.UUID, error)
- func (s PG) QueueRecordingRunOutput(ctx context.Context, runID uuid.UUID, retention, retryAfter time.Duration, ...) error
- func (s PG) QueueRunnerAction(ctx context.Context, a types.RunnerPendingAction) (types.RunnerPendingAction, bool, error)
- func (s PG) QueueRunnerTeardown(ctx context.Context, runnerID uuid.UUID, kind types.RunnerActionKind, ...) (types.RunnerPendingAction, bool, error)
- func (s PG) ReacquireAttachLease(ctx context.Context, l AttachLease, ttl time.Duration) (bool, error)
- func (s PG) ReadRunOutputChunks(ctx context.Context, runID uuid.UUID, limit int) (RunOutputChunks, error)
- func (s PG) ReclampRunLimits(ctx context.Context, from types.AgentRun, toLimits types.RunLimits, ...) (bool, error)
- func (s PG) RecordPushPathList(ctx context.Context, approvalID, runID uuid.UUID, l types.PushPathList, ...) (bool, error)
- func (s PG) RecordRunnerActionResult(ctx context.Context, runnerID, runID, actionID uuid.UUID, ...) (types.RunnerPendingAction, bool, error)
- func (s PG) RecordRunnerContainmentTx(ctx context.Context, tx pgx.Tx, proof RunnerContainmentProof, ...) error
- func (s PG) RecordRunnerPosture(ctx context.Context, id uuid.UUID, p types.RunnerPosture, now time.Time) (bool, error)
- func (s PG) RefreshAPITokenIdentity(ctx context.Context, principal, role, userType string, groups []string, ...) error
- func (s PG) RefreshRunOutputClaim(ctx context.Context, runID uuid.UUID) error
- func (s PG) RefreshSSHKeyRoles(ctx context.Context, principal, role string, checkedAt time.Time) error
- func (s PG) ReissueDeferredAssertedRunnerActions(ctx context.Context, runnerID uuid.UUID, sessionID string) (int, error)
- func (s PG) ReleaseAttachLease(ctx context.Context, runID, holderID uuid.UUID) (bool, error)
- func (s PG) RemoveOwnRunnerFromPool(ctx context.Context, id, runnerID uuid.UUID, owner string) (bool, int64, error)
- func (s PG) RemoveRemoteRunnerFromUserPool(ctx context.Context, id uuid.UUID, remoteRunner, owner string) (bool, int64, error)
- func (s PG) RemoveRunnerPoolExecutor(ctx context.Context, id uuid.UUID, executor string, refuseGoverned bool) (removed bool, rev int64, err error)
- func (s PG) RenameScimGroup(ctx context.Context, id uuid.UUID, displayName string) error
- func (s PG) RenewAttachLease(ctx context.Context, runID, holderID uuid.UUID, ttl time.Duration) (bool, error)
- func (s PG) ReopenDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey) error
- func (s PG) ReplaceUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, []uuid.UUID, error)
- func (s PG) ReserveAttachLease(ctx context.Context, runID, from uuid.UUID, taker, replica string, ...) (AttachLease, uuid.UUID, bool, error)
- func (s PG) ResetFederation(ctx context.Context) error
- func (s PG) ResolveGovernanceProfile(ctx context.Context, userSubjects, groups []string, userType string) (*types.GovernanceProfile, types.CapabilitySubjectType, error)
- func (s PG) ResolveReauthApproval(ctx context.Context, id uuid.UUID, decision types.ApprovalDecision, ...) (types.ApprovalRequest, error)
- func (s PG) ResolveUserDrive(ctx context.Context, userSubjects, groups []string, userType string) (*types.UserDrive, *types.UserDriveGrant, types.CapabilitySubjectType, error)
- func (s PG) ResolveUserDrives(ctx context.Context, userSubjects, groups []string, userType string) ([]UserDriveWinner, error)
- func (s PG) ResumeGroupRemoval(ctx context.Context, groupID, identityID uuid.UUID) (bool, error)
- func (s PG) RetireServiceIdentity(ctx context.Context, name, by string) (ServiceIdentityChanged, error)
- func (s PG) RetryRunnerExitTail(ctx context.Context, runnerID, runID, generation uuid.UUID, ...) error
- func (s PG) RevokeAPIToken(ctx context.Context, id uuid.UUID, principal string, now time.Time) (types.APIToken, error)
- func (s PG) RevokeDelegate(ctx context.Context, id uuid.UUID, now time.Time) (types.Delegate, error)
- func (s PG) RevokeDevice(ctx context.Context, id uuid.UUID, now time.Time) (types.Device, error)
- func (s PG) RevokeEnrolmentToken(ctx context.Context, id uuid.UUID, now time.Time) (types.DeviceEnrolmentToken, error)
- func (s PG) RevokeInvitation(ctx context.Context, id uuid.UUID, by string, now time.Time) (types.Invitation, error)
- func (s PG) RevokeRunner(ctx context.Context, id uuid.UUID, now time.Time, by, reason string) (RunnerRevocation, error)
- func (s PG) RevokeRunnerRegistrationToken(ctx context.Context, id uuid.UUID, now time.Time) (types.RunnerRegistrationToken, error)
- func (s PG) RunAgentStopped(ctx context.Context, id uuid.UUID) (bool, error)
- func (s PG) RunCapacity(ctx context.Context, o RunCapacityOpts) (RunCapacity, error)
- func (s PG) RunHasOpenRequest(ctx context.Context, id uuid.UUID) (bool, error)
- func (s PG) RunHasPendingRunnerAction(ctx context.Context, runID uuid.UUID) (bool, error)
- func (s PG) RunHeldContainedOnRunner(ctx context.Context, runID uuid.UUID) (bool, error)
- func (s PG) RunIDsCreatedBy(ctx context.Context, createdBy string) ([]uuid.UUID, error)
- func (s PG) RunQueueFacts(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]RunQueueFact, error)
- func (s PG) RunQueuePosition(ctx context.Context, id uuid.UUID) (int, error)
- func (s PG) RunTokenRenewedAt(ctx context.Context, runID uuid.UUID) (time.Time, error)
- func (s PG) RunWatcherFresh(ctx context.Context, id uuid.UUID, staleAfter time.Duration) (bool, error)
- func (s PG) RunnerArchCounts(ctx context.Context) (map[string]int, error)
- func (s PG) RunnerExecutionOf(ctx context.Context, runID uuid.UUID) (RunnerExecution, error)
- func (s PG) RunnerPoolSlotCounts(ctx context.Context, poolIDs []uuid.UUID) (map[uuid.UUID]PoolCounts, error)
- func (s PG) RunnerPoolsOf(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID][]types.RunnerPoolRef, error)
- func (s PG) RunnerSlotHolders(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]int, error)
- func (s PG) RunnerUsage(ctx context.Context, runners []uuid.UUID, remotes []string, except uuid.UUID) (map[string]types.RunnerTally, error)
- func (s PG) SaveChunkedRunOutput(ctx context.Context, runID uuid.UUID, maskScope string, limit int) (bool, error)
- func (s PG) SaveFinalRunOutput(ctx context.Context, o RunOutput) error
- func (s PG) SaveGapRunOutput(ctx context.Context, runID uuid.UUID) (bool, error)
- func (s PG) SaveRecordingRunOutput(ctx context.Context, claim RecordingOutputClaim, o RunOutput, ...) (bool, error)
- func (s PG) ScimGroupMembers(ctx context.Context, id uuid.UUID) ([]uuid.UUID, error)
- func (s PG) SearchIdentities(ctx context.Context, issuer, attr, value string, limit int) ([]PrincipalIdentity, error)
- func (s PG) SearchScimGroups(ctx context.Context, attr, value string, limit int) ([]ScimGroup, error)
- func (s PG) ServiceStillSponsored(ctx context.Context, name, sponsor string, openedAt time.Time) (bool, error)
- func (s PG) SetAuditDeliveryCursor(ctx context.Context, dest string, seq int64, rowHash string) error
- func (s PG) SetAuditDeliveryError(ctx context.Context, dest, msg string, halted bool) error
- func (s PG) SetAuditRetentionPolicy(ctx context.Context, days int) (AuditRetentionPolicyChange, error)
- func (s PG) SetBrandingLogo(ctx context.Context, logo []byte, logoType string, fromFile bool, ...) (bool, error)
- func (s PG) SetCapabilityRestriction(ctx context.Context, capability, value string, restricted bool, by string) error
- func (s PG) SetFederationCursor(ctx context.Context, seq int64, rowHash string) error
- func (s PG) SetPromotedStatusDetail(ctx context.Context, id uuid.UUID, detail string) error
- func (s PG) SetQueueWait(ctx context.Context, id uuid.UUID, detail string) error
- func (s PG) SetRemoteRunnerPeople(ctx context.Context, id string, revision *int64, ...) (before, after types.RemoteRunner, err error)
- func (s PG) SetRunAgentExecID(ctx context.Context, id uuid.UUID, execID string) error
- func (s PG) SetRunContainmentError(ctx context.Context, id uuid.UUID, msg string, now time.Time) error
- func (s PG) SetRunDiskMiB(ctx context.Context, id uuid.UUID, mib int) error
- func (s PG) SetRunEndAndWait(ctx context.Context, id uuid.UUID, fromLimits types.RunLimits, ...) (bool, error)
- func (s PG) SetRunFailureHint(ctx context.Context, id uuid.UUID, hint string) error
- func (s PG) SetRunImage(ctx context.Context, id uuid.UUID, image string) error
- func (s PG) SetRunProxyRelease(ctx context.Context, id uuid.UUID, release string) error
- func (s PG) SetRunSizing(ctx context.Context, id uuid.UUID, z RunSizing) error
- func (s PG) SetRunStatusDetail(ctx context.Context, id uuid.UUID, detail string) error
- func (s PG) SetRunTitle(ctx context.Context, id uuid.UUID, title string) error
- func (s PG) SetRunnerArch(ctx context.Context, id uuid.UUID, arch string) error
- func (s PG) SetRunnerMachineName(ctx context.Context, id uuid.UUID, name string) error
- func (s PG) SetSandboxRef(ctx context.Context, id uuid.UUID, ref string) error
- func (s PG) SetSourceScanResult(ctx context.Context, id uuid.UUID, profile []byte, ...) (types.Source, error)
- func (s PG) SetSourceScanResultUnfenced(ctx context.Context, id uuid.UUID, profile []byte, ...) (types.Source, error)
- func (s PG) SetWorkspaceApprovedEgress(ctx context.Context, id uuid.UUID, domains []string) (types.Workspace, error)
- func (s PG) SetWorkspaceBuiltImage(ctx context.Context, id uuid.UUID, observedRef, imageRef, builtHash string, ...) (bool, error)
- func (s PG) SetWorkspaceDeniedEgress(ctx context.Context, id uuid.UUID, domains []string) (types.Workspace, error)
- func (s PG) SetWorkspaceImportState(ctx context.Context, id uuid.UUID, status types.WorkspaceStatus, ...) (types.Workspace, bool, error)
- func (s PG) SetWorkspaceLLMCred(ctx context.Context, id uuid.UUID, cred *types.WorkspaceLLMCred) (types.Workspace, error)
- func (s PG) SetWorkspaceOwner(ctx context.Context, id uuid.UUID, owner string) (types.Workspace, error)
- func (s PG) SetWorkspaceRecordResult(ctx context.Context, id uuid.UUID, taskKey string, result json.RawMessage, ...) (types.Workspace, bool, error)
- func (s PG) SetWorkspaceRequirements(ctx context.Context, id uuid.UUID, reqs map[string]types.WorkspaceRequirement) (types.Workspace, error)
- func (s PG) SpendApprovalOnce(ctx context.Context, id uuid.UUID, jti string) (bool, error)
- func (s PG) StageRunnerExit(ctx context.Context, runnerID, runID uuid.UUID, exit runnerwire.AgentExit) error
- func (s PG) StalePromotedRuns(ctx context.Context, staleAfter time.Duration) ([]types.AgentRun, error)
- func (s PG) StampRunActive(ctx context.Context, id uuid.UUID) (bool, error)
- func (s PG) StampRunTokenRenewed(ctx context.Context, id uuid.UUID) (bool, error)
- func (s PG) StampServerRun(ctx context.Context, id uuid.UUID, remote string, reserved types.RunnerAmounts) error
- func (s PG) StartGroupRemoval(ctx context.Context, groupID, identityID uuid.UUID) error
- func (s PG) StartQueuedRun(ctx context.Context, id uuid.UUID, st QueueStart) (run types.AgentRun, ok bool, err error)
- func (s PG) StopKeptRunIf(ctx context.Context, id uuid.UUID, to types.RunState, lostAt *time.Time, ...) (bool, error)
- func (s PG) SubjectKeyDestroyedSince(ctx context.Context, owner, purpose string, since time.Time) (bool, error)
- func (s PG) SuspendIdentity(ctx context.Context, p SuspendPlan) (SuspendResult, error)
- func (s PG) TemplateGroupAdminGroups(ctx context.Context, persons []string) ([]string, error)
- func (s PG) TemplateGroupLabels(ctx context.Context, groups []string) (map[string]string, error)
- func (s PG) TokenDispositionFacts(ctx context.Context, now time.Time) (TokenDispositionFacts, error)
- func (s PG) TouchAPIToken(ctx context.Context, id uuid.UUID, now time.Time) error
- func (s PG) TouchDevice(ctx context.Context, id uuid.UUID, now time.Time) error
- func (s PG) TouchRun(ctx context.Context, id uuid.UUID) error
- func (s PG) TouchRunner(ctx context.Context, id uuid.UUID, version string, now time.Time) error
- func (s PG) TouchRunnerActivity(ctx context.Context, runnerID, runID uuid.UUID) error
- func (s PG) UnbindIdentity(ctx context.Context, id uuid.UUID, principal string) error
- func (s PG) UpdateBaseImageName(ctx context.Context, id uuid.UUID, name string) (types.BaseImageEntry, error)
- func (s PG) UpdateComponent(ctx context.Context, c types.Component) (types.Component, error)
- func (s PG) UpdatePolicy(ctx context.Context, id uuid.UUID, name string, spec types.RunPolicySpec) (types.RunPolicy, error)
- func (s PG) UpdateRemoteRunner(ctx context.Context, id string, revision int64, name *string, ...) (before, after types.RemoteRunner, err error)
- func (s PG) UpdateRunStateIf(ctx context.Context, id uuid.UUID, fromState, toState types.RunState) (bool, error)
- func (s PG) UpdateRunStateIfCreatedBefore(ctx context.Context, id uuid.UUID, fromState, toState types.RunState, ...) (bool, error)
- func (s PG) UpdateRunStateIfIdle(ctx context.Context, id uuid.UUID, fromState, toState types.RunState, ...) (bool, error)
- func (s PG) UpdateRunnerLimits(ctx context.Context, id uuid.UUID, owner string, limits types.RunnerLimits) (before *types.RunnerLimits, after types.Runner, err error)
- func (s PG) UpdateRunnerPool(ctx context.Context, id uuid.UUID, revision int64, name *string, ...) (types.RunnerPool, error)
- func (s PG) UpdateServiceIdentity(ctx context.Context, name string, ch ServiceIdentityChange) (ServiceIdentityChanged, error)
- func (s PG) UpdateSourceConfig(ctx context.Context, id uuid.UUID, name string, ...) (types.Source, error)
- func (s PG) UpdateTemplate(ctx context.Context, t types.RunTemplate, expected int, ...) (types.RunTemplate, error)
- func (s PG) UpdateUserType(ctx context.Context, t types.UserType) (types.UserType, error)
- func (s PG) UpdateUserTypeMetadata(ctx context.Context, t types.UserType) (types.UserType, error)
- func (s PG) UpdateWorkspace(ctx context.Context, id uuid.UUID, ws types.Workspace, stampEgressEdit bool) (types.Workspace, error)
- func (s PG) UpsertBaseImage(ctx context.Context, b types.BaseImageEntry) (types.BaseImageEntry, error)
- func (s PG) UpsertCapabilityGrant(ctx context.Context, g types.CapabilityGrant) (types.CapabilityGrant, error)
- func (s PG) UpsertGovernanceAssignment(ctx context.Context, a types.GovernanceAssignment) (types.GovernanceAssignment, error)
- func (s PG) UpsertGovernanceProfile(ctx context.Context, p types.GovernanceProfile) (types.GovernanceProfile, error)
- func (s PG) UpsertLoginIdentity(ctx context.Context, in LoginIdentity, now time.Time) (PrincipalIdentity, error)
- func (s PG) UpsertRoleMapping(ctx context.Context, m types.RoleMapping) (types.RoleMapping, error)
- func (s PG) UpsertSource(ctx context.Context, src types.Source) (types.Source, error)
- func (s PG) UpsertUserDrive(ctx context.Context, d types.UserDrive, refuseIfAllocated bool) (types.UserDrive, error)
- func (s PG) UpsertUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, error)
- func (s PG) UpsertUserDriveGrantWithinTier(ctx context.Context, g types.UserDriveGrant, ...) (types.UserDriveGrant, []uuid.UUID, error)
- func (s PG) UserTypeReferences(ctx context.Context, id string) (int, error)
- func (s PG) UserTypeTokenStamps(ctx context.Context, id string) (int, error)
- func (s PG) VerifyAuditChain(ctx context.Context) (AuditChainStatus, error)
- func (s PG) WithIdentityShared(ctx context.Context, g IdentityGuard, fn func() error) error
- func (s PG) WorkspacesAttaching(ctx context.Context, id uuid.UUID) ([]string, error)
- func (s PG) WorkspacesUsingBaseImage(ctx context.Context, id uuid.UUID) ([]string, error)
- func (s PG) WriteGovernanceProfile(ctx context.Context, id uuid.UUID, build GovernanceProfileBuild) (types.GovernanceProfile, error)
- type Page
- type Pager
- type PartitionDigest
- type PartitionManifest
- type PauseCandidate
- type PauseSettle
- type PauseSettler
- type PendingGroupRemoval
- type PendingLeaver
- type PeopleDirectoryFilter
- type PeopleDirectoryPage
- type PeopleDirectoryStore
- type PersonErasureStore
- type PersonListing
- type PersonStore
- type PoolCounts
- type PresetWrite
- type PrincipalDirectoryStore
- type PrincipalIdentity
- type PrincipalIdentityStore
- type PrincipalInUseError
- type PrincipalPrefStore
- type PromotePass
- type PromotedRun
- type PushPathListStore
- type Querier
- type QueueAdmit
- type QueueHeld
- type QueueStart
- type QueueVerdict
- type Recorder
- type RecordingOutputClaim
- type RemoteRunnerRow
- type RemoteRunnerStore
- type RestrictedComponentCreator
- type RestrictedComponentDeleter
- type RunAuditMatcher
- type RunCapacity
- type RunCapacityAge
- type RunCapacityOpts
- type RunCapacityOwner
- type RunCapacityRunner
- type RunCapacitySums
- type RunCapacityUnschedulable
- type RunFilter
- type RunHarnessStore
- type RunLayoutStore
- type RunLeaser
- type RunLimitsReclamper
- type RunLoser
- type RunOutput
- type RunOutputChunkStore
- type RunOutputChunks
- type RunOutputStore
- type RunPAT
- type RunPATFilter
- type RunPATReader
- type RunPATStore
- type RunPauser
- type RunProxyConfigs
- type RunProxyRelease
- type RunQueueEntry
- type RunQueueFact
- type RunReviver
- type RunSetupsErased
- type RunSizing
- type RunTitler
- type RunWatcherLeaser
- type RunnerAtCapacityError
- type RunnerContainment
- type RunnerContainmentProof
- type RunnerExecution
- type RunnerExitWork
- type RunnerInventoryResult
- type RunnerInventoryStore
- type RunnerKilledRun
- type RunnerPoolCatalogueRow
- type RunnerPoolDeletion
- type RunnerPoolFullError
- type RunnerPoolStore
- type RunnerRegistrationStore
- type RunnerRevocation
- type RunnerStore
- type RunsByCreatorOrSponsorPager
- type RunsByCreatorPager
- type RunsFilteredPager
- type SSHKeysByPrincipalPager
- type ScimGroup
- type ScimGroupStore
- type ServiceIdentityChange
- type ServiceIdentityChanged
- type ServiceIdentityStore
- type Store
- type SuspendPlan
- type SuspendResult
- type TemplateGrantCheck
- type TemplateLimitError
- type TemplateRevisionConflictError
- type TemplateStore
- type TokenDispositionFacts
- type TokenMoveStore
- type TokenReplacement
- type UserDriveCatalogueStore
- type UserDriveGrantTierWriter
- type UserDriveGrantWidensError
- type UserDriveGrantWriter
- type UserDriveWinner
- type WorkspacesByOwnerPager
Constants ¶
const ( AuditOriginDevice = "device" AuditOriginOrganisation = "organisation" )
The two AuditFilter.Origin values: rows a device forwarded, and rows the organisation wrote itself (FederatedDeviceID decides which is which).
const ( RetentionNotOldest = "audit_retention_not_oldest" RetentionNotClosed = "audit_retention_not_closed" RetentionInsideWindow = "audit_retention_inside_window" RetentionLiveRun = "audit_retention_live_run" RetentionDigestMismatch = "audit_retention_digest_mismatch" )
The refusal reasons audit_retention_drop (migration 0123) raises, one SQLSTATE each. They are also the wire reasons of POST /audit/retention/drop, registered in internal/authz.
const ( SplitNotOwner = "audit_split_not_migrator" SplitNotPartitioned = "audit_split_not_partitioned" SplitNoLegacy = "audit_split_no_legacy_partition" SplitEmpty = "audit_split_legacy_empty" SplitChainBroken = "audit_split_chain_broken" SplitNameTaken = "audit_split_name_taken" )
The refusal reasons of SplitLegacyAudit. Each is a state the split must not run in; nothing was changed.
const ( JobKindSuspend = "suspend" // JobStepCutoff is step 1 of a suspension: the cutoff, the deactivation and the epoch bump. JobStepCutoff = "cutoff" )
Job kinds and the one step name every kind shares.
const ( SearchExternalID = "externalId" SearchUserName = "userName" SearchEmail = "emails.value" )
SearchIdentities attrs, as SCIM spells them.
const ( JobKindPurge = "purge" JobStepAuditDeprovision = "audit_deprovision" )
JobKindPurge is the ledger kind of a purge; JobStepAuditDeprovision is the step it ends on, and the one MarkIdentityPurged records pending so a purge that dies right after the mark is still on the ledger.
const ( PeopleDirectoryDefaultLimit = 50 PeopleDirectoryMaxLimit = 200 )
A Limit of zero is PeopleDirectoryDefaultLimit; one above PeopleDirectoryMaxLimit is clamped to it.
const ( TemplatesMaxPerPerson = 200 TemplatesMaxPerGroup = 200 TemplatesMaxOrg = 500 )
The most templates one audience holds: each person's own, each group's, and the organisation's. Counted and inserted under templateAudienceLockSQL, so two creates racing for the last slot cannot both land.
const ( RunnerPoolsMax = 200 RunnerPoolsPerOwnerMax = 10 RunnerPoolsOversightMax = 1000 )
RunnerPoolsMax bounds the organisation's live pools and RunnerPoolsPerOwnerMax one person's, so a person's catalogue read is bounded and no person's pools can crowd the organisation's out of it. RunnerPoolsOversightMax bounds the oversight read, which lists the organisation's pools and then the caller's own before anyone else's, so neither can drop out of it.
const ( JobKindGroupRemove = "group_remove" GroupStepSessions = "sessions" GroupStepTokens = "tokens" GroupStepAudit = "audit" )
The group removal ledger (migration 0127's group_remove kind): one set of rows per person and group, the target of every step being the group's id.
const ADOSignInEndsStaleAfter = 10 * time.Minute
ADOSignInEndsStaleAfter is how long an end that began and never finished (its replica died) still counts as running. Past it the count settles, so a person's mints stop revoking themselves; an end finishes in seconds.
const AuditTargetTruncatedMarker = "…[truncated]"
AuditTargetTruncatedMarker is appended to a capped target so the row says what happened to it. Without it a truncated path reads as a real one, and an operator matching `target = '/api/v1/policies/aaa…'` would believe it.
const FederatedClaimHashSQL = `` /* 334-byte string literal not displayed */
FederatedClaimHashSQL recomputes, from one stored federated row aliased e, the hash the device claimed for it: equals e.data->'device_origin'->>'row_hash' for every row IngestDeviceAudit accepts. Claimed actor/source_ip/prev_hash live in device_origin; the claimed object is stored data minus that key; a data-less claim is named by device_origin.data_null ("json" for JSON null, "sql" for absent).
const HoldsSandboxSQL = `(lost_at IS NULL OR (lost_reason = '` + string(types.LostOutage) + `' AND agent_stopped_at IS NULL))`
HoldsSandboxSQL is TRUE when the agent_runs row's agent may still be running: the run is not kept, or it was kept after a control-plane outage and no stop of its agent is recorded (agent_stopped_at, written by MarkRunAgentStopped once the lease sweep stopped it past its end). A failed stop records nothing, so the run holds its slot past its end until the stop is confirmed. A run kept after its end or a reboot, or an outage-kept run whose agent was stopped, has no agent, even if an extension has since moved its end ahead. It is the one rule for a live run under WARDYN_MAX_CONCURRENT_RUNS, in the fleet capacity view and under WARDYN_RUN_MAX_AGE.
const MaxAuditTargetLen = 512
MaxAuditTargetLen bounds the audit row's `target` column (plain TEXT, unbounded). An authenticated caller looping a huge path via authz.denied (unrate-limited, unlike auth.fail) could otherwise write megabytes per second into a table whose Postgres trigger forbids DELETE; 512 bytes holds every real target this tree writes with an order of magnitude to spare.
const PeopleDirectoryActiveSessionWindow = 24 * time.Hour
PeopleDirectoryActiveSessionWindow is how recent a sign-in must be to count as a live session. Sessions are stateless signed cookies the server keeps no row for, so the directory knows only when a person last signed in, not how many cookies are out: it counts one when that sign-in is inside this window and no revoke cutoff has passed it.
const ReauthHoldMax = 1800 * time.Second
ReauthHoldMax is the longest a credential re-auth hold keeps the agent's connection parked (WARDYN_CREDENTIAL_REAUTH_TIMEOUT's ceiling). A re-auth request counts toward a waiting pause only once it is older than this: until then the agent is still inside the connection that asked, and freezing it would cut a sign-in the person may be finishing.
const SearchDisplayName = "displayName"
SearchDisplayName is the Groups filter attribute that SearchExternalID shares the rest of with Users.
const SystemAuditActor = "wardynd"
SystemAuditActor is the actor an unattended retention drop (WARDYN_AUDIT_RETENTION_AUTODROP) records: audit_retention_drop treats exactly this name as the system and marks the chained event unattested.
Variables ¶
var ( // ErrTemplateNameTaken: another template of the same audience has the name, // compared case-insensitively. ErrTemplateNameTaken = errors.New("store: a template available to the same people already uses this name") // ErrTemplateGrantGone: a group write found no grant for the writer when it // re-read it inside its own transaction. ErrTemplateGrantGone = errors.New("store: the template group grant is gone") )
var ( // ErrRunnerPoolStale: the caller's revision is not the pool's. ErrRunnerPoolStale = errors.New("store: runner pool revision is stale") // ErrRunnerPoolGoverned: a detach that was decided as direct met a use policy under the locks. ErrRunnerPoolGoverned = errors.New("store: runner pool now has a use policy, so the detach must be held") // ErrRunnerPoolLimit: the organisation is at RunnerPoolsMax pools, or the owner at RunnerPoolsPerOwnerMax. ErrRunnerPoolLimit = errors.New("store: too many runner pools") // ErrRunnerPoolScope: a self-hosted runner was offered to an organization pool, which takes // remote-hosted runners only. ErrRunnerPoolScope = errors.New("store: organization pools take remote-hosted runners only") // ErrRunnerPoolHasPolicy: a pool with a use policy is not deleted, because the delete would clear // the policy outside the second-human hold; clear the policy first. ErrRunnerPoolHasPolicy = errors.New("store: the runner pool still has a use policy") )
var AuditChainPageSize int32 = 1000
AuditChainPageSize is how many rows one page of the verify sweep reads — bounds memory to a page, never the table. Large enough that the per-page round trip is noise against re-hashing a thousand rows, small enough to stay a few hundred kilobytes. A var only so the parity test can shrink it and cross page boundaries.
var ErrAlreadyDecided = types.ErrApprovalAlreadyDecided
ErrAlreadyDecided is returned when DecideApproval targets an approval that has already left PENDING. Fail closed: a second decision never overwrites the first.
var ErrAuditPartitionOpen = errors.New("store: audit partition is still open")
ErrAuditPartitionOpen is a partition that can still receive rows: it has no digest yet.
var ErrConflict = errors.New("store: conflict")
ErrConflict reports a fenced write losing its race: a source scan slot already claimed, or the requirements merge hitting the key cap.
var ErrDeviceRevoked = errors.New("store: device is revoked")
ErrDeviceRevoked is IngestDeviceAudit's answer for a device revoked after its request was authenticated. Distinct from ErrConflict so the caller answers it as revocation, never a broken chain.
var ErrDriveAllocated = fmt.Errorf( "%w: this user drive gained an allocation while the write was being prepared", ErrConflict)
ErrDriveAllocated is returned by UpsertUserDrive when the caller asked for the write to apply only while the drive has no allocations (refuseIfAllocated) and the row has some. It is the statement-level half of the API's re-home guard: since a plain read-then-write would let a grant created in between get silently re-homed, the precondition rides the writing statement under a FOR UPDATE on the drive row in the same transaction, making it race-free.
var ErrDriveHomeNamespaceConflict = fmt.Errorf( "%w: another host_path drive on this host_root derives home directory names by a different rule", ErrConflict)
ErrDriveHomeNamespaceConflict is returned by UpsertUserDrive when a host_path drive would share a host_root with another host_path drive that derives home directory NAMES by a different rule. Wraps ErrConflict (as do ErrDriveSlugConflict and ErrDriveAllocated below) so callers asking only "is this a 409?" keep working, while the remedy stays distinguishable from a plain UNIQUE(name) collision.
var ErrDriveSlugConflict = fmt.Errorf( "%w: another user drive's name folds to the same storage-object name", ErrConflict)
ErrDriveSlugConflict is returned by UpsertUserDrive when a drive's name folds to a storage-object slug another drive already holds — "Corp NAS" against an existing "corp nas", or "Corp NAS (eng)" against "corp-nas-eng". Distinct from UNIQUE(name): the name itself is free, but types.DriveSlug(name) — the fragment every minted object name is built from — collides, so the remedy is a name differing by more than case or punctuation.
var ErrDuplicatePending = types.ErrDuplicatePendingApproval
ErrDuplicatePending is returned by CreateApproval when a partial unique index rejects a second open PENDING approval for the same dedup key (a concurrent raise lost the race). Callers treat it as a dedup signal — re-read and return the existing PENDING row — not a hard failure.
var ErrFederatedOrgRun = errors.New("store: federated row names an organisation run")
ErrFederatedOrgRun refuses a batch where a row's run_id names one of this organisation's own runs: phase one federates audit rows, never run records, so a laptop's row can't legitimately belong to one.
var ErrFederatedRowInvalid = errors.New("store: federated row cannot be stored as claimed")
ErrFederatedRowInvalid refuses a batch holding a row this organisation can't store (FederatedRowProblem) or a value Postgres can't represent (SQLSTATE class 22); the caller answers 4xx so the forwarder stops rather than retrying a 5xx forever.
var ErrGovernanceChangeStale = errors.New("store: the governance change is stale")
ErrGovernanceChangeStale is what a decision's apply returns when the target is no longer what the proposal reviewed. DecideGovernanceChange moves the change to stale and commits that, and returns this error.
var ErrIdentityBindingMismatch = errors.New("store: identity bound to another principal")
ErrIdentityBindingMismatch is a sign-in's refusal when the identity it names is already bound to another principal: issuing its session under the new one would leave it outside the identity's deactivation and epoch checks. Nothing is written.
var ErrIdentityDeactivated = errors.New("store: identity deactivated")
ErrIdentityDeactivated is the refusal of anything that would give a deactivated, purged or stale-epoch identity a new session, credential or run.
var ErrIdentityNotRebindable = errors.New("store: identity has no object id and cannot be re-bound")
ErrIdentityNotRebindable is UnbindIdentity's refusal of a row with no object id: such a row is found only by its principal, so an unbound one is never reached again and the next sign-in would create a second row without this one's epoch or SCIM linkage.
var ErrIdentityPurged = errors.New("store: identity purged")
ErrIdentityPurged is a reactivation's refusal: a purged identity is a permanent tombstone.
var ErrIdentityRebound = errors.New("store: the identity was bound since the suspension was planned")
ErrIdentityRebound is a SuspendPlan made before a sign-in bound the identity row: its forms miss the newly bound principal, so the caller reads the row again and makes a new plan.
var ErrInvitationCap = errors.New("store: too many pending invitations for the target")
ErrInvitationCap is CreateInvitation's refusal when the target already has the maximum pending.
var ErrInvitationNotPending = errors.New("store: invitation is not pending")
ErrInvitationNotPending is ClaimInvitation's and RevokeInvitation's refusal of an invitation that is claimed, revoked or expired, or was before a concurrent writer got there.
var ErrLoginLockNoCapacity = db.ErrAdvisoryLockNoCapacity
ErrLoginLockNoCapacity is the one LockLoginSupersede error a caller may proceed unlocked on (the pool can't spare a connection); any other error means the caller should refuse.
var ErrMemberDriveBusy = fmt.Errorf("%w: this drive is already being deleted", ErrConflict)
ErrMemberDriveBusy is returned by a delete Begin when another delete of the same drive started less than a minute ago.
var ErrMemberDriveLimit = errors.New("store: the most drives one person may hold already exist")
ErrMemberDriveLimit is returned by CreateMemberDrive when the owner already holds the most drives allowed. Rows being deleted still count.
var ErrMemberDriveNameTaken = fmt.Errorf("%w: you already have a drive with this name", ErrConflict)
ErrMemberDriveNameTaken is returned by CreateMemberDrive when the owner already has a drive whose name folds to the same slug.
var ErrMoveTargetUnknown = errors.New("store: no such service identity")
ErrMoveTargetUnknown is MoveAPIToken's refusal of a service identity that does not exist. A retired one is ErrServiceIdentityInactive.
var ErrNotFound = errors.New("store: not found")
ErrNotFound is returned when a Get* call finds no row.
var ErrPushPathListCap = errors.New("store: this run has stored its limit of push path lists")
ErrPushPathListCap is RecordPushPathList's refusal: the run already has its limit of lists.
var ErrRecordingOutputErased = errors.New("store: recording-derived output was erased")
ErrRecordingOutputErased refuses a new copy of an erased recording while leaving independently captured stdout and pane snapshots alone.
var ErrRecordingOutputUncovered = errors.New("store: recording output lost masking coverage")
ErrRecordingOutputUncovered refuses a historical read whose masking manifest was fenced or removed before the recovered row could commit.
var ErrRunCapReached = errors.New("store: deployment run cap reached")
ErrRunCapReached is CreateRunUnderCap's refusal: the deployment already holds its cap of non-terminal runs.
var ErrRunOutputErased = errors.New("store: the run's output was erased")
ErrRunOutputErased is every writer's and reader's answer for a run whose output was erased: the tombstone is checked in the same transaction as the write or read, under the run's lock, so no replica can recreate or serve it.
var ErrRunQueueFull = errors.New("store: run queue is full for this owner")
ErrRunQueueFull is CreateQueuedRun's refusal: the owner already has the most runs waiting for the pool.
var ErrRunnerActionRefused = errors.New("runner pending action refused")
ErrRunnerActionRefused covers a pending action or action_result whose runner, owner, run, ref, generation or loss does not match the org's current record.
var ErrRunnerAtCapacity = errors.New("store: runner is running its limit of runs at once")
ErrRunnerAtCapacity is the refusal when a runner has no room for the run: it already holds its Runs at once, a total would be passed, the run is past its per-run limit, or it declares no limits.
var ErrRunnerClaimMismatch = errors.New("store: runner claim does not match the owner or key fingerprint")
ErrRunnerClaimMismatch is ClaimRunner's refusal when the runner is unclaimed but the caller is not its owner or the fingerprint differs: the API answers runner_claim_mismatch.
var ErrRunnerExecutionRefused = errors.New("runner execution refused")
ErrRunnerExecutionRefused covers foreign, stale and incomplete incarnations.
var ErrRunnerPoolFull = errors.New("store: runner pool is full")
ErrRunnerPoolFull is a revive's refusal when its pool is at its concurrent-run cap or has runs waiting: a waiting run is first in line, so a revive never jumps it (pool-queue.md section 10).
var ErrRunnerReconciliationRequired = errors.New("runner lifecycle reconciliation required")
ErrRunnerReconciliationRequired refuses READY without issuing an RPC from the checked STATE handler; page intake commits any containment action first.
var ErrRunnerSpoolRefused = errors.New("runner audit replay refused")
ErrRunnerSpoolRefused does not distinguish an unknown run from a foreign or revoked runner. A failed checked stream event must not receive an ACK.
var ErrScimGroupExists = errors.New("store: scim group exists")
ErrScimGroupExists is a create whose externalId already names a group.
var ErrServiceIdentityInactive = errors.New("store: the service identity is not active")
ErrServiceIdentityInactive is the refusal of a write to a service identity that is retired, or, for a token mint, suspended or sponsored by someone else than the minter.
var ErrServiceNameTaken = errors.New("store: that service identity name is already in use")
ErrServiceNameTaken is CreateServiceIdentity's refusal of a name a principal-keyed table already holds (or a service identity already carries), so no new identity inherits another's grants or history.
var ErrServiceSponsorInvalid = errors.New("store: the sponsor is not a bound, active identity")
ErrServiceSponsorInvalid is the refusal of a sponsor that is not exactly the principal of a bound, non-deactivated identity.
var ErrServiceTokenCap = errors.New("store: the service identity holds the maximum number of live tokens")
ErrServiceTokenCap is CreateServiceToken's refusal when the identity already holds the most live tokens.
var ErrServiceUserTypeUnknown = errors.New("store: no such user type")
ErrServiceUserTypeUnknown is CreateServiceIdentity's refusal for a user type with no user_types row.
var ErrTokenNotMovable = errors.New("store: the token is not a live admin-minted token")
ErrTokenNotMovable is MoveAPIToken's refusal of a token that is revoked or expired, or that no admin minted for someone else.
var ErrUserDriveGrantChanged = errors.New("store: the allocation changed while it was being written")
ErrUserDriveGrantChanged is UpsertUserDriveGrantWithinTier's answer when an allocation for the subject appeared while the write was judged against there being none.
var GroupRemovalSteps = []string{GroupStepSessions, GroupStepTokens, GroupStepAudit}
GroupRemovalSteps are the steps StartGroupRemoval opens, in the order they run.
Functions ¶
func AddRunnerPoolExecutorQ ¶ added in v0.9.0
func AddRunnerPoolExecutorQ(ctx context.Context, q Querier, id uuid.UUID, executor string) (m types.RunnerPoolMember, added bool, rev int64, err error)
AddRunnerPoolExecutorQ is AddRunnerPoolExecutor's statement on q (a pgx.Tx), which a held change applies through inside the decision transaction.
func CapAuditTarget ¶ added in v0.7.4
CapAuditTarget bounds one audit target. A target already within the cap is returned BYTE-IDENTICAL: audit queries match this column exactly, so the cap must be invisible to every row that is not abusive.
func CreateServiceIdentityQ ¶ added in v0.9.0
func CreateServiceIdentityQ(ctx context.Context, tx Querier, si types.ServiceIdentity) (types.ServiceIdentity, error)
CreateServiceIdentityQ is CreateServiceIdentity's statements on tx (a pgx.Tx), which a held governance change applies inside the decision transaction.
func DeleteCapabilityGrantQ ¶ added in v0.8.6
DeleteCapabilityGrantQ is DeleteCapabilityGrant's statement on q.
func DeleteGovernanceAssignmentQ ¶ added in v0.8.6
DeleteGovernanceAssignmentQ is DeleteGovernanceAssignment's statement on q.
func DeleteGovernanceProfileQ ¶ added in v0.8.6
DeleteGovernanceProfileQ is DeleteGovernanceProfile's body on a caller's transaction (q must be a pgx.Tx: it takes the transaction-scoped graph lock) and answers the same errors.
func DeleteRoleMappingQ ¶ added in v0.8.6
DeleteRoleMappingQ is DeleteRoleMapping's statement on q.
func DeleteRunnerPoolUsePolicyQ ¶ added in v0.9.0
DeleteRunnerPoolUsePolicyQ is DeleteRunnerPoolUsePolicy's statement on q.
func ExecRevocationCut ¶ added in v0.9.0
ExecRevocationCut runs one cut write (an upsert into oidc_session_revocations or oidc_session_cuts) under the exclusive revocation-order lock, as a single pipelined transaction.
func FederatedActor ¶ added in v0.8.0
FederatedActor is the actor a federated row is stored under: the forwarding device's own actor (device:<id>), a slash, then the claimed principal, so an org-principal filter never matches a laptop's claim.
func FederatedDeviceID ¶ added in v0.8.0
func FederatedDeviceID(ev types.AuditEvent) *uuid.UUID
FederatedDeviceID reports which device forwarded ev, or nil for the organisation's own row. TRUST BOUNDARY: federated only when both marks agree — data.device_origin.device_id and the FederatedActor prefix naming the same device — so no writer controlling only one can make its own row read as a device's. federatedRowSQL is the same predicate in SQL.
func FederatedRowProblem ¶ added in v0.8.0
func FederatedRowProblem(r types.FederatedAuditEvent) string
FederatedRowProblem says why r cannot be stored so its claim re-checks from the stored row, or "" when it can. data must be a JSON object without a top-level device_origin key (this organisation's marker), JSON null, or absent; target must be one CapAuditTarget leaves unchanged; device_id is this organisation's to derive, never the device's to claim. Exported so the API refuses with a 400 before any database work.
func GetCapabilityEnforcementQ ¶ added in v0.8.6
GetCapabilityEnforcementQ is GetCapabilityEnforcement on q.
func GetCapabilityGrantByKeyQ ¶ added in v0.8.6
func GetCapabilityGrantByKeyQ(ctx context.Context, q Querier, subjectType, subject, capability, value string, forUpdate bool) (types.CapabilityGrant, error)
GetCapabilityGrantByKeyQ reads the grant at one natural key on q, ErrNotFound when none; forUpdate locks the row.
func GetCapabilityGrantQ ¶ added in v0.8.6
func GetCapabilityGrantQ(ctx context.Context, q Querier, id uuid.UUID, forUpdate bool) (types.CapabilityGrant, error)
GetCapabilityGrantQ reads one grant by id on q, ErrNotFound when none; forUpdate locks the row.
func GetCredentialDeliveryPolicyQ ¶ added in v0.9.0
func GetCredentialDeliveryPolicyQ(ctx context.Context, q Querier) (types.CredentialDeliveryPolicyDoc, error)
GetCredentialDeliveryPolicyQ is GetCredentialDeliveryPolicy on q (a governance decision's transaction).
func GetGovernanceAssignmentByKeyQ ¶ added in v0.8.6
func GetGovernanceAssignmentByKeyQ(ctx context.Context, q Querier, subjectType, subject string, forUpdate bool) (types.GovernanceAssignment, error)
GetGovernanceAssignmentByKeyQ reads the assignment at one natural key on q, ErrNotFound when none.
func GetGovernanceAssignmentQ ¶ added in v0.8.6
func GetGovernanceAssignmentQ(ctx context.Context, q Querier, id uuid.UUID, forUpdate bool) (types.GovernanceAssignment, error)
GetGovernanceAssignmentQ reads one assignment by id on q, ErrNotFound when none; forUpdate locks the row for the transaction.
func GetGovernanceProfileQ ¶ added in v0.8.6
func GetGovernanceProfileQ(ctx context.Context, q Querier, id uuid.UUID, forUpdate bool) (types.GovernanceProfile, error)
GetGovernanceProfileQ reads one profile row (raw, as GetGovernanceProfile does) on q.
func GetLiveAPITokenQ ¶ added in v0.8.6
GetLiveAPITokenQ re-reads one token by id on q (a caller's transaction), and only while it can still authenticate: revoked and expired rows are ErrNotFound, as in GetAPITokenByRaw. A decision that must still hold the authority of the token it was made with reads it again through this, not through the context the request was authenticated with.
func GetRemoteRunnerQ ¶ added in v0.9.0
func GetRemoteRunnerQ(ctx context.Context, q Querier, id string, forUpdate bool) (types.RemoteRunner, error)
GetRemoteRunnerQ reads one remote runner on q, locked FOR UPDATE when forUpdate.
func GetRunnerPoolUsePolicyQ ¶ added in v0.9.0
func GetRunnerPoolUsePolicyQ(ctx context.Context, q Querier, id uuid.UUID) (types.RunnerPoolUsePolicy, error)
GetRunnerPoolUsePolicyQ reads one pool's use policy on q, ErrNotFound when it has none.
func GetServiceIdentityForUpdateQ ¶ added in v0.9.0
func GetServiceIdentityForUpdateQ(ctx context.Context, tx Querier, name string) (types.ServiceIdentity, error)
GetServiceIdentityForUpdateQ reads name FOR UPDATE on tx (a pgx.Tx), retired or not; ErrNotFound when missing.
func GetSiteConfigQ ¶ added in v0.9.0
GetSiteConfigQ is GetSiteConfig on q.
func GetUserTypeQ ¶ added in v0.8.6
func GetUserTypeQ(ctx context.Context, q Querier, id string, forUpdate bool) (types.UserType, error)
GetUserTypeQ is GetUserType on q; forUpdate locks the row for the transaction.
func IdentityBlockedQ ¶ added in v0.8.9
IdentityBlockedQ checks identity admission on q, including an existing transaction.
func InsertAuditEvent ¶
InsertAuditEvent appends a single audit event. Implements audit.Recorder. The Postgres trigger blocks UPDATE/DELETE; this function only ever INSERTs.
ev is taken by POINTER so the hash chain can be handed back: on success ev.PrevHash/ev.RowHash carry the values Postgres computed, and ev.RowHash IS the chain head at that instant, which fanoutRecorder emits to the audit sinks so an external SIEM ends up holding a head hash Wardyn cannot later disown.
Runs in a transaction because pg_advisory_xact_lock must be held across the append: this caller's seq allocation and head read must not interleave with another writer's, keeping seq order and chain order identical. audit_append takes the same lock itself (the only way a row enters the table since 0111); the lock here is re-entrant and free, and keeps the bounded wait below in front of it.
func InsertAuditEventTx ¶ added in v0.8.6
InsertAuditEventTx is InsertAuditEvent's body on a caller-supplied transaction: the same target cap, pinned lock-wait bound and advisory lock on the chain, so a row written this way links exactly as every other row does.
func LiftComponentRestrictionQ ¶ added in v0.8.9
LiftComponentRestrictionQ is LiftComponentRestriction's statements on q, for a caller already in a transaction (a held change's apply). The availability lock is taken again, which is free inside one transaction, so the existence check and the delete are ordered against a component delete either way.
func ListCapabilityGrantsQ ¶ added in v0.8.6
ListCapabilityGrantsQ is ListCapabilityGrants on q.
func ListCapabilityRestrictionsQ ¶ added in v0.8.6
func ListCapabilityRestrictionsQ(ctx context.Context, q Querier) (map[string]map[string]bool, error)
ListCapabilityRestrictionsQ is ListCapabilityRestrictions on q.
func ListGovernanceProfilesQ ¶ added in v0.8.6
ListGovernanceProfilesQ reads every profile by name on q.
func ListRoleMappingsQ ¶ added in v0.8.6
ListRoleMappingsQ is ListRoleMappings on q.
func ListUserTypesQ ¶ added in v0.8.6
ListUserTypesQ is ListUserTypes on q.
func LockGovernanceAssignmentKey ¶ added in v0.8.6
LockGovernanceAssignmentKey takes the transaction-scoped lock keyed to one assignment's natural key, so a write to that key and the approval of a held change to it serialize. q must be a pgx.Tx.
func LockGovernanceGraph ¶ added in v0.8.6
LockGovernanceGraph takes the transaction-scoped lock every write to the governance profile graph holds, so one write at a time sees and changes it. q must be a pgx.Tx.
func LockGovernanceTarget ¶ added in v0.8.6
LockGovernanceTarget takes the transaction-scoped lock for one target of a governance change: the direct write to it and the approval of a held change to it serialize on it. parts are the target's natural key. q must be a pgx.Tx.
func LockLivePoolQ ¶ added in v0.9.0
LockLivePoolQ takes the pool row lock of a live pool on q, ErrNotFound when there is none. A held change takes it right after its target lock, so every member write waits for the decision.
func LockRevocationOrder ¶ added in v0.9.0
LockRevocationOrder takes the exclusive revocation-order lock for the rest of tx, which must contain the cut write it protects. tx must be a pgx.Tx.
func LockSiteConfig ¶ added in v0.9.0
LockSiteConfig takes the transaction-scoped form of the lock the site-config writers hold (db.SiteConfigLockClass, the class's single document lock), so a held change applied inside the decision transaction cannot interleave with a PUT /site-config read-modify-write. q must be a pgx.Tx.
func PutCapabilityEnforcementQ ¶ added in v0.8.6
func PutCapabilityEnforcementQ(ctx context.Context, q Querier, enabled map[string]bool) (map[string]bool, error)
PutCapabilityEnforcementQ is PutCapabilityEnforcement's statements on q. A held governance change applies through it inside the decision transaction.
func PutCredentialDeliveryPolicyQ ¶ added in v0.9.0
func PutCredentialDeliveryPolicyQ(ctx context.Context, q Querier, policy json.RawMessage, by string, now time.Time) (types.CredentialDeliveryPolicyDoc, error)
PutCredentialDeliveryPolicyQ is PutCredentialDeliveryPolicy on q.
func PutRunnerPoolUsePolicyQ ¶ added in v0.9.0
func PutRunnerPoolUsePolicyQ(ctx context.Context, q Querier, id uuid.UUID, revision *int64, subjects []types.RunnerPoolSubject, by string) (types.RunnerPoolUsePolicy, error)
PutRunnerPoolUsePolicyQ is PutRunnerPoolUsePolicy's statement on q (a pgx.Tx, the pool row locked here). ErrNotFound: no such live organization pool.
func PutSiteConfigQ ¶ added in v0.9.0
func PutSiteConfigQ(ctx context.Context, q Querier, cfg types.SiteConfig) (types.SiteConfig, error)
PutSiteConfigQ is PutSiteConfig on q. A held governance change applies through it inside the decision transaction.
func ReadRevocationSeq ¶ added in v0.9.0
ReadRevocationSeq is the ordering value a credential issued now records. Always at least 1 once migration 0176 has run; the caller stores it as the credential's rev_seq.
func RemoveRunnerPoolExecutorQ ¶ added in v0.9.0
func RemoveRunnerPoolExecutorQ(ctx context.Context, q Querier, id uuid.UUID, executor string) (bool, int64, error)
RemoveRunnerPoolExecutorQ is RemoveRunnerPoolExecutor's statement on q (a pgx.Tx), which a held detach applies through inside the decision transaction.
func RunnerPoolExecutorIDsQ ¶ added in v0.9.0
RunnerPoolExecutorIDsQ lists a pool's remote-hosted members, sorted, never nil.
func SetCapabilityRestrictionQ ¶ added in v0.8.6
func SetCapabilityRestrictionQ(ctx context.Context, q Querier, capability, value string, restricted bool, by string) error
SetCapabilityRestrictionQ is SetCapabilityRestriction's statement on q.
func SetRemoteRunnerPeopleQ ¶ added in v0.9.0
func SetRemoteRunnerPeopleQ(ctx context.Context, q Querier, id string, revision *int64, pools types.RemoteRunnerPeoplePools, subjects []types.RunnerPoolSubject, by string) (types.RemoteRunner, error)
SetRemoteRunnerPeopleQ writes a remote runner's people policy on q (a pgx.Tx holding the governance target lock): pools off clears the list, listed stores subjects. A non-nil revision must be the runner's (ErrRunnerPoolStale). ErrNotFound: no such runner.
func TemplateLimit ¶ added in v0.9.0
func TemplateLimit(owner types.TemplateOwner) int
TemplateLimit is the most templates owner's audience may hold.
func UpdateUserTypeQ ¶ added in v0.8.6
UpdateUserTypeQ is UpdateUserType's statement on q. A held governance change applies through it inside the decision transaction.
func UpsertCapabilityGrantQ ¶ added in v0.8.6
func UpsertCapabilityGrantQ(ctx context.Context, q Querier, g types.CapabilityGrant) (types.CapabilityGrant, error)
UpsertCapabilityGrantQ is UpsertCapabilityGrant's statement on q. A held governance change applies through it inside the decision transaction.
func UpsertGovernanceAssignmentQ ¶ added in v0.8.6
func UpsertGovernanceAssignmentQ(ctx context.Context, q Querier, a types.GovernanceAssignment) (types.GovernanceAssignment, error)
UpsertGovernanceAssignmentQ is UpsertGovernanceAssignment's statement on q.
func UpsertRoleMappingQ ¶ added in v0.8.6
func UpsertRoleMappingQ(ctx context.Context, q Querier, m types.RoleMapping) (types.RoleMapping, error)
UpsertRoleMappingQ is UpsertRoleMapping's statement on q (the doc above is its contract). A held governance change applies through it inside the decision transaction.
func WithIdentityGuard ¶ added in v0.8.6
func WithIdentityGuard(ctx context.Context, g IdentityGuard) context.Context
WithIdentityGuard makes the insert writers that honour it (CreateRun, CreateRunUnderCap, CreateAPIToken, AddSSHKey) read the owner's identity rows FOR SHARE in their own transaction. Suspension takes the same rows FOR UPDATE, so a write either commits before the suspension's first step, where the sweep after it finds it, or reads the deactivation and is refused.
func WriteGovernanceProfileQ ¶ added in v0.8.6
func WriteGovernanceProfileQ(ctx context.Context, q Querier, id uuid.UUID, build GovernanceProfileBuild) (types.GovernanceProfile, error)
WriteGovernanceProfileQ is WriteGovernanceProfile's body on a caller's transaction: q must be a pgx.Tx, because the graph lock it takes is transaction-scoped. A held governance change applies through it inside the decision transaction.
Types ¶
type ADOSignInEndState ¶ added in v0.8.6
type ADOSignInEndState struct {
Gen int64
Running bool // an end began and has not finished, within ADOSignInEndsStaleAfter
Reason string
}
ADOSignInEndState is one person's count.
type ADOSignInEndStore ¶ added in v0.8.6
type ADOSignInEndStore interface {
// BeginADOSignInEnd marks the start of an end of owner's sign-in.
BeginADOSignInEnd(ctx context.Context, owner, reason string) error
// FinishADOSignInEnd marks its finish.
FinishADOSignInEnd(ctx context.Context, owner string) error
// ADOSignInEnds is owner's count now; a person with no row has gen 0.
ADOSignInEnds(ctx context.Context, owner string) (ADOSignInEndState, error)
}
ADOSignInEndStore is the sign-in end counter. Optional like RunOutputStore: the api layer type-asserts, and a store without it counts in the process.
type APITokensByIdentityLister ¶ added in v0.9.0
type APITokensByIdentityLister interface {
ListAPITokensByIdentity(ctx context.Context, name string) ([]types.APIToken, error)
}
APITokensByIdentityLister is the indexed read behind a per-person revocation: the tokens one name owns under either form. An absent implementation falls back to ListAPITokensByPrincipal plus a scan of ListAPITokens (see ListAPITokensByIdentity for the one place the two differ).
type APITokensByPrincipalPager ¶ added in v0.8.0
type APITokensByPrincipalPager interface {
ListAPITokensByPrincipalPage(ctx context.Context, principal string, p Page) ([]types.APIToken, error)
}
APITokensByPrincipalPager is the scoped analogue of Pager for GET /me/tokens, same safe-fallback posture as GrantsByRunPager (ListAPITokensByPrincipal is already WHERE principal=$1).
type AWSSSOSpentTokenStore ¶ added in v0.8.0
type AWSSSOSpentTokenStore interface {
// MarkAWSSSOTokenSpent upserts one spent-token row, idempotent: re-marking
// an already-spent fingerprint is a no-op, so row age stays "since first
// spent" for the prune below.
MarkAWSSSOTokenSpent(ctx context.Context, fingerprint, owner string, markedAt time.Time) error
// AWSSSOTokenSpent reports whether fingerprint is already known dead; its
// one caller memoizes the answer, so a miss costs at most one query per
// fingerprint per process lifetime.
AWSSSOTokenSpent(ctx context.Context, fingerprint string) (bool, error)
// PruneAWSSSOSpentTokens deletes rows marked before cutoff, reporting the
// count removed. Called from the reaper's existing per-tick advisory lock.
PruneAWSSSOSpentTokens(ctx context.Context, cutoff time.Time) (int, error)
}
AWSSSOSpentTokenStore persists the AWS SSO refresh-token "spent" mark (internal/api/awssso_refresh.go's ssoRefreshSpent map) so it survives a daemon restart, through Store/PG rather than the secret/blob store since the mark is written precisely because that blob store failed.
type ActiveRunsAtPathReader ¶ added in v0.7.0
type ActiveRunsAtPathReader interface {
ActiveRunsAtWorkspacePath(ctx context.Context, workspacePath string) ([]types.AgentRun, error)
}
ActiveRunsAtPathReader answers which OTHER non-terminal runs already operate on one host workspace path, checked on every run create. Its absence falls back to the unbounded ListRuns + an in-Go filter, SAFE (same answer, merely slower) since the warning is advisory and never blocks a launch.
type ActiveRunsByCreatorReader ¶ added in v0.7.5
type ActiveRunsByCreatorReader interface {
ActiveRunsByCreator(ctx context.Context, createdBy, task, agent string) ([]types.AgentRun, error)
}
ActiveRunsByCreatorReader answers which of a person's runs of one task+agent are still non-terminal, so a new sign-in's supersede (supersedeCallerLoginRuns) can end them. Its absence has no fallback; PG implements it in production. task and agent, not "provider": a run row carries no provider column (it lives in the harness.login.start audit datum).
type ApprovalNotifyReader ¶ added in v0.8.6
type ApprovalNotifyReader interface {
// ApprovalEscalations reads, in one query, the escalation state of every approval in ids that has
// outbox rows. Approvals with none are absent from the map.
ApprovalEscalations(ctx context.Context, ids []uuid.UUID, now time.Time) (map[uuid.UUID]types.ApprovalEscalation, error)
// ApprovalNotifyChannelStats returns one row per channel that has outbox rows.
ApprovalNotifyChannelStats(ctx context.Context, now time.Time) ([]types.ApprovalNotifyChannelStat, error)
}
ApprovalNotifyReader is the read side of the approval notification outbox that the console needs: where each pending approval sits on its escalation schedule, and each channel's delivery history. A capability interface like ApprovalsForRunsPager: an absent implementation leaves the projection and the status endpoint empty, never an error, since both only describe notifications.
type ApprovalsByRunCreatorPager ¶ added in v0.5.0
type ApprovalsByRunCreatorPager interface {
ListApprovalsPageByRunCreator(ctx context.Context, createdBy string, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
}
ApprovalsByRunCreatorPager is the ownership-scoped analogue of Pager.ListApprovalsPage: a member's GET /approvals (no ?run_id=) is scoped to approvals on runs THEY created, via a JOIN on agent_runs (approvals carry no created_by of their own). TRUST BOUNDARY: same fail-closed contract as RunsByCreatorPager — an absent implementation must never fall back to the unscoped list.
type ApprovalsByRunPager ¶ added in v0.7.0
type ApprovalsByRunPager interface {
ListApprovalsPageByRun(ctx context.Context, runID uuid.UUID, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
}
ApprovalsByRunPager is Pager.ListApprovalsPage narrowed to ONE run, the ?run_id= shape of GET /api/v1/approvals. Without it, a run-scoped poll falls back to fetching every approval the deployment has ever written and filtering in Go, a cost growing with deployment age since decided rows are never deleted.
Fail-safe like Pager (not fail-closed like ApprovalsByRunCreatorPager): ownership scoping happens before this is reached (getRunAuthorized), so the fallback is a performance question, not a privilege one.
type ApprovalsForRunsPager ¶ added in v0.8.0
type ApprovalsForRunsPager interface {
// ListPendingApprovalsForRuns returns every state=PENDING approval whose
// run_id is in runIDs — no other state, since only PENDING can be held or
// contribute to Pending's count.
ListPendingApprovalsForRuns(ctx context.Context, runIDs []uuid.UUID) ([]types.ApprovalRequest, error)
// CountPendingApprovals returns how many approvals in the whole deployment
// are state=PENDING — GET /me/attention's admin-view pending_approvals,
// counted in the database rather than by listing every row.
CountPendingApprovals(ctx context.Context) (int, error)
// CountPendingApprovalsByRunCreator returns how many PENDING approvals are
// raised on runs createdBy owns — GET /me/attention's user-view
// pending_approvals, counted rather than listed.
CountPendingApprovalsByRunCreator(ctx context.Context, createdBy string) (int, error)
}
ApprovalsForRunsPager is the attention projection's read surface — kept out of Store like every capability interface in this package, since widening Store would silently route a test double's unoverridden method to the unscoped behaviour. SECURITY: an absent implementation fails CLOSED at the api-layer call site (attention projection refuses rather than silently omitting `attention` from every run).
type AttachLease ¶ added in v0.8.6
type AttachLease struct {
RunID uuid.UUID
HolderID uuid.UUID
Replica string // the replica serving the holder's socket
Principal string
Source string // "web" or "ssh"
Since time.Time
Epoch int64 // moves at each takeover of the row
ExpiresAt time.Time
Live bool // read-only: ExpiresAt was ahead of the database's clock
}
AttachLease is one row of run_attach_leases. HolderID is the lease's identity: whatever writes into the terminal must still be the holder.
type AttachLeaseStore ¶ added in v0.8.6
type AttachLeaseStore interface {
// AcquireAttachLease takes runID's lease for l.HolderID when it is free, has lapsed, or is
// held by from (uuid.Nil: nobody in particular), for ttl. It reports whether it did.
AcquireAttachLease(ctx context.Context, l AttachLease, from uuid.UUID, ttl time.Duration) (bool, error)
// ReacquireAttachLease takes runID's lease back for l.HolderID, a holder that had it, when
// the row is gone, has lapsed or is still l.HolderID's, for ttl. It never takes a live row of
// another holder, a reservation for a take-over's taker included. It reports whether it did.
ReacquireAttachLease(ctx context.Context, l AttachLease, ttl time.Duration) (bool, error)
// RenewAttachLease extends holderID's lease by ttl, reporting whether holderID still held it.
RenewAttachLease(ctx context.Context, runID, holderID uuid.UUID, ttl time.Duration) (bool, error)
// HoldsAttachLease reports whether holderID holds runID's lease right now, unlapsed.
HoldsAttachLease(ctx context.Context, runID, holderID uuid.UUID) (bool, error)
// ReleaseAttachLease deletes the lease if holderID holds it, reporting whether it did.
ReleaseAttachLease(ctx context.Context, runID, holderID uuid.UUID) (bool, error)
// ReserveAttachLease is a take-over: it replaces the live lease held by from (uuid.Nil:
// whoever holds it) with a reservation for taker, which only taker's own client may take, for
// ttl, so no queued client of someone else gets the slot the take-over freed. It returns the
// lease it replaced and the reservation's holder id; found is false when no live lease was
// held by from.
ReserveAttachLease(ctx context.Context, runID, from uuid.UUID, taker, replica string, ttl time.Duration) (prev AttachLease, reservation uuid.UUID, found bool, err error)
// GetAttachLease returns runID's lease, lapsed or not (Live says which).
GetAttachLease(ctx context.Context, runID uuid.UUID) (AttachLease, bool, error)
}
AttachLeaseStore is the attach lease record. Optional like RunOutputStore: the api layer type-asserts, and a store without it keeps the writer slot in the process.
type AttachTicket ¶ added in v0.5.0
type AttachTicket struct {
RunID uuid.UUID
ActorType types.ActorType
Principal string
Role string
// Via is the delegated lane the ticket was minted on (#1142), nil
// otherwise; the ticket lane replays it onto the rows it writes.
Via *types.DelegationVia
// AuthorizedAt is when the minting request was admitted, and Email the
// verified email a session revoke may name ("" on the admin-token and local
// lanes). Redemption checks both against the revoke cutoff (#1474). A zero
// AuthorizedAt is a row written before the column existed: never exempt.
AuthorizedAt time.Time
Email string
// RevSeq is the revocation sequence the minting credential recorded (ReadRevocationSeq); 0 is a
// row from before it existed, ordered on AuthorizedAt.
RevSeq int64
}
AttachTicket is what one redeemed single-use WS attach ticket carries: the run it's bound to, the minting principal (audit attribution), and that principal's role at mint time. The ?ticket= WS lane bypasses humanOrAdminAuth entirely, so this stamped role is the only signal available to re-check owner-or-admin at consume time.
type AuditChainStatus ¶ added in v0.6.0
type AuditChainStatus struct {
// OK is true when every chained row re-hashed to its stored row_hash and
// linked to its predecessor.
OK bool `json:"ok"`
// Checked is how many chained rows the sweep walked.
Checked int64 `json:"checked"`
// Legacy is how many rows carry NO hash and sit BELOW the first chained
// row (pre-migration-0047) — expected, not a failure. A hashless row
// ABOVE that prefix is a break instead (auditChainWalk.step).
Legacy int64 `json:"legacy"`
// FirstSeq/HeadSeq bound the chained range (both 0 when Checked is 0).
FirstSeq int64 `json:"first_seq"`
HeadSeq int64 `json:"head_seq"`
// HeadHash is the row_hash of the newest chained row: the value to compare
// against what a SIEM recorded off the sink stream.
HeadHash string `json:"head_hash,omitempty"`
// AnchorSeq is the last seq of the newest attested retention drop the sweep started from: the first
// retained row must chain to that drop's recorded tail. 0 when no partition was ever dropped.
AnchorSeq int64 `json:"anchor_seq,omitempty"`
// BrokenSeq/Reason are set only when OK is false.
BrokenSeq int64 `json:"broken_seq,omitempty"`
Reason string `json:"reason,omitempty"`
}
AuditChainStatus is one verification sweep's verdict (migration 0047). OK is the only field an alert should key on; BrokenSeq/Reason name the FIRST row that failed, not every row after it, since one edited row makes every later link mismatch too and listing them all buries the edit.
func VerifyAuditChainTx ¶ added in v0.9.0
VerifyAuditChainTx is VerifyAuditChain on a transaction the caller owns, for a caller that has one connection and no pool to give it (wardynd -recovery-rehearse). The caller begins it repeatable-read and read-only.
type AuditChainVerifier ¶ added in v0.6.0
type AuditChainVerifier interface {
VerifyAuditChain(ctx context.Context) (AuditChainStatus, error)
}
AuditChainVerifier is the OPTIONAL store capability behind GET /api/v1/audit/chain/verify: a test fake or non-Postgres store has no chain, and the handler answers 501 rather than reporting a chain it never wrote as clean.
Operator-invoked, never run at boot (O(whole audit log)). Not a substitute for comparing HeadHash against an off-box copy: an actor who can rewrite one row can usually rewrite and re-chain the tail, which then verifies clean. See docs/OPERATIONS.md.
type AuditDeliveryStatus ¶ added in v0.9.0
type AuditDeliveryStatus struct {
Destination string
HeadSeq int64
AckedSeq int64
Resets int64
AckedAt *time.Time
OldestUndelivered *time.Time
LastError string
Halted bool
}
AuditDeliveryStatus is one destination's checkpoint plus the head it lags behind, the whole input the delivery metrics emit. AckedAt and OldestUndelivered are nil when nothing has been acknowledged yet and when the checkpoint is caught up.
type AuditFilter ¶ added in v0.4.4
type AuditFilter struct {
Since time.Time // events at or after this instant
Until time.Time // events strictly before this instant
Action string // exact action, e.g. "run.kill"
ActionPrefix string // action family, e.g. "credential." or "egress."
Actor string // exact principal, e.g. "alice@corp.example" (human evidence)
ActorType types.ActorType // human / agent / system
Outcome string // success / failure / warn
Origin string // AuditOriginDevice or AuditOriginOrganisation
// ActorAlt is a second stored actor that also matches Actor: the "subject:<id>"
// a row holds for the person Actor names under WARDYN_AUDIT_SEAL=full. Rows
// written before it was turned on keep the name, so both must match.
ActorAlt string
// Target is the exact target column, e.g. a person's principal for a person.*
// row. TargetAlt is its second stored form, as ActorAlt is Actor's: the
// "subject:<id>" a person-target row holds under WARDYN_AUDIT_SEAL=full.
Target string
TargetAlt string
// DataContains is a JSON object the row's data must contain (Postgres
// `data @> $n::jsonb`): every key present with an equal value, objects
// recursively. A string, not a map, so the filter stays comparable (IsZero).
DataContains string
}
AuditFilter narrows the audit feed to answer the questions a bigger window never can — "what happened between 14:00 and 16:00", "every secret.write this quarter", "every failure" — where the answer is 40 events inside 200k. The zero value matches everything, so an unfiltered read keeps taking the plain QueryRecentAuditEventsPage / QueryAuditEventsPage path unchanged.
It renders TWO ways from one declaration — SQL (where) for the Pager path and Go (Matches) for the fetch-all fallback — because a filter applied on only one of them returns silently UNFILTERED events on the other, which in a governance product is a quiet wrong answer. Keep the two in step; they are deliberately adjacent.
Actor IS filterable: for a HUMAN event it is the operator/member principal (e.g. "alice@corp.example"), so ?actor= answers "everything developer X did" — the per-principal evidence a vendor/compliance question needs and that no wider window yields. (An earlier note dismissed actor as filterable because for an AGENT event it is the per-run SPIFFE ID and would merely restate ?run_id= — but that reasoning only ever considered agent events; a human's approvals, kills, and policy writes all carry their principal here, and that is exactly what the finding asks for.) The agent-side "everything under X's runs" view still needs the agent_runs.created_by join, which does not fit this table-local filter.
func (AuditFilter) IsZero ¶ added in v0.4.4
func (f AuditFilter) IsZero() bool
IsZero reports whether the filter narrows nothing.
func (AuditFilter) Keep ¶ added in v0.4.4
func (f AuditFilter) Keep(events []types.AuditEvent) []types.AuditEvent
Keep returns the events matching f, in order. A zero filter returns events unchanged (no copy).
func (AuditFilter) Matches ¶ added in v0.4.4
func (f AuditFilter) Matches(ev types.AuditEvent) bool
Matches reports whether ev satisfies every set predicate.
type AuditPartitionExporter ¶ added in v0.8.6
type AuditPartitionExporter interface {
// ExportAuditPartition reads one closed partition in seq order from ONE snapshot. header is called
// once, before any row, with the manifest of that snapshot; row once per row. ErrNotFound when name
// is not a partition of the audit log, ErrAuditPartitionOpen when it can still receive rows; in
// both cases neither callback ran. An error from either callback stops the read and is returned.
ExportAuditPartition(ctx context.Context, name string, header func(PartitionManifest) error, row func(AuditPartitionRow) error) error
}
AuditPartitionExporter is the OPTIONAL store capability behind GET /audit/export?partition=. A test fake or non-Postgres store has no partitions.
type AuditPartitionRow ¶ added in v0.8.6
type AuditPartitionRow struct {
Seq int64
RecordedUS int64
TimeUS int64
ID uuid.UUID
RunID *uuid.UUID
ActorType string
Actor string
Action string
Target string
Outcome string
SourceIP string
// Data is the jsonb's own text form, the exact bytes audit_row_hash embeds; nil for SQL NULL.
Data *string
// PrevHash and RowHash are nil for a row from before the chain began.
PrevHash *string
RowHash *string
// FoldHash is what the digest folds: RowHash, or for a hashless row the hash it would have had.
FoldHash string
}
AuditPartitionRow is one stored row of a partition, exactly as the table holds it: the columns audit_row_hash covers, the hashes, and the position.
type AuditRetention ¶ added in v0.8.6
type AuditRetention interface {
AuditRetentionStatus(ctx context.Context) (AuditRetentionStatus, error)
// DropAuditPartition calls audit_retention_drop; actorType is the type the chained event is recorded
// under (the sweeper's name is always the system actor). A refusal is *AuditRetentionRefused; a name that is
// not a partition of the audit log is ErrNotFound.
DropAuditPartition(ctx context.Context, partition, digest, actor string, actorType types.ActorType) (AuditRetentionDrop, error)
// AutodropAuditPartition drops the oldest partition if it is eligible, computing its digest in the
// database, as the system actor. ok is false (and nothing was dropped) when it is not.
AutodropAuditPartition(ctx context.Context) (drop AuditRetentionDrop, ok bool, err error)
// SetAuditRetentionPolicy calls audit_retention_set_policy.
SetAuditRetentionPolicy(ctx context.Context, days int) (AuditRetentionPolicyChange, error)
// EnsureAuditPartitions calls audit_ensure_partitions and returns how many months it created.
EnsureAuditPartitions(ctx context.Context, months int) (int, error)
// AuditPartitionsAhead is how many months past the current one already have a partition.
AuditPartitionsAhead(ctx context.Context) (int, error)
}
AuditRetention is the OPTIONAL store capability behind the retention endpoints, the daily partition ensure and the leader sweeper's autodrop: a test fake or non-Postgres store has no partitions.
type AuditRetentionDrop ¶ added in v0.8.6
type AuditRetentionDrop = types.AuditRetentionDrop
The retention wire types live in internal/types, shared with pkg/client; these are their store-side names.
type AuditRetentionPartition ¶ added in v0.8.6
type AuditRetentionPartition = types.AuditRetentionPartition
The retention wire types live in internal/types, shared with pkg/client; these are their store-side names.
type AuditRetentionPolicy ¶ added in v0.8.6
type AuditRetentionPolicy = types.AuditRetentionPolicy
The retention wire types live in internal/types, shared with pkg/client; these are their store-side names.
type AuditRetentionPolicyChange ¶ added in v0.8.6
type AuditRetentionPolicyChange = types.AuditRetentionPolicyChange
The retention wire types live in internal/types, shared with pkg/client; these are their store-side names.
type AuditRetentionRefused ¶ added in v0.8.6
AuditRetentionRefused is a drop the database refused. Reason is one of the Retention* constants.
func (*AuditRetentionRefused) Error ¶ added in v0.8.6
func (e *AuditRetentionRefused) Error() string
type AuditRetentionStatus ¶ added in v0.8.6
type AuditRetentionStatus = types.AuditRetentionStatus
The retention wire types live in internal/types, shared with pkg/client; these are their store-side names.
type AuditSplitRange ¶ added in v0.8.6
type AuditSplitRange struct {
Name string
Rows int64
SeqLo int64
SeqHi int64
// RecordedLo and RecordedHi are the smallest and largest recorded_at the range's rows now carry.
RecordedLo time.Time
RecordedHi time.Time
// Digest is the range's partition digest (audit_partition_digest), equal to the fold over its source rows.
Digest string
}
AuditSplitRange is one seq-contiguous range the legacy partition was split into.
type AuditSplitRefused ¶ added in v0.8.6
AuditSplitRefused is a legacy split that was not attempted, or was undone, for a named reason.
func (*AuditSplitRefused) Error ¶ added in v0.8.6
func (e *AuditSplitRefused) Error() string
type AuditSplitResult ¶ added in v0.8.6
type AuditSplitResult struct {
Rows int64
Checked int64
Legacy int64
Ranges []AuditSplitRange
}
AuditSplitResult is what one split did. Checked and Legacy are the chain verifier's counts, which were the same before the split and after it: the split removed no row from the chain.
func SplitLegacyAudit ¶ added in v0.8.6
SplitLegacyAudit splits the legacy partition, which holds all of the audit history from before 0.8.6 under one recorded_at, into seq-contiguous ranges that ordinary retention can drop one at a time. It is the one-shot offline tool behind `wardynd -audit-split-legacy`.
It runs on tx, a read-write transaction on the migrator's connection that the caller commits only when this returns nil. The caller has already made sure no writer is running; this takes db.AuditPartitionLockKey and then db.AuditChainLockKey for the transaction (the order the retention drop takes them), so a writer that slipped in is held out, not interleaved.
A range is not a month of the rows' own time. The boundaries are where the running maximum of "time" first crosses a month, walking the rows in seq order, and each row's new recorded_at is that running maximum (never past the cutover). A spool replay writes an old "time" late, so splitting by "time" would scatter a month through the chain and leave an interior link behind when its range was dropped; the running maximum cannot go backwards, so every range is a contiguous prefix of chain order, and its largest recorded_at is the largest "time" it holds. row_hash does not cover recorded_at, so no hash changes.
Every range is copied to a new table, attached, and proved against its source (the same fold audit_partition_digest computes, and a row-for-row comparison), the legacy table is dropped, the ranges are written to the expected manifest and a 'split' anchor each, and the chain is verified again. The verification must see exactly the rows it saw before.
type BrandingStore ¶ added in v0.8.0
type BrandingStore interface {
// GetBranding returns the record, or ErrNotFound for an unbranded console.
GetBranding(ctx context.Context) (types.Branding, error)
// PutBranding replaces the record. keepLogo leaves the stored logo as it
// is and ignores b.Logo/b.LogoType.
PutBranding(ctx context.Context, b types.Branding, keepLogo bool) (types.Branding, error)
// DeleteBranding removes the record; false when there was none.
DeleteBranding(ctx context.Context) (bool, error)
// SetBrandingLogo replaces only the logo and its file-delivered mark; an
// empty logo removes it. false when there is no record to attach it to.
SetBrandingLogo(ctx context.Context, logo []byte, logoType string, fromFile bool, updatedBy string) (bool, error)
}
BrandingStore is the OPTIONAL store capability behind console branding, optional for DeviceStore's reason: a fake without it answers the public read as unbranded and refuses a write, never a silent no-op.
type CapabilityGrantsForPager ¶ added in v0.8.0
type CapabilityGrantsForPager interface {
ListCapabilityGrantsForPage(ctx context.Context, users, groups []string, userType string, p Page) ([]types.CapabilityGrant, error)
}
CapabilityGrantsForPager is the scoped analogue of Pager for GET /me/capabilities, same safe-fallback posture as GrantsByRunPager; exists for the uniform list-route contract (?limit=&offset=+X-Wardyn-Truncated), not because grant lists routinely truncate.
type ComponentRestrictionLifter ¶ added in v0.8.9
type ComponentRestrictionLifter interface {
// LiftComponentRestriction deletes the restriction row of the component id, in one transaction
// under the availability lock, after checking that an org row (owner "") has that id. ErrNotFound
// when none does, and then nothing is written: lifting a deleted id's restriction would open an id
// that must stay closed.
LiftComponentRestriction(ctx context.Context, id uuid.UUID, by string) error
}
ComponentRestrictionLifter lifts an organisation component's restriction only while the component exists. Optional beside ComponentStore: a store without it lifts like any other kind.
type ComponentStore ¶ added in v0.8.9
type ComponentStore interface {
// CreateComponent inserts c at version 1 under the id the CALLER chose, and never replaces a
// row: ErrConflict when the id exists or the owner already has a component of that name. The
// caller choosing the id is what lets it record who may use an org component before the row
// exists, so no reader can find the row first. Timestamps are the database's.
CreateComponent(ctx context.Context, c types.Component) (types.Component, error)
// UpdateComponent replaces the name and definition of the row with c's id AND owner and moves
// its version by one. ErrNotFound when that owner has no such row; ErrConflict on a name the
// owner already uses.
UpdateComponent(ctx context.Context, c types.Component) (types.Component, error)
// DeleteComponent removes owner's row and returns it, or ErrNotFound. Snapshots of it on
// runs already launched are kept.
DeleteComponent(ctx context.Context, id uuid.UUID, owner string) (types.Component, error)
GetComponent(ctx context.Context, id uuid.UUID, owner string) (types.Component, error)
// ListComponents returns owner's rows by name.
ListComponents(ctx context.Context, owner string) ([]types.Component, error)
// ListComponentsByIDs returns the rows among ids that are the organisation's or owner's own.
// An id it does not return is absent or another person's; the two are not told apart.
ListComponentsByIDs(ctx context.Context, owner string, ids []uuid.UUID) ([]types.Component, error)
CountComponents(ctx context.Context, owner string) (int, error)
// PutRunComponents writes run runID's snapshot, once, in one transaction; each row's position
// in comps is its ordinal, and its RunID, Ordinal and Erased fields are not read. ErrNotFound
// when the run does not exist; ErrConflict when it already has a snapshot, which is never
// replaced — its rows are the run's authorization record. An empty comps is refused: a run
// launched without components writes no snapshot, so the caller does not call this.
PutRunComponents(ctx context.Context, runID uuid.UUID, comps []types.RunComponent) error
// ListRunComponents returns a run's snapshot in request order, erased rows included (Erased,
// with only SelfDefined left beside the key); empty for a run launched without components.
// It is what revive re-checks: an org row (SelfDefined false) needs its ComponentID's grant,
// any SelfDefined row the custom-component feature.
ListRunComponents(ctx context.Context, runID uuid.UUID) ([]types.RunComponent, error)
// DeleteComponentsByOwner and EraseRunComponentsByOwner are a person's erasure. The first
// deletes the components they saved. The second clears the descriptive content of the
// snapshot rows of what they defined, across every run, and KEEPS each row as that run's
// authorization tombstone. Each returns how many rows it changed and refuses owner "" — the
// organisation's rows are no person's.
DeleteComponentsByOwner(ctx context.Context, owner string) (int, error)
EraseRunComponentsByOwner(ctx context.Context, owner string) (int, error)
// EraseRunComponentsOfRun clears, on run runID only, what EraseRunComponentsByOwner clears:
// a create that finds a saved component gone after its snapshot write leaves no content
// behind. It returns how many rows it changed and refuses owner "".
EraseRunComponentsOfRun(ctx context.Context, runID uuid.UUID, owner string) (int, error)
}
ComponentStore persists custom components (migration 0136_components) and the snapshot of the ones a run launched with (migration 0137_run_components); bodies in store_components.go. Optional like RunLayoutStore, so the doubles that implement Store need not grow: callers type-assert. A caller that finds it absent must REFUSE a request that names a component, never drop the component and carry on.
Owner "" is the organisation's rows; any other owner is one person's principal. Every read and write of a component is scoped to an owner, so another person's row answers exactly as an absent one.
type DecidedAlwaysEgressPager ¶ added in v0.9.0
type DecidedAlwaysEgressPager interface {
// ListDecidedAlwaysEgressPage returns up to limit egress_domain approvals in
// state whose decision scope is `always`, newest request first, strictly
// after the keyset (afterRequestedAt, afterID); a nil afterID starts at the
// newest row. Each row carries only ID, RunID, Kind, RequestedScope, State,
// RequestedAt, DecidedAt and DecisionScope: the reason and the other decided
// columns are never read.
ListDecidedAlwaysEgressPage(ctx context.Context, state types.ApprovalState, afterRequestedAt time.Time, afterID uuid.UUID, limit int) ([]types.ApprovalRequest, error)
}
DecidedAlwaysEgressPager is the read behind the leader-term heal of `always` egress verdicts (api.ReconcileWorkspaceEgressDecisions). A capability interface like ApprovalsForRunsPager, asserted on the approval service.
type DelegateReader ¶ added in v0.9.0
type DelegateReader interface {
GetDelegateByID(ctx context.Context, id uuid.UUID) (types.Delegate, error)
}
DelegateReader reads one portal by id whatever its state, so the pool queue's start can tell a portal that was revoked while a run waited from one that still stands. Separate from DelegateStore for the same reason that interface is optional: a test double that implements one need not the other.
type DelegateStore ¶ added in v0.8.0
type DelegateStore interface {
CreateDelegate(ctx context.Context, d types.Delegate, raw string) (types.Delegate, error)
GetDelegateByRaw(ctx context.Context, raw string) (types.Delegate, error)
ListDelegates(ctx context.Context) ([]types.Delegate, error)
RevokeDelegate(ctx context.Context, id uuid.UUID, now time.Time) (types.Delegate, error)
MintDelegatedToken(ctx context.Context, t types.DelegatedToken, raw string, now time.Time) (types.DelegatedToken, error)
GetDelegatedTokenByRaw(ctx context.Context, raw string, now time.Time) (types.DelegatedToken, error)
GetDelegatedTokenByID(ctx context.Context, id uuid.UUID, now time.Time) (types.DelegatedToken, error)
}
DelegateStore is optional, type-asserted like DeviceStore: without it the exchange and delegated lane fail closed instead of silently no-op.
Authenticating reads filter revoked/expired rows in their WHERE, so revoked, expired, unknown, and mismatched credentials all answer ErrNotFound — the boundary gives no oracle signal.
type DeprovisionFailure ¶ added in v0.8.6
DeprovisionFailure is a ledger row of a suspension or purge that is still pending and has failed at least once: the step, and the error its last attempt ended on. The console's SCIM card lists them.
type DeprovisionJob ¶ added in v0.8.6
type DeprovisionJob struct {
IdentityID uuid.UUID
Kind string
Step string
Target string
Done bool
Attempts int
LastError string
Detail map[string]int
}
DeprovisionJob is one row of the step ledger.
type DeviceIngestResult ¶ added in v0.8.0
DeviceIngestResult reports what one IngestDeviceAudit call did. Accepted is how many rows were newly appended: 0 on any refusal (whole batch is one transaction) and also on an idempotent retry. Reset is true when accepted rows began with a genesis (empty-PrevHash) row while the device already had a recorded chain — a "device chain reset", accepted rather than refused.
type DeviceStore ¶ added in v0.8.0
type DeviceStore interface {
MintEnrolmentToken(ctx context.Context, token string, t types.DeviceEnrolmentToken) (types.DeviceEnrolmentToken, error)
ConsumeEnrolmentToken(ctx context.Context, token string, now time.Time) (types.DeviceEnrolmentToken, bool, error)
ListEnrolmentTokens(ctx context.Context, now time.Time) ([]types.DeviceEnrolmentToken, error)
RevokeEnrolmentToken(ctx context.Context, id uuid.UUID, now time.Time) (types.DeviceEnrolmentToken, error)
CreateDevice(ctx context.Context, d types.Device, raw string) (types.Device, error)
GetDeviceByRaw(ctx context.Context, raw string) (types.Device, error)
TouchDevice(ctx context.Context, id uuid.UUID, now time.Time) error
ListDevices(ctx context.Context) ([]types.Device, error)
RevokeDevice(ctx context.Context, id uuid.UUID, now time.Time) (types.Device, error)
IngestDeviceAudit(ctx context.Context, deviceID uuid.UUID, peer string, rows []types.FederatedAuditEvent) (DeviceIngestResult, error)
ListAuditEventsAfterSeq(ctx context.Context, seq int64, limit int) ([]types.FederatedAuditEvent, error)
GetFederationCursor(ctx context.Context) (seq int64, rowHash string, err error)
SetFederationCursor(ctx context.Context, seq int64, rowHash string) error
}
DeviceStore is the optional store capability behind hybrid enrolment and audit federation (docs/design/0.8/PLAN.md, epic #78). Optional like Pager and AuditChainVerifier: a test fake or future non-Postgres store implements neither, so mounting routes must type-assert and answer 501/401 rather than silently no-op. SECURITY (fail-closed): nothing here has a default no-op on Store, so a skipped assertion is a compile error and a failed one has an explicit absent branch.
GetDeviceByRaw's WHERE carries `revoked_at IS NULL` so a revoked credential is not an oracle.
type DueIdentity ¶ added in v0.9.0
DueIdentity is one identity PurgeDueIdentities lists. Suspended says the identity's current deactivation is its own suspension's (ownSuspension). One without that proof was deactivated alongside another identity's suspension, or by a version that did not record it, and the sweeper does not purge it.
type EndedKept ¶ added in v0.8.0
EndedKept is the condition a write on a run kept by its OWN end (LostEnded) lands under during its files grace: the row must still carry the exact ended mark decided on (LostAt), after KeptAfter (Now less the ended-run grace). A grace that runs out between check and write refuses the write; nothing here moves the mark, so no write renews the grace. A revive also needs the run's end to be after Now.
type ErrGovernanceChangeNotPending ¶ added in v0.8.6
ErrGovernanceChangeNotPending is a decision's refusal when the change is no longer pending. State is what it is now; Lapsed is true when this very decision found it past expires_at and moved it to expired.
func (*ErrGovernanceChangeNotPending) Error ¶ added in v0.8.6
func (e *ErrGovernanceChangeNotPending) Error() string
type ErrGovernanceChangePending ¶ added in v0.8.6
ErrGovernanceChangePending is a proposal's refusal when a live change already holds the target: ID is that change.
func (*ErrGovernanceChangePending) Error ¶ added in v0.8.6
func (e *ErrGovernanceChangePending) Error() string
type ErrProfileHasChildren ¶ added in v0.8.6
type ErrProfileHasChildren struct{ Names []string }
ErrProfileHasChildren is DeleteGovernanceProfile's refusal when other profiles still compose on the row: Names are those children, sorted.
func (*ErrProfileHasChildren) Error ¶ added in v0.8.6
func (e *ErrProfileHasChildren) Error() string
type ExpiredGovernanceChange ¶ added in v0.8.6
ExpiredGovernanceChange is a lapsed change a proposal moved to expired: its id and its own target key, which differs from the proposal's when it was a create of the same name.
type GovernanceDecideFunc ¶ added in v0.8.6
type GovernanceDecideFunc func(q Querier, ch types.GovernanceChange) error
GovernanceDecideFunc runs inside the decision transaction with the change as it was locked. A nil error commits the decision; ErrGovernanceChangeStale commits the change as stale; any other error rolls everything back, the change still pending.
type GovernanceDecision ¶ added in v0.8.6
type GovernanceDecision struct {
// To is types.GovernanceChangeApplied or types.GovernanceChangeRejected.
To string
By string
ByEmail string
Reason string
}
GovernanceDecision is what a decision records on the change row.
type GovernanceProfileBuild ¶ added in v0.8.6
type GovernanceProfileBuild func(all []types.GovernanceProfile) (types.GovernanceProfile, error)
GovernanceProfileBuild produces the row a graph write stores, given every profile as the write transaction sees it under the graph lock. A refusal it returns aborts the write unchanged.
type GrantsByRunPager ¶ added in v0.8.0
type GrantsByRunPager interface {
ListGrantsByRunPage(ctx context.Context, runID uuid.UUID, p Page) ([]types.CredentialGrant, error)
}
GrantsByRunPager is the scoped analogue of Pager for GET /runs/{id}/grants: ListGrantsByRun is already WHERE run_id=$1, so an absent implementation is safe (not fail-closed) — the fallback windows the same scoped rows in Go.
type IdentityGuard ¶ added in v0.8.6
IdentityGuard names the owner a write acts for and the authority epoch its caller was admitted under. Epoch < 0 means the caller carries no epoch (an API token, a request-free caller): only a deactivation refuses.
type IdentityUnbinder ¶ added in v0.9.0
type IdentityUnbinder interface {
GetIdentity(ctx context.Context, id uuid.UUID) (PrincipalIdentity, error)
// UnbindIdentity clears the principal of identity id, so the next sign-in binds the row afresh, and
// cuts the released principal's sessions as a suspension does. principal is the one the caller read the
// row bound to: a row bound to another by the time it is locked is ErrIdentityRebound. Refused, with
// nothing written: a deactivated or purged row (ErrIdentityDeactivated), a row with no principal
// (ErrConflict), a row with no object id (ErrIdentityNotRebindable), a principal that still holds an API
// token, SSH key or non-terminal run, sponsors a non-retired service identity or is the target of a
// pending invitation (*PrincipalInUseError), a missing row (ErrNotFound). Once the row is
// re-bound, deactivation and the kill sweep reach only the new principal, so the old one must hold
// nothing. The epoch, the deactivation columns and the SCIM linkage are untouched.
UnbindIdentity(ctx context.Context, id uuid.UUID, principal string) error
}
IdentityUnbinder is the optional store seam behind POST /admin/identities/{id}/unbind.
type IdentityUpdate ¶ added in v0.8.6
type IdentityUpdate struct {
ExternalID string
UserName string
Emails []string
// Reactivate clears the deactivation and the purge schedule on the identity and on every row
// bound to the same principal. A purged identity is ErrIdentityPurged.
Reactivate bool
// PeoplePrincipals are the people rows whose deactivation a reactivation clears.
PeoplePrincipals []string
}
IdentityUpdate is one SCIM write to an identity row. A projection update never touches a binding column; ExternalID is set only when the caller has already checked it against the binding.
type InvitationClaim ¶ added in v0.9.0
type InvitationClaim struct {
ID uuid.UUID
Target string
Now time.Time
Token types.APIToken
Raw string
}
InvitationClaim is one claim: the invitation, the only principal that may claim it, the clock that decides expiry, and the token to mint with its plaintext.
type InvitationClaimed ¶ added in v0.9.0
type InvitationClaimed struct {
Invitation types.Invitation
Token types.APIToken
Retired *types.APIToken
}
InvitationClaimed is what a claim committed. Retired is the admin-minted token the invitation replaced, nil when it had none or that token was no longer live.
type InvitationStore ¶ added in v0.9.0
type InvitationStore interface {
// CreateInvitation inserts inv, or returns ErrInvitationCap when maxPending invitations are
// already pending for inv.Target at now.
CreateInvitation(ctx context.Context, inv types.Invitation, maxPending int, now time.Time) (types.Invitation, error)
// GetInvitation is the row with exactly id, or ErrNotFound. A non-empty target also has to match:
// the claim reads by id AND target, so another person's id is ErrNotFound.
GetInvitation(ctx context.Context, id uuid.UUID, target string) (types.Invitation, error)
// ListInvitations returns invitations newest first, narrowed to target and state when set.
ListInvitations(ctx context.Context, target string, state types.InvitationState, now time.Time, p Page) ([]types.Invitation, error)
// RevokeInvitation revokes a pending invitation: ErrNotFound for no such id, ErrInvitationNotPending otherwise.
RevokeInvitation(ctx context.Context, id uuid.UUID, by string, now time.Time) (types.Invitation, error)
// ClaimInvitation, in one transaction, inserts c.Token, marks the invitation claimed by it and
// revokes the token the invitation replaces. ErrInvitationNotPending leaves nothing behind.
ClaimInvitation(ctx context.Context, c InvitationClaim) (InvitationClaimed, error)
}
InvitationStore holds person invitations (migration 0157, #1508). Optional, like PersonStore: the API answers 501 on a store without it.
type JobKey ¶ added in v0.8.6
type JobKey struct{ Step, Target string }
JobKey names a ledger row within one identity and kind.
type LaunchIntentRecord ¶ added in v0.9.0
type LaunchIntentRecord struct {
RunID uuid.UUID
Title string
Shape string
CreatedAt time.Time
Document json.RawMessage
}
LaunchIntentRecord is one kept intent. Title is the run's title now; Shape is the document's intent.shape. Document is set by GetLaunchIntent only.
type LaunchIntentStore ¶ added in v0.9.0
type LaunchIntentStore interface {
// ListLaunchIntents returns createdBy's intents, newest first, at most limit, without documents.
ListLaunchIntents(ctx context.Context, createdBy string, limit int) ([]LaunchIntentRecord, error)
// GetLaunchIntent returns the run's intent when createdBy created the run; ErrNotFound otherwise.
GetLaunchIntent(ctx context.Context, runID uuid.UUID, createdBy string) (LaunchIntentRecord, error)
// DeleteLaunchIntentsCreatedBy erases createdBy's intents and returns how many. It waits for every
// launch of theirs that is writing one, and a launch that reaches the write after it began keeps none.
DeleteLaunchIntentsCreatedBy(ctx context.Context, createdBy string) (int, error)
}
LaunchIntentStore reads and erases launch intents (migration 0171_run_launch_intents): the setup a person launched a run with, kept as a kind Run document for Run again. It has no write method: CreateRun and CreateRunUnderCap insert AgentRun.LaunchIntent in the run row's own transaction, so a run and its intent are written together or not at all. Optional like ComponentStore: callers type-assert.
type LeaverStore ¶ added in v0.8.6
type LeaverStore interface {
GetIdentity(ctx context.Context, id uuid.UUID) (PrincipalIdentity, error)
SearchIdentities(ctx context.Context, issuer, attr, value string, limit int) ([]PrincipalIdentity, error)
IdentitiesByAlias(ctx context.Context, issuer, valueLower string) ([]PrincipalIdentity, error)
IdentityAliasValues(ctx context.Context, id uuid.UUID) ([]string, error)
CreateScimIdentity(ctx context.Context, issuer, tenantID, objectID string, u IdentityUpdate, now time.Time) (PrincipalIdentity, bool, error)
ApplyIdentityUpdate(ctx context.Context, id uuid.UUID, u IdentityUpdate, now time.Time) (PrincipalIdentity, error)
SuspendIdentity(ctx context.Context, p SuspendPlan) (SuspendResult, error)
ListNonTerminalRunsBy(ctx context.Context, createdBy string) ([]types.AgentRun, error)
EnsureDeprovisionJobs(ctx context.Context, identityID uuid.UUID, kind string, keys []JobKey) error
ListDeprovisionJobs(ctx context.Context, identityID uuid.UUID, kind string) ([]DeprovisionJob, error)
FinishDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey, detail map[string]int) error
FailDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey, cause error) error
ReopenDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey) error
MarkIdentityPurged(ctx context.Context, id uuid.UUID, requireDue bool) (bool, error)
PurgeDueIdentities(ctx context.Context, limit int) ([]DueIdentity, error)
PendingLeavers(ctx context.Context, idleFor time.Duration, limit int) ([]PendingLeaver, error)
DeleteUserSubjectRows(ctx context.Context, id uuid.UUID, principals, emails []string) (grants, assignments, kept int64, err error)
HeldEmails(ctx context.Context, id uuid.UUID, principals, emails []string) ([]string, error)
ListDeactivatedIdentities(ctx context.Context, limit int) ([]PrincipalIdentity, error)
ListDeprovisionFailures(ctx context.Context, limit int) ([]DeprovisionFailure, error)
}
LeaverStore is optional, like PrincipalIdentityStore: callers type-assert it.
type LoginIdentity ¶ added in v0.8.6
type LoginIdentity struct {
Principal string
Issuer string
TenantID string
ObjectID string
Email string
}
LoginIdentity is what an approved sign-in tells the store.
type LoginLocker ¶ added in v0.8.0
type LoginLocker interface {
LockLoginSupersede(ctx context.Context, actor string) (release func(), err error)
}
LoginLocker serializes one person's sign-in launches, and the credential capture that follows one, against every other replica — the piece the deterministic tie-break in api.supersedeOlderLoginRuns couldn't supply. Its absence falls back UNLOCKED (as serialized as 0.7.8 was); PG implements it in production.
Keyed by ACTOR, not credential scope: under the `shared` roster every sign-in resolves to the same empty scope owner, so a scope-keyed lock would serialize the whole deployment without serializing what it needs to.
type MemRunPATs ¶ added in v0.8.2
type MemRunPATs struct {
// contains filtered or unexported fields
}
MemRunPATs is RunPATStore in memory, for the tests of every lane that creates or revokes a token and has no database.
func NewMemRunPATs ¶ added in v0.8.2
func NewMemRunPATs() *MemRunPATs
NewMemRunPATs returns an empty MemRunPATs.
func (*MemRunPATs) InsertRunPAT ¶ added in v0.8.2
func (m *MemRunPATs) InsertRunPAT(_ context.Context, p RunPAT) error
func (*MemRunPATs) LastRunPAT ¶ added in v0.8.2
func (*MemRunPATs) ListRunPATs ¶ added in v0.8.2
func (*MemRunPATs) ListUnrevokedRunPATs ¶ added in v0.8.2
func (m *MemRunPATs) ListUnrevokedRunPATs(_ context.Context, f RunPATFilter) ([]RunPAT, error)
func (*MemRunPATs) MarkRunPATRevoked ¶ added in v0.8.2
func (*MemRunPATs) NoteRunPATRevokeFailed ¶ added in v0.8.2
type MemberDriveStore ¶ added in v0.9.0
type MemberDriveStore interface {
// CreateMemberDrive inserts d for d.OwnerSubject (non-empty) unless the owner
// already holds limit rows: ErrMemberDriveLimit, or ErrMemberDriveNameTaken
// when the owner has a drive whose name folds to the same slug.
CreateMemberDrive(ctx context.Context, d types.UserDrive, limit int) (types.UserDrive, error)
// ListMemberDrivesOf returns owner's drives, tombstoned ones included.
ListMemberDrivesOf(ctx context.Context, owner string) ([]types.UserDrive, error)
// GetMemberDriveOf returns drive id only if owner owns it, else ErrNotFound.
GetMemberDriveOf(ctx context.Context, owner string, id uuid.UUID) (types.UserDrive, error)
// BeginMemberDriveDelete tombstones owner's drive and returns the tombstone:
// ErrNotFound when not owned, ErrMemberDriveBusy while another delete holds it.
BeginMemberDriveDelete(ctx context.Context, owner string, id uuid.UUID) (types.UserDrive, time.Time, error)
// BeginMemberDriveDeleteAdmin is BeginMemberDriveDelete for any owner's drive.
BeginMemberDriveDeleteAdmin(ctx context.Context, id uuid.UUID) (types.UserDrive, time.Time, error)
// AbortMemberDriveDelete clears only the tombstone started names.
AbortMemberDriveDelete(ctx context.Context, id uuid.UUID, started time.Time) error
// FinishMemberDriveDelete removes the row only while it carries started.
FinishMemberDriveDelete(ctx context.Context, id uuid.UUID, started time.Time) error
// ListMemberDrives returns one page of every person's drives and the total.
ListMemberDrives(ctx context.Context, p Page) ([]types.UserDrive, int, error)
}
MemberDriveStore persists member drives: a person's own user_drives row, owned by its owner_subject, with no grant rows. Bodies in member_drives.go. Optional like RunnerStore: callers type-assert.
type PG ¶
type PG struct {
Pool *pgxpool.Pool
// Now is THE APP CLOCK, letting a test run one that disagrees with the
// database's. Nil means time.Now. Every stamp this store writes belongs on
// the DATABASE's clock; the app clock only measures an ELAPSED TIME (a
// difference of two readings, carrying no skew) measured after a successful DB-clock read. See db.CaptureAppClock.
Now func() time.Time
// SIEM, when set, receives the audit rows this store writes in its own transaction (the retention
// policy change, the partition drop, the reauth resolve), which no recorder chain sees. Nil sends them
// nowhere.
SIEM audit.Sink
}
PG is the Postgres-backed Store: its methods (defined in store.go) hold the query bodies directly, so there is exactly one implementation of each query.
func (PG) ADOSignInEnds ¶ added in v0.8.6
ADOSignInEnds — see ADOSignInEndStore.
func (PG) AWSSSOTokenSpent ¶ added in v0.8.0
AWSSSOTokenSpent reports whether fingerprint has a persisted spent-token row.
func (PG) AbortMemberDriveDelete ¶ added in v0.9.0
AbortMemberDriveDelete clears the tombstone started set, and only that one. ErrNotFound when it is gone (finished, or taken over).
func (PG) AcceptRunnerExit ¶ added in v0.9.0
func (s PG) AcceptRunnerExit(ctx context.Context, runnerID, runID uuid.UUID, exit runnerwire.AgentExit, prepare func(context.Context, types.AuditEvent) (types.AuditEvent, error)) (bool, error)
AcceptRunnerExit atomically commits the generation-bound terminal transition, audit and receipt. It deliberately does not perform terminal side effects; RetryRunnerExitTail owns their serialized, retryable completion.
func (PG) AcquireAttachLease ¶ added in v0.8.6
func (s PG) AcquireAttachLease(ctx context.Context, l AttachLease, from uuid.UUID, ttl time.Duration) (bool, error)
AcquireAttachLease — see AttachLeaseStore.
func (PG) ActiveRunsAtWorkspacePath ¶ added in v0.7.0
func (s PG) ActiveRunsAtWorkspacePath(ctx context.Context, workspacePath string) ([]types.AgentRun, error)
ActiveRunsAtWorkspacePath returns the slot-holding runs bound to one host workspace path (a QUEUED run has no sandbox on it yet). Uses the POSITIVE state list, same reasoning as ActiveRunsByCreator: a forgotten new state merely under-warns rather than mis-treating it as active.
ponytail: no new index. workspace_path is selective and the state filter is a cheap check over matching rows; a composite (workspace_path, state) index is the upgrade if a deployment ever has enough runs on ONE path.
func (PG) ActiveRunsByCreator ¶ added in v0.7.5
func (s PG) ActiveRunsByCreator(ctx context.Context, createdBy, task, agent string) ([]types.AgentRun, error)
ActiveRunsByCreator returns createdBy's non-terminal runs of one task+agent. Uses the POSITIVE state list (types.NonTerminalRunStates): a state added to the enum and forgotten here merely misses a supersede, whereas `NOT IN (terminal)` would hand a new terminal state to the kill cascade.
ponytail: no new index. agent_runs_created_by_idx already indexes the selective column and one person owns few runs; upgrade to a composite if a deployment ever has enough history to notice.
func (PG) AddOwnRunnerToPool ¶ added in v0.9.0
func (s PG) AddOwnRunnerToPool(ctx context.Context, id, runnerID uuid.UUID, owner, orgURLSHA256 string) (types.RunnerPoolMember, bool, int64, error)
AddOwnRunnerToPool adds a self-hosted runner to a live user pool only when owner owns both the pool and the runner, the runner is claimed and bound to this organisation's URL, all decided in the insert itself so a revocation or a transfer cannot slip between a check and the write. An organization pool is ErrRunnerPoolScope: it takes remote-hosted runners only. ErrNotFound covers every other case alike: an unknown pool or runner, and a pool or a runner that is not the owner's.
func (PG) AddRemoteRunnerToUserPool ¶ added in v0.9.0
func (s PG) AddRemoteRunnerToUserPool(ctx context.Context, id uuid.UUID, remoteRunner, owner string, peopleRevision int64) (types.RunnerPoolMember, bool, int64, error)
AddRemoteRunnerToUserPool adds a remote-hosted runner to owner's own live user pool. The caller checked the runner's people policy at peopleRevision; the runner row is read FOR SHARE here, so a policy write (which takes it FOR UPDATE and raises its revision) cannot slip between that check and this insert: a moved revision is ErrRunnerPoolStale. ErrNotFound: the pool is not owner's live user pool, or the runner has no row.
func (PG) AddRunnerPoolExecutor ¶ added in v0.9.0
func (s PG) AddRunnerPoolExecutor(ctx context.Context, id uuid.UUID, executor string) (types.RunnerPoolMember, bool, int64, error)
AddRunnerPoolExecutor adds a remote-hosted runner (executor is its id) to a live organization pool; added is false when it was already a member (no revision change). revision is the pool's revision after the call, read under the pool lock. ErrNotFound: no such live organization pool, or no such remote-hosted runner row.
func (PG) AddSSHKey ¶ added in v0.5.0
func (s PG) AddSSHKey(ctx context.Context, k types.SSHPublicKey) (types.SSHPublicKey, error)
AddSSHKey inserts a new registered key. Returns ErrConflict when the fingerprint (PK) already exists — a 23505 here means that exact key material is already registered.
func (PG) AddScimGroupMembers ¶ added in v0.8.6
func (s PG) AddScimGroupMembers(ctx context.Context, id uuid.UUID, identities []uuid.UUID, now time.Time) error
AddScimGroupMembers records each identity as a member, leaving one already recorded as it is and skipping an id that names no identity row.
func (PG) AddUserDriveGrant ¶ added in v0.9.0
func (s PG) AddUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, error)
AddUserDriveGrant allocates one drive to one subject BESIDE the subject's other drives, keyed on UNIQUE(subject_type, subject, drive_id) (migration 0169): writing the same subject and drive again updates that row and returns its id; another drive is another row. The guards and error mapping are UpsertUserDriveGrant's.
func (PG) AddWorkspaceEgressDecision ¶ added in v0.5.0
func (s PG) AddWorkspaceEgressDecision(ctx context.Context, id uuid.UUID, host string, allow bool, maxApprovedEgress int) (types.Workspace, error)
AddWorkspaceEgressDecision records one `always`-scoped egress decision for host: on allow it is added to approved_egress (capped, deduped) and removed from denied_egress; on deny the mirror. Returns ErrConflict, not a bare "not found", when id exists but the cap guard refused the write.
func (PG) AppendRunOutputChunk ¶ added in v0.8.6
func (s PG) AppendRunOutputChunk(ctx context.Context, runID uuid.UUID, replica string, b []byte, keep int) (bool, error)
AppendRunOutputChunk — see RunOutputChunkStore.
func (PG) ApplyIdentityUpdate ¶ added in v0.8.6
func (s PG) ApplyIdentityUpdate(ctx context.Context, id uuid.UUID, u IdentityUpdate, now time.Time) (PrincipalIdentity, error)
ApplyIdentityUpdate applies u to the identity in one transaction: the projection, then the reactivation when asked. A purged identity refuses a reactivation and nothing else changes.
func (PG) ApprovalEscalations ¶ added in v0.8.6
func (s PG) ApprovalEscalations(ctx context.Context, ids []uuid.UUID, now time.Time) (map[uuid.UUID]types.ApprovalEscalation, error)
ApprovalEscalations — see ApprovalNotifyReader.
func (PG) ApprovalNotifyChannelStats ¶ added in v0.8.6
func (s PG) ApprovalNotifyChannelStats(ctx context.Context, now time.Time) ([]types.ApprovalNotifyChannelStat, error)
ApprovalNotifyChannelStats — see ApprovalNotifyReader.
func (PG) AuditDeliveryStatuses ¶ added in v0.9.0
func (s PG) AuditDeliveryStatuses(ctx context.Context) ([]AuditDeliveryStatus, error)
AuditDeliveryStatuses returns one row per checkpoint destination, ordered by destination, with the audit table's head and the recorded_at of the oldest event past the checkpoint. One statement, so a lag reading cannot straddle two queries; the subqueries read the append-only table, so it answers on any replica, not just the leader.
func (PG) AuditHeadSeq ¶ added in v0.8.0
AuditHeadSeq is this deployment's newest audit_events seq, 0 on an empty table: the head the forwarder measures lag against, read every tick whether or not a push succeeds.
func (PG) AuditKeyDestroyedAt ¶ added in v0.8.6
AuditKeyDestroyedAt is when the latest generation of owner's audit-seal key was destroyed. ok is false while none has been.
func (PG) AuditPartitionsAhead ¶ added in v0.8.6
func (PG) AuditPrincipalOf ¶ added in v0.8.6
AuditPrincipalOf is the principal a subject id names. ok is false for an id that is not a uuid or that no bound identity row carries.
func (PG) AuditRetentionStatus ¶ added in v0.8.6
func (s PG) AuditRetentionStatus(ctx context.Context) (AuditRetentionStatus, error)
func (PG) AuditSubjectFor ¶ added in v0.8.6
AuditSubjectFor is principal's subject id. ok is false when the person has no identity row.
func (PG) AutodropAuditPartition ¶ added in v0.8.6
func (PG) BeginADOSignInEnd ¶ added in v0.8.6
BeginADOSignInEnd — see ADOSignInEndStore.
func (PG) BeginMemberDriveDelete ¶ added in v0.9.0
func (s PG) BeginMemberDriveDelete(ctx context.Context, owner string, id uuid.UUID) (types.UserDrive, time.Time, error)
BeginMemberDriveDelete tombstones owner's drive id. ErrNotFound when owner does not own it; ErrMemberDriveBusy when another delete holds it.
func (PG) BeginMemberDriveDeleteAdmin ¶ added in v0.9.0
func (s PG) BeginMemberDriveDeleteAdmin(ctx context.Context, id uuid.UUID) (types.UserDrive, time.Time, error)
BeginMemberDriveDeleteAdmin is BeginMemberDriveDelete for any owner.
func (PG) BeginRunnerExecution ¶ added in v0.9.0
func (s PG) BeginRunnerExecution(ctx context.Context, runnerID, runID, previous, generation uuid.UUID, operation string) (RunnerExecution, error)
BeginRunnerExecution persists the H3-selected generation before LEASE and Exec/Start. Retries retain generation; a new incarnation supplies the previous generation as a CAS. The existing run-operation lock serializes its entire state phases with exit teardown. H3 releases this phase before waiting for remote Exec/Start, then reacquires through Bind with the exact generation.
func (PG) BeginRunnerInventory ¶ added in v0.9.0
BeginRunnerInventory captures original candidates before fresh PENDING/STATE. The authenticated Hub invokes it under its per-runner session admission lock. Repeating the same session never resets a partially consumed inventory.
func (PG) BindRunnerExecution ¶ added in v0.9.0
func (s PG) BindRunnerExecution(ctx context.Context, runnerID, runID, generation uuid.UUID, execID string) error
BindRunnerExecution accepts only H3's correlated Exec/Start result or its explicit generation-bound reconciliation. It must never be called with a first-seen agent_exit handle as proof of which execution the org dispatched.
func (PG) BlankRunTasks ¶ added in v0.8.6
func (PG) BootstrapRunnerPools ¶ added in v0.9.0
func (s PG) BootstrapRunnerPools(ctx context.Context, executors []string, name string) (*types.RunnerPool, *types.RunnerPoolDefaults, error)
BootstrapRunnerPools is the one-time upgrade step: when this deployment has configured remote-hosted runners and no organization pool has ever existed (a deleted one still counts, so an administrator's deletion sticks), it creates one organization pool named name holding exactly those runners and makes it the organisation's default pool, so a launch that names no pool still resolves. Defaults the organisation saved before any pool existed keep their barrier. It gives nobody a runner they lacked (no use policy, and no user pool is ever made); it is still a placement change, since a run may then land on any member that advertises its class. With no runners or a catalogue that has existed it does nothing. Each runner's row is EnsureRemoteRunners'. Returns the pool it created and the organisation defaults it left, both nil when it did nothing.
func (PG) ClaimInvitation ¶ added in v0.9.0
func (s PG) ClaimInvitation(ctx context.Context, c InvitationClaim) (InvitationClaimed, error)
func (PG) ClaimRecordingRunOutput ¶ added in v0.8.9
func (s PG) ClaimRecordingRunOutput(ctx context.Context, runID uuid.UUID, retention, staleAfter time.Duration) (RecordingOutputClaim, bool, error)
ClaimRecordingRunOutput — see RunOutputStore.
func (PG) ClaimRunner ¶ added in v0.9.0
func (s PG) ClaimRunner(ctx context.Context, id uuid.UUID, owner, fingerprint string, now time.Time) (types.Runner, error)
ClaimRunner moves an unclaimed runner to claimed in one conditional UPDATE, only for its owner and the fingerprint it was registered with. ErrNotFound: no such runner. ErrConflict: it is not unclaimed (claimed twice, revoked). ErrRunnerClaimMismatch: wrong owner or fingerprint.
func (PG) ClaimSourceActiveRun ¶ added in v0.5.0
ClaimSourceActiveRun fences a source's in-flight scan run, mirroring ClaimWorkspaceActiveRun. Returns ErrConflict when another run holds the slot.
func (PG) ClaimStaleRunWatchers ¶ added in v0.5.0
func (s PG) ClaimStaleRunWatchers(ctx context.Context, owner string, staleAfter time.Duration) ([]types.AgentRun, error)
ClaimStaleRunWatchers atomically takes the watcher lease, for owner, on every non-terminal run with a sandbox whose lease has been silent longer than staleAfter, returning the runs claimed for re-adoption.
The conditional UPDATE ... RETURNING is the mutual exclusion: replicas sweeping at once re-evaluate WHERE against the row version they blocked on, so the loser sees the winner's fresh heartbeat and gets no row — no advisory lock needed (one per in-flight run via db.TryAdvisoryLock would exhaust the pool, which holds a connection for the whole lock).
Two predicates carry the sweep's safety: nonTerminalRunStates matches agent_runs_watcher_sweep_idx's predicate verbatim (complement of types.RunState.IsTerminal, so a finished run is never re-adopted); and a non-empty sandbox_ref limits it to runs with something to watch — a row exists through the whole pre-dispatch window (grant writes, then a multi-minute build) and would otherwise look abandoned, so cleanup there stays boot-only.
A KEPT run (lost_at set, migration 0073) is also never claimed: its agent is stopped on purpose, and a watcher would read that as exit and finalize the run, tearing down files it's kept for. updated_at is deliberately not touched: it's the idle reaper's activity signal, and a lease write isn't activity.
func (PG) ClaimWorkspaceActiveRun ¶
func (s PG) ClaimWorkspaceActiveRun(ctx context.Context, id, runID uuid.UUID, expected *uuid.UUID) (types.Workspace, bool, error)
ClaimWorkspaceActiveRun compare-and-sets active_run_id from expected (possibly nil) to runID, the serial-import-step gate: of two concurrent launches racing the same slot, the loser gets applied=false and must NOT launch.
func (PG) ClearPauseSettle ¶ added in v0.8.6
ClearPauseSettle — see PauseSettler.
func (PG) ClearRunContainmentError ¶ added in v0.8.0
ClearRunContainmentError — see RunLeaser.
func (PG) ClearRunPaused ¶ added in v0.8.0
ClearRunPaused — see RunPauser.
func (PG) ClearSourceActiveRun ¶ added in v0.5.0
ClearSourceActiveRun releases the fence (idempotent; only the named run's claim is cleared, so a stale clear can't stomp a newer claim).
func (PG) ClearWorkspaceActiveRun ¶
ClearWorkspaceActiveRun clears active_run_id ONLY while it still points at runID, so a terminal run's cleanup can never clobber a step that was concurrently launched and now owns the pointer.
func (PG) ConsumeAttachTicket ¶ added in v0.5.0
func (s PG) ConsumeAttachTicket(ctx context.Context, token string, now time.Time) (AttachTicket, bool, error)
ConsumeAttachTicket redeems token exactly once, returning the ticket it stood for. The DELETE ... RETURNING is the single-use guarantee: two racing redemptions can only have one return a row.
The run-id binding is checked by the CALLER, not here, so a redemption against the wrong run still BURNS the ticket (a leaked ticket probed against a guessed run must not survive the probe). A miss and an expired row are both (ok=false), indistinguishable to the caller.
func (PG) ConsumeEnrolmentToken ¶ added in v0.8.0
func (s PG) ConsumeEnrolmentToken(ctx context.Context, token string, now time.Time) (types.DeviceEnrolmentToken, bool, error)
ConsumeEnrolmentToken redeems token exactly once: a single-row conditional UPDATE...RETURNING, the same atomic consume-once shape as ConsumeAttachTicket, adapted to an UPDATE since the row is worth keeping after redemption for CreateDevice. TRUST BOUNDARY: an unknown, already-consumed, and expired token all answer (zero, false, nil) alike — no oracle, matching ConsumeAttachTicket.
func (PG) ConsumeRunnerRegistrationToken ¶ added in v0.9.0
func (s PG) ConsumeRunnerRegistrationToken(ctx context.Context, raw, orgHash string, now time.Time) (types.RunnerRegistrationToken, bool, error)
ConsumeRunnerRegistrationToken atomically spends a token bound to this org URL. Unknown, expired, consumed and differently bound tokens share the same refusal.
func (PG) CountActiveRunsBy ¶ added in v0.7.0
CountActiveRunsBy counts createdBy's runs that have not ended yet — the governance quota's one read (GovernanceLimits.MaxConcurrentRuns).
The state predicate is a POSITIVE list (types.NonTerminalRunStates), not `NOT IN (terminal)`: a state added to the enum and forgotten here merely undercounts, whereas the negated form would treat a new terminal state as active and wedge a capped member with nothing to stop it. Pinned against RunState.IsTerminal by a test in internal/types.
ponytail: no new index — agent_runs_created_by_idx already covers the selective column and the state filter is cheap over one member's rows.
func (PG) CountApprovalsForRun ¶ added in v0.7.2
CountApprovalsForRun returns how many approvals a run has raised, in ANY state — the per-run DoS bound behind handleInternalRequestApproval (maxApprovalsPerRun), since a sandbox picks the hosts it asks about and could otherwise raise rows without limit. Counted in the database rather than List + filter in Go, which would read every approval row in the deployment.
func (PG) CountComponents ¶ added in v0.8.9
CountComponents — see ComponentStore.
func (PG) CountHiddenRuns ¶ added in v0.8.0
func (s PG) CountHiddenRuns(ctx context.Context, f RunFilter) (olderHidden, killedHidden int, err error)
CountHiddenRuns — see RunsFilteredPager.
func (PG) CountNonTerminalRuns ¶ added in v0.8.6
CountNonTerminalRuns is the number of run rows that hold a slot: a slot-holding state (types.SlotHoldingRunStates, never QUEUED) whose agent still runs (HoldsSandboxSQL), the quantity CreateRunUnderCap holds under the cap. except is a run never counted (uuid.Nil for none): a revive counts the OTHER runs, as markRunRevivedUnderCap does. It takes no lock: a pre-flight read for a refusal that must come before an identity is minted, never the authority.
func (PG) CountPendingApprovals ¶ added in v0.8.0
CountPendingApprovals — see ApprovalsForRunsPager. Backed by the partial approvals_state_idx: an index-only count, not a table scan.
func (PG) CountPendingApprovalsByRunCreator ¶ added in v0.8.0
CountPendingApprovalsByRunCreator — see ApprovalsForRunsPager. Same semi-join ListApprovalsPageByRunCreator's own query uses (approvals has no created_by column of its own), counted instead of listed.
func (PG) CountPushPathLists ¶ added in v0.8.0
func (PG) CountQueuedRunsByOwner ¶ added in v0.9.0
func (s PG) CountQueuedRunsByOwner(ctx context.Context, poolID uuid.UUID, owner string) (int, error)
CountQueuedRunsByOwner is how many runs owner has waiting for poolID: the flood limit's one read.
func (PG) CountRunnerPoolSlotHolders ¶ added in v0.9.0
CountRunnerPoolSlotHolders is countPoolSlotHolders without the lock, a read for a display; the authority is the in-transaction count.
func (PG) CreateAPIToken ¶ added in v0.6.0
func (s PG) CreateAPIToken(ctx context.Context, t types.APIToken, raw string) (types.APIToken, error)
CreateAPIToken inserts one token row. raw is the PLAINTEXT credential; only its hash is stored, and the caller must return the plaintext to its creator exactly once (unrecoverable afterwards). t.Token is ignored — passing the secret twice would be the one way to accidentally persist it.
A unique_violation (23505) on token_sha256 is ErrConflict: a raw collision in a 256-bit space means the caller reused a token value rather than minting a fresh one.
SECURITY: groups_truncated binds as SQL NULL when nil. NULL means "minted before anything recorded this", and consumers read that as TRUNCATED, not false. A plain bool or DEFAULT FALSE would assert "complete" for every legacy row — fail OPEN, the exact thing the marker exists to prevent.
func (PG) CreateApproval ¶
func (s PG) CreateApproval(ctx context.Context, a types.ApprovalRequest) (types.ApprovalRequest, error)
CreateApproval inserts a new approval request. With approval notifications configured it also inserts the approval's outbox rows in the same transaction, so no crash can leave an approval nobody was told about; without them the INSERT is the only write.
func (PG) CreateComponent ¶ added in v0.8.9
CreateComponent — see ComponentStore.
func (PG) CreateDelegate ¶ added in v0.8.0
func (s PG) CreateDelegate(ctx context.Context, d types.Delegate, raw string) (types.Delegate, error)
CreateDelegate registers one portal. raw is the PLAINTEXT credential; only its hash is stored. Returns ErrConflict on a credential_sha256 collision (a reused credential in a 256-bit space).
func (PG) CreateDevice ¶ added in v0.8.0
CreateDevice inserts one device row, following CreateAPIToken's shape: raw is the plaintext device credential minted at enrolment. SECURITY: only its hash is stored, and d.CredentialSHA256 is ignored, so the caller can never accidentally persist the secret twice; raw is returned to the device exactly once, unrecoverable afterwards. ErrConflict on a credential_sha256 collision, same 256-bit space as MintEnrolmentToken.
func (PG) CreateGrant ¶
func (s PG) CreateGrant(ctx context.Context, g types.CredentialGrant) (types.CredentialGrant, error)
CreateGrant inserts a credential grant (eligibility record) and returns it.
func (PG) CreateInvitation ¶ added in v0.9.0
func (PG) CreateMemberDrive ¶ added in v0.9.0
func (s PG) CreateMemberDrive(ctx context.Context, d types.UserDrive, limit int) (types.UserDrive, error)
CreateMemberDrive inserts d as owner d.OwnerSubject's drive unless the owner already holds limit rows. The count and the insert run in one READ COMMITTED transaction under the owner's MemberDriveLockClass lock. The row's managed fields are fixed here: no host root, the hash home, the id object scheme, reclaim delete, writable.
func (PG) CreatePerson ¶ added in v0.8.0
func (PG) CreatePolicy ¶
CreatePolicy inserts a policy and returns the persisted row. Returns ErrConflict when the name's UNIQUE constraint (run_policies.name) rejects a duplicate — the caller maps that to 409, never the raw driver error.
func (PG) CreateQueuedRun ¶ added in v0.9.0
func (s PG) CreateQueuedRun(ctx context.Context, r types.AgentRun, e RunQueueEntry, maxPerOwner int) (types.AgentRun, error)
CreateQueuedRun inserts r (state QUEUED, bound to a pool), its launch intent when it carries one, and its queue row in one transaction that holds the pool row FOR NO KEY UPDATE, the lock promotion takes first, so the owner's waiting count and the insert cannot interleave with a promotion. maxPerOwner <= 0 is unlimited; otherwise an owner with that many runs already waiting for the pool gets ErrRunQueueFull and nothing is written. The queue row's pool and owner are the run's own.
func (PG) CreateRestrictedComponent ¶ added in v0.8.9
func (s PG) CreateRestrictedComponent(ctx context.Context, c types.Component, capability, by string) (types.Component, error)
CreateRestrictedComponent — see RestrictedComponentCreator.
func (PG) CreateRun ¶
CreateRun inserts a new run and returns the persisted row. A run bound to a runner pool is inserted only while that pool is still active at the recorded revision, else ErrRunnerPoolStale. A run that carries a LaunchIntent is inserted with it in one transaction (store_launch_intents.go); the returned run carries it only when it was kept.
func (PG) CreateRunUnderCap ¶ added in v0.8.6
func (s PG) CreateRunUnderCap(ctx context.Context, r types.AgentRun, limit int) (types.AgentRun, error)
CreateRunUnderCap is CreateRun with a deployment-wide ceiling on non-terminal runs (WARDYN_MAX_CONCURRENT_RUNS). The count and the insert share one transaction-scoped advisory lock, so two replicas racing at the cap admit exactly the cap. limit <= 0 is unlimited and takes no lock. Rows are counted, not kept in a counter, so a crashed path cannot drift it. A run bound to a runner of either kind is also held to that runner's limits (Runs at once, its totals and its per-run limit, what it reserves counted) under its row lock, cap or none (RunnerAtCapacityError).
func (PG) CreateRunner ¶ added in v0.9.0
CreateRunner inserts an unclaimed runner: state, claim and posture on r are ignored, since every registration starts unclaimed. ErrConflict on a key fingerprint already registered. r.Limits, when set, is the runner's limit set and its Runs at once; without it the runner declares no limits and r.MaxRuns 0 is types.RunnerMaxRunsDefault.
func (PG) CreateRunnerPool ¶ added in v0.9.0
func (s PG) CreateRunnerPool(ctx context.Context, p types.RunnerPool, by string) (types.RunnerPool, error)
CreateRunnerPool inserts an active pool at revision 1, owned by p.Owner when it is set. ErrConflict: a live pool of the same owner (or of the organisation) has the name. ErrRunnerPoolLimit: the organisation, or the owner, is at its cap.
func (PG) CreateScimGroup ¶ added in v0.8.6
func (s PG) CreateScimGroup(ctx context.Context, externalID, displayName string, now time.Time) (ScimGroup, error)
CreateScimGroup stores a group. An externalId any group already holds, in any case, is ErrScimGroupExists.
func (PG) CreateScimIdentity ¶ added in v0.8.6
func (s PG) CreateScimIdentity(ctx context.Context, issuer, tenantID, objectID string, u IdentityUpdate, now time.Time) (PrincipalIdentity, bool, error)
CreateScimIdentity records a SCIM user as an identity row with no principal, keyed by the object id, or finds the row already holding it (created=false). The first sign-in binds the principal.
func (PG) CreateServiceIdentity ¶ added in v0.9.0
func (s PG) CreateServiceIdentity(ctx context.Context, si types.ServiceIdentity) (types.ServiceIdentity, error)
func (PG) CreateServiceToken ¶ added in v0.9.0
func (PG) CreateTemplate ¶ added in v0.9.0
func (s PG) CreateTemplate(ctx context.Context, t types.RunTemplate, grant *TemplateGrantCheck) (types.RunTemplate, error)
CreateTemplate — see TemplateStore.
func (PG) CreateUserType ¶ added in v0.8.0
CreateUserType inserts a custom type (built_in is never set here). ErrConflict when the id or name is taken, or the id is still named by an orphaned subject row.
func (PG) CreateWorkspace ¶
CreateWorkspace inserts an onboarded workspace and returns the persisted row.
func (PG) DecideApproval ¶
func (s PG) DecideApproval(ctx context.Context, id uuid.UUID, decision types.ApprovalDecision) (types.ApprovalRequest, error)
DecideApproval transitions an approval from PENDING to decision.State. Returns ErrAlreadyDecided if the approval is not PENDING (fail-closed), via a single UPDATE with WHERE state='PENDING' to prevent TOCTOU races. SET is kept separate from RETURNING: updating only RETURNING would echo an un-updated row back as a green result over a silent no-op.
func (PG) DecideGovernanceChange ¶ added in v0.8.6
func (s PG) DecideGovernanceChange(ctx context.Context, id uuid.UUID, d GovernanceDecision, fn GovernanceDecideFunc) (types.GovernanceChange, error)
DecideGovernanceChange decides one change in one transaction:
- lock the change row;
- require it pending and unexpired. A lapsed pending row is moved to expired here and that is committed, and the caller gets *ErrGovernanceChangeNotPending with Lapsed set;
- run fn on the transaction (the target's checks and apply);
- move the row to d.To, stamping the decider and the time;
- commit.
fn returning ErrGovernanceChangeStale moves the row to stale instead and commits that. Any other error from fn, or from the state move, rolls the whole transaction back: a target written by fn is then unwritten and the change is still pending. ErrNotFound when no such change.
func (PG) DeleteBaseImage ¶ added in v0.5.0
DeleteBaseImage removes a catalog row; detach=true drops every workspace reference first (falling back to the derived recommended build — NULL is the marker, so "detach" is honest, not destructive). detach=false mirrors DeleteSource's residual race (STORE-2): a concurrent commit between the NOT EXISTS check and delete is instead caught by the base_image_id FK (0031:61), surfacing as 23503 — mapped to ErrConflict below.
func (PG) DeleteBranding ¶ added in v0.8.0
DeleteBranding implements BrandingStore.
func (PG) DeleteCapabilityGrant ¶ added in v0.6.0
DeleteCapabilityGrant removes one grant by id. Returns ErrNotFound when no row matched — this is an admin-only surface, so there is no principal to scope the delete to and no existence oracle to worry about.
func (PG) DeleteComponent ¶ added in v0.8.9
func (s PG) DeleteComponent(ctx context.Context, id uuid.UUID, owner string) (types.Component, error)
DeleteComponent — see ComponentStore.
func (PG) DeleteComponentsByOwner ¶ added in v0.8.9
DeleteComponentsByOwner — see ComponentStore.
func (PG) DeleteGovernanceAssignment ¶ added in v0.7.0
DeleteGovernanceAssignment removes one assignment by id, ErrNotFound when no row matched. Unassigning is the SUPPORTED way to widen someone back to the deployment ceiling.
func (PG) DeleteGovernanceProfile ¶ added in v0.7.0
DeleteGovernanceProfile removes one profile by id. ErrNotFound when no row matched.
ErrConflict when the row is still ASSIGNED: governance_assignments' ON DELETE RESTRICT refuses (23503) rather than cascading, since cascading would silently widen every assigned member back to the deployment ceiling. Translated into a sentinel so the route answers a caller-fixable 409 instead of a 500. *ErrProfileHasChildren when other profiles still compose on it (named under the graph lock, so the answer matches what the delete saw).
func (PG) DeleteLaunchIntentsCreatedBy ¶ added in v0.9.0
DeleteLaunchIntentsCreatedBy — see LaunchIntentStore.
func (PG) DeleteLaunchPreset ¶ added in v0.8.0
DeleteLaunchPreset removes a preset by name, returning the removed row, or ErrNotFound. Runs launched from it keep their preset/preset_version stamp.
func (PG) DeletePolicy ¶
DeletePolicy removes a policy by id. Returns ErrNotFound when no row matched. agent_runs.policy_id has no foreign key, so referencing runs keep a dangling policy_id; their authorization envelope survives via the run.policy.resolve audit event dispatch already recorded.
func (PG) DeleteRef ¶ added in v0.3.1
DeleteRef removes the row for ref. Idempotent: deleting a missing ref is nil.
func (PG) DeleteRestrictedComponent ¶ added in v0.8.9
func (s PG) DeleteRestrictedComponent(ctx context.Context, id uuid.UUID, capability, by string) (types.Component, int, bool, error)
DeleteRestrictedComponent — see RestrictedComponentDeleter.
func (PG) DeleteRoleMapping ¶ added in v0.7.0
DeleteRoleMapping removes one row by id. Returns ErrNotFound when no row matched — admin-only surface, so there is no principal to scope the delete to and no existence oracle to worry about, exactly DeleteCapabilityGrant.
func (PG) DeleteRunOutputsOlderThan ¶ added in v0.8.6
DeleteRunOutputsOlderThan — see RunOutputStore.
func (PG) DeleteRunProxyConfig ¶ added in v0.8.0
DeleteRunProxyConfig — see RunProxyConfigs.
func (PG) DeleteRunnerPool ¶ added in v0.9.0
DeleteRunnerPool tombstones a live pool, ends the runs waiting for it (KILLED, runner_pool_removed, their queue rows with them), drops its members, and clears the organisation default slots that name it, all in one transaction: ErrNotFound for an unknown or already deleted one, ErrRunnerPoolHasPolicy while it has a use policy. The row stays, so a run bound to it keeps its history.
func (PG) DeleteRunnerPoolUsePolicy ¶ added in v0.9.0
DeleteRunnerPoolUsePolicy removes a pool's use policy, which widens the pool back to everyone who may launch remote runs, and raises the pool's revision. ErrNotFound: the pool has none (or is gone).
func (PG) DeleteRunnerPoolsByOwner ¶ added in v0.9.0
func (s PG) DeleteRunnerPoolsByOwner(ctx context.Context, owner string) ([]RunnerPoolDeletion, error)
DeleteRunnerPoolsByOwner is a person's erasure of their pools: each live pool owner holds is deleted as DeleteRunnerPool deletes one, and then every pool of theirs, the tombstones included, forgets them (owner and created_by cleared). It holds the lock every create takes, so a pool the person creates meanwhile is either deleted here or made after it. Returns the deletions, in pool id order.
func (PG) DeleteSSHKey ¶ added in v0.5.0
DeleteSSHKey removes fingerprint, scoped to principal so a human can only delete their OWN key. Returns ErrNotFound whether the fingerprint doesn't exist or belongs to someone else — indistinguishable on purpose, no existence leak across principals.
func (PG) DeleteSSHKeys ¶ added in v0.8.0
DeleteSSHKeys removes a principal's registered keys, or every key when principal is empty. The count comes from the DELETE, not a prior snapshot.
func (PG) DeleteScimGroup ¶ added in v0.8.6
DeleteScimGroup removes the group row and, by cascade, its members. Its ledger rows stay.
func (PG) DeleteSource ¶ added in v0.5.0
DeleteSource removes a library source. detach=true strips every workspace attachment referencing it (?force=1) UNLESS that would leave a workspace with zero attachments (workspacesOrphanedBySource) — '[]' must stay unreachable (STORE-1). The check and the detach are two statements, so this only narrows, never closes (STORE-2), the race against a concurrent attach; same residual race as the detach=false path below.
func (PG) DeleteTemplate ¶ added in v0.9.0
func (s PG) DeleteTemplate(ctx context.Context, id uuid.UUID, grant *TemplateGrantCheck) (types.RunTemplate, error)
DeleteTemplate — see TemplateStore.
func (PG) DeleteTemplateGroupAdmin ¶ added in v0.9.0
DeleteTemplateGroupAdmin — see TemplateStore.
func (PG) DeleteUserDrive ¶ added in v0.7.0
DeleteUserDrive removes one admin drive by id. ErrNotFound if no row matched, including a member drive, which only the member-drive delete removes; ErrConflict if it's still allocated (user_drive_grants.drive_id is ON DELETE RESTRICT — Postgres refuses rather than cascading away grants whose directories may still hold someone's work).
func (PG) DeleteUserDriveGrant ¶ added in v0.7.0
DeleteUserDriveGrant removes one grant by id and returns it (ErrNotFound if no match) — removing only the binding, never the volume/claim/directory. RETURNING lets the caller audit-log what was removed without a prior scan.
func (PG) DeleteUserSubjectRows ¶ added in v0.8.6
func (s PG) DeleteUserSubjectRows(ctx context.Context, id uuid.UUID, principals, emails []string) (grants, assignments, kept int64, err error)
DeleteUserSubjectRows deletes the user-subject capability grants and governance assignments of the purged identity id, matched case-insensitively, and says how many of each; the same user subjects are stripped from every runner pool use policy. A direct delete, never the GOV4 apply path. Rows keyed by one of principals go: the subject is a purged identity that can never authenticate again. Rows keyed by one of emails go only while no other principal holds that address, because an address can be recycled and the new holder's deny rows are theirs: another identity that is neither deactivated nor purged, or an API token or people row under a principal that is not in principals (or the address itself, a form of the leaver). Rows kept for that reason are counted in kept.
func (PG) DeleteUserType ¶ added in v0.8.0
DeleteUserType removes a custom type that nothing names. ErrNotFound when no row has the id; ErrConflict when it is built in, still referenced, or held by a foreign key (role_mappings.user_type is ON DELETE RESTRICT). The reference check rides the DELETE itself, so a row written between the caller's check and this statement still refuses; a service identity created concurrently is ordered by userTypeWriteLock.
func (PG) DeleteWorkspace ¶
DeleteWorkspace removes a workspace by id. Returns ErrNotFound when no row matched.
func (PG) DropAuditPartition ¶ added in v0.8.6
func (PG) DryRunGovernance ¶ added in v0.8.6
DryRunGovernance runs fn on a transaction that is always rolled back, and returns fn's error. It is how a proposal learns whether a write would be accepted (and what it would produce) by running the very code that applies it, with nothing left behind.
func (PG) DuePauseSettles ¶ added in v0.8.6
func (s PG) DuePauseSettles(ctx context.Context) ([]PauseSettle, error)
DuePauseSettles — see PauseSettler.
func (PG) EnsureAuditDeliveryCursor ¶ added in v0.9.0
EnsureAuditDeliveryCursor creates dest's checkpoint at the audit table's CURRENT head, so the first enable sends only new events, never the whole history. ON CONFLICT DO NOTHING keeps the row an existing checkpoint already holds, so a restart (or a second replica's call) never rewinds delivery.
func (PG) EnsureAuditPartitions ¶ added in v0.8.6
func (PG) EnsureDeprovisionJobs ¶ added in v0.8.6
func (s PG) EnsureDeprovisionJobs(ctx context.Context, identityID uuid.UUID, kind string, keys []JobKey) error
EnsureDeprovisionJobs adds each key as a pending ledger row, leaving rows that exist as they are.
func (PG) EnsureRemoteRunners ¶ added in v0.9.0
func (s PG) EnsureRemoteRunners(ctx context.Context, ids []string, proposals map[string]types.RunnerLimits) (made, proposed []types.RemoteRunner, err error)
func (PG) EraseGovernanceChangePersonalFields ¶ added in v0.8.6
func (s PG) EraseGovernanceChangePersonalFields(ctx context.Context, principals, emails []string) (int, error)
EraseGovernanceChangePersonalFields clears the proposer and decider (their emails too, and the reason a decider typed) of every change whose recorded principal is one of principals or whose recorded email is one of emails (case folded), and returns how many rows it touched. A principal is never matched against the email column: that column holds the claim the proposer signed in with, which can spell another person's principal. A pending change whose proposer is erased leaves pending in the same statement (to expired), so a change with no recorded proposer can never be approved. Idempotent: a row already cleared matches nothing.
func (PG) EraseInvitationsOf ¶ added in v0.9.0
func (s PG) EraseInvitationsOf(ctx context.Context, person string) (deleted, cleared int, err error)
EraseInvitationsOf removes person from person_invitations in one transaction. Every invitation that targets them is deleted, whatever its state, since a target is never blank. Where they created or revoked another person's, their name is cleared and the row stays: a claimed one is what tells that person's replaced token apart (TokenDispositionFacts), and a pending one can still be claimed.
func (PG) EraseRecordingRunOutputs ¶ added in v0.8.9
EraseRecordingRunOutputs — see RunOutputStore.
func (PG) EraseRunComponentsByOwner ¶ added in v0.8.9
EraseRunComponentsByOwner — see ComponentStore. It clears content and keeps the row: the row is the run's authorization tombstone.
func (PG) EraseRunComponentsOfRun ¶ added in v0.8.9
func (s PG) EraseRunComponentsOfRun(ctx context.Context, runID uuid.UUID, owner string) (int, error)
EraseRunComponentsOfRun — see ComponentStore. The same clear as EraseRunComponentsByOwner, on one run.
func (PG) EraseRunOutputs ¶ added in v0.8.6
EraseRunOutputs — see RunOutputStore. The locks are taken in key order, so two overlapping erasures cannot each hold what the other waits for.
func (PG) EraseRunSetupsOf ¶ added in v0.9.0
EraseRunSetupsOf — see TemplateStore.
func (PG) EraseServiceIdentityAttributionOf ¶ added in v0.9.0
func (s PG) EraseServiceIdentityAttributionOf(ctx context.Context, person string) (cleared int, sponsored []string, err error)
EraseServiceIdentityAttributionOf clears person as the creator, suspender and retirer of every service identity, and returns how many rows that changed and, by name, the identities that are not retired and that person still sponsors. A sponsor is never cleared: tokens and runs are checked against it, so such an identity is handed to another sponsor or retired first. A retired identity keeps its last sponsor.
func (PG) ExitQueuedRun ¶ added in v0.9.0
func (s PG) ExitQueuedRun(ctx context.Context, id uuid.UUID, to types.RunState, detail, hint string) (bool, error)
ExitQueuedRun moves a QUEUED run to a terminal state through LeaveRunQueue and, in the same statement, writes the reason the queue ended it: status_detail ("queue: <token>") and the sentence for failure_hint. false means another exit won first.
func (PG) ExpireUnclaimedRunners ¶ added in v0.9.0
ExpireUnclaimedRunners deletes unclaimed runners registered before createdBefore (an unclaimed runner lives 24h) and returns how many.
func (PG) ExpiredQueueEntries ¶ added in v0.9.0
func (s PG) ExpiredQueueEntries(ctx context.Context, now time.Time, limit int) ([]RunQueueEntry, error)
ExpiredQueueEntries are the waiting runs whose deadline is at or before now, oldest deadline first.
func (PG) ExportAuditPartition ¶ added in v0.8.6
func (s PG) ExportAuditPartition(ctx context.Context, name string, header func(PartitionManifest) error, row func(AuditPartitionRow) error) error
func (PG) FailDeprovisionJob ¶ added in v0.8.6
func (s PG) FailDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey, cause error) error
FailDeprovisionJob records a failed attempt and leaves the step pending.
func (PG) FederationRevoked ¶ added in v0.8.0
FederationRevoked reports whether the organisation revoked this laptop's device credential (MarkFederationRevoked), false when no row exists.
func (PG) FinishADOSignInEnd ¶ added in v0.8.6
FinishADOSignInEnd — see ADOSignInEndStore.
func (PG) FinishDeprovisionJob ¶ added in v0.8.6
func (s PG) FinishDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey, detail map[string]int) error
FinishDeprovisionJob marks a step done, storing the counts it produced.
func (PG) FinishMemberDriveDelete ¶ added in v0.9.0
FinishMemberDriveDelete removes the row while it still carries the tombstone started set. ErrNotFound when it does not.
func (PG) GetAPITokenByRaw ¶ added in v0.6.0
GetAPITokenByRaw is the auth-time lookup: given a bearer string, resolve the LIVE token it stands for. Deliberately UNSCOPED by principal — this call is what authenticates the caller.
SECURITY: `revoked_at IS NULL` and the not-expired test (apiTokenLive) are in the WHERE, not checked separately — a revoked, expired, unknown, or non-matching token all fail IDENTICALLY with ErrNotFound, so the boundary is never an oracle for "this token once existed".
func (PG) GetApproval ¶
GetApproval returns the approval for id, or ErrNotFound.
func (PG) GetAttachLease ¶ added in v0.8.6
GetAttachLease — see AttachLeaseStore.
func (PG) GetAuditDeliveryCursor ¶ added in v0.9.0
GetAuditDeliveryCursor returns dest's acknowledged position and the row_hash that seq carried, (0, "") while no checkpoint row exists — the same zero-value-on-no-row contract as GetFederationCursor, so a cursor loaded before Ensure reads as "deliver from the beginning".
func (PG) GetBaseImage ¶ added in v0.5.0
GetBaseImage returns the catalog row for id, or ErrNotFound. Not on the Store interface (no handler reads one image by id); kept as a PG method because store_hydrate_pg_test.go round-trips through it.
func (PG) GetBaseImagesByIDs ¶ added in v0.5.0
func (s PG) GetBaseImagesByIDs(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]types.BaseImageEntry, error)
GetBaseImagesByIDs is hydrateAll's own batched read, not a Store-interface method — its only caller is inside this package. Returns the base images for ids in ONE query, keyed by id, mirroring GetSourcesByIDs. Missing ids are simply absent (hydrateWorkspace leaves BaseImage nil for them).
func (PG) GetBranding ¶ added in v0.8.0
GetBranding implements BrandingStore.
func (PG) GetCapabilityEnforcement ¶ added in v0.6.0
GetCapabilityEnforcement returns the per-kind switch map. An ABSENT row means NOT ENFORCED, so the returned map is sparse by design and a missing key reads as false — that default is the whole zero-config back-compat story (see the migration). Never nil.
func (PG) GetComponent ¶ added in v0.8.9
GetComponent — see ComponentStore.
func (PG) GetCredentialDeliveryPolicy ¶ added in v0.9.0
func (s PG) GetCredentialDeliveryPolicy(ctx context.Context) (types.CredentialDeliveryPolicyDoc, error)
GetCredentialDeliveryPolicy reads the local_credential_delivery document: an empty one (every class refuses) when none was written.
func (PG) GetDelegateByID ¶ added in v0.9.0
GetDelegateByID returns the portal with id, revoked or not (ErrNotFound only for an id that was never registered). The authenticating reads above filter revoked rows; this one exists to see them.
func (PG) GetDelegateByRaw ¶ added in v0.8.0
GetDelegateByRaw resolves the LIVE portal a credential stands for.
func (PG) GetDelegatedTokenByID ¶ added in v0.8.5
func (s PG) GetDelegatedTokenByID(ctx context.Context, id uuid.UUID, now time.Time) (types.DelegatedToken, error)
GetDelegatedTokenByID is GetDelegatedTokenByRaw by the grant's id: live while unexpired at now AND its portal still registered. A UI session opened through a portal re-asks it, so the session ends with the grant (#1475). Expired rows are swept on any mint, so ErrNotFound means ended.
func (PG) GetDelegatedTokenByRaw ¶ added in v0.8.0
func (s PG) GetDelegatedTokenByRaw(ctx context.Context, raw string, now time.Time) (types.DelegatedToken, error)
GetDelegatedTokenByRaw is the delegated lane's auth lookup: the token must be unexpired at now AND its portal still registered — the join is what makes revoking a portal kill all its tokens on their next request.
func (PG) GetDeviceByRaw ¶ added in v0.8.0
GetDeviceByRaw is the device auth-time lookup: given the bearer a device presented, resolve the live row it stands for. TRUST BOUNDARY: `revoked_at IS NULL` is in the WHERE (mirrors GetAPITokenByRaw), so a revoked/unknown/mismatched credential all fail identically with ErrNotFound.
func (PG) GetFederationCursor ¶ added in v0.8.0
GetFederationCursor returns how far this deployment's forwarder has pushed audit_events upward, and the row_hash the organisation acknowledged at that seq — 0 and "" when nothing forwarded yet (matching GetSiteConfig's zero-value-on-no-row contract).
func (PG) GetGovernanceChange ¶ added in v0.8.6
GetGovernanceChange returns one change, ErrNotFound when none; a pending row past its expiry reads as expired.
func (PG) GetGovernanceProfile ¶ added in v0.7.0
func (s PG) GetGovernanceProfile(ctx context.Context, id uuid.UUID) (types.GovernanceProfile, error)
GetGovernanceProfile returns one profile by id, or ErrNotFound. The RAW row: a composed profile carries no authority here (see GetGovernanceProfileChain).
func (PG) GetGovernanceProfileChain ¶ added in v0.8.6
func (s PG) GetGovernanceProfileChain(ctx context.Context, id uuid.UUID) ([]types.GovernanceProfile, error)
GetGovernanceProfileChain reads one profile and its ancestors in ONE statement, leaf first, bounded at depth 3 (the profile, its base, that base's base). ErrNotFound when the leaf is gone. It returns whatever the bound reached, cycle or overflow included: the caller refuses a chain whose last row still names a base or whose ids repeat, and never composes a partial one.
func (PG) GetIdentity ¶ added in v0.8.6
GetIdentity is the row stored under id, or ErrNotFound.
func (PG) GetIdentityByObject ¶ added in v0.8.6
func (PG) GetInvitation ¶ added in v0.9.0
func (PG) GetLaunchIntent ¶ added in v0.9.0
func (s PG) GetLaunchIntent(ctx context.Context, runID uuid.UUID, createdBy string) (LaunchIntentRecord, error)
GetLaunchIntent — see LaunchIntentStore.
func (PG) GetLaunchPreset ¶ added in v0.8.0
GetLaunchPreset returns one preset by name, or ErrNotFound.
func (PG) GetMemberDriveOf ¶ added in v0.9.0
func (s PG) GetMemberDriveOf(ctx context.Context, owner string, id uuid.UUID) (types.UserDrive, error)
GetMemberDriveOf returns drive id if owner owns it, else ErrNotFound.
func (PG) GetPrincipalPref ¶ added in v0.8.0
func (PG) GetPushPathList ¶ added in v0.8.0
func (PG) GetRef ¶ added in v0.3.1
GetRef returns the substrate name for ref. A missing row is (found=false, nil error) — pre-migration and unknown refs are expected, not errors.
func (PG) GetRemoteRunner ¶ added in v0.9.0
func (PG) GetRunLayout ¶ added in v0.5.0
GetRunLayout reads the one (principal, preset) row scoped to principal — a layout is never looked up by anything but its owner.
func (PG) GetRunOutput ¶ added in v0.8.6
GetRunOutput — see RunOutputStore.
func (PG) GetRunProxyConfig ¶ added in v0.8.0
GetRunProxyConfig — see RunProxyConfigs.
func (PG) GetRunQueueEntry ¶ added in v0.9.0
GetRunQueueEntry is one waiting run's queue row, or ErrNotFound once the run has left the queue.
func (PG) GetRunnerPool ¶ added in v0.9.0
func (PG) GetRunnerPoolOrgDefaults ¶ added in v0.9.0
GetRunnerPoolOrgDefaults reads the organisation's defaults; the zero value when none were written.
func (PG) GetSSHKeyByFingerprint ¶ added in v0.5.0
func (s PG) GetSSHKeyByFingerprint(ctx context.Context, fingerprint string) (types.SSHPublicKey, error)
GetSSHKeyByFingerprint is the gateway's pre-auth lookup: resolves which principal (if any) registered the offered fingerprint, and with which role, the admin-override signal. Deliberately UNSCOPED by principal — the caller has not authenticated yet; this call is what authenticates them. Returns ErrNotFound when unregistered.
func (PG) GetScimGroup ¶ added in v0.8.6
GetScimGroup is the group stored under id, or ErrNotFound.
func (PG) GetServiceIdentity ¶ added in v0.9.0
func (PG) GetSiteConfig ¶
GetSiteConfig returns the operator-wide site config, or a ZERO-VALUE SiteConfig (not an error) when no row has been written yet — first boot has no config, and "unconfigured" is a valid, common state rather than a failure the caller must special-case.
func (PG) GetSourcesByIDs ¶ added in v0.5.0
func (s PG) GetSourcesByIDs(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]types.Source, error)
GetSourcesByIDs returns the sources for ids in ONE query, keyed by id — the hydrate pass's bulk read. Missing ids are simply absent (a dangling attachment contributes nothing; fold and mount-gate each handle it).
func (PG) GetTemplate ¶ added in v0.9.0
GetTemplate — see TemplateStore.
func (PG) GetTemplateRevision ¶ added in v0.9.0
func (s PG) GetTemplateRevision(ctx context.Context, id uuid.UUID, revision int) (types.RunTemplate, error)
GetTemplateRevision — see TemplateStore.
func (PG) GetUserDrive ¶ added in v0.7.0
GetUserDrive returns one drive by id, or ErrNotFound.
func (PG) GetUserType ¶ added in v0.8.0
GetUserType returns one type by id, or ErrNotFound.
func (PG) GetWorkspace ¶
GetWorkspace returns the workspace for id, or ErrNotFound.
func (PG) GroupRemovalFailures ¶ added in v0.8.6
GroupRemovalFailures is ListDeprovisionFailures for the pendingGroupRemovalWhere rows with a recorded error: one row per identity and step, with the error of the target touched last.
func (PG) GroupRemovalIdentities ¶ added in v0.8.6
GroupRemovalIdentities is every identity a group's deletion must remove as a mover: the recorded members, and anyone whose removal from this group is still pending.
func (PG) HasGroupTierAssignments ¶ added in v0.7.0
HasGroupTierAssignments reports whether ANY group-tier assignment exists: the gate on the stale-snapshot refusal (see hasGroupTierRows).
func (PG) HasGroupTierDriveGrants ¶ added in v0.7.0
HasGroupTierDriveGrants reports whether ANY group-tier grant exists: the gate on the stale-snapshot refusal (see hasGroupTierRows).
func (PG) HasRunAuditEvent ¶ added in v0.8.0
HasRunAuditEvent reports whether runID has an audit row matching f.
func (PG) HeartbeatRunWatcher ¶ added in v0.5.0
HeartbeatRunWatcher refreshes the lease on id for owner: the "still watching" write every watcher goroutine repeats while alive; its silence lets another replica's ClaimStaleRunWatchers take over.
Unconditional on current owner, since a watcher can't abort its blocking Runner.Wait anyway and two watchers are harmless (the terminal transition is a CAS). Doesn't bump updated_at either, like the claim: a heartbeat there would make every run look forever-active and disable idle auto-stop. A missing row isn't an error; the lease is advisory.
func (PG) HeldEmails ¶ added in v0.8.6
func (s PG) HeldEmails(ctx context.Context, id uuid.UUID, principals, emails []string) ([]string, error)
HeldEmails is the emails another principal holds, by DeleteUserSubjectRows' rule: another identity than id that is neither deactivated nor purged, or a live API token (unrevoked, unexpired) or people row (not deactivated) under a principal that is neither one of principals nor the address itself and whose identity is neither deactivated nor purged. A previous holder that is gone holds nothing. Matched case-insensitively; the answer is lower-cased.
func (PG) HoldsAttachLease ¶ added in v0.8.6
HoldsAttachLease — see AttachLeaseStore.
func (PG) IdentitiesByAlias ¶ added in v0.8.6
func (s PG) IdentitiesByAlias(ctx context.Context, issuer, valueLower string) ([]PrincipalIdentity, error)
IdentitiesByAlias is the rows under issuer that have no object id and were seen under valueLower as an email or a userName: the removal-only link a SCIM user with no object-id match falls to.
func (PG) IdentitiesByPrincipal ¶ added in v0.8.6
func (PG) IdentityAliasValues ¶ added in v0.8.6
IdentityAliasValues is every alias value (email and userName) the identity has been seen under, sorted.
func (PG) IdentityBlocked ¶ added in v0.8.6
IdentityBlocked reports whether principal's identity rows refuse a credential admitted under epoch (epoch < 0: only a deactivation refuses). It is the read the cookie, API-token and SSH-key lanes make at authentication, as one statement.
func (PG) IdentityRefused ¶ added in v0.8.6
func (s PG) IdentityRefused(ctx context.Context, issuer, tenantID, objectID, principal string) (bool, error)
IdentityRefused is the admission half of the sign-in gate, read-only: whether the identity a sign-in names is deactivated or purged. An Entra sign-in is named by (issuer, tenant, object id), and every sign-in by its resolved principal; either match refuses.
func (PG) IngestDeviceAudit ¶ added in v0.8.0
func (s PG) IngestDeviceAudit(ctx context.Context, deviceID uuid.UUID, peer string, rows []types.FederatedAuditEvent) (DeviceIngestResult, error)
IngestDeviceAudit appends one device's forwarded batch to this organisation's own audit_events, as the organisation's own chained rows ("one chain per writer"). A federated row keeps the device's claimed actor_type, action, target and outcome; what marks it forwarded is the device's provenance folded into `data` (mergeDeviceOrigin), not a new audit action, so no filter/SIEM rule keyed on `action` has to learn about it. TRUST BOUNDARY: three fields are never the device's to choose — actor is FederatedActor (claim kept in data.device_origin.actor); source_ip is peer (claim kept in data.device_origin.source_ip); and a run_id naming one of this organisation's own runs refuses the batch (ErrFederatedOrgRun).
Order of work, chosen so a device can make the org's own audit writers wait for at most its inserts:
- Every row must be storable (FederatedRowProblem) and representable by Postgres, or ErrFederatedRowInvalid.
- Every claimed RowHash is recomputed in SQL before any transaction or lock, in ONE statement (verifyClaimedHashes), against its own claimed PrevHash. A refused or replayed batch never touches the chain lock.
- The device row is locked FOR UPDATE, serializing this device's concurrent pushes before either reaches the chain lock (deadlock-free: no transaction takes the chain lock then a device row). A revoked device answers ErrDeviceRevoked.
- Idempotency rides the cursor and the hash, not audit_events.id: rows at or before LastSeq that are the rows held here (heldPrefix) are skipped — the forwarder's cursor can lag what was committed. A reused seq is not a re-send.
- The first new row's claimed PrevHash is either empty (genesis, accepted — a chain reset if one was already recorded) or equal to LastRowHash with seq past LastSeq; every later row's claimed PrevHash equals the preceding row's claimed RowHash. Otherwise ErrConflict.
- Only then the chain lock (db.AuditChainLockKey), under the lock timeout, and the inserts: field for field as claimed except actor, source_ip and merged data. Cursor advances in the same transaction.
Any refusal refuses the entire batch, never a verified prefix: it's the retry unit, and a partial accept would leave the cursor mid-batch with no way to tell the caller which rows to resend.
func (PG) IngestRunnerDecision ¶ added in v0.9.0
func (s PG) IngestRunnerDecision(ctx context.Context, runnerID uuid.UUID, row runnerspool.Record, prepare func(context.Context, types.AuditEvent) (types.AuditEvent, error)) (bool, error)
IngestRunnerDecision atomically appends audit history and advances its replay receipt. Terminal-run acceptance is audit only: this transaction never touches lifecycle, idle clocks, credentials, grants, approvals or token renewal.
func (PG) InsertPendingRunOutput ¶ added in v0.8.6
InsertPendingRunOutput — see RunOutputStore.
func (PG) InsertRunPAT ¶ added in v0.8.2
InsertRunPAT — see RunPATStore.
func (PG) IntakeRunnerStatePage ¶ added in v0.9.0
func (s PG) IntakeRunnerStatePage(ctx context.Context, runnerID uuid.UUID, sessionID string, page runnerwire.StatePage) (RunnerInventoryResult, error)
IntakeRunnerStatePage commits a bounded page and its cursor together. A partial page never checks omissions. This path performs no wire call, credential renewal, lifecycle transition or accepted-exit acknowledgement.
func (PG) IssueLoginIdentity ¶ added in v0.8.6
func (s PG) IssueLoginIdentity(ctx context.Context, in LoginIdentity, now time.Time) (epoch int64, err error)
IssueLoginIdentity is the issuance half of the sign-in gate: in one transaction it upserts and binds the identity row (a failure refuses the sign-in), re-checks deactivation on every row bound to the principal and reads the authority epoch the session cookie will carry. The rows stay locked until the commit, so a suspension either precedes it, and the sign-in is refused with ErrIdentityDeactivated, or follows it, and bumps the epoch past the one returned. A sign-in whose identity is bound to another principal is ErrIdentityBindingMismatch: its session would carry neither that identity's deactivation nor its epoch. A refused sign-in writes nothing.
func (PG) KillRunAtLifetimeIf ¶ added in v0.9.0
func (s PG) KillRunAtLifetimeIf(ctx context.Context, id uuid.UUID, reason types.RunEndReason, detail string, now time.Time) (bool, error)
KillRunAtLifetimeIf moves a RUNNING run to KILLED and writes its status_detail in the one statement, but only while the reason still holds on the row as it stands at now: the lease sweep decides from a row it listed earlier, and a person may have moved the end, or another replica kept the run at its end, since. The conditions are the reason's own, as MarkRunEnded's are for the keep:
- "end_reached": a Background run whose end is at or before now and before its lifetime cap (an end at the cap is the maximum);
- "max_lifetime_reached": the lifetime cap is at or before now, and the run is not a Background run whose end came first (that run is end_reached).
Both refuse a run its own end already kept (lost_reason 'ended'): a kept run keeps its files grace. False with a nil error is a no-op for the caller: no kill, no audit row. detail is what status_detail becomes ("lifetime: <reason>").
func (PG) LastRunPAT ¶ added in v0.8.2
LastRunPAT — see RunPATReader.
func (PG) LatestAuditEventByAction ¶
LatestAuditEventByAction returns the most recent audit event whose action equals the given action, or ErrNotFound when none exists. Used by /healthz to find the latest kernel.sensor.ping driving the eBPF health state.
Most recent by `time`, picked from a seq-ordered window: the audit spool replays at-least-once while keeping each event's original ev.Time, so a beat spooled through a DB blip could carry the highest seq but an hours-old time and falsely mark the sensor degraded. The window orders by seq to keep using the purpose-built (action, seq DESC) index; ordering by time directly would sort the whole action's history on every probe. Twenty is a window, not a proof — a longer replay backlog can push the fresh row out, bounding the staleness to one heartbeat interval against /healthz's own TTL.
func (PG) LeaveRunQueue ¶ added in v0.9.0
func (s PG) LeaveRunQueue(ctx context.Context, id uuid.UUID, to types.RunState, admittedAt *time.Time) (bool, error)
LeaveRunQueue is the one way a run leaves QUEUED: one statement moves it to `to` (only while it is still QUEUED) and deletes its run_queue row, so no exit can keep the row or drop it without the state. admittedAt is promotion's stamp (QUEUED to PENDING) and nil for every other exit. false with a nil error means another exit won first. UpdateRunStateIf from QUEUED is this call with no stamp.
func (PG) LiftComponentRestriction ¶ added in v0.8.9
LiftComponentRestriction — see ComponentRestrictionLifter.
func (PG) ListAPITokens ¶ added in v0.6.0
ListAPITokens returns every token in the deployment, newest first (admin GET /tokens); revoked rows included, same reason as the self-service list.
func (PG) ListAPITokensByIdentity ¶ added in v0.9.0
ListAPITokensByIdentity returns the tokens whose principal is name or whose email equals it ignoring case (the match IsSessionRevoked's email arm makes), revoked rows included. The principal matches come first, newest first, then the rows only the email names. It reads api_tokens_principal_idx and api_tokens_lower_email_idx (migration 0176), not the whole table. The email arm follows the session-cut rule (lower(sub) = lower($2)), so for non-ASCII case pairs PG lower() can differ from the scan fallback's strings.EqualFold. name must not be empty: "" is the revoke-all arm, which lists everything.
func (PG) ListAPITokensByPrincipal ¶ added in v0.6.0
func (s PG) ListAPITokensByPrincipal(ctx context.Context, principal string) ([]types.APIToken, error)
ListAPITokensByPrincipal returns principal's own tokens, newest first (self-service GET /me/tokens). Revoked rows are INCLUDED so a human can confirm a retired token is retired; the row carries no usable credential either way.
func (PG) ListAPITokensByPrincipalPage ¶ added in v0.8.0
func (s PG) ListAPITokensByPrincipalPage(ctx context.Context, principal string, p Page) ([]types.APIToken, error)
ListAPITokensByPrincipalPage is ListAPITokensByPrincipal bounded by p.
func (PG) ListApprovals ¶
func (s PG) ListApprovals(ctx context.Context, stateFilter types.ApprovalState) ([]types.ApprovalRequest, error)
ListApprovals returns approvals filtered by state. Pass empty string to list all.
func (PG) ListApprovalsPage ¶ added in v0.3.1
func (s PG) ListApprovalsPage(ctx context.Context, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
ListApprovalsPage returns approvals filtered by state (empty = all) in reverse request order, bounded by p. The all-state feed rides approvals_requested_at_idx; a single-state filter rides approvals_state_requested_at_idx, serving both WHERE and ORDER BY without a sort.
func (PG) ListApprovalsPageByRun ¶ added in v0.7.0
func (s PG) ListApprovalsPageByRun(ctx context.Context, runID uuid.UUID, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
ListApprovalsPageByRun is ListApprovalsPage narrowed to one run, same state filter and ordering.
ponytail: no new index. approvals_run_idx already makes this an index scan, and one run's approvals are few enough that sorting by requested_at is free — upgrade to a composite (run_id, requested_at DESC) if that changes.
func (PG) ListApprovalsPageByRunCreator ¶ added in v0.5.0
func (s PG) ListApprovalsPageByRunCreator(ctx context.Context, createdBy string, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
ListApprovalsPageByRunCreator is ListApprovalsPage narrowed to approvals on runs createdBy owns, via a JOIN on agent_runs (approvals has no created_by of its own). Same state filter and ordering as ListApprovalsPage.
func (PG) ListAuditEventsAfterSeq ¶ added in v0.8.0
func (s PG) ListAuditEventsAfterSeq(ctx context.Context, seq int64, limit int) ([]types.FederatedAuditEvent, error)
ListAuditEventsAfterSeq returns this deployment's own audit_events strictly after seq, oldest first — the forwarder's read of its local chain to build the next batch IngestDeviceAudit expects. limit<=0 defaults to 1000, matching QueryAuditEvents/QueryRecentAuditEvents.
func (PG) ListBaseImages ¶ added in v0.5.0
ListBaseImages returns the whole catalog, newest first.
func (PG) ListCapabilityGrants ¶ added in v0.6.0
ListCapabilityGrants returns every grant, oldest first — the admin Permissions screen's whole table in one read.
func (PG) ListCapabilityGrantsFor ¶ added in v0.6.0
func (s PG) ListCapabilityGrantsFor(ctx context.Context, users, groups []string, userType string) ([]types.CapabilityGrant, error)
ListCapabilityGrantsFor returns every grant that could apply to one caller: `all` rows, `user` rows naming any of users (the caller's lowercased sub AND email), `group` rows naming any of groups, and `user_type` rows naming the caller's one type. An empty userType matches no row, since the write boundary refuses an empty subject.
Deliberately NOT filtered by capability: the resolver needs one kind and GET /me/capabilities needs all four, and one round trip serving both beats two indexes and two queries. Per-kind/per-value matching happens in Go.
ponytail: no cache. This runs per request, on the (subject_type, subject) index; a process-local cache is the HA blocker OPERATIONS already names for other state, and a stale permission cache is a security bug, not a slow page. Add one only behind a shared invalidation channel.
func (PG) ListCapabilityGrantsForPage ¶ added in v0.8.0
func (s PG) ListCapabilityGrantsForPage(ctx context.Context, users, groups []string, userType string, p Page) ([]types.CapabilityGrant, error)
ListCapabilityGrantsForPage is ListCapabilityGrantsFor bounded by p: same four subject arms, so a page never drops a `user_type` grant the unpaged read returns.
func (PG) ListCapabilityRestrictions ¶ added in v0.8.0
ListCapabilityRestrictions returns every restricted value, kind -> set. The table holds one row per restricted admin-configured resource, so one read per resolution answers every value it asks about. Never nil.
func (PG) ListComponents ¶ added in v0.8.9
ListComponents — see ComponentStore.
func (PG) ListComponentsByIDs ¶ added in v0.8.9
func (s PG) ListComponentsByIDs(ctx context.Context, owner string, ids []uuid.UUID) ([]types.Component, error)
ListComponentsByIDs — see ComponentStore.
func (PG) ListDeactivatedIdentities ¶ added in v0.8.6
ListDeactivatedIdentities is the identities deactivated and not purged, most recently deactivated first, at most limit.
func (PG) ListDecidedAlwaysEgressPage ¶ added in v0.9.0
func (s PG) ListDecidedAlwaysEgressPage(ctx context.Context, state types.ApprovalState, afterRequestedAt time.Time, afterID uuid.UUID, limit int) ([]types.ApprovalRequest, error)
ListDecidedAlwaysEgressPage — see DecidedAlwaysEgressPager.
func (PG) ListDelegates ¶ added in v0.8.0
ListDelegates returns every portal, newest first, including revoked — admins need to see that a retired portal is retired.
func (PG) ListDeprovisionFailures ¶ added in v0.8.6
ListDeprovisionFailures is the suspend and purge ledger rows that are pending with a recorded error for an identity still deactivated or purged (the sweeper's scope: a reactivated person's leftover rows are not unfinished work), oldest identity first, at most limit. One row per identity, kind and step: a step that fails for several targets is listed once, with the error of the one touched last.
func (PG) ListDeprovisionJobs ¶ added in v0.8.6
func (s PG) ListDeprovisionJobs(ctx context.Context, identityID uuid.UUID, kind string) ([]DeprovisionJob, error)
ListDeprovisionJobs is the ledger of one identity and kind, oldest first.
func (PG) ListDevices ¶ added in v0.8.0
ListDevices returns every enrolled device, newest first, revoked rows included (an admin needs to see a retired device is retired). Phase one has no console surface for this (CLI/API only).
func (PG) ListEnrolmentTokens ¶ added in v0.8.0
func (s PG) ListEnrolmentTokens(ctx context.Context, now time.Time) ([]types.DeviceEnrolmentToken, error)
ListEnrolmentTokens returns every token still redeemable at now (unconsumed, unexpired), newest first — the ones an admin may still cancel; a redeemed or expired token is never listed.
func (PG) ListGovernanceAssignments ¶ added in v0.7.0
ListGovernanceAssignments returns every assignment in the order the resolver itself would rank them (tier, then priority, then subject), so the console's table reads top-down as the precedence rule.
func (PG) ListGovernanceChanges ¶ added in v0.8.6
func (s PG) ListGovernanceChanges(ctx context.Context, state string) ([]types.GovernanceChange, error)
ListGovernanceChanges returns changes newest first. state narrows to one state ("" is every state); a pending row past its expiry reads as expired.
func (PG) ListGovernanceProfiles ¶ added in v0.7.0
ListGovernanceProfiles returns every profile by name (the handle an admin looks for), unlike the creation order other List* calls use. Deployment- wide config, so there's no per-caller scoping to filter on.
func (PG) ListGrantsByRun ¶
ListGrantsByRun returns all grants for a run.
func (PG) ListGrantsByRunPage ¶ added in v0.8.0
func (s PG) ListGrantsByRunPage(ctx context.Context, runID uuid.UUID, p Page) ([]types.CredentialGrant, error)
ListGrantsByRunPage is ListGrantsByRun bounded by p.
func (PG) ListGroupDenyGrants ¶ added in v0.7.0
func (s PG) ListGroupDenyGrants(ctx context.Context, capability string) ([]types.CapabilityGrant, error)
ListGroupDenyGrants returns the GROUP-subject DENY rows of one capability kind — the only rows internal/api's unresolvable-group-deny check can match.
It exists because that check runs on the FAIL-CLOSED path every caller with an unanswerable group snapshot takes (every pre-0.7 API token, every request): answering it with ListCapabilityGrants would let one such token force an unbounded full-table read per checked value — an authorization question whose cost scales with table size is an availability surface, not just a slow page. The predicate is what internal/api applied in Go afterwards, moved into SQL; value-overlap matching stays in Go (TestCapUnresolvableGroupDenyMatchesFullScan pins the two together). The (subject_type, subject) index already serves it.
ponytail: no EXISTS fast path in front of it. It would be a second round trip to save a query that already returns nothing on the deployments the fast path would help.
func (PG) ListInvitations ¶ added in v0.9.0
func (PG) ListLapsedTokenRuns ¶ added in v0.8.0
ListLapsedTokenRuns — see RunLoser. Both sides use the database's clock, so replica clock skew cannot make a live run look lapsed.
func (PG) ListLaunchIntents ¶ added in v0.9.0
func (s PG) ListLaunchIntents(ctx context.Context, createdBy string, limit int) ([]LaunchIntentRecord, error)
ListLaunchIntents — see LaunchIntentStore.
func (PG) ListLaunchPresets ¶ added in v0.8.0
ListLaunchPresets returns every preset by name.
func (PG) ListLeasedRuns ¶ added in v0.8.0
ListLeasedRuns reads the runs the lease sweep acts on. RUNNING only: a run still starting reaches its end on the first sweep after it is up, and a terminal run has nothing left to end.
func (PG) ListLiveRunnerRuns ¶ added in v0.9.0
ListLiveRunnerRuns is every run bound to the runner that is starting, running or held for a confirmation and not lost: the runs a runner's new session must be leased again.
func (PG) ListMemberDrives ¶ added in v0.9.0
ListMemberDrives returns one page of every person's drives, by owner then name, and the total count.
func (PG) ListMemberDrivesOf ¶ added in v0.9.0
ListMemberDrivesOf returns owner's drives by name, tombstoned ones included.
func (PG) ListNonTerminalRunsBy ¶ added in v0.8.6
ListNonTerminalRunsBy is createdBy's runs that have not ended.
func (PG) ListPauseCandidates ¶ added in v0.8.0
ListPauseCandidates — see RunPauser.
func (PG) ListPendingApprovalsForRuns ¶ added in v0.8.0
func (s PG) ListPendingApprovalsForRuns(ctx context.Context, runIDs []uuid.UUID) ([]types.ApprovalRequest, error)
ListPendingApprovalsForRuns — see ApprovalsForRunsPager. Backed by approvals_run_idx and the partial approvals_state_idx: an index scan over run_id = ANY($1) intersected with the partial index, not a table scan.
func (PG) ListPendingRecordingRunOutputs ¶ added in v0.8.9
func (s PG) ListPendingRecordingRunOutputs(ctx context.Context, staleAfter time.Duration, limit int) ([]uuid.UUID, error)
ListPendingRecordingRunOutputs — see RunOutputStore.
func (PG) ListPendingRunnerActions ¶ added in v0.9.0
func (s PG) ListPendingRunnerActions(ctx context.Context, runnerID uuid.UUID) ([]types.RunnerPendingAction, bool, error)
ListPendingRunnerActions is the runner's PENDING payload: at most one page of its oldest open bound actions, and whether more remain. A row from before the binding is never delivered; it keeps fencing its run instead.
func (PG) ListPeople ¶ added in v0.8.0
func (PG) ListPeopleDirectory ¶ added in v0.8.6
func (s PG) ListPeopleDirectory(ctx context.Context, f PeopleDirectoryFilter) (PeopleDirectoryPage, error)
func (PG) ListPolicies ¶
ListPolicies returns all policies in reverse creation order. The slice is empty (never nil) when no policies exist.
func (PG) ListPoliciesPage ¶ added in v0.3.1
ListPoliciesPage returns policies in reverse creation order, bounded by p (run_policies_created_at_idx covers the ORDER BY).
func (PG) ListProfiledLiveRuns ¶ added in v0.8.0
ListProfiledLiveRuns — see RunLimitsReclamper.
func (PG) ListRemoteRunners ¶ added in v0.9.0
func (s PG) ListRemoteRunners(ctx context.Context) ([]RemoteRunnerRow, error)
func (PG) ListRoleMappings ¶ added in v0.7.0
ListRoleMappings returns every row, oldest first — both the console's People screen and internal/auth/oidc's login-time merge (mergeRoleMaps) read the whole table in one call; there is no per-caller scoping to filter on, this is deployment-wide config.
func (PG) ListRunComponents ¶ added in v0.8.9
ListRunComponents — see ComponentStore.
func (PG) ListRunHarnesses ¶ added in v0.9.0
ListRunHarnesses — see RunHarnessStore.
func (PG) ListRunPATs ¶ added in v0.8.2
ListRunPATs — see RunPATReader. The primary key's run_id prefix serves it.
func (PG) ListRunProxyReleases ¶ added in v0.8.0
func (s PG) ListRunProxyReleases(ctx context.Context) ([]RunProxyRelease, error)
ListRunProxyReleases — see RunReviver.
func (PG) ListRunnerExitWork ¶ added in v0.9.0
ListRunnerExitWork pages by run UUID. Generation cannot advance while one incomplete receipt exists, so a run has at most one item in this work list.
func (PG) ListRunnerLapsedRuns ¶ added in v0.9.0
func (s PG) ListRunnerLapsedRuns(ctx context.Context, runnerID, after uuid.UUID) ([]types.AgentRun, error)
ListRunnerLapsedRuns is a bounded page for the offline callback. The loss claim rechecks all authority and DB lapse in MarkRunnerRunLost; this list is only a candidate scan and grants no authority to mutate a run.
func (PG) ListRunnerPoolCatalogue ¶ added in v0.9.0
func (s PG) ListRunnerPoolCatalogue(ctx context.Context, owner string, all bool) ([]RunnerPoolCatalogueRow, error)
ListRunnerPoolCatalogue returns the live organization pools and owner's own live user pools (with all, every person's: the organisation's first, then owner's own), by name, each with its use policy, remote-hosted members, the count of owner's own claimed runners it holds and the ids of owner's runners in it.
func (PG) ListRunnerPoolMembers ¶ added in v0.9.0
func (PG) ListRunnerPoolRunners ¶ added in v0.9.0
ListRunnerPoolRunners is a Self-Hosted pool's member runners, newest first: only runners its owner holds, so a pool never shows anyone else's runner. A Remote Provided pool has none.
func (PG) ListRunners ¶ added in v0.9.0
ListRunners returns every runner, newest first, revoked included.
func (PG) ListRunnersByOwner ¶ added in v0.9.0
func (PG) ListRunnersPage ¶ added in v0.9.0
func (s PG) ListRunnersPage(ctx context.Context, filter types.RunnerFilter, now time.Time, p Page) ([]types.Runner, error)
ListRunnersPage — see RunnerInventoryStore.
func (PG) ListRunsFiltered ¶ added in v0.8.0
ListRunsFiltered is ListRunsPage narrowed and reordered per f. Owner- scoped reads ride agent_runs_created_by_idx (bitmap scan + in-memory sort); an org-wide read is a parallel seq scan with top-N heapsort — both linear in the caller's history, which the spec accepted (no ended_at index backs this CASE-based order/window).
func (PG) ListRunsPage ¶ added in v0.3.1
ListRunsPage returns runs in reverse creation order, bounded by p. agent_runs_created_at_idx makes the ORDER BY + LIMIT an index scan.
func (PG) ListRunsPageByCreator ¶ added in v0.5.0
func (s PG) ListRunsPageByCreator(ctx context.Context, createdBy string, p Page) ([]types.AgentRun, error)
ListRunsPageByCreator is ListRunsPage narrowed to one creator, same order. ponytail: no dedicated (created_by, created_at) index yet — agent_runs is small enough per-operator that the existing created_at index plus a filter scan is fine; add one if a member's run list ever gets slow.
func (PG) ListRunsPageByCreatorOrSponsor ¶ added in v0.9.0
func (s PG) ListRunsPageByCreatorOrSponsor(ctx context.Context, principal string, p Page) ([]types.AgentRun, error)
ListRunsPageByCreatorOrSponsor is ListRunsPageByCreator plus the runs of the service identities principal sponsors, same order.
func (PG) ListSSHKeysByPrincipal ¶ added in v0.5.0
func (s PG) ListSSHKeysByPrincipal(ctx context.Context, principal string) ([]types.SSHPublicKey, error)
ListSSHKeysByPrincipal returns principal's own registered keys, newest first — the self-service GET /me/ssh-keys list.
func (PG) ListSSHKeysByPrincipalPage ¶ added in v0.8.0
func (s PG) ListSSHKeysByPrincipalPage(ctx context.Context, principal string, p Page) ([]types.SSHPublicKey, error)
ListSSHKeysByPrincipalPage is ListSSHKeysByPrincipal bounded by p.
func (PG) ListServiceIdentities ¶ added in v0.9.0
func (PG) ListSources ¶ added in v0.5.0
ListSources returns the whole library, newest first.
func (PG) ListStalePendingRunOutputs ¶ added in v0.8.6
func (s PG) ListStalePendingRunOutputs(ctx context.Context, age time.Duration, limit int) ([]uuid.UUID, error)
ListStalePendingRunOutputs — see RunOutputStore.
func (PG) ListTemplateGroupAdmins ¶ added in v0.9.0
ListTemplateGroupAdmins — see TemplateStore.
func (PG) ListTemplatesVisible ¶ added in v0.9.0
func (s PG) ListTemplatesVisible(ctx context.Context, person string, groups []string) ([]types.RunTemplate, error)
ListTemplatesVisible — see TemplateStore.
func (PG) ListUnrevokedRunPATs ¶ added in v0.8.2
ListUnrevokedRunPATs — see RunPATStore.
func (PG) ListUnusedRunnerRegistrationTokensPage ¶ added in v0.9.0
func (s PG) ListUnusedRunnerRegistrationTokensPage(ctx context.Context, now time.Time, owner string, p Page) ([]types.RunnerRegistrationToken, error)
ListUnusedRunnerRegistrationTokensPage — see RunnerInventoryStore. Never a token value: the table holds only its hash, which the wire type does not serialize.
func (PG) ListUserDriveGrants ¶ added in v0.7.0
ListUserDriveGrants returns every grant in the order the resolver itself would rank them (tier, then priority, then subject) so the console's table reads top-down as the precedence rule, not insertion order.
func (PG) ListUserDriveGrantsPage ¶ added in v0.7.0
ListUserDriveGrantsPage is ListUserDriveGrants bounded to one window. The LIMIT changes the plan, not just the size: this ORDER BY has no serving index, so unbounded it's a Seq Scan + full sort (50k rows, PG17: 149.7ms disk sort); LIMIT turns it into a top-N heapsort (37.7ms, in memory). The Seq Scan itself needs an index (a migration) to remove.
func (PG) ListUserDrives ¶ added in v0.7.0
ListUserDrives returns every drive by name (the handle an admin looks for) with its grant count, in one read — the console's whole table. The count rides along so the delete affordance is honest (a drive with grants answers 409, visible before clicking); a grouped subquery, not a JOIN, keeps the drive row single. Member drives are listed too, for the recovery rehearsal; the admin handler filters them out.
func (PG) ListUserTypes ¶ added in v0.8.0
ListUserTypes returns every type: the built-in first, then by priority (highest first) and name.
func (PG) ListWorkspaces ¶
ListWorkspaces returns all workspaces in reverse creation order. The slice is empty (never nil) when no workspaces exist.
func (PG) ListWorkspacesPage ¶ added in v0.3.1
ListWorkspacesPage returns workspaces in reverse creation order, bounded by p (workspaces_created_at_idx covers the ORDER BY). The id breaks a tie, so the order is total: a run's fold reads this list twice and credits a source two workspaces carry from it.
func (PG) ListWorkspacesPageForOwner ¶ added in v0.6.0
func (s PG) ListWorkspacesPageForOwner(ctx context.Context, owner string, p Page) ([]types.Workspace, error)
ListWorkspacesPageForOwner is ListWorkspacesPage narrowed to what one member may see: their own owned rows plus every operator-owned row (”, every pre-0.6 workspace). workspaces_owned_by_idx covers the IN.
func (PG) LockLoginSupersede ¶ added in v0.8.0
LockLoginSupersede holds db.LoginSupersedeLockClass keyed to actor for up to db.LoginSupersedeLockWait. Session-scoped, not transaction-scoped: it guards several independent statements, including a later read-modify-write on the capture path. Borrows one connection from this pool for the hold's duration; see ErrLoginLockNoCapacity for the one error a caller may proceed on.
func (PG) Locker ¶ added in v0.8.6
Locker is the cross-replica locker over this store's database (db.LockerFor): every PG over one pool shares it. The api package takes its ordered locks through it when the store offers one, and falls back to an in-process locker for a store with no database (nil here, for a PG with no pool).
func (PG) MarkAWSSSOTokenSpent ¶ added in v0.8.0
func (s PG) MarkAWSSSOTokenSpent(ctx context.Context, fingerprint, owner string, markedAt time.Time) error
MarkAWSSSOTokenSpent upserts idempotently: ON CONFLICT DO NOTHING keeps row age "since first spent" even on a second failed persist or invalid_grant.
func (PG) MarkFederationRevoked ¶ added in v0.8.0
MarkFederationRevoked durably records that the organisation revoked this laptop, so a restart comes back still refusing new runs.
func (PG) MarkIdentityPurged ¶ added in v0.8.6
MarkIdentityPurged turns the identity into a permanent tombstone (purged_at set) and records the purge's last step as pending, in one transaction that holds the row FOR UPDATE. It reports whether this call marked it: false when the row was already purged and, with requireDue, when it is not (still) deactivated by its own suspension (ownSuspension) with a purge_after that has passed. The re-check under the lock is what lets a reactivation that committed first win; once the mark commits a reactivation is ErrIdentityPurged.
func (PG) MarkPersonSignedIn ¶ added in v0.8.0
func (PG) MarkRunAgentStopped ¶ added in v0.9.0
MarkRunAgentStopped — see RunLeaser.
func (PG) MarkRunEnded ¶ added in v0.8.0
MarkRunEnded — see RunLeaser.
func (PG) MarkRunEndingSoon ¶ added in v0.8.0
func (s PG) MarkRunEndingSoon(ctx context.Context, id uuid.UUID, endsAt time.Time, thresholdSec int) (bool, error)
MarkRunEndingSoon — see RunLeaser. Keyed on the end itself, so moving the end re-arms every warning without anyone having to reset a counter.
func (PG) MarkRunLost ¶ added in v0.8.0
func (s PG) MarkRunLost(ctx context.Context, id uuid.UUID, reason types.LostReason, now time.Time, tokenLife time.Duration) (bool, error)
MarkRunLost — see RunLoser.
func (PG) MarkRunOutputIncomplete ¶ added in v0.8.6
MarkRunOutputIncomplete — see RunOutputStore.
func (PG) MarkRunPATRevoked ¶ added in v0.8.2
func (s PG) MarkRunPATRevoked(ctx context.Context, runID, authorizationID uuid.UUID, reason, lastError string) (bool, error)
MarkRunPATRevoked — see RunPATStore.
func (PG) MarkRunPaused ¶ added in v0.8.0
func (s PG) MarkRunPaused(ctx context.Context, id uuid.UUID, reason types.PauseReason, activeAt *time.Time) (bool, error)
MarkRunPaused — see RunPauser.
func (PG) MarkRunRevived ¶ added in v0.8.0
func (s PG) MarkRunRevived(ctx context.Context, id uuid.UUID, from types.LostReason, ended *EndedKept, limit int, startsAgent bool) (bool, error)
MarkRunRevived — see RunReviver.
func (PG) MarkRunnerRunLost ¶ added in v0.9.0
func (s PG) MarkRunnerRunLost(ctx context.Context, runnerID, runID uuid.UUID, expectedRef string, at time.Time) (bool, error)
MarkRunnerRunLost uses the existing loss CAS, with authenticated ownership checked in the same committing transaction. A fresh drop never claims loss.
func (PG) MergeWorkspaceRequirements ¶ added in v0.5.0
func (s PG) MergeWorkspaceRequirements(ctx context.Context, id uuid.UUID, add map[string]types.WorkspaceRequirement) (types.Workspace, error)
MergeWorkspaceRequirements ADDS rows to a workspace's requirements overlay atomically (`jsonb ||`), so a concurrent edit can never be clobbered by read-modify-write. The WHERE clause enforces the same key-count cap the PUT endpoint does, evaluated on the POST-merge total so a multi-key merge can't overshoot it in one jump; at the cap it returns ErrConflict.
func (PG) MintAttachTicket ¶ added in v0.5.0
func (s PG) MintAttachTicket(ctx context.Context, token string, t AttachTicket, now, expiresAt time.Time) error
MintAttachTicket records one outstanding ticket, expiring at expiresAt, and sweeps already-expired rows in the same statement. The sweep compares against the caller's clock (now), NOT now(), so a DB clock running ahead can't silently delete live tickets.
ponytail: the sweep rides the mint instead of a background worker — the table holds only unredeemed tickets inside a 30s TTL, i.e. a handful of rows. Add a sweeper (or an expires_at index) only if mint volume ever makes that false.
func (PG) MintDelegatedToken ¶ added in v0.8.0
func (s PG) MintDelegatedToken(ctx context.Context, t types.DelegatedToken, raw string, now time.Time) (types.DelegatedToken, error)
MintDelegatedToken stores one token (raw is plaintext; only its hash persists), stamps the portal's last use, and sweeps expired tokens. created_at is written on the DB clock, back-dated by t.CreatedAt's age like CreateAPIToken, since it's compared against a session cutoff that Postgres stamps.
ponytail: the sweep rides the mint, like MintAttachTicket — rows live only ten minutes. Add a real sweeper if mint volume ever breaks that.
func (PG) MintEnrolmentToken ¶ added in v0.8.0
func (s PG) MintEnrolmentToken(ctx context.Context, token string, t types.DeviceEnrolmentToken) (types.DeviceEnrolmentToken, error)
MintEnrolmentToken inserts one single-use enrolment token. ErrConflict on a unique_violation (23505) against token_sha256 — a raw collision in a 256-bit random space, same as CreateAPIToken's.
func (PG) MintRunnerRegistrationToken ¶ added in v0.9.0
func (s PG) MintRunnerRegistrationToken(ctx context.Context, raw string, token types.RunnerRegistrationToken) (types.RunnerRegistrationToken, error)
MintRunnerRegistrationToken never stores the raw bearer.
func (PG) MoveAPIToken ¶ added in v0.9.0
func (PG) NotePauseSettle ¶ added in v0.8.6
func (s PG) NotePauseSettle(ctx context.Context, id uuid.UUID, after time.Duration) (time.Time, error)
NotePauseSettle — see PauseSettler.
func (PG) NoteRunPATRevokeFailed ¶ added in v0.8.2
func (s PG) NoteRunPATRevokeFailed(ctx context.Context, runID, authorizationID uuid.UUID, lastError string) error
NoteRunPATRevokeFailed — see RunPATStore.
func (PG) PendingGroupRemovals ¶ added in v0.8.6
func (s PG) PendingGroupRemovals(ctx context.Context, idleFor time.Duration, limit int) ([]PendingGroupRemoval, error)
PendingGroupRemovals is the pendingGroupRemovalWhere removals that no step of the same removal has touched for idleFor (a request still working on it is not one the sweeper may race), at most limit.
func (PG) PendingLeavers ¶ added in v0.8.6
func (s PG) PendingLeavers(ctx context.Context, idleFor time.Duration, limit int) ([]PendingLeaver, error)
PendingLeavers is the identities with a suspend or purge ledger row still pending that no step has touched for idleFor (a request still working on it is not one the sweeper may race), at most limit. An identity that is neither deactivated nor purged has a stale ledger and is not listed.
func (PG) Ping ¶ added in v0.6.0
Ping proves the pool can actually reach Postgres (a live query round-trip, not just a constructed pool).
func (PG) PoolSlotsUsed ¶ added in v0.9.0
PoolSlotsUsed is the number of slot-holding runs per pool that has any, the count promotion judges a pool's cap by.
func (PG) PrincipalAliases ¶ added in v0.8.6
func (PG) PrincipalEntraNames ¶ added in v0.9.0
func (PG) PrincipalForName ¶ added in v0.8.6
PrincipalForName maps a name an event carries (a principal, an entra:<tenant>:<object> form, an email the person signed in with) to the person's principal through PrincipalsNamed, the one answer erasure resolves by. A name that resolves to none, or to more than one, is returned as it is. The audit sealer keys rows by it.
func (PG) PrincipalsNamed ¶ added in v0.9.0
func (PG) PrincipalsSharingObject ¶ added in v0.9.0
func (PG) PromoteRunQueue ¶ added in v0.9.0
func (s PG) PromoteRunQueue(ctx context.Context, pass PromotePass, admit QueueAdmit) ([]PromotedRun, []QueueHeld, error)
PromoteRunQueue moves waiting runs of one pool to PENDING, oldest first, while the pool has a free slot. It judges first, holding no lock: the pool's room and each candidate's verdict are read as they stand. Then one transaction takes the pool row (FOR NO KEY UPDATE, the lock an enqueue takes) and the deployment cap's advisory lock, always in that order, counts the slot-holders again, and moves the admitted runs by a state CAS while there is room. A run the verdict will not admit keeps its place and the pass judges the next, so one run that cannot be placed never blocks another's. An error with promoted runs is a judging cut short (a page read failed, or its time ran out) after those were admitted: they are promoted all the same, and the caller starts them.
func (PG) ProposeGovernanceChange ¶ added in v0.8.6
func (s PG) ProposeGovernanceChange(ctx context.Context, ch types.GovernanceChange, ttl time.Duration) (types.GovernanceChange, []ExpiredGovernanceChange, error)
ProposeGovernanceChange stores ch as pending, expiring ttl from now on the database's clock. In the same transaction it first moves any lapsed pending change for the same target to expired (returned, for the audit rows), so a live one is the only thing the one-pending-per-target index can refuse: that is *ErrGovernanceChangePending naming it. A create, and an update that renames a profile, also hold the name they take (claimCreateName).
func (PG) PruneAWSSSOSpentTokens ¶ added in v0.8.0
PruneAWSSSOSpentTokens deletes spent-token rows older than cutoff (aws_sso_spent_tokens_marked_at_idx backs the WHERE clause).
func (PG) PurgeAssertedRunnerSubjects ¶ added in v0.9.0
PurgeAssertedRunnerSubjects deletes every action row of an asserted subject whose quarantine succeeded more than RunnerAssertedEvidenceTTL ago. The runner deletes its own evidence for that run on the same clock.
func (PG) PurgeDueIdentities ¶ added in v0.8.6
PurgeDueIdentities is the identities deactivated and not yet purged whose purge_after has passed, those deactivated by their own suspension first, then oldest first, at most limit. It is only a candidate read: MarkIdentityPurged re-checks under the lock.
func (PG) PurgeTerminalRunProxyConfigs ¶ added in v0.8.0
PurgeTerminalRunProxyConfigs — see RunProxyConfigs. The terminal test is types.RunState.IsTerminal itself, not a copy of its set in SQL.
func (PG) PutBranding ¶ added in v0.8.0
func (s PG) PutBranding(ctx context.Context, b types.Branding, keepLogo bool) (types.Branding, error)
PutBranding implements BrandingStore.
func (PG) PutCapabilityEnforcement ¶ added in v0.6.0
func (s PG) PutCapabilityEnforcement(ctx context.Context, enabled map[string]bool) (map[string]bool, error)
PutCapabilityEnforcement replaces the WHOLE switch map: any capability not named in enabled loses its row (absent == not enforced). One statement, not a transaction: the DELETE and INSERT run against the same CTE snapshot over disjoint capability sets, so the pair is already atomic.
func (PG) PutCredentialDeliveryPolicy ¶ added in v0.9.0
func (s PG) PutCredentialDeliveryPolicy(ctx context.Context, policy json.RawMessage, by string, now time.Time) (types.CredentialDeliveryPolicyDoc, error)
PutCredentialDeliveryPolicy upserts the document. The caller has validated it (placement.DeliveryPolicy.Validate).
func (PG) PutLaunchPreset ¶ added in v0.8.0
func (s PG) PutLaunchPreset(ctx context.Context, p types.LaunchPreset) (types.LaunchPreset, PresetWrite, error)
PutLaunchPreset creates p at version 1, or replaces the named row and moves its version by one. A write identical to the stored row changes nothing, not even the version, so re-applying an unchanged document is a no-op. The comparison and the bump are one statement, so two concurrent writers cannot both land on the same version.
func (PG) PutPrincipalPref ¶ added in v0.8.0
func (PG) PutRef ¶ added in v0.3.1
PutRef upserts the ref -> substrate-name row (ref is the primary key).
func (PG) PutRunComponents ¶ added in v0.8.9
func (s PG) PutRunComponents(ctx context.Context, runID uuid.UUID, comps []types.RunComponent) error
PutRunComponents — see ComponentStore.
func (PG) PutRunHarnesses ¶ added in v0.9.0
PutRunHarnesses — see RunHarnessStore.
func (PG) PutRunLayout ¶ added in v0.5.0
func (s PG) PutRunLayout(ctx context.Context, principal, preset string, layout []types.RunLayoutWidget) (types.RunLayout, error)
PutRunLayout upserts principal's layout for preset. ON CONFLICT DO UPDATE makes this one idempotent write with no read-then-decide round trip and no lost-update race between two tabs saving the same preset back to back.
func (PG) PutRunProxyConfig ¶ added in v0.8.0
PutRunProxyConfig — see RunProxyConfigs.
func (PG) PutRunnerPoolOrgDefaults ¶ added in v0.9.0
func (s PG) PutRunnerPoolOrgDefaults(ctx context.Context, d types.RunnerPoolDefaults, by string) error
PutRunnerPoolOrgDefaults replaces the organisation's defaults. The caller has checked the pool; a default only names one, and the resolver refuses a name that has since gone or been switched off.
func (PG) PutRunnerPoolUsePolicy ¶ added in v0.9.0
func (s PG) PutRunnerPoolUsePolicy(ctx context.Context, id uuid.UUID, revision *int64, subjects []types.RunnerPoolSubject, by string) (types.RunnerPoolUsePolicy, error)
PutRunnerPoolUsePolicy sets a live organization pool's use policy and raises the pool's revision; a non-nil revision must be the pool's, checked under the pool lock (ErrRunnerPoolStale). It takes the governance target lock an approval of a held change takes too.
func (PG) PutSiteConfig ¶
func (s PG) PutSiteConfig(ctx context.Context, cfg types.SiteConfig) (types.SiteConfig, error)
PutSiteConfig upserts the single operator-wide site config row. The `singleton` primary key (CHECKed true) makes a second row impossible at the schema level. A write replaces every key types.SiteConfig declares (no partial merge; the API validates the full document first) but keeps any key it doesn't, which only a newer wardynd could have written (declaredJSONKeys).
func (PG) PutTemplateGroupAdmin ¶ added in v0.9.0
func (s PG) PutTemplateGroupAdmin(ctx context.Context, g types.TemplateGroupAdmin) (types.TemplateGroupAdmin, error)
PutTemplateGroupAdmin — see TemplateStore.
func (PG) QueryAuditEvents ¶
func (s PG) QueryAuditEvents(ctx context.Context, runID uuid.UUID, limit int) ([]types.AuditEvent, error)
QueryAuditEvents returns audit events for a run in time order. limit <= 0 means no explicit limit (returns up to 1000).
func (PG) QueryAuditEventsFilteredPage ¶ added in v0.4.4
func (s PG) QueryAuditEventsFilteredPage(ctx context.Context, runID *uuid.UUID, f AuditFilter, p Page) ([]types.AuditEvent, error)
QueryAuditEventsFilteredPage returns audit events narrowed by f, bounded by p. A non-nil runID scopes to one run and keeps that trail's chronological seq ASC order (the per-run contract in docs/sdk.md); nil is the newest-first global feed. Only a request that actually sets a predicate takes this path — an unfiltered read stays on the two plain queries above, whose plans are unchanged.
No new index: 0001 covers (time) and 0017 (action, seq DESC); a bounded LIMIT query index-scans the pkey backward and filters, which is what the caps are for. DataContains adds a per-row `data @>` test with no GIN index behind it; the planner walks the pkey or the (time) index and filters, and the LIMIT plus a Since window bound it (about 0.1 s over 2M rows in the #1449 review).
func (PG) QueryAuditEventsPage ¶ added in v0.3.1
func (s PG) QueryAuditEventsPage(ctx context.Context, runID uuid.UUID, p Page) ([]types.AuditEvent, error)
QueryAuditEventsPage returns a run's audit events in seq (chronological) order, bounded by p. audit_events_run_seq_idx makes WHERE run_id + ORDER BY seq an indexed range scan with no sort; OFFSET pages forward without flipping to DESC, so the per-run trail stays ASC (docs/sdk.md's exit-code contract) and a caller pages to the newest events with ?offset=.
func (PG) QueryRecentAuditEvents ¶
QueryRecentAuditEvents returns the most-recent audit events across ALL runs, newest first — the global SIEM-style feed the Audit view renders, unlike the chronological per-run QueryAuditEvents.
func (PG) QueryRecentAuditEventsPage ¶ added in v0.3.1
QueryRecentAuditEventsPage returns the newest-first global audit feed, bounded by p. seq is the audit_events PRIMARY KEY, so ORDER BY seq DESC + LIMIT is an index-scan-backward with no added index.
func (PG) QueueDepth ¶ added in v0.9.0
QueueDepth is the number of waiting runs per pool that has any.
func (PG) QueueEntriesOfRevokedRunners ¶ added in v0.9.0
QueueEntriesOfRevokedRunners are the waiting runs whose launch names a runner (its request's runner_id) that is revoked, oldest first: no promotion can ever place them.
func (PG) QueueOwnerEntries ¶ added in v0.9.0
QueueOwnerEntries are the waiting runs of one owner, the leaver purge's and an erasure's work list.
func (PG) QueuePoolIDs ¶ added in v0.9.0
QueuePoolIDs are the pools that have waiting runs: the sweep's and a kick's work list.
func (PG) QueueRecordingRunOutput ¶ added in v0.8.9
func (s PG) QueueRecordingRunOutput(ctx context.Context, runID uuid.UUID, retention, retryAfter time.Duration, newRecording bool) error
QueueRecordingRunOutput — see RunOutputStore.
func (PG) QueueRunnerAction ¶ added in v0.9.0
func (s PG) QueueRunnerAction(ctx context.Context, a types.RunnerPendingAction) (types.RunnerPendingAction, bool, error)
QueueRunnerAction durably queues a containment action (kill, end, stop_proxy) for a's claimed runner, bound to the identity the org holds at commit: the runner's owner, the run's exact ref and the expected execution generation (uuid.Nil asserts none was issued), and for stop_proxy the exact kept outage loss in LostAt. Any mismatch is ErrRunnerActionRefused and writes nothing. A replayed action ID, an open action of the same kind for the run, or a deferred stop_proxy for the same loss is returned with queued=false only when every binding matches; otherwise ErrConflict. A runner that is not claimed, or a run that is gone, is ErrNotFound: the runner row is locked FOR SHARE, so a queue meeting a revoke waits for it and then refuses. Recovery, quarantine and retirement need explicit org authority that this queue does not establish, so they refuse.
func (PG) QueueRunnerTeardown ¶ added in v0.9.0
func (s PG) QueueRunnerTeardown(ctx context.Context, runnerID uuid.UUID, kind types.RunnerActionKind, ref string) (types.RunnerPendingAction, bool, error)
QueueRunnerTeardown queues the org's own offline teardown of ref (the remote substrate's Queue seam): it binds the run's identity as the org holds it under the same locks, then queues through the exact-binding path. A stop_proxy binds the current kept outage loss and refuses without one.
func (PG) ReacquireAttachLease ¶ added in v0.9.0
func (s PG) ReacquireAttachLease(ctx context.Context, l AttachLease, ttl time.Duration) (bool, error)
ReacquireAttachLease — see AttachLeaseStore. AcquireAttachLease's rule without its two hand-over arms: no from, and no reservation taken by its taker's principal.
func (PG) ReadRunOutputChunks ¶ added in v0.8.6
func (s PG) ReadRunOutputChunks(ctx context.Context, runID uuid.UUID, limit int) (RunOutputChunks, error)
ReadRunOutputChunks — see RunOutputChunkStore.
func (PG) ReclampRunLimits ¶ added in v0.8.0
func (s PG) ReclampRunLimits(ctx context.Context, from types.AgentRun, toLimits types.RunLimits, toEnd *time.Time, toWait int, endTightenedAt *time.Time) (bool, error)
ReclampRunLimits — see RunLimitsReclamper. The compare on the limits read is what keeps a PATCH decided against the old gate from landing after it, and this write from landing over a PATCH's.
func (PG) RecordPushPathList ¶ added in v0.8.0
func (PG) RecordRunnerActionResult ¶ added in v0.9.0
func (s PG) RecordRunnerActionResult(ctx context.Context, runnerID, runID, actionID uuid.UUID, outcome, reason string, observedAt time.Time, prepare func(context.Context, types.AuditEvent) (types.AuditEvent, error)) (types.RunnerPendingAction, bool, error)
RecordRunnerActionResult records an authenticated action_result: runnerID is the stream's stored identity and runID the event's run; both must be the action's own. The outcomes are success, deferred and refused; only refused carries a reason, and its first receipt closes the action and writes runner.action.refuse in the same transaction. observedAt is the runner's assertion and applied_at is the org clock. The first receipt rechecks the owner, ref and execution generation the action was bound to; a stop_proxy success on the still-kept loss records late containment in the same transaction, so the receipt and its audit commit or roll back together. An identical repeat returns first=false with no further effect; a changed one is ErrConflict.
func (PG) RecordRunnerContainmentTx ¶ added in v0.9.0
func (s PG) RecordRunnerContainmentTx(ctx context.Context, tx pgx.Tx, proof RunnerContainmentProof, prepare func(context.Context, types.AuditEvent) (types.AuditEvent, error)) error
RecordRunnerContainmentTx is called exactly once after H3's first successful exact action-result CAS, inside that same READ COMMITTED transaction. A duplicate CAS must skip this hook. H3 owns pending clearance and commits only if this hook succeeds. No lifecycle or credential state is restored here.
func (PG) RecordRunnerPosture ¶ added in v0.9.0
func (s PG) RecordRunnerPosture(ctx context.Context, id uuid.UUID, p types.RunnerPosture, now time.Time) (bool, error)
RecordRunnerPosture stores a posture report from a claimed runner and says whether it differs from the one held, so only a change writes runner.posture.record. A runner that is not claimed is ErrNotFound.
func (PG) RefreshAPITokenIdentity ¶ added in v0.8.0
func (s PG) RefreshAPITokenIdentity(ctx context.Context, principal, role, userType string, groups []string, truncated bool) error
RefreshAPITokenIdentity re-stamps role, user type, and the group snapshot (with its completeness bit) on EVERY token principal holds — the api-token twin of RefreshSSHKeyRoles; OnLogin fires both so one login bounds both frozen credentials.
SECURITY: a token's identity is frozen at mint with nothing else to refresh it — without this, demoting an admin leaves their wdn_ tokens authenticating AS AN ADMIN until explicitly revoked, and a token keeps authorizing against stale group memberships until a fresh mint.
truncated is bound EXACTLY as passed, never defaulted or inferred: it must come from the login's own session-completeness signal, the same bit a fresh mint stamps. A NULL groups_truncated already reads as TRUNCATED downstream (fail closed); silently defaulting this to false would assert "these are all their groups" for a snapshot that isn't — the wrong direction for an authorization decision.
identity_stamped_at moves with the role in the SAME statement, so a login that stamps a token's role stamps its age too, and a failed statement leaves that principal's tokens stale rather than half-updated. WARDYN_ROLE_STAMP_TTL reads it; `revoked_at IS NULL` stays in the WHERE, so a login never revives a revoked token (an expired one keeps its own expiry, which this never writes).
Still bounded-stale, not live: the ceiling is the owner's next login (see docs/SSH.md §Bounds for the key lane's equivalent). No error when the principal holds no tokens — a zero-row UPDATE is the ordinary case.
SECURITY: a token an admin minted FOR this principal (minted_by set) is revoked instead of re-stamped when the login's role differs from its stamp — its role was derived before the person's own groups were known and the minter saw its plaintext, so re-stamping upward would hand the minter's tier to whoever holds that credential. SET reads the row's OLD role, so the comparison is against the stamp.
func (PG) RefreshRunOutputClaim ¶ added in v0.8.6
RefreshRunOutputClaim — see RunOutputStore.
func (PG) RefreshSSHKeyRoles ¶ added in v0.6.0
func (s PG) RefreshSSHKeyRoles(ctx context.Context, principal, role string, checkedAt time.Time) error
RefreshSSHKeyRoles re-stamps role and role_checked_at for every key owned by principal, from the OIDC OnLogin hook, with that login's freshly-derived role. This bounds the admin-override stamp to at most WARDYN_SSH_ROLE_TTL stale: it overwrites role too, not only the timestamp, so a demoted or promoted human's keys take effect on their very next login, with no delete-then-re-register needed. No registered keys is a normal, silent no-op.
A CAPPED key (registered in the user view) keeps its user role — the login refreshes only its timestamp, never promotes it.
func (PG) ReissueDeferredAssertedRunnerActions ¶ added in v0.9.0
func (s PG) ReissueDeferredAssertedRunnerActions(ctx context.Context, runnerID uuid.UUID, sessionID string) (int, error)
ReissueDeferredAssertedRunnerActions is the reconciler for an asserted subject's deferred kill or quarantine: a deferred receipt is final for its action, so the obligation continues in a fresh successor with the identical binding and proof. It runs off the read loop as a fresh session is admitted (before its inventory begins), and only when the runner's previous session completed its inventory, so each obligation gets at most one successor per completed inventory. It returns how many successors it queued.
func (PG) ReleaseAttachLease ¶ added in v0.8.6
ReleaseAttachLease — see AttachLeaseStore.
func (PG) RemoveOwnRunnerFromPool ¶ added in v0.9.0
func (s PG) RemoveOwnRunnerFromPool(ctx context.Context, id, runnerID uuid.UUID, owner string) (bool, int64, error)
RemoveOwnRunnerFromPool removes owner's own runner (in any state, so a revoked one can be tidied away) from a pool; removed is false when it was not a member or not owner's.
func (PG) RemoveRemoteRunnerFromUserPool ¶ added in v0.9.0
func (s PG) RemoveRemoteRunnerFromUserPool(ctx context.Context, id uuid.UUID, remoteRunner, owner string) (bool, int64, error)
RemoveRemoteRunnerFromUserPool takes a remote-hosted runner out of owner's own user pool; removed is false when it was not a member. ErrNotFound: no such live pool of owner's.
func (PG) RemoveRunnerPoolExecutor ¶ added in v0.9.0
func (s PG) RemoveRunnerPoolExecutor(ctx context.Context, id uuid.UUID, executor string, refuseGoverned bool) (removed bool, rev int64, err error)
RemoveRunnerPoolExecutor removes a remote-hosted member of an organization pool; removed is false when it was not one. The caller decided on a catalogue read taken before the locks whether the detach is held; refuseGoverned says it decided "not held", and ErrRunnerPoolGoverned answers a use policy that was approved in between.
func (PG) RenameScimGroup ¶ added in v0.8.6
RenameScimGroup changes a group's display name; its externalId never changes.
func (PG) RenewAttachLease ¶ added in v0.8.6
func (s PG) RenewAttachLease(ctx context.Context, runID, holderID uuid.UUID, ttl time.Duration) (bool, error)
RenewAttachLease — see AttachLeaseStore.
func (PG) ReopenDeprovisionJob ¶ added in v0.8.6
func (s PG) ReopenDeprovisionJob(ctx context.Context, identityID uuid.UUID, kind string, k JobKey) error
ReopenDeprovisionJob makes a finished step pending again: a run the ledger counted done that is found live once more.
func (PG) ReplaceUserDriveGrant ¶ added in v0.9.0
func (s PG) ReplaceUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, []uuid.UUID, error)
ReplaceUserDriveGrant is UpsertUserDriveGrant that also returns the drives the subject lost: the drive ids of the rows it removed and of the kept row's drive before the repoint.
func (PG) ReserveAttachLease ¶ added in v0.8.6
func (s PG) ReserveAttachLease(ctx context.Context, runID, from uuid.UUID, taker, replica string, ttl time.Duration) (AttachLease, uuid.UUID, bool, error)
ReserveAttachLease — see AttachLeaseStore.
func (PG) ResetFederation ¶ added in v0.8.0
ResetFederation is a (re-)enrolment: a new device identity starts an empty chain at the organisation, resetting the cursor to 0 and clearing the revoked mark. The only writer that clears it.
func (PG) ResolveGovernanceProfile ¶ added in v0.7.0
func (s PG) ResolveGovernanceProfile(ctx context.Context, userSubjects, groups []string, userType string) (*types.GovernanceProfile, types.CapabilitySubjectType, error)
ResolveGovernanceProfile returns THE ONE profile that applies to a caller, or ErrNotFound when no assignment matches (which the caller reads as "fall through to the deployment ceiling", the absent-row back-compat rule).
The whole precedence rule is the ORDER BY, deliberately: one indexed read on the UNIQUE(subject_type, subject) btree, so there's no second implementation in Go to skip, mis-order, or forget. subjectMatch and subjectPrecedence are the same fragments ResolveUserDrive splices, so the ceiling and the drive can't disagree about "most specific".
SECURITY: users/groups are normalized from nil to empty for the same reason ListCapabilityGrantsFor does: a nil Go slice binds as SQL NULL and `x = ANY(NULL)` is NULL, not false. Fails closed either way, but a predicate whose behavior hinges on a driver detail has no place at an authorization boundary.
userType is the caller's one type id; "" matches no row.
func (PG) ResolveReauthApproval ¶ added in v0.7.6
func (s PG) ResolveReauthApproval(ctx context.Context, id uuid.UUID, decision types.ApprovalDecision, ev types.AuditEvent) (types.ApprovalRequest, error)
ResolveReauthApproval moves a credential_reauth approval to APPROVED and writes its credential.reauth.resolve audit row in ONE transaction: the state change unblocks a HELD credential request, and the audit row is the only durable record that a human acted behind it. Committed separately, a crash between them would leave a run resuming with nothing in the trail saying who resolved it (invariant I7). If either write fails the approval stays PENDING and the idempotent reconcile-on-read tries again.
It is NOT part of the Store interface (see iface.go on transactional surfaces): internal/api type-asserts for it.
The CAS is DecideApproval's own: WHERE state='PENDING', so a concurrent resolver loses cleanly with ErrAlreadyDecided and writes no second audit row.
func (PG) ResolveUserDrive ¶ added in v0.7.0
func (s PG) ResolveUserDrive(ctx context.Context, userSubjects, groups []string, userType string) ( *types.UserDrive, *types.UserDriveGrant, types.CapabilitySubjectType, error)
ResolveUserDrive returns THE ONE drive that applies to a caller, the winning grant, and its tier — or ErrNotFound. The whole precedence rule lives in the ORDER BY (subjectMatch/subjectPrecedence, shared with ResolveGovernanceProfile since both rank the same subject vocabulary): one indexed read on UNIQUE(subject_type, subject), so there's no second Go implementation to mis-order.
Disabled grants stay in the query; the winner's own `enabled` decides PAUSED vs MOUNTED. Excluding them in the WHERE would let a paused row fall through to a wider `all`-tier drive no admin chose for this member — silently, since the only visible signal would be a mount appearing rather than one stopping (DESIGN §2.2).
userSubjects/groups are normalized from nil to empty: a nil Go slice binds as SQL NULL, and `x = ANY(NULL)` is NULL rather than false — same reasoning as ResolveGovernanceProfile.
userType is the caller's one type id; "" matches no row.
func (PG) ResolveUserDrives ¶ added in v0.9.0
func (s PG) ResolveUserDrives(ctx context.Context, userSubjects, groups []string, userType string) ([]UserDriveWinner, error)
ResolveUserDrives is ResolveUserDrive per drive: DISTINCT ON keeps each drive's top-ranked row, then the outer ORDER BY ranks the winners. Both orders are subjectPrecedence, so the per-drive pick and the single-drive pick cannot rank differently.
func (PG) ResumeGroupRemoval ¶ added in v0.8.6
ResumeGroupRemoval says whether the sweeper may go on with a removal it selected earlier: true only when the pair's ledger still has a pending step and the person is not recorded a member again. It never opens a removal or deletes a membership, so a candidate the identity provider added back since it was selected is dropped, not removed again. The identity row is locked FOR UPDATE first, in a statement of its own: a membership insert's foreign-key check holds that row, so the lock waits for an add in flight to commit or roll back. The membership is then read by a second statement, whose snapshot is taken after the lock and so sees that add; an add that starts later waits for this transaction, and is ordered after the answer.
func (PG) RetireServiceIdentity ¶ added in v0.9.0
func (PG) RetryRunnerExitTail ¶ added in v0.9.0
func (s PG) RetryRunnerExitTail(ctx context.Context, runnerID, runID, generation uuid.UUID, tail func(context.Context, types.AgentRun, runnerwire.AgentExit) error) error
RetryRunnerExitTail holds the run-operation lock over validation, destructive effects and receipt completion. BeginRunnerExecution uses the same barrier; a completed old receipt never touches a newer incarnation.
func (PG) RevokeAPIToken ¶ added in v0.6.0
func (s PG) RevokeAPIToken(ctx context.Context, id uuid.UUID, principal string, now time.Time) (types.APIToken, error)
RevokeAPIToken marks id revoked. principal scopes the UPDATE when non-empty (self-service: a human may only revoke their OWN token). SECURITY: someone else's id is ErrNotFound, not a distinguishable 403 — no existence leak across principals. An EMPTY principal is the ADMIN path and revokes anyone's.
Already-revoked is ErrNotFound too (`revoked_at IS NULL` in the WHERE): revoke is idempotent, so a second call must not emit a second token.revoke audit row for an act that didn't happen.
func (PG) RevokeDelegate ¶ added in v0.8.0
func (s PG) RevokeDelegate(ctx context.Context, id uuid.UUID, now time.Time) (types.Delegate, error)
RevokeDelegate marks id revoked. Unknown or already-revoked is ErrNotFound, so a second revoke writes no second audit row. Outstanding delegated tokens need no write of their own: GetDelegatedTokenByRaw joins on this column.
func (PG) RevokeDevice ¶ added in v0.8.0
RevokeDevice marks id revoked. Already-revoked is ErrNotFound too (`revoked_at IS NULL` in the WHERE): idempotent, so a second call emits no second revoke audit row.
func (PG) RevokeEnrolmentToken ¶ added in v0.8.0
func (s PG) RevokeEnrolmentToken(ctx context.Context, id uuid.UUID, now time.Time) (types.DeviceEnrolmentToken, error)
RevokeEnrolmentToken cancels a redeemable token by setting consumed_at (the column ConsumeEnrolmentToken's WHERE requires NULL), so a revoke can't race a redemption. Already-redeemed/revoked/expired/unknown is ErrNotFound.
func (PG) RevokeInvitation ¶ added in v0.9.0
func (PG) RevokeRunner ¶ added in v0.9.0
func (s PG) RevokeRunner(ctx context.Context, id uuid.UUID, now time.Time, by, reason string) (RunnerRevocation, error)
RevokeRunner revokes a runner in one transaction: the runner row with who revoked it and why, every run holding a slot on it ended KILLED, and every unsettled pending action of it settled 'revoked'. A QUEUED run holds no slot and is not ended here: the caller ends the ones waiting for this runner alone. Rows are kept as evidence. The fence lifts only because the run is terminal in the same commit, never before. Already revoked or unknown is ErrNotFound, so a second call ends nothing. Lock order is runner, then runs by id, then actions, as everywhere else.
func (PG) RevokeRunnerRegistrationToken ¶ added in v0.9.0
func (s PG) RevokeRunnerRegistrationToken(ctx context.Context, id uuid.UUID, now time.Time) (types.RunnerRegistrationToken, error)
RevokeRunnerRegistrationToken spends an unused token by setting the column ConsumeRunnerRegistrationToken requires NULL, in one conditional UPDATE: a revoke and a redemption of the same token take the same row lock, so exactly one of them wins. A token that was redeemed, revoked, expired or never existed is ErrNotFound.
func (PG) RunAgentStopped ¶ added in v0.9.0
RunAgentStopped reports whether MarkRunAgentStopped persisted a stop for id: its agent_stopped_at is set.
func (PG) RunCapacity ¶ added in v0.8.6
func (s PG) RunCapacity(ctx context.Context, o RunCapacityOpts) (RunCapacity, error)
RunCapacity reads every non-terminal row in one query (the positive types.NonTerminalRunStates list, never NOT IN terminal, so a new terminal state cannot be counted as active) and folds it per the state table in the 0.8.6 fleet design: STARTING, RUNNING and WAITING_FOR_CONFIRMATION rows with lost_at NULL hold capacity, paused ones included; kept rows (lost_at set) count as Kept; PENDING and QUEUED rows appear only in States (a QUEUED run holds no slot and no reservation, but wardyn_runs_active still reports it). A kept row whose agent may still run (HoldsSandboxSQL: kept after an outage, no agent stop recorded) also holds its agent's reservation, without the proxy that was stopped. A run bound to a placement outside this deployment (a registered runner, or an executor it does not run) is counted in States, Kept and Paused only: its sizing, whatever runner_kind it was stamped with and even when unstamped, is not this deployment's.
func (PG) RunHasOpenRequest ¶ added in v0.8.0
RunHasOpenRequest — see RunPauser.
func (PG) RunHasPendingRunnerAction ¶ added in v0.9.0
RunHasPendingRunnerAction is the fence: a run with an open action, or a deferred one, gets no relay, call, generation or revival.
func (PG) RunHeldContainedOnRunner ¶ added in v0.9.0
RunHeldContainedOnRunner reports whether the run's runner holds it contained: a kill, end, stop_proxy or quarantine was queued for it and no later recover_containment succeeded. Such a runner refuses any lease for the run, and a refused lease ends its session.
func (PG) RunIDsCreatedBy ¶ added in v0.8.6
func (PG) RunQueueFacts ¶ added in v0.9.0
RunQueueFacts reads the place of each of ids that is still waiting, in one read; a run that is not QUEUED has no entry. Only the pools of the asked runs are ranked.
func (PG) RunQueuePosition ¶ added in v0.9.0
RunQueuePosition is how many runs wait ahead of run id in its pool (a count, never whose), or ErrNotFound when the run is not waiting.
func (PG) RunTokenRenewedAt ¶ added in v0.9.0
RunTokenRenewedAt is the run's token renewal stamp, the one the lapsed-token sweep reads.
func (PG) RunWatcherFresh ¶ added in v0.5.0
func (s PG) RunWatcherFresh(ctx context.Context, id uuid.UUID, staleAfter time.Duration) (bool, error)
RunWatcherFresh reports whether id's watcher lease is younger than staleAfter — mirrors ClaimStaleRunWatchers' own staleness predicate (a live watcher owns it). A missing row → (false, nil): nothing is watching it, so the reaper may proceed.
func (PG) RunnerArchCounts ¶ added in v0.9.1
RunnerArchCounts counts the non-revoked runners per reported CPU architecture. A runner that has not reported one is not counted.
func (PG) RunnerExecutionOf ¶ added in v0.9.0
RunnerExecutionOf is the run's persisted execution intent, ErrNotFound while it has none. It is the check an issued generation is verified against, never a source for one.
func (PG) RunnerPoolSlotCounts ¶ added in v0.9.0
func (s PG) RunnerPoolSlotCounts(ctx context.Context, poolIDs []uuid.UUID) (map[uuid.UUID]PoolCounts, error)
RunnerPoolSlotCounts is every listed pool's PoolCounts in one grouped read, taken without any lock: advisory, since a launch counts again under the pool row's lock. Used counts what countPoolSlotHolders counts. A pool with neither is present with zeros.
func (PG) RunnerPoolsOf ¶ added in v0.9.0
func (s PG) RunnerPoolsOf(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID][]types.RunnerPoolRef, error)
RunnerPoolsOf — see RunnerInventoryStore. Only a pool whose owner is the runner's owner is named, so a runner never lists a pool of anyone else's, in one read for the whole page.
func (PG) RunnerSlotHolders ¶ added in v0.9.0
RunnerSlotHolders is the number of sandbox-holding runs on each of ids (RunnerUsage's runs). A runner with none is absent.
func (PG) RunnerUsage ¶ added in v0.9.0
func (s PG) RunnerUsage(ctx context.Context, runners []uuid.UUID, remotes []string, except uuid.UUID) (map[string]types.RunnerTally, error)
RunnerUsage is the In use of each runner named, by key, without a lock: what every read shows and placement chooses by, never the authority. except is a run never counted (uuid.Nil for none): a promoted run's start does not count the run's own place. A runner with nothing on it is absent.
func (PG) SaveChunkedRunOutput ¶ added in v0.8.6
func (s PG) SaveChunkedRunOutput(ctx context.Context, runID uuid.UUID, maskScope string, limit int) (bool, error)
SaveChunkedRunOutput — see RunOutputChunkStore.
func (PG) SaveFinalRunOutput ¶ added in v0.8.6
SaveFinalRunOutput — see RunOutputStore.
func (PG) SaveGapRunOutput ¶ added in v0.8.6
SaveGapRunOutput — see RunOutputStore.
func (PG) SaveRecordingRunOutput ¶ added in v0.8.9
func (s PG) SaveRecordingRunOutput(ctx context.Context, claim RecordingOutputClaim, o RunOutput, retention time.Duration) (bool, error)
SaveRecordingRunOutput — see RunOutputStore.
func (PG) ScimGroupMembers ¶ added in v0.8.6
ScimGroupMembers is the identity ids recorded as members of the group, oldest first.
func (PG) SearchIdentities ¶ added in v0.8.6
func (s PG) SearchIdentities(ctx context.Context, issuer, attr, value string, limit int) ([]PrincipalIdentity, error)
SearchIdentities is the identity rows a SCIM filter `attr eq value` selects under issuer, at most limit. externalId matches the SCIM projection or the bound object id; userName and emails.value match the projection, the login email and every alias the identity has been seen under.
func (PG) SearchScimGroups ¶ added in v0.8.6
func (s PG) SearchScimGroups(ctx context.Context, attr, value string, limit int) ([]ScimGroup, error)
SearchScimGroups is the groups a SCIM filter `attr eq value` selects, at most limit. Both attributes match case-insensitively.
func (PG) ServiceStillSponsored ¶ added in v0.9.0
func (PG) SetAuditDeliveryCursor ¶ added in v0.9.0
func (s PG) SetAuditDeliveryCursor(ctx context.Context, dest string, seq int64, rowHash string) error
SetAuditDeliveryCursor advances dest's checkpoint after the collector accepted a batch. The zero position is written only after a cursor reset (the acknowledged row is gone or its hash changed), which is why seq 0 counts one reset and leaves acked_at alone: an acceptance that delivered nothing is not an acceptance at all.
func (PG) SetAuditDeliveryError ¶ added in v0.9.0
SetAuditDeliveryError records the collector's last answer and whether it halted delivery until wardynd restarts or another replica takes over delivery (a terminal 4xx). An empty msg with halted false clears both.
func (PG) SetAuditRetentionPolicy ¶ added in v0.8.6
func (PG) SetBrandingLogo ¶ added in v0.8.4
func (s PG) SetBrandingLogo(ctx context.Context, logo []byte, logoType string, fromFile bool, updatedBy string) (bool, error)
SetBrandingLogo implements BrandingStore.
func (PG) SetCapabilityRestriction ¶ added in v0.8.0
func (s PG) SetCapabilityRestriction(ctx context.Context, capability, value string, restricted bool, by string) error
SetCapabilityRestriction restricts one value (inserts its row, keeping the first writer's provenance) or lifts the restriction (deletes it).
func (PG) SetFederationCursor ¶ added in v0.8.0
SetFederationCursor durably advances the forwarder's cursor (seq and the local row's row_hash, so a later tick can tell it from a table-reset row at the same seq), upserting the singleton row. Called after a batch is accepted upstream, so a crash between accept and this write only costs an idempotent retry (see IngestDeviceAudit), never a gap.
func (PG) SetPromotedStatusDetail ¶ added in v0.9.0
SetPromotedStatusDetail writes the status_detail of a promoted run that has not been dispatched, so the reason a start refused it lands before the FAILED transition and a reader never sees a failed queue run without its token. It is a no-op once the run has left PENDING.
func (PG) SetQueueWait ¶ added in v0.9.0
SetQueueWait records why a waiting run keeps its place: its "queue: <token>" status_detail, written only when it differs from what the run carries and only while the run is still QUEUED.
func (PG) SetRemoteRunnerPeople ¶ added in v0.9.0
func (s PG) SetRemoteRunnerPeople(ctx context.Context, id string, revision *int64, pools types.RemoteRunnerPeoplePools, subjects []types.RunnerPoolSubject, by string) (before, after types.RemoteRunner, err error)
func (PG) SetRunAgentExecID ¶ added in v0.3.1
SetRunAgentExecID scoped-writes ONLY agent_exec_id, once the driver execs the agent. The crash reconciler reads it to observe agent liveness across a restart.
func (PG) SetRunContainmentError ¶ added in v0.8.0
func (s PG) SetRunContainmentError(ctx context.Context, id uuid.UUID, msg string, now time.Time) error
SetRunContainmentError — see RunLeaser.
func (PG) SetRunDiskMiB ¶ added in v0.8.0
SetRunDiskMiB scoped-writes ONLY the resolved ephemeral-disk-cap column. Called once applyEphemeralDisk resolves the effective disk_mib, since that needs dispatch-time inputs unavailable at CreateRun.
func (PG) SetRunEndAndWait ¶ added in v0.8.0
func (s PG) SetRunEndAndWait(ctx context.Context, id uuid.UUID, fromLimits types.RunLimits, fromEnd *time.Time, fromWait int, toEnd *time.Time, toWait int, ended *EndedKept) (bool, error)
SetRunEndAndWait — see RunLeaser. The compare on the values the caller read is what makes the caller's clamp and gate decision the one that lands: a concurrent change, the lease sweep ending the run, or a re-clamp tightening the limits the gate was read from turns this into a no-op.
func (PG) SetRunFailureHint ¶ added in v0.6.0
SetRunFailureHint scoped-writes ONLY failure_hint — the one-line operator reason a run FAILED before its agent started, known only at the failure site (failAndRevoke). Best-effort at the call site; ErrNotFound when no row matched.
func (PG) SetRunImage ¶ added in v0.2.0
SetRunImage scoped-writes ONLY the resolved-image provenance column, once the image resolves after the row is inserted.
func (PG) SetRunProxyRelease ¶ added in v0.8.0
SetRunProxyRelease — see RunReviver.
func (PG) SetRunSizing ¶ added in v0.8.6
SetRunSizing scoped-writes ONLY the dispatch-time sizing columns. It does not bump updated_at: the record is not activity, and the idle clock reads updated_at.
func (PG) SetRunStatusDetail ¶ added in v0.7.6
SetRunStatusDetail scoped-writes ONLY status_detail — what the substrate says a STARTING run is waiting on, or the control plane's own `image: Building` line on a PENDING run (a lifetime end reason rides KillRunAtLifetimeIf). Fed by runner.SandboxSpec.OnWaiting, once per CHANGE of reason. Deliberately does NOT bump updated_at: that column is also what the idle reaper and the killed-run tail-upload grace measure by, and a diagnostic line a kubelet triggers must never buy a run more life or hold a terminal run's upload door open.
func (PG) SetRunTitle ¶ added in v0.8.0
SetRunTitle — see RunTitler.
func (PG) SetRunnerArch ¶ added in v0.9.1
SetRunnerArch records the CPU architecture a runner reported on connect, the latest kept; a revoked runner keeps the one it had. The caller has checked it with types.ValidArch.
func (PG) SetRunnerMachineName ¶ added in v0.9.0
SetRunnerMachineName records the host name a runner reported on connect, the latest kept; a revoked runner keeps the one it had. The caller has checked it with types.ValidMachineName.
func (PG) SetSandboxRef ¶
SetSandboxRef records the runner reference (container ID / pod name). A non-empty ref also records this release as the one that started the run's proxy (proxy_release, migration 0084).
func (PG) SetSourceScanResult ¶ added in v0.5.0
func (s PG) SetSourceScanResult(ctx context.Context, id uuid.UUID, profile []byte, status types.WorkspaceStatus, runID uuid.UUID, seed map[string]types.WorkspaceRequirement) (types.Source, error)
SetSourceScanResult persists a scan outcome FENCED on the claiming run: only the run holding active_run_id may write, so a stale upload from a superseded run can never clobber a fresher result. `seed` rebuilds the scan_seeded subset of requirements (provenance-aware, see sourceScanRebuild); NULL (failed scan) leaves the contract untouched, while a non-nil empty seed still rebuilds — see sourceRequirementsParam.
func (PG) SetSourceScanResultUnfenced ¶ added in v0.5.0
func (s PG) SetSourceScanResultUnfenced(ctx context.Context, id uuid.UUID, profile []byte, status types.WorkspaceStatus, seed map[string]types.WorkspaceRequirement) (types.Source, error)
SetSourceScanResultUnfenced persists a SYNCHRONOUS (inline local_dir) scan, which never claimed a run slot to fence against. Same provenance-aware rebuild semantics as the fenced writer (sourceScanRebuild).
func (PG) SetWorkspaceApprovedEgress ¶
func (s PG) SetWorkspaceApprovedEgress(ctx context.Context, id uuid.UUID, domains []string) (types.Workspace, error)
SetWorkspaceApprovedEgress replaces ONLY the approved-egress column (plus updated_at and egress_edited_at), scoped so it can never clobber a concurrently-persisted async scan. egress_edited_at always bumps, even for an identical list, since ReconcileWorkspaceEgressDecisions treats it as "the operator confirmed this at this moment".
func (PG) SetWorkspaceBuiltImage ¶
func (s PG) SetWorkspaceBuiltImage(ctx context.Context, id uuid.UUID, observedRef, imageRef, builtHash string, rec *types.ImageBuild) (bool, error)
SetWorkspaceBuiltImage scoped-writes ONLY the image cache columns and the build record (build-once/reuse-many) in one statement. It is a compare-and-swap on the image_ref the caller observed: that is what fences a run-launch build against a concurrent build (design env-build-record §3.1). applied=false means another build moved image_ref first (or the workspace is gone); the caller keeps its own image and must not reclaim the old tag.
func (PG) SetWorkspaceDeniedEgress ¶ added in v0.5.0
func (s PG) SetWorkspaceDeniedEgress(ctx context.Context, id uuid.UUID, domains []string) (types.Workspace, error)
SetWorkspaceDeniedEgress is denied_egress's mirror of SetWorkspaceApprovedEgress: same anti-clobber scoping, same full-list replace, same egress_edited_at stamp (removing a permanent DENY is an operator override the boot heal must not undo).
func (PG) SetWorkspaceImportState ¶
func (s PG) SetWorkspaceImportState(ctx context.Context, id uuid.UUID, status types.WorkspaceStatus, activeRunID *uuid.UUID, expectedActive *uuid.UUID) (types.Workspace, bool, error)
SetWorkspaceImportState is the scoped writer the scan orchestrator uses to advance status + the in-flight run pointer. Fenced on expectedActive (the active_run_id observed in the read the decision came from; nil means "no in-flight run"), so a caller deciding from a STALE read cannot land it. applied=false means the slot moved under the caller, which must re-read rather than retry blindly.
func (PG) SetWorkspaceLLMCred ¶ added in v0.4.0
func (s PG) SetWorkspaceLLMCred(ctx context.Context, id uuid.UUID, cred *types.WorkspaceLLMCred) (types.Workspace, error)
SetWorkspaceLLMCred replaces ONLY the model/harness cred binding column (plus updated_at), scoped so it can never clobber a concurrently-persisted async scan. Pass nil to clear the binding.
func (PG) SetWorkspaceOwner ¶ added in v0.6.0
func (s PG) SetWorkspaceOwner(ctx context.Context, id uuid.UUID, owner string) (types.Workspace, error)
SetWorkspaceOwner replaces ONLY the owned_by column (plus updated_at) — the offboarding reassign (decision O6). Deliberately the ONLY writer of the column after CreateWorkspace: UpdateWorkspace omits owned_by, so an ordinary edit can never move ownership.
func (PG) SetWorkspaceRecordResult ¶
func (s PG) SetWorkspaceRecordResult(ctx context.Context, id uuid.UUID, taskKey string, result json.RawMessage, onlyIfStatus string) (types.Workspace, bool, error)
SetWorkspaceRecordResult atomically upserts ONE task's entry in the Record Mode record_results map (jsonb merge, so concurrent writers of DIFFERENT tasks never lose each other's entries). When onlyIfStatus is non-empty the write is a compare-and-set against the task's stored status. Returns applied=false (no error) on a guard miss.
func (PG) SetWorkspaceRequirements ¶ added in v0.5.0
func (s PG) SetWorkspaceRequirements(ctx context.Context, id uuid.UUID, reqs map[string]types.WorkspaceRequirement) (types.Workspace, error)
SetWorkspaceRequirements replaces ONLY the requirements-contract column (plus updated_at), scoped like SetWorkspaceApprovedEgress. Pass the FULL desired map — this replaces rather than merges.
func (PG) SpendApprovalOnce ¶ added in v0.7.10
SpendApprovalOnce spends a `once` Azure DevOps capability approval: it writes jti into the row's minted_jti if, and only if, nothing has spent it yet. spent=false means another request already did (or the row is not an approved, once-scoped escalation) and the caller must not forward. The empty-minted_jti condition is the whole exactly-once argument: two concurrent re-resolves both reach this UPDATE, Postgres serialises them on the row, and the second finds the column already written.
Not part of the Store interface (see ResolveReauthApproval): the api package type-asserts for it.
func (PG) StageRunnerExit ¶ added in v0.9.0
func (s PG) StageRunnerExit(ctx context.Context, runnerID, runID uuid.UUID, exit runnerwire.AgentExit) error
StageRunnerExit is the checked read-loop path. It stores one immutable, bounded candidate for the issued generation without binding its asserted handle or changing lifecycle/audit. The durable stage is sufficient for ACK.
func (PG) StalePromotedRuns ¶ added in v0.9.0
func (s PG) StalePromotedRuns(ctx context.Context, staleAfter time.Duration) ([]types.AgentRun, error)
StalePromotedRuns are the runs that were promoted out of the queue, are still PENDING with no sandbox, and whose start has not touched its lease for staleAfter: the process that promoted them is gone. Only promotion writes admitted_at, so a plain run in its image build, whose heartbeat is its insert time, is never listed.
func (PG) StampRunActive ¶ added in v0.8.0
StampRunActive — see RunPauser.
func (PG) StampRunTokenRenewed ¶ added in v0.8.0
StampRunTokenRenewed — see RunLoser.
func (PG) StampServerRun ¶ added in v0.9.0
func (s PG) StampServerRun(ctx context.Context, id uuid.UUID, remote string, reserved types.RunnerAmounts) error
StampServerRun records the remote-hosted runner a run Wardyn launched itself (a sign-in, a probe, a source scan) is dispatched to, and what it reserves there, so it counts in that runner's In use. Such a run is not placed through a pool and is not held to the runner's limits; it only counts. A run already bound to a runner of either kind is left as it is.
func (PG) StartGroupRemoval ¶ added in v0.8.6
StartGroupRemoval opens the ledger of one person leaving one group, in one transaction with the removal of the membership row. The three steps join as pending when the person was recorded a member (a new removal, so an earlier finished one is cleared) or when no removal of this pair was ever recorded (a member whose add never reached Wardyn is still removed). A pair whose last removal finished and who has not been added since is a repeat and changes nothing, so an identity provider that repeats the request costs nothing, and a removal still pending is resumed.
func (PG) StartQueuedRun ¶ added in v0.9.0
func (s PG) StartQueuedRun(ctx context.Context, id uuid.UUID, st QueueStart) (run types.AgentRun, ok bool, err error)
StartQueuedRun writes the start's columns on a run that was promoted (PENDING, admitted_at set) and has not been dispatched, and returns the row. ok is false when the run is no longer in that state, so a kill that won leaves nothing written. A run bound to a runner of either kind is held to that runner's limits at the size it starts with (Reserved, written to the row in the same statement), the run itself not counted, under the runner rows' locks: RunnerID when it has room (the promotion found it room there), else the first of RunnerFallbacks that has, else RunnerAtCapacityError; a remote-hosted run, RunnerPoolExecutor and then RemoteFallbacks, alike.
func (PG) StopKeptRunIf ¶ added in v0.8.0
func (s PG) StopKeptRunIf(ctx context.Context, id uuid.UUID, to types.RunState, lostAt *time.Time, lostReason types.LostReason, endsAt *time.Time) (bool, error)
StopKeptRunIf — see RunLeaser.
func (PG) SubjectKeyDestroyedSince ¶ added in v0.8.6
func (PG) SuspendIdentity ¶ added in v0.8.6
func (s PG) SuspendIdentity(ctx context.Context, p SuspendPlan) (SuspendResult, error)
SuspendIdentity is step 1 of a suspension, one transaction. It takes every row it will change FOR UPDATE, in id order (so a sign-in holding one of them finishes first or is refused), writes the session cutoff for every sub and email form, deactivates the identity rows and bumps their authority epoch, stamps the people rows, records the step done and the plan's pending steps. A suspension of an active identity first clears the ledger of any earlier one.
func (PG) TemplateGroupAdminGroups ¶ added in v0.9.0
TemplateGroupAdminGroups — see TemplateStore.
func (PG) TemplateGroupLabels ¶ added in v0.9.0
TemplateGroupLabels — see TemplateStore.
func (PG) TokenDispositionFacts ¶ added in v0.9.0
func (PG) TouchAPIToken ¶ added in v0.6.0
TouchAPIToken records that id was just used. BEST EFFORT: the auth branch ignores the error, since failing to record a touch must never fail an otherwise-valid request.
ponytail: one UPDATE per authenticated request; add a throttle only if a hot token ever makes that write volume a problem.
func (PG) TouchDevice ¶ added in v0.8.0
TouchDevice records that id was just used. Best effort, like TouchAPIToken: the request path must never fail an otherwise-valid request over a lost keepalive write.
func (PG) TouchRun ¶
TouchRun bumps a run's updated_at to now() without changing any other field — the activity keepalive interactive-attach calls so the idle reaper doesn't stop a run a human is attached to. The TERMINAL-run guard lives HERE, in one WHERE clause, rather than at each of the four callers: updated_at is also the clock the killed-run tail-upload grace is measured from, so an authenticated caller touching a killed run's row on a cadence could hold that upload door open indefinitely. State predicate is the positive list, for the reason given on CountActiveRunsBy.
func (PG) TouchRunner ¶ added in v0.9.0
TouchRunner records an authenticated session: last_seen_at and the runner's version. Best effort in the caller, like TouchDevice.
func (PG) TouchRunnerActivity ¶ added in v0.9.0
TouchRunnerActivity is only for H2's current-connection, nonreplayed signal. The committing transaction rechecks runner ownership and lapse; timestamps come from the database. Neither audit ingestion nor replay calls this method.
func (PG) UnbindIdentity ¶ added in v0.9.0
func (PG) UpdateBaseImageName ¶ added in v0.5.0
func (s PG) UpdateBaseImageName(ctx context.Context, id uuid.UUID, name string) (types.BaseImageEntry, error)
UpdateBaseImageName renames a catalog base-image row — the explicit, scoped rename path, mirroring UpdateSourceConfig above. handleCreateBaseImage is the only caller, on an identity hit where the REQUEST carried an explicit name (never via UpsertBaseImage's own conflict clause — see its doc).
func (PG) UpdateComponent ¶ added in v0.8.9
UpdateComponent — see ComponentStore.
func (PG) UpdatePolicy ¶
func (s PG) UpdatePolicy(ctx context.Context, id uuid.UUID, name string, spec types.RunPolicySpec) (types.RunPolicy, error)
UpdatePolicy replaces a policy's name and spec and bumps updated_at. Returns ErrNotFound when no policy has the given id, and ErrConflict when the rename collides with run_policies.name's UNIQUE constraint — same mapping as CreatePolicy, since a rename onto a taken name is the same caller-fixable mistake as an insert under one. The caller validates the spec before calling.
func (PG) UpdateRemoteRunner ¶ added in v0.9.0
func (PG) UpdateRunStateIf ¶
func (s PG) UpdateRunStateIf(ctx context.Context, id uuid.UUID, fromState, toState types.RunState) (bool, error)
UpdateRunStateIf conditionally transitions a run from fromState to toState in a single UPDATE ... WHERE id=$ AND state=$from, returning whether it applied. TOCTOU-safe: a concurrent kill/stop that already moved the run to a terminal state is never clobbered. From QUEUED it is LeaveRunQueue, so the run's queue row goes in the same statement. False with a nil error means someone else won the transition (or the run doesn't exist); the caller does nothing.
func (PG) UpdateRunStateIfCreatedBefore ¶ added in v0.8.6
func (s PG) UpdateRunStateIfCreatedBefore(ctx context.Context, id uuid.UUID, fromState, toState types.RunState, createdNotAfter time.Time) (bool, error)
UpdateRunStateIfCreatedBefore transitions a run only when still in fromState, its age anchor (admitted_at when it waited in the pool queue, else created_at) is at or before createdNotAfter, and its agent still runs (HoldsSandboxSQL: not kept, or kept after an outage with no agent stop recorded; a run kept with its agent stopped is left to its files grace). The max-age stop's own predicate on the run's age: it carries neither the idleness guard nor the open-request guard of UpdateRunStateIfIdle, because an absolute age cap exists to end a run that is not going to finish by itself.
func (PG) UpdateRunStateIfIdle ¶
func (s PG) UpdateRunStateIfIdle(ctx context.Context, id uuid.UUID, fromState, toState types.RunState, notAfter time.Time) (bool, error)
UpdateRunStateIfIdle is UpdateRunStateIf plus an idleness guard: it transitions a run only when still in fromState, updated_at has not advanced past notAfter (the caller's snapshot), it has no lost/end mark, and it has no open hold-aware request within its wait. Closes the reaper's idleness TOCTOU — an active `wardyn run attach` TouchRun can bump updated_at between snapshot and UPDATE, so guarding on state alone could stop a now-active run; notAfter makes a touched-since-snapshot run no-op instead. The hold-aware clause enforces "idle stop never fires while a request is open within its wait" inside the same atomic CAS, since a request raised in that window is visible only to a check inside the statement.
func (PG) UpdateRunnerLimits ¶ added in v0.9.0
func (s PG) UpdateRunnerLimits(ctx context.Context, id uuid.UUID, owner string, limits types.RunnerLimits) (before *types.RunnerLimits, after types.Runner, err error)
UpdateRunnerLimits declares the limits of a runner its owner holds, unclaimed or claimed, and returns the set it had (nil for none) and the row as it is now. Another person's runner, a revoked one and an absent id are ErrNotFound alike. Lowering a limit ends no run: the runs over it keep running, and no new run is placed there until the runner is under it.
func (PG) UpdateRunnerPool ¶ added in v0.9.0
func (s PG) UpdateRunnerPool(ctx context.Context, id uuid.UUID, revision int64, name *string, state *types.RunnerPoolState, limits *types.RunnerPoolLimits) (types.RunnerPool, error)
UpdateRunnerPool renames, switches or re-limits a pool, only at the revision the caller read: ErrRunnerPoolStale otherwise, ErrNotFound for an unknown or deleted pool, ErrConflict when the name is taken. A non-nil limits replaces the stored block whole; nil leaves it. A change that moves nothing, limits compared as canonical JSON, writes nothing and keeps the revision.
func (PG) UpdateServiceIdentity ¶ added in v0.9.0
func (s PG) UpdateServiceIdentity(ctx context.Context, name string, ch ServiceIdentityChange) (ServiceIdentityChanged, error)
func (PG) UpdateSourceConfig ¶ added in v0.5.0
func (s PG) UpdateSourceConfig(ctx context.Context, id uuid.UUID, name string, reqs map[string]types.WorkspaceRequirement) (types.Source, error)
UpdateSourceConfig replaces a source's operator-editable fields (name, requirements) — scoped, never touching scan-owned columns.
func (PG) UpdateTemplate ¶ added in v0.9.0
func (s PG) UpdateTemplate(ctx context.Context, t types.RunTemplate, expected int, grant *TemplateGrantCheck) (types.RunTemplate, error)
UpdateTemplate — see TemplateStore.
func (PG) UpdateUserType ¶ added in v0.8.0
UpdateUserType rewrites a type's name, description and priority; id and built_in never change. ErrNotFound when missing, ErrConflict on name clash.
func (PG) UpdateUserTypeMetadata ¶ added in v0.8.6
UpdateUserTypeMetadata rewrites a type's name and description and never its priority, so an edit that was judged metadata-only cannot overwrite a priority change approved after it was read. ErrNotFound when missing, ErrConflict on name clash.
func (PG) UpdateWorkspace ¶
func (s PG) UpdateWorkspace(ctx context.Context, id uuid.UUID, ws types.Workspace, stampEgressEdit bool) (types.Workspace, error)
UpdateWorkspace replaces a workspace's editable composition via a FULL-column write of every scan-owned field (profile, image_ref, built_profile_hash, status, etc.), WITH ONE DELIBERATE EXCEPTION: denied_egress is NOT in this SET clause (see Workspace.DeniedEgress) — a permanent deny survives a composition edit, unlike ApprovedEgress. Callers must round-trip the fetched row. Returns ErrNotFound for an unknown id.
egress_edited_at is passed through unless stampEgressEdit marks this write as the operator action the column records: unconditional stamping would suppress the boot heal for a decision nobody undid, while plain omission let this writer clear approved_egress without moving the stamp, so ReconcileWorkspaceEgressDecisions re-widened the list on restart. The stamp is now() from the database, not wardynd's clock, since it's compared against approvals.decided_at and clock skew there fails OPEN.
func (PG) UpsertBaseImage ¶ added in v0.5.0
func (s PG) UpsertBaseImage(ctx context.Context, b types.BaseImageEntry) (types.BaseImageEntry, error)
UpsertBaseImage inserts a catalog image or returns the row with the same identity (kind, image, steps) — the identity index is the dedupe rule. The CHECK constraint refuses 'recommended' structurally: that build is derived per-workspace and has no catalog identity.
An identity hit does NOT touch name, deliberately: this upsert is also the PASSTHROUGH path a workspace/run resolves its base-image spec through, which always derives an auto-placeholder name — applying EXCLUDED.name unconditionally would silently rename an operator's custom-named row back to that placeholder. See UpdateBaseImageName for the rename path.
func (PG) UpsertCapabilityGrant ¶ added in v0.6.0
func (s PG) UpsertCapabilityGrant(ctx context.Context, g types.CapabilityGrant) (types.CapabilityGrant, error)
UpsertCapabilityGrant writes one grant, keyed on the natural (subject_type, subject, capability, value) UNIQUE: re-granting the same triple FLIPS the effect in place rather than leaving two contradictory rows (which would resolve as a permanent deny). The returned row carries the EXISTING id on a conflict, not g.ID, so a re-submit gets the id the DELETE route needs.
func (PG) UpsertGovernanceAssignment ¶ added in v0.7.0
func (s PG) UpsertGovernanceAssignment(ctx context.Context, a types.GovernanceAssignment) (types.GovernanceAssignment, error)
UpsertGovernanceAssignment binds one subject to one profile, keyed on the natural UNIQUE (subject_type, subject): re-assigning a subject REPOINTS its single row rather than leaving a second one behind (two rows for one subject would make "which profile does Bob get" a tie-break instead of the admin's last write).
The returned row carries the EXISTING id on conflict, not a.ID, so the caller gets the id the DELETE route needs.
Returns ErrNotFound when profile_id names no profile (FK 23503 → 404).
func (PG) UpsertGovernanceProfile ¶ added in v0.7.0
func (s PG) UpsertGovernanceProfile(ctx context.Context, p types.GovernanceProfile) (types.GovernanceProfile, error)
UpsertGovernanceProfile writes one profile exactly as given. It is WriteGovernanceProfile with nothing to decide, so it takes the same graph lock and a write can never skip it.
func (PG) UpsertLoginIdentity ¶ added in v0.8.6
func (s PG) UpsertLoginIdentity(ctx context.Context, in LoginIdentity, now time.Time) (PrincipalIdentity, error)
func (PG) UpsertRoleMapping ¶ added in v0.7.0
func (s PG) UpsertRoleMapping(ctx context.Context, m types.RoleMapping) (types.RoleMapping, error)
UpsertRoleMapping writes one row, keyed on the natural UNIQUE (value): re-adding an already-mapped value FLIPS its role in place rather than leaving a second row behind — the same "re-granting the same key updates it" contract UpsertCapabilityGrant follows, for the same reason (two rows for one value cannot happen; the UNIQUE index already forbids it, this just makes the natural retry path a clean update instead of a 409).
The returned row carries the row's real id, which on a conflict is the EXISTING one, not m.ID — the caller needs the id the DELETE route will be given, and an admin re-submitting the same value must not be handed an id that names no row.
A user_type naming no user_types row fails the foreign key; that is ErrNotFound, so the caller can tell a type deleted between its check and this write from a store fault.
The conflict path updates role and user_type only, deliberately NOT created_by — creation provenance (who ADDED this mapping) stays with the original creator across a later role flip by a different admin, the same way created_at is untouched on conflict (no SET at all, so Postgres leaves it).
The conflict path also forces migrated_from_member to false, UNCONDITIONALLY — on a flip to admin/security_admin too, not only a real type pick (never EXCLUDED.migrated_from_member, which the caller never sets to true anyway — see the type's own doc comment). Decision, not an oversight: the marker means "a person still needs to look at this row", and an admin choosing ANYTHING for it — a type or a tier — is that look. The alternative (clear only on a type pick) would let the marker survive a flip to admin and ride along if the row is later flipped BACK to user with no type named — a "migrated" chip on a row an admin, in the interim, explicitly decided was an admin mapping, which is a worse answer than "the row was touched, the flag's job is done" for a marker the design itself frames as a one-time prompt, never a permanent history bit. TestPG_RoleMappings_UpsertClearsMigratedFromMemberOnAdminFlip pins this call.
func (PG) UpsertSource ¶ added in v0.5.0
UpsertSource inserts a library source or returns the existing row with the same identity (kind, locator, ref) — ONE statement, no read-then-write race: the UNIQUE constraint IS the dedupe rule. Identity fields must arrive CANONICALIZED (the api layer owns that) — the store stores what it is given.
func (PG) UpsertUserDrive ¶ added in v0.7.0
func (s PG) UpsertUserDrive(ctx context.Context, d types.UserDrive, refuseIfAllocated bool) (types.UserDrive, error)
UpsertUserDrive writes one drive keyed on ID: INSERT if absent, else UPDATE in place — renaming is allowed while grants still point at it, since ON DELETE RESTRICT rules out delete-and-recreate for an allocated drive. A rename moves the PVC's name; existing members bind an object that no longer exists until they re-mount (docs/OPERATIONS.md "User drives on Kubernetes"). Returns ErrConflict on UNIQUE(name).
An identity-affecting PUT on an already-allocated drive is refused 409 (ErrDriveAllocated) unless ?confirm=rehome; the precondition is re-asserted in this statement, under the row lock UpsertUserDrive takes, so a grant created between the guard's read and this write can't be silently re-homed.
SECURITY: two host_path shares over the same root must derive home names the same way (namespace is the host_root, not the drive — see shareBackend). Different home_templates (`sub` vs `email_local`) could otherwise fold two principals onto one directory name, breaking migration 0059's one-home-per-principal invariant on a backend its index can't reach; same-template drives on one root stay legal. Enforced in the statement itself, not a prior read — not a hard constraint under READ COMMITTED, but the case that actually happens (one admin registering a second view) can't race itself.
created_by/created_at are untouched on update: provenance stays with whoever registered the drive.
func (PG) UpsertUserDriveGrant ¶ added in v0.7.0
func (s PG) UpsertUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, error)
UpsertUserDriveGrant allocates one drive to one subject and REPLACES whatever the subject was allocated before: the subject ends with exactly this drive, and an existing row is repointed rather than a second left beside it, so the admin's last write decides which drive the subject gets. Since migration 0169 a subject may hold several rows (AddUserDriveGrant); this keeps one, repoints it, and removes the others, in one transaction. On a repoint the returned id is the EXISTING row's, not g.ID. Returns ErrNotFound when drive_id names no drive (FK, 23503).
SECURITY: refuses (ErrConflict) if another subject already holds the same home_override in the same object-name NAMESPACE (host_root, not drive — see shareBackend) — one home_override must name one person's directory, or two people end up sharing a minted volume with every bind-time check passing. Guard checks same-drive OR two host_path drives on the same host_root (compared as the stored string; driveHostRootNesting handles the symlink case on the drive-write path). Enforced in the statement itself, one round trip: migration 0059's partial unique index is the race-free floor for the same-drive case; the cross-drive case has none, so here the statement is the whole guard — sufficient for the case that happens, one admin typing one name twice. Residual: a DERIVED (non-override) home can still collide across same-root shares with different templates; not refusable here since a group/all grant doesn't know its principals until sign-in.
enabled is written verbatim, so a zero-value grant is disabled by default — fail-closed at the API boundary, where the omission is still visible.
SECURITY: also guards a silent re-home. Clearing home_override moves that person to the derived name next run, stranding their old directory unnamed. homeOverrideStated is the API's tri-state for "the client said nothing": false refuses the update on a row with a stated override (no row returned, read as ErrConflict); stating it IS the confirmation, no ?confirm= to invent. The zero value is safe — a caller that forgets the argument gets a refusal, not a silent clear.
func (PG) UpsertUserDriveGrantWithinTier ¶ added in v0.9.0
func (s PG) UpsertUserDriveGrantWithinTier(ctx context.Context, g types.UserDriveGrant, homeOverrideStated, additional bool) (types.UserDriveGrant, []uuid.UUID, error)
UpsertUserDriveGrantWithinTier is the allocation write of either verb, ReplaceUserDriveGrant or with additional AddUserDriveGrant, judged by types.DriveGrantWidens in the write's own transaction. The drive is read FOR SHARE, then the subject's allocation lock is taken, then the judged row is read FOR UPDATE: with additional the row for this subject and drive, otherwise the row the replace keeps and repoints. A concurrent edit of the drive or of that row therefore lands wholly before the judgement or waits for the write, and nothing is removed before the judgement. A write judged against there being no row is written only while there is still none (ErrUserDriveGrantChanged otherwise). The removed drives are ReplaceUserDriveGrant's. READ COMMITTED is pinned for UpsertUserDrive's reason. ErrNotFound for an unknown drive.
func (PG) UserTypeReferences ¶ added in v0.8.0
UserTypeReferences counts the capability-grant, governance-assignment, drive-grant and unretired service-identity rows that name the type.
func (PG) UserTypeTokenStamps ¶ added in v0.8.0
UserTypeTokenStamps counts the unrevoked API tokens stamped with the type.
func (PG) VerifyAuditChain ¶ added in v0.6.0
func (s PG) VerifyAuditChain(ctx context.Context) (AuditChainStatus, error)
VerifyAuditChain walks the audit_events hash chain oldest-first, re-hashing every row with migration 0047's audit_row_hash — the SAME function the insert trigger uses, so there's no second implementation to drift.
The sweep is paged as a correctness property, not just a cost one: an unbounded `ORDER BY seq` can plan as Seq Scan -> Sort, buffering the whole table before returning row one — the tamper-investigation endpoint would get slowest over time. Keyset paging (`seq > $1 ORDER BY seq LIMIT n`) is an index scan with a bound instead, so memory is one page and an early break genuinely stops the work.
Paging does not verify less: since migration 0056 the trigger allocates seq while holding the chain lock and releases it at commit, so seq order IS commit order, and a row can never appear below a cursor the walk already passed. Walk state is carried across pages by one auditChainWalk, so a chain longer than a page is one continuous chain.
Everything runs in ONE repeatable-read snapshot, so the chain, the newest attested retention drop, the high-water mark and the partition manifest are the same instant: an append between two reads cannot read as a removed tail. The walk starts from the newest `drop` anchor that dropped rows (row_count above 0: an empty partition leaves nothing to chain to; the first retained row must chain to its recorded tail) and still inspects every retained row. The chain alone cannot see a removed NEWEST tail, so after it the newest row must also match audit_partition_meta's high-water mark, and every partition the expected manifest names must be present unless an anchor accounts for it.
func (PG) WithIdentityShared ¶ added in v0.8.6
WithIdentityShared runs fn while g's identity rows are held FOR SHARE and unchanged: the write a sign-in's captured credential makes lands before a suspension takes the rows, or is refused with ErrIdentityDeactivated. fn may write through another connection (the secret store).
The rows are held on a connection dialled for this call, outside the pool: fn borrows from the pool, and a hold taken from it would wait on itself once the pool is down to that one connection. The dials are bounded like the lock connections: at most db.LockPoolMaxConns at once per pool, process-wide, and a call that finds them all in use waits db.LockPoolAcquireWait and is then refused with db.ErrLockNoCapacity.
func (PG) WorkspacesAttaching ¶ added in v0.5.0
WorkspacesAttaching returns the names of workspaces whose attachments reference source id — the loud half of delete-in-use (one GIN probe on workspaces_attachments_gin). DELETE refuses with these names rather than silently orphaning a workspace to a source that no longer exists.
func (PG) WorkspacesUsingBaseImage ¶ added in v0.5.0
WorkspacesUsingBaseImage is the catalog's delete-in-use check.
func (PG) WriteGovernanceProfile ¶ added in v0.8.6
func (s PG) WriteGovernanceProfile(ctx context.Context, id uuid.UUID, build GovernanceProfileBuild) (types.GovernanceProfile, error)
WriteGovernanceProfile writes one profile keyed on its PRIMARY KEY: an unminted id INSERTs, an existing one UPDATEs in place (name included, so a profile can be renamed while assignments still point at it, since ON DELETE RESTRICT makes delete-and-recreate impossible for an assigned profile). One statement serves POST (fresh id) and PUT (id from the path).
The whole write is one transaction under a graph-wide advisory lock: build sees every profile as that transaction reads them, decides the row (merging what a PUT left absent, refusing a cycle, a depth overflow or an overlay its base does not permit) and the row is stored before the lock is released, so two concurrent writes cannot together make a cycle or a depth-4 chain.
contact follows GovernanceProfile.ContactSet: written (or cleared, when empty) only when it is true, otherwise the stored value stays. A composed row (Overlay set) binds '{}' for ceiling and limits and sets them outright, since it stores no raw authority; its composition columns are always written from the row as given.
Returns ErrConflict when UNIQUE(name) rejects the write. created_by and created_at are NOT touched on update: creation provenance stays with whoever authored the profile.
type Page ¶ added in v0.3.1
Page bounds a List query to Limit rows after Offset, ordered by the query's own ORDER BY. Limit<=0 means unbounded, used by internal callers needing the whole table; public read handlers always pass an explicit Limit (capped by api.parseListPage).
type Pager ¶ added in v0.3.1
type Pager interface {
ListRunsPage(ctx context.Context, p Page) ([]types.AgentRun, error)
ListPoliciesPage(ctx context.Context, p Page) ([]types.RunPolicy, error)
ListWorkspacesPage(ctx context.Context, p Page) ([]types.Workspace, error)
ListApprovalsPage(ctx context.Context, stateFilter types.ApprovalState, p Page) ([]types.ApprovalRequest, error)
QueryAuditEventsPage(ctx context.Context, runID uuid.UUID, p Page) ([]types.AuditEvent, error)
QueryRecentAuditEventsPage(ctx context.Context, p Page) ([]types.AuditEvent, error)
// QueryAuditEventsFilteredPage serves a narrowed audit read (time range,
// action, outcome, actor type); see AuditFilter in auditfilter.go.
QueryAuditEventsFilteredPage(ctx context.Context, runID *uuid.UUID, f AuditFilter, p Page) ([]types.AuditEvent, error)
// ListUserDriveGrantsPage serves the drives console's allocation table;
// its ORDER BY has no index, so unbounded it sorts every allocation on
// every load of the admin screen.
ListUserDriveGrantsPage(ctx context.Context, p Page) ([]types.UserDriveGrant, error)
}
Pager is the paginated read surface, deliberately excluded from Store: widening Store would silently route a test double's embedded-but-not- overridden methods to it. Handlers type-assert for Pager, falling back to unbounded List* + in-Go windowing when a store doesn't implement it; PG always does.
type PartitionDigest ¶ added in v0.8.6
type PartitionDigest struct {
// contains filtered or unexported fields
}
PartitionDigest is the streaming fold of a closed partition, in seq order:
d_0 = sha256(Header) d_i = sha256(d_{i-1} || row_hash_i)
every value lowercase hex text. It holds one 64-byte state however many rows are added, so a partition larger than Postgres's 1 GB field limit digests in constant memory.
func NewPartitionDigest ¶ added in v0.8.6
func NewPartitionDigest(m PartitionManifest) *PartitionDigest
NewPartitionDigest starts the fold at the manifest's header.
func (*PartitionDigest) Add ¶ added in v0.8.6
func (p *PartitionDigest) Add(rowHash string)
Add folds one row's hash (the stored row_hash; a row from before the chain began folds the hash audit_row_hash(NULL, ...) would have given it) into the digest.
func (*PartitionDigest) Sum ¶ added in v0.8.6
func (p *PartitionDigest) Sum() string
Sum is the digest so far, as 64 hex characters.
type PartitionManifest ¶ added in v0.8.6
type PartitionManifest struct {
Partition string `json:"partition"`
Rows int64 `json:"row_count"`
SeqLo int64 `json:"seq_lo"`
SeqHi int64 `json:"seq_hi"`
RecordedLoUS int64 `json:"recorded_lo_us"`
RecordedHiUS int64 `json:"recorded_hi_us"`
}
PartitionManifest is what a partition's digest binds besides its rows: its name, the range of seq and recorded_at it actually holds (recorded_at as integer microseconds since the epoch, the unit audit_row_hash uses) and its row count. An empty partition has Rows 0 and every range zero.
Header is the canonical text the digest starts from. It is the migration 0119 definition, which audit_partition_digest(p_partition) implements in the database: the two are pinned together by a test.
func (PartitionManifest) Header ¶ added in v0.8.6
func (m PartitionManifest) Header() string
Header is the JSON array of strings the fold starts from, in jsonb's own text form (a comma and a space between elements), so a manifest the database and Go each render is byte-identical. A range of an empty partition renders as an empty string.
type PauseCandidate ¶ added in v0.8.0
type PauseCandidate struct {
Run types.AgentRun
// OpenRequest: the run has a PENDING request inside its wait (openHoldSQL).
OpenRequest bool
// WaitingRequest: one of those counts toward a waiting pause
// (waitingHoldSQL).
WaitingRequest bool
}
PauseCandidate is one live run as the pause sweep sees it.
type PauseSettle ¶ added in v0.8.6
PauseSettle is one run a pause compensation may have left with its agent container not matching its pause mark (migration 0132).
type PauseSettler ¶ added in v0.8.6
type PauseSettler interface {
// NotePauseSettle records run id as owing a settle from after on (the
// database's clock), moving a due_at already recorded only forward, and
// returns the due_at it holds.
NotePauseSettle(ctx context.Context, id uuid.UUID, after time.Duration) (time.Time, error)
// DuePauseSettles lists the runs whose settle is due.
DuePauseSettles(ctx context.Context) ([]PauseSettle, error)
// ClearPauseSettle deletes run id's record only while it still reads due,
// so a later note survives.
ClearPauseSettle(ctx context.Context, id uuid.UUID, due time.Time) error
}
PauseSettler is the durable record of the runs whose container may not match their pause mark. Optional like RunPauser; production is always PG.
type PendingGroupRemoval ¶ added in v0.8.6
PendingGroupRemoval is one person's removal from one group with ledger rows still pending.
type PendingLeaver ¶ added in v0.8.6
PendingLeaver is an identity with ledger rows still pending: a suspension its identity provider stopped retrying, or a purge begun and not finished.
type PeopleDirectoryFilter ¶ added in v0.8.6
type PeopleDirectoryFilter struct {
// Query keeps people whose principal starts with it (case-sensitive) or whose email starts
// with it (case-insensitive). Empty keeps everyone.
Query string
// State is "active" (not deactivated), "deactivated", or "" for both.
State string
// After is the last principal of the previous page; empty starts at the top.
After string
Limit int
}
PeopleDirectoryFilter narrows and pages ListPeopleDirectory.
type PeopleDirectoryPage ¶ added in v0.8.6
type PeopleDirectoryPage struct {
People []PersonListing
Next string
}
PeopleDirectoryPage is one page; Next is the principal to pass as After, or "" on the last page.
type PeopleDirectoryStore ¶ added in v0.8.6
type PeopleDirectoryStore interface {
// ListPeopleDirectory returns one page of the directory, ordered by principal.
ListPeopleDirectory(ctx context.Context, f PeopleDirectoryFilter) (PeopleDirectoryPage, error)
}
PeopleDirectoryStore lists the people a deployment knows: every identity that has signed in (principal_identities, migration 0113) and every person an admin set up beforehand (people, migration 0090). Optional, like PersonStore.
type PersonErasureStore ¶ added in v0.8.6
type PersonErasureStore interface {
// RunIDsCreatedBy lists every run created_by createdBy.
RunIDsCreatedBy(ctx context.Context, createdBy string) ([]uuid.UUID, error)
// BlankRunTasks empties the task text of every run created_by createdBy and
// returns how many it changed. It never touches updated_at: the idle reaper
// reads it.
BlankRunTasks(ctx context.Context, createdBy string) (int, error)
// PrincipalAliases lists the names the identity directory knows principal
// by: the emails it signed in with (lowercased) and its entra:<tenant>:<object>
// form. A row sealed under a name the directory did not yet know is under
// that name's own key, so an erasure destroys these too.
// Its email values are the claim text a sign-in sent, never checked for an @, so they can
// spell another person's principal or entra form: match on them, never destroy by them.
PrincipalAliases(ctx context.Context, principal string) ([]string, error)
// PrincipalEntraNames lists the entra:<tenant>:<object> forms of principal's own sign-in
// rows, built from their tenant and object ids and never from an alias value.
PrincipalEntraNames(ctx context.Context, principal string) ([]string, error)
// PrincipalsSharingObject lists the other principals bound to a sign-in with the same tenant and object
// id as one of principal's own, under another issuer: often the same human, never the same principal.
PrincipalsSharingObject(ctx context.Context, principal string) ([]string, error)
// EraseGovernanceChangePersonalFields clears the proposer and decider (and the decider's reason) of
// every governance change whose recorded principal is one of principals or whose recorded email is
// one of emails (case-folded), and moves a pending change whose proposer is one of them to expired.
// A principal is never matched against the email column, where an email claim can spell it. It
// returns the rows it touched.
EraseGovernanceChangePersonalFields(ctx context.Context, principals, emails []string) (int, error)
// SubjectKeyDestroyedSince reports whether any generation of owner's key
// for purpose has a destroyed_at after since.
SubjectKeyDestroyedSince(ctx context.Context, owner, purpose string, since time.Time) (bool, error)
}
PersonErasureStore is what erasing a person reads and writes beyond the stores that own a scope: the person's runs, and the identity directory that maps the names an audit row carries onto one principal. Optional like PrincipalIdentityStore: callers type-assert and refuse a scope the store cannot serve rather than report it erased.
type PersonListing ¶ added in v0.8.6
type PersonListing struct {
Principal string
Email string
// Entra is true for a person keyed by Entra tenant and object id.
Entra bool
PreCreated bool
// FirstSignInAt and LastSignInAt are nil for a person who has never signed in.
FirstSignInAt *time.Time
LastSignInAt *time.Time
DeactivatedAt *time.Time
// ActiveSessions is 0 or 1, see PeopleDirectoryActiveSessionWindow.
ActiveSessions int
APITokens int
SSHKeys int
Credentials int
ActiveRuns int
// Groups, GroupsTruncated and GroupsVerified are the person's last verified login groups
// (key_domain_login_groups, stamped at every SSO sign-in). GroupsVerified is false when no
// snapshot exists; GroupsTruncated is the login's own bit that its groups claim was cut short.
Groups []string
GroupsTruncated bool
GroupsVerified bool
}
PersonListing is one directory row.
type PersonStore ¶ added in v0.8.0
type PersonStore interface {
// CreatePerson inserts p, or returns the row already stored under
// p.Principal with created=false. A different principal holding the same
// email (case-insensitively) is ErrConflict.
CreatePerson(ctx context.Context, p types.Person) (out types.Person, created bool, err error)
// GetPerson is the row stored under exactly principal, or ErrNotFound.
GetPerson(ctx context.Context, principal string) (types.Person, error)
// ListPeople returns every row, oldest first.
ListPeople(ctx context.Context) ([]types.Person, error)
// MarkPersonSignedIn stamps first_signed_in_at on principal's row the first
// time they sign in. No row is not an error: most people were never
// pre-created.
MarkPersonSignedIn(ctx context.Context, principal string, now time.Time) error
}
PersonStore holds the identities an admin created or confirmed before their first sign-in (migration 0090, #1157; the Entra object-id key, 0099, #1195). Optional, like DeviceStore: the API answers 501 on a store without it.
type PoolCounts ¶ added in v0.9.0
PoolCounts is how busy one runner pool is: runs holding one of its slots, and runs waiting for one. Counts only; no run, owner or executor is named.
type PresetWrite ¶ added in v0.8.0
type PresetWrite string
PresetWrite is what PutLaunchPreset did: created the row, replaced it (and moved its version), or found it already identical and wrote nothing.
const ( PresetCreated PresetWrite = "created" PresetUpdated PresetWrite = "updated" PresetUnchanged PresetWrite = "unchanged" )
type PrincipalDirectoryStore ¶ added in v0.9.0
type PrincipalDirectoryStore interface {
// PrincipalsNamed returns the distinct principals name stands for, a person created by
// object id who has signed in under a pairwise subject counting as that subject. The
// first of these that matches decides: the exact principal, the
// entra:<tenant>:<object> form built from tenant and object ids, the principal
// case-folded, then, for a name with an @ only, an email (case-folded) that a
// sign-in, an API token or a pre-created person carries. A principal, a people
// row an admin created included, therefore always wins over an email claim that
// spells it. The one exception is a typed entra:<tenant>:<object> name that matches
// only a people row no sign-in follows and no principal carries: the tenant and object id match
// under any issuer is added to the answer, so a person who signed in under another issuer is ambiguous. More than one is ambiguous; none is a name nobody is recorded under.
PrincipalsNamed(ctx context.Context, name string) ([]string, error)
}
PrincipalDirectoryStore answers who a name an admin typed is, from every place a principal is recorded: the identity directory (principal_identities and its aliases), the people an admin pre-created, API tokens and workspace owners. Every route that erases, deletes or assigns by a person's name resolves through it, and the audit sealer keys rows by it. Optional like PersonErasureStore.
type PrincipalIdentity ¶ added in v0.8.6
type PrincipalIdentity struct {
ID uuid.UUID
Principal string
Issuer string
TenantID string
ObjectID string
EmailLower string
// ScimExternalID and ScimUserName are the SCIM projection, not binding columns.
ScimExternalID string
ScimUserName string
DeactivatedAt *time.Time
AuthorityEpoch int64
PurgeAfter *time.Time
PurgedAt *time.Time
CreatedAt time.Time
LastLoginAt *time.Time
}
PrincipalIdentity is one human identity Wardyn has seen sign in. An Entra identity is (Issuer, TenantID, ObjectID); any other issuer has an empty TenantID and ObjectID and is keyed by (Issuer, Principal). Principal is "" on a row written before the person's first sign-in.
type PrincipalIdentityStore ¶ added in v0.8.6
type PrincipalIdentityStore interface {
// UpsertLoginIdentity records an approved sign-in: it creates the identity row, or finds the
// one for the same (issuer, tenant, object id) on Entra and (issuer, principal) elsewhere, binds
// its principal if it has none, stamps the sign-in time and keeps the email as an alias. A row's
// principal, issuer, tenant and object id are never changed once bound; a sign-in that would
// change one writes nothing: ErrIdentityBindingMismatch when its row is bound to another
// principal, ErrConflict when it names no row at all.
UpsertLoginIdentity(ctx context.Context, in LoginIdentity, now time.Time) (PrincipalIdentity, error)
// GetIdentityByObject is the row for exactly (issuer, tenantID, objectID), or ErrNotFound. An
// empty objectID is always ErrNotFound.
GetIdentityByObject(ctx context.Context, issuer, tenantID, objectID string) (PrincipalIdentity, error)
// IdentitiesByPrincipal is every row bound to principal, oldest first (one per issuer it has
// signed in on); empty when it has none.
IdentitiesByPrincipal(ctx context.Context, principal string) ([]PrincipalIdentity, error)
}
PrincipalIdentityStore is optional, like PersonStore: it is not part of Store, so callers type-assert and treat its absence as "nothing recorded".
type PrincipalInUseError ¶ added in v0.9.0
type PrincipalInUseError struct{ APITokens, SSHKeys, ActiveRuns, Sponsored, PendingInvitations int }
PrincipalInUseError is UnbindIdentity's refusal while the principal it would release still holds something the leaver flow reaches only through the row's principal.
func (*PrincipalInUseError) Error ¶ added in v0.9.0
func (e *PrincipalInUseError) Error() string
type PrincipalPrefStore ¶ added in v0.8.0
type PrincipalPrefStore interface {
// GetPrincipalPref returns principal's value for key, or ErrNotFound.
GetPrincipalPref(ctx context.Context, principal, key string) (json.RawMessage, error)
// PutPrincipalPref upserts principal's value for key.
PutPrincipalPref(ctx context.Context, principal, key string, value json.RawMessage) error
}
PrincipalPrefStore persists per-person preferences. Like RunLayoutStore it is not part of Store, so the api test doubles need not grow it; the api type-asserts and treats its absence as "nothing remembered".
type PromotePass ¶ added in v0.9.0
type PromotePass struct {
PoolID uuid.UUID
// DeploymentCap is WARDYN_MAX_CONCURRENT_RUNS, 0 for none. The pass counts the deployment's
// slot-holders under the same advisory lock a create takes, so it never exceeds the cap.
DeploymentCap int
// ScanLimit is how many waiting runs the pass reads at a time; it reads on past runs it holds while it
// still has room to fill. 0 reads them all at once.
ScanLimit int
// WatcherOwner is the lease holder written on each promoted run: the promoting process.
WatcherOwner string
// AtCapacityDetail is the status_detail of a run waiting behind the pool's cap. A pass that finds the
// pool full writes it on every waiting run of the pool that says something else, so a run that waited
// for a runner goes back to waiting for a slot. "" writes nothing.
AtCapacityDetail string
}
PromotePass is one promotion pass over one pool.
type PromotedRun ¶ added in v0.9.0
type PromotedRun struct {
Run types.AgentRun
Entry RunQueueEntry
}
PromotedRun is a run the pass moved to PENDING, with the queue row it carried.
type PushPathListStore ¶ added in v0.8.0
type PushPathListStore interface {
// RecordPushPathList stores approvalID's list once, for runID. A second
// call for the same approval stores nothing and reports false; a list
// past the run's limit returns ErrPushPathListCap. Count and insert are
// one step, so concurrent calls for a run serialize.
RecordPushPathList(ctx context.Context, approvalID, runID uuid.UUID, l types.PushPathList, limit int) (bool, error)
// GetPushPathList returns approvalID's list, or ErrNotFound.
GetPushPathList(ctx context.Context, approvalID uuid.UUID) (types.PushPathList, error)
// CountPushPathLists counts the lists stored for runID's approvals.
CountPushPathLists(ctx context.Context, runID uuid.UUID) (int, error)
}
PushPathListStore keeps each push_content approval's types.PushPathList. Like PrincipalPrefStore it is not part of Store, so the api test doubles need not grow it; the api type-asserts it.
type Querier ¶ added in v0.8.6
type Querier interface {
Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)
Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)
QueryRow(ctx context.Context, sql string, args ...any) pgx.Row
}
Querier is the statement surface a store write needs: satisfied by *pgxpool.Pool (one statement, its own implicit transaction) and by pgx.Tx (a statement inside a caller's transaction). A write written against Querier runs the same SQL either way, which is what lets a held governance change apply inside the decision transaction.
A write that relies on a transaction-scoped lock (an advisory xact lock) must be handed a pgx.Tx: on a pool the lock is released as soon as its own statement ends.
type QueueAdmit ¶ added in v0.9.0
type QueueAdmit func(ctx context.Context, pool types.RunnerPool, e RunQueueEntry) (QueueVerdict, error)
QueueAdmit judges one waiting run before the pass takes any lock (pool-queue.md section 7 step 4), so it may read the store and ask the substrate. It must not write to the queue. An error leaves that run in its place and the pass judges the next.
type QueueStart ¶ added in v0.9.0
type QueueStart struct {
SPIFFEID string
ConfinementClass types.ConfinementClass
ModelProviderID string
AutonomyLevel types.AutonomyLevel
EndsAt *time.Time
WaitBudgetSec int
RunLimits types.RunLimits
GovernanceProfileID *uuid.UUID
LifetimeCapAt *time.Time
LifetimeCapSource types.LimitSource
Placement types.Placement
PlacementFilled bool
RunnerID *uuid.UUID
// RunnerFallbacks are the run's other runners, in order: when RunnerID has no room under its lock the
// start takes the first of these that has, so a run is never ended for one full runner while another
// can take it.
RunnerFallbacks []uuid.UUID
EvidenceSource types.RunEvidenceSource
RunnerPoolExecutor string
// RemoteFallbacks are the run's other remote-hosted runners, RunnerFallbacks' counterpart.
RemoteFallbacks []string
// Reserved is what the run holds on its runner as it starts: the start folds the run afresh, so
// this is the size it starts with, never the one it joined the queue with.
Reserved types.RunnerAmounts
}
QueueStart is the columns the start of a promoted run writes: everything a QUEUED run left empty (the identity, the end and its cap, the governance capture) and the placement the start settled.
type QueueVerdict ¶ added in v0.9.0
type QueueVerdict struct {
// Admit promotes the run. Wait is the reason it keeps its place otherwise, "" for none to say.
Admit bool
Wait string
// Stop says no run can be admitted this pass (the host has no room), so the rest are not judged.
Stop bool
// Owner says a held run's reason is its owner's (none of their runners can take a run), so their
// later runs are passed over this pass. A run held for a reason of its own holds only itself.
Owner bool
// Runners are the registered runners an admitted run may be placed on, each with room as judged;
// Remotes the remote-hosted runners. Both empty for a run placed on none. The promotion binds the
// run to the self-hosted runner with the most room left that still fits it under the runner rows'
// locks, else to such a remote-hosted runner, and leaves the run waiting when none has room.
Runners []uuid.UUID
Remotes []string
// Needs is the size the run would start with on each of those runners, by runner key: the promotion
// holds that size to the runner under its lock and writes it as the run's reservation. A runner
// with none is held to the size the run joined the queue with.
Needs map[string]types.RunnerAmounts
}
QueueVerdict is the pass's answer for one waiting run.
type Recorder ¶
Recorder wraps a pool and implements audit.Recorder via InsertAuditEvent.
type RecordingOutputClaim ¶ added in v0.8.9
RecordingOutputClaim identifies one read of a committed recording. Generation invalidates reads predating a new upload; Token also fences stale-lease owners.
type RemoteRunnerRow ¶ added in v0.9.0
type RemoteRunnerRow struct {
Runner types.RemoteRunner
Pools []types.RemoteRunnerPoolRef
}
RemoteRunnerRow is a remote-hosted runner with every live pool it is in, user pools included.
type RemoteRunnerStore ¶ added in v0.9.0
type RemoteRunnerStore interface {
// EnsureRemoteRunners inserts a row, with its default name and the limits proposals holds for it,
// for each id that has none, and returns the rows it inserted (made). A row that already exists and
// declares no limits gets its proposal (proposed); one that declares limits keeps them, since they
// are an administrator's from the first boot on.
EnsureRemoteRunners(ctx context.Context, ids []string, proposals map[string]types.RunnerLimits) (made, proposed []types.RemoteRunner, err error)
ListRemoteRunners(ctx context.Context) ([]RemoteRunnerRow, error)
GetRemoteRunner(ctx context.Context, id string) (RemoteRunnerRow, error)
// UpdateRemoteRunner changes the display name, the limits or both at the revision the caller read,
// and returns the runner before and after.
UpdateRemoteRunner(ctx context.Context, id string, revision int64, name *string, limits *types.RunnerLimits, by string) (before, after types.RemoteRunner, err error)
// SetRemoteRunnerPeople writes the people policy under the governance target lock a held change's
// decision takes, and returns the runner before and after.
SetRemoteRunnerPeople(ctx context.Context, id string, revision *int64, pools types.RemoteRunnerPeoplePools, subjects []types.RunnerPoolSubject, by string) (before, after types.RemoteRunner, err error)
}
RemoteRunnerStore is the optional store capability behind the remote-hosted runner routes.
type RestrictedComponentCreator ¶ added in v0.8.9
type RestrictedComponentCreator interface {
// CreateRestrictedComponent inserts the org row c (Owner "") at version 1 under its caller-chosen
// id and restricts (capability, c.ID) in the SAME transaction, so no reader can find the row
// while it is open to every member, and a failed insert leaves no restriction behind. Errors as
// CreateComponent; ErrConflict also rolls the restriction back.
CreateRestrictedComponent(ctx context.Context, c types.Component, capability, by string) (types.Component, error)
}
RestrictedComponentCreator creates an organisation component together with the capability restriction that keeps it attachable by nobody until an admin names who may. Optional beside ComponentStore, for the same reason: a store without it must make the caller refuse, never create the row unrestricted.
type RestrictedComponentDeleter ¶ added in v0.8.9
type RestrictedComponentDeleter interface {
// DeleteRestrictedComponent deletes the org row id, restricts (capability, id) if it is not
// restricted already, and deletes every grant of capability whose value is id, in ONE
// transaction: the id ends restricted with no grant naming it, or nothing changed. It returns
// the deleted row, how many grants went, and whether the restriction insert wrote a row (false
// when the id was still restricted, true when a lift had opened it and this put it back).
// ErrNotFound when no org row has the id, and then nothing is written. A wildcard grant names no
// id and is kept.
DeleteRestrictedComponent(ctx context.Context, id uuid.UUID, capability, by string) (types.Component, int, bool, error)
}
RestrictedComponentDeleter deletes an organisation component without ever leaving its id open. Optional for the reason RestrictedComponentCreator is: a store without it must make the caller refuse, never delete the row and leave the rest undone.
type RunAuditMatcher ¶ added in v0.8.0
type RunAuditMatcher interface {
HasRunAuditEvent(ctx context.Context, runID uuid.UUID, f AuditFilter) (bool, error)
}
RunAuditMatcher answers "does this run have ANY audit row matching f?" as an EXISTS, so the answer does not depend on how many other rows the run has or where the match sits in its trail — which a bounded, oldest-first QueryAuditEvents window cannot promise. A capability interface for the reason Pager gives.
type RunCapacity ¶ added in v0.8.6
type RunCapacity struct {
States map[string]int `json:"states"`
Paused int `json:"paused"`
Kept int `json:"kept"`
Totals RunCapacityRunner `json:"totals"`
AgeBuckets []RunCapacityAge `json:"age_buckets"`
ByRunner map[string]RunCapacityRunner `json:"by_runner"`
ByOwner []RunCapacityOwner `json:"by_owner"`
ByOwnerTruncated bool `json:"by_owner_truncated"`
Unschedulable []RunCapacityUnschedulable `json:"unschedulable"`
UnschedulableTotal int `json:"unschedulable_total"`
// OldestActiveSeconds is the age since created_at of the oldest holding run (0 when none).
OldestActiveSeconds int64 `json:"oldest_active_seconds"`
}
RunCapacity is the fleet's configured reservations, computed from the non-terminal rows.
type RunCapacityAge ¶ added in v0.8.6
RunCapacityAge is one age bucket (since created_at) of holding runs.
type RunCapacityOpts ¶ added in v0.8.6
type RunCapacityOpts struct {
Now time.Time
CurrentKind string
UnschedulableReason func(detail string) string
LocalExecutor func(executor string) bool
}
RunCapacityOpts parameterises RunCapacity. CurrentKind is the deployment's runner kind; Totals carries only that kind's entry; other kinds appear only under ByRunner. UnschedulableReason maps a status_detail to its capacity-blocker reason, or "" when it is not one. LocalExecutor says whether a run's bound executor is one of this deployment's own substrates; nil treats every executor as one.
type RunCapacityOwner ¶ added in v0.8.6
type RunCapacityOwner struct {
Owner string `json:"owner"`
Holding int `json:"holding"`
Runners map[string]RunCapacitySums `json:"by_runner"`
}
RunCapacityOwner is one owner's holding runs, summed per runner kind (never across kinds). Ordering uses the deployment's current kind.
type RunCapacityRunner ¶ added in v0.8.6
type RunCapacityRunner struct {
Basis string `json:"basis"`
RunCapacitySums
}
RunCapacityRunner is one runner kind's sums. Basis says what they mean: Kubernetes sums requests, Docker has no reservation and reports caps.
type RunCapacitySums ¶ added in v0.8.6
type RunCapacitySums struct {
Holding int `json:"holding"`
Unknown int `json:"unknown"`
AgentCPURequestMillis int64 `json:"agent_cpu_request_millis"`
AgentCPULimitMillis int64 `json:"agent_cpu_limit_millis"`
AgentMemoryRequestMiB int64 `json:"agent_memory_request_mib"`
AgentMemoryLimitMiB int64 `json:"agent_memory_limit_mib"`
ProxyCPUMillis int64 `json:"proxy_cpu_millis"`
ProxyMemoryMiB int64 `json:"proxy_memory_mib"`
// ProxyCPUUncapped counts recorded rows whose proxy had no CPU cap (Docker).
ProxyCPUUncapped int `json:"proxy_cpu_uncapped"`
HeldCPUMillis int64 `json:"held_cpu_millis"`
HeldMemoryMiB int64 `json:"held_memory_mib"`
}
RunCapacitySums is one set of configured-reservation sums. Holding counts the rows that hold capacity; Unknown counts the holding rows whose reservation was never recorded (runner_kind NULL), which add to no sum. A run's held figure is its agent request plus its proxy.
type RunCapacityUnschedulable ¶ added in v0.8.6
type RunCapacityUnschedulable struct {
ID uuid.UUID `json:"id"`
Owner string `json:"owner"`
WaitedSeconds int64 `json:"waited_seconds"`
Reason string `json:"reason"`
RunnerKind *string `json:"runner_kind"`
AgentCPURequestMillis *int64 `json:"agent_cpu_request_millis"`
AgentMemoryRequestMiB *int64 `json:"agent_memory_request_mib"`
ProxyCPUMillis *int64 `json:"proxy_cpu_millis"`
ProxyMemoryMiB *int64 `json:"proxy_memory_mib"`
}
RunCapacityUnschedulable is one STARTING run waiting for room, with its recorded reservation (nil where unrecorded).
type RunFilter ¶ added in v0.8.0
type RunFilter struct {
// Owner exact-matches created_by; empty = every creator. The api layer
// resolves ?owner=me|all before calling down.
Owner string
// WithSponsored widens Owner to the runs of every service identity Owner sponsors (#1508): a
// sponsor reads those runs. Ignored with no Owner.
WithSponsored bool
// Statuses is a subset of "active"/"ended"/"failed"/"killed", OR'd
// together; empty = no filter. "needs" is rejected at the api layer.
Statuses []string
// EndedWithin bounds ended rows' age; <= 0 = unbounded. Live rows are
// never windowed by this.
EndedWithin time.Duration
// IncludeKilled disables killedVisibleFor's default hide.
IncludeKilled bool
// NoEnd keeps only live runs with no end (ends_at NULL): the ones nothing will
// stop but a person, an idle stop or a kill (#1319).
NoEnd bool
// Workspace exact-matches COALESCE(NULLIF(repo,”), workspace_path).
Workspace string
// Query ILIKE-searches title/task/repo/created_by. Raw — the store
// escapes '%', '_' and '\' itself.
Query string
}
RunFilter narrows ListRunsFiltered/CountHiddenRuns to the landing page's opt-in contract. Zero value matches every row (killed rows still subject to killedVisibleFor).
type RunHarnessStore ¶ added in v0.9.0
type RunHarnessStore interface {
// PutRunHarnesses writes run runID's rows, once, in one transaction; each row's position in
// hs is its ordinal. ErrNotFound when the run does not exist; ErrConflict when the run
// already has rows, a harness repeats, or more than one row starts. An empty hs is refused: a
// run launched without harnesses writes nothing, so the caller does not call this.
PutRunHarnesses(ctx context.Context, runID uuid.UUID, hs []types.RunHarness) error
// ListRunHarnesses returns a run's rows in request order; empty for a run launched without
// any.
ListRunHarnesses(ctx context.Context, runID uuid.UUID) ([]types.RunHarness, error)
}
RunHarnessStore persists the harnesses a run was launched with and the model provider each was granted (migration run_harnesses). The rows are the run's authorisation tombstone; they hold configuration ids only, so erasure never clears them.
type RunLayoutStore ¶ added in v0.5.0
type RunLayoutStore interface {
// GetRunLayout returns ErrNotFound when nothing has been saved yet; the
// api layer treats that as the default shape, not an error.
GetRunLayout(ctx context.Context, principal, preset string) (types.RunLayout, error)
// PutRunLayout upserts principal's layout for preset and returns the
// stored row, including the server-assigned updated_at.
PutRunLayout(ctx context.Context, principal, preset string, layout []types.RunLayoutWidget) (types.RunLayout, error)
}
RunLayoutStore is the run-cockpit widget-layout persistence surface. Deliberately NOT part of the Store interface: ~30 test doubles embed store.Store, and widening it would break every one for a feature they have nothing to do with. The api layer type-asserts s.cfg.Store to RunLayoutStore and degrades when absent (GET returns the default shape, PUT 501s); production is always PG, which has it.
type RunLeaser ¶ added in v0.8.0
type RunLeaser interface {
// ListLeasedRuns returns every RUNNING run that has an end, a lifetime cap or is kept.
ListLeasedRuns(ctx context.Context) ([]types.AgentRun, error)
// MarkRunEnded marks run id kept-and-ended at now, only while still
// RUNNING, not already kept, and its end is at or before now; clears a
// pause. The conditional UPDATE is the cross-replica mutual exclusion:
// exactly one caller sees true and runs the end.
MarkRunEnded(ctx context.Context, id uuid.UUID, now time.Time) (bool, error)
// MarkRunEndingSoon records that the thresholdSec-before-endsAt warning
// went out, reporting whether this call recorded it: false when that
// warning (or a closer one) already went for this end, or the end changed.
MarkRunEndingSoon(ctx context.Context, id uuid.UUID, endsAt time.Time, thresholdSec int) (bool, error)
// SetRunEndAndWait moves run id's end/wait from (fromEnd, fromWait) to
// (toEnd, toWait), only while the run still has those values, limits
// fromLimits, and isn't terminal. A run lost to a reboot/outage may still
// move its end — extending it is how it becomes revivable again. A run
// kept by its OWN end (LostEnded) moves only with ended set, exactly as
// EndedKept describes. false means the run changed since the read (end,
// wait, or a re-clamped profile); nil ends mean "no end". Moving the end
// clears end_tightened_at.
SetRunEndAndWait(ctx context.Context, id uuid.UUID, fromLimits types.RunLimits, fromEnd *time.Time, fromWait int, toEnd *time.Time, toWait int, ended *EndedKept) (bool, error)
// StopKeptRunIf makes a kept run (RUNNING with a lost/end mark) terminal,
// only while the row still carries the EXACT kept mark read (lostAt,
// lostReason, endsAt), checked atomically with the state guard in one
// UPDATE. Closes the same TOCTOU class UpdateRunStateIfIdle closes for the
// idle reaper: a stale lease-sweep row must never win the destructive
// RUNNING->terminal transition and tear down a run it no longer describes.
// false means the mark or state changed; the caller's re-assert next sweep
// pass makes dropping that safe.
StopKeptRunIf(ctx context.Context, id uuid.UUID, to types.RunState, lostAt *time.Time, lostReason types.LostReason, endsAt *time.Time) (bool, error)
// SetRunContainmentError records that a kept run's stop (proxy or agent)
// failed with msg, only while RUNNING and kept. Message refreshes on every
// call; containment_error_at keeps the first failure's time.
SetRunContainmentError(ctx context.Context, id uuid.UUID, msg string, now time.Time) error
// ClearRunContainmentError clears it once the stop is confirmed; true only
// for the call that cleared a recorded error, so resolution is audited
// once across replicas.
ClearRunContainmentError(ctx context.Context, id uuid.UUID) (bool, error)
// MarkRunAgentStopped records that the agent of id, a run kept after an
// outage (lostAt is its mark), was stopped, so it holds no sandbox whatever
// an extension later does to its end (HoldsSandboxSQL). A no-op unless the
// row is RUNNING and still carries that outage mark with no stop recorded;
// a revive clears it.
MarkRunAgentStopped(ctx context.Context, id uuid.UUID, lostAt time.Time) error
}
RunLeaser is the lease surface. Optional like RunWatcherLeaser and for the same reason: the ~30 test doubles that embed store.Store would route these calls to a nil interface. The api layer type-asserts and runs no lease sweep when a store lacks it; production is always PG.
type RunLimitsReclamper ¶ added in v0.8.0
type RunLimitsReclamper interface {
// ListProfiledLiveRuns returns every non-terminal run that captured a
// governance profile at create and is not kept by its own end (LostEnded).
// A run lost to a reboot or a control-plane outage is still profiled-live:
// tightening its limits must still land, the same way extending its end
// still does (F1, long-holds design rev 4 §2.3).
ListProfiledLiveRuns(ctx context.Context) ([]types.AgentRun, error)
// ReclampRunLimits writes run id's tightened limits, end and wait, but only
// while the run still has the limits, end and wait in from (the run as the
// caller read it), is not terminal and is not kept by its own end
// (LostEnded). A non-nil endTightenedAt is stamped as end_tightened_at.
// false means the run changed since it was read; the next sweep reads it
// again.
ReclampRunLimits(ctx context.Context, from types.AgentRun, toLimits types.RunLimits, toEnd *time.Time, toWait int, endTightenedAt *time.Time) (bool, error)
}
RunLimitsReclamper is the re-clamp surface. Optional like RunLeaser and for the same reason; the api layer runs no re-clamp when a store lacks it.
type RunLoser ¶ added in v0.8.0
type RunLoser interface {
// StampRunTokenRenewed records id's token renewal at the database's clock.
// false means the run is already kept (lost/ended), so the renew must be
// refused — a lost run's identity must never carry forward.
StampRunTokenRenewed(ctx context.Context, id uuid.UUID) (bool, error)
// ListLapsedTokenRuns returns every RUNNING, not-kept run whose token was
// last renewed more than life ago, by the database's clock.
ListLapsedTokenRuns(ctx context.Context, life time.Duration) ([]types.AgentRun, error)
// MarkRunLost marks id kept and lost for reason at now, only while RUNNING
// and not already kept; with tokenLife>0 it re-requires the token still
// lapsed by that much, so a race with a renew resolves to the renew.
// Exactly one caller sees true. It clears a pause only for reboot — the
// one reason whose container is truly gone — since an outage's agent
// keeps running (frozen or not) and clearing here would make resume skip
// a thaw a still-frozen agent still needs.
MarkRunLost(ctx context.Context, id uuid.UUID, reason types.LostReason, now time.Time, tokenLife time.Duration) (bool, error)
}
RunLoser is the lost-run surface, kept optional because test doubles that embed store.Store would otherwise route these calls to a nil interface; the api layer type-asserts, and production is always PG.
type RunOutput ¶ added in v0.8.6
type RunOutput struct {
RunID uuid.UUID
Output []byte
Truncated bool
Incomplete bool
CaptureGap bool
Source string // "stdout", "pane_snapshot" or "recording"
MaskScope string // "run", "globals_only" or ""
CapturedAt *time.Time
ClaimedAt time.Time
// RecordingErased is independent of found: its durable source fence remains
// after the derived row is deleted, without hiding unrelated stdout/panes.
RecordingErased bool
}
RunOutput is one row of run_outputs. CapturedAt is nil while the row is pending (a capture is owed); MaskScope is "" when the row carries none.
type RunOutputChunkStore ¶ added in v0.8.6
type RunOutputChunkStore interface {
// AppendRunOutputChunk adds b, which the caller's masker has already passed, as runID's next
// chunk, then deletes the oldest chunks until what is left is the fewest that still hold
// keep bytes. It reports false, and writes nothing, once the run's final row exists: a
// writer that was slower than the finisher never recreates what the final row replaced.
AppendRunOutputChunk(ctx context.Context, runID uuid.UUID, replica string, b []byte, keep int) (bool, error)
// ReadRunOutputChunks returns the last limit bytes of runID's chunks.
ReadRunOutputChunks(ctx context.Context, runID uuid.UUID, limit int) (RunOutputChunks, error)
// SaveChunkedRunOutput writes runID's row from its chunks, as an incomplete capture gap (what
// the replica that wrote them had not flushed is lost), and deletes them, in one transaction.
// It reports false, writing nothing, when the run has no chunks or already has a final row.
SaveChunkedRunOutput(ctx context.Context, runID uuid.UUID, maskScope string, limit int) (bool, error)
}
RunOutputChunkStore is the live-chunk record. Optional like RunOutputStore: the api layer type-asserts, and a store without it keeps the tail in the writing process only. Every method checks the run's erasure tombstone in its own transaction and answers ErrRunOutputErased.
type RunOutputChunks ¶ added in v0.8.6
RunOutputChunks is a run's live tail as stored: the chunks' bytes in order, ending at the newest. Found is false when no chunk is held. Truncated says bytes older than Bytes were printed: chunks were trimmed, or the read cut the front.
type RunOutputStore ¶ added in v0.8.6
type RunOutputStore interface {
// InsertPendingRunOutput records that a capture is owed for runID. A row
// that already exists is left as it is.
InsertPendingRunOutput(ctx context.Context, runID uuid.UUID) error
// RefreshRunOutputClaim stamps a pending row's claimed_at: the final write
// is being retried, so the sweeper must not resolve it yet.
RefreshRunOutputClaim(ctx context.Context, runID uuid.UUID) error
// SaveFinalRunOutput writes the run's final row (output, flags and
// mask_scope as given), replacing a pending or stdout capture-gap row. The
// database stamps captured_at.
SaveFinalRunOutput(ctx context.Context, o RunOutput) error
// SaveGapRunOutput writes a capture-gap row with no bytes, only over a
// pending row or none: a final row already committed is never overwritten.
// It reports whether it wrote.
SaveGapRunOutput(ctx context.Context, runID uuid.UUID) (bool, error)
// MarkRunOutputIncomplete sets incomplete on runID's final row, reporting
// whether a final row was there to mark.
MarkRunOutputIncomplete(ctx context.Context, runID uuid.UUID) (bool, error)
// GetRunOutput returns runID's row, pending or final. found is false when
// there is none.
GetRunOutput(ctx context.Context, runID uuid.UUID) (o RunOutput, found bool, err error)
// EraseRunOutputs writes a tombstone for each run and deletes its rows, in
// one transaction: all of it or none of it.
EraseRunOutputs(ctx context.Context, runIDs []uuid.UUID) error
// DeleteRunOutputsOlderThan deletes final rows captured longer ago than age
// (the database's clock), returning how many went.
DeleteRunOutputsOlderThan(ctx context.Context, age time.Duration) (int, error)
// ListStalePendingRunOutputs returns the runs whose pending row was claimed
// longer ago than age and which are terminal, oldest first, at most limit.
ListStalePendingRunOutputs(ctx context.Context, age time.Duration, limit int) ([]uuid.UUID, error)
// QueueRecordingRunOutput records recovery work after a committed upload.
// newRecording also invalidates a running claim; false is bounded read repair.
QueueRecordingRunOutput(ctx context.Context, runID uuid.UUID, retention, retryAfter time.Duration, newRecording bool) error
// ClaimRecordingRunOutput reserves one eligible terminal run; source reads
// happen after this transaction releases its connection.
ClaimRecordingRunOutput(ctx context.Context, runID uuid.UUID, retention, staleAfter time.Duration) (RecordingOutputClaim, bool, error)
// SaveRecordingRunOutput accepts only the current claim/generation and never
// replaces final direct stdout or a pane snapshot. It consumes the claim.
SaveRecordingRunOutput(ctx context.Context, claim RecordingOutputClaim, o RunOutput, retention time.Duration) (bool, error)
// ListPendingRecordingRunOutputs bounds one elected recovery pass.
ListPendingRecordingRunOutputs(ctx context.Context, staleAfter time.Duration, limit int) ([]uuid.UUID, error)
// EraseRecordingRunOutputs fences future recording-derived rows and deletes
// only that source, independently of the currently configured recording store.
EraseRecordingRunOutputs(ctx context.Context, runIDs []uuid.UUID) (int, error)
}
RunOutputStore is the run-output record. Optional like RunWatcherLeaser: the ~30 test doubles that embed Store would route these to a nil interface, so the api layer type-asserts and keeps output in memory only when a store lacks it. Production is always PG. Capture and read transactions check the general erasure tombstone; erasure and housekeeping remain permitted afterwards.
type RunPAT ¶ added in v0.8.2
type RunPAT struct {
RunID uuid.UUID
AuthorizationID uuid.UUID
Owner string // whose token: the run's creator
ProviderRowID string // the provider row the run was dispatched on
Org string // the Azure DevOps organisation the token is scoped to
Scope string // the space-joined scope string it was created with
ValidTo time.Time
CreatedAt time.Time // stamped by the store on insert; ignored on the way in
RevokedAt *time.Time // nil while Wardyn believes the token is live
RevokeReason string
LastError string // why the last revoke attempt failed; "" otherwise
}
RunPAT is one row of ado_run_pats.
type RunPATFilter ¶ added in v0.8.2
RunPATFilter narrows ListUnrevokedRunPATs; a zero field matches everything.
type RunPATReader ¶ added in v0.8.2
type RunPATReader interface {
// ListRunPATs returns every token recorded for runID, revoked or not,
// oldest first. Empty, never nil, when there is none.
ListRunPATs(ctx context.Context, runID uuid.UUID) ([]RunPAT, error)
// LastRunPAT returns the newest token recorded for owner on
// providerRowID; found=false when there is none.
LastRunPAT(ctx context.Context, owner, providerRowID string) (p RunPAT, found bool, err error)
}
RunPATReader reads the run-token record for display. Optional like RunPATStore: a store without it has no tokens to show.
type RunPATStore ¶ added in v0.8.2
type RunPATStore interface {
// InsertRunPAT records a token BEFORE its first use. ErrConflict when that
// (run, authorization id) is already recorded. CreatedAt is the store's.
InsertRunPAT(ctx context.Context, p RunPAT) error
// MarkRunPATRevoked closes a token's record: it was revoked, or its valid_to
// has passed. reason is required (one of api's adoPATRevoke* values). It
// reports whether it closed the row: false when the row is unknown or
// already closed, so two revokers race harmlessly. lastError, if non-empty,
// keeps why the last revoke attempt failed.
MarkRunPATRevoked(ctx context.Context, runID, authorizationID uuid.UUID, reason, lastError string) (bool, error)
// NoteRunPATRevokeFailed records why a revoke attempt failed and leaves the
// row OPEN, so the sweep retries and the setup check can list a token Wardyn
// could not revoke while its valid_to is ahead. A closed or unknown row is
// left as it is.
NoteRunPATRevokeFailed(ctx context.Context, runID, authorizationID uuid.UUID, lastError string) error
// ListUnrevokedRunPATs returns the tokens still recorded live that match f,
// oldest first.
ListUnrevokedRunPATs(ctx context.Context, f RunPATFilter) ([]RunPAT, error)
}
RunPATStore is the run-token record. Optional like RunPauser: it is not part of Store because the test doubles that embed Store would route these to a nil interface; the api layer type-asserts. Production is always PG; MemRunPATs is the same contract without a database. Unlike RunPauser, a caller that finds no RunPATStore must REFUSE TO MINT: a token is never created unrecorded.
type RunPauser ¶ added in v0.8.0
type RunPauser interface {
// ListPauseCandidates returns every RUNNING, not-kept run with a sandbox,
// paused or not, and the store's own clock read with them.
ListPauseCandidates(ctx context.Context) ([]PauseCandidate, time.Time, error)
// StampRunActive moves run id's presence clock to now, and reports whether
// the run is paused. A terminal or missing run is not stamped (false, nil).
StampRunActive(ctx context.Context, id uuid.UUID) (paused bool, err error)
// MarkRunPaused marks run id paused for reason, but only while it is still
// RUNNING, not kept, not paused, its presence clock still reads activeAt
// (the snapshot the caller judged idle; nil is "never stamped"), and — for
// a waiting pause — it still has a request the waiting pause counts, or —
// for an idle pause — it has no open request. The conditional UPDATE is
// what makes a keystroke, or a request closing or opening, between the
// caller's read and this write win: false means leave the run running.
MarkRunPaused(ctx context.Context, id uuid.UUID, reason types.PauseReason, activeAt *time.Time) (bool, error)
// ClearRunPaused clears run id's pause, and reports whether it was paused.
// Clearing one restarts the run's presence clock in the same write: a
// resume is the newest thing that happened to the run, so the sweep counts
// its quiet period from there and not from the stamp the pause was judged on.
ClearRunPaused(ctx context.Context, id uuid.UUID) (bool, error)
// RunHasOpenRequest reports whether run id has a PENDING request inside
// its wait.
RunHasOpenRequest(ctx context.Context, id uuid.UUID) (bool, error)
}
RunPauser is the pause surface. Optional like RunLeaser and for the same reason; the api layer runs no pause sweep, and stamps no presence, when a store lacks it. Production is always PG.
type RunProxyConfigs ¶ added in v0.8.0
type RunProxyConfigs interface {
// PutRunProxyConfig writes run id's sealed config, replacing any.
PutRunProxyConfig(ctx context.Context, id uuid.UUID, sealed []byte) error
// GetRunProxyConfig reads it; ErrNotFound when there is none.
GetRunProxyConfig(ctx context.Context, id uuid.UUID) ([]byte, error)
// DeleteRunProxyConfig removes it. Idempotent.
DeleteRunProxyConfig(ctx context.Context, id uuid.UUID) error
// PurgeTerminalRunProxyConfigs removes every row whose run is terminal,
// the backstop for a delete that failed, and returns how many it removed.
PurgeTerminalRunProxyConfigs(ctx context.Context) (int64, error)
}
RunProxyConfigs stores each run's sealed proxy config. The caller seals and opens it; the store never sees it in the clear. Optional for RunLeaser's reason: the api layer type-asserts, and production is always PG.
type RunProxyRelease ¶ added in v0.8.0
type RunProxyRelease struct {
RunID uuid.UUID `json:"run_id"`
CreatedBy string `json:"created_by"`
State types.RunState `json:"state"`
LostReason types.LostReason `json:"lost_reason,omitempty"`
Release string `json:"proxy_release"`
}
RunProxyRelease is one row of the version-window listing.
type RunQueueEntry ¶ added in v0.9.0
type RunQueueEntry struct {
RunID uuid.UUID
PoolID uuid.UUID
Owner string
QueuedAt time.Time
DeadlineAt time.Time
PolicyRef json.RawMessage
Authority json.RawMessage
Launch json.RawMessage
}
RunQueueEntry is one waiting run's queue row. PolicyRef, Authority and Launch are JSON documents the enqueue path owns; Authority and Launch are personal data and go with the row.
func ListRunQueueForUpdate ¶ added in v0.9.0
func ListRunQueueForUpdate(ctx context.Context, q Querier, poolID uuid.UUID, limit int) ([]RunQueueEntry, error)
ListRunQueueForUpdate is the promoter's scan: poolID's waiting runs oldest first (queued_at, then run_id), each row locked FOR UPDATE SKIP LOCKED so a second promoter passes over what the first holds. q must be a transaction that already holds the pool row's lock. limit <= 0 is every row.
type RunQueueFact ¶ added in v0.9.0
RunQueueFact is a waiting run's place in its pool's queue: Ahead is the number of waiting runs before it (queued_at, then run_id), a count and never whose.
type RunReviver ¶ added in v0.8.0
type RunReviver interface {
// MarkRunRevived claims run id for a new proxy: while it is RUNNING and still as the revive read
// it, live (from "") or lost to an outage or a reboot (from that reason), it clears the lost
// mark (and any unresolved containment error — the old proxy it was about is replaced), stamps
// the token as just renewed (the revive mints a fresh one, and the lapsed-token sweep must not
// read the old stamp), and refreshes the watcher lease (a stopped agent starts only after the
// new proxy, and the watcher sweep must not probe it before then).
//
// A run kept by its own end (from LostEnded) is claimed only with ended set: its exact mark,
// its files grace still live, and its end after ended.Now. It also clears a pause ONLY when
// from is a reboot: that revive restarts the agent container (docker start), so a stale pause
// mark would 409 the run's files/resources reads over an agent that's actually running. A live
// restart (from "") or an outage revive never touch the agent's own process, frozen or not, so
// their pause mark, if any, must survive for the thaw an eventual resume still needs to
// perform (a lease end already cleared the pause of a run kept by its own end).
//
// false means the run went terminal, ended, was lost or revived since, or its grace or end ran
// out (an outage-kept run's end too, as revive admission requires) — it gets no proxy.
//
// startsAgent is a revive that starts the run's stopped agent (a reboot, an end, or an
// outage whose agent was stopped). With limit > 0 its claim takes a slot under the
// deployment cap like a create does: under CreateRunUnderCap's lock,
// ErrRunCapReached when every OTHER run that holds a sandbox already reaches limit,
// the run left as it was. The row's own count is not trusted for this: an outage-kept
// run whose end was moved later reads as holding a sandbox though its agent is
// stopped. A revive that starts no agent (a live restart, an outage revive whose agent
// still runs) adds nothing and is never refused.
MarkRunRevived(ctx context.Context, id uuid.UUID, from types.LostReason, ended *EndedKept, limit int, startsAgent bool) (bool, error)
// SetRunProxyRelease records release as the one that started run id's
// proxy, once a revive's new proxy runs.
SetRunProxyRelease(ctx context.Context, id uuid.UUID, release string) error
// ListRunProxyReleases returns every non-terminal run that has a sandbox,
// with the release that started its proxy ("" before migration 0084).
ListRunProxyReleases(ctx context.Context) ([]RunProxyRelease, error)
}
RunReviver is the revive surface. Optional for RunLeaser's reason: the test doubles that embed store.Store would route these calls to a nil interface. The api layer type-asserts; production is always PG.
type RunSetupsErased ¶ added in v0.9.0
type RunSetupsErased struct {
Templates int `json:"templates"`
Grants int `json:"grants"`
AuthorshipCleared int `json:"authorship_cleared"`
// LaunchIntents is set by the caller that also erases the person's launch intents (LaunchIntentStore).
LaunchIntents int `json:"launch_intents"`
}
RunSetupsErased is what EraseRunSetupsOf removed and cleared.
type RunSizing ¶ added in v0.8.6
type RunSizing struct {
RunnerKind string
AgentCPURequestMillis int64
AgentCPULimitMillis int64
AgentMemoryRequestMiB int64
AgentMemoryLimitMiB int64
ProxyCPUMillis *int64
ProxyMemoryMiB int64
}
RunSizing is the configured reservation recorded at dispatch (migration 0117). A nil ProxyCPUMillis means the proxy had no CPU cap.
type RunTitler ¶ added in v0.8.0
type RunTitler interface {
// SetRunTitle overwrites run id's title unconditionally — a rename is
// allowed in any run state (design.md §3.4), unlike the lease's end/wait,
// so there is no state guard and no compare-and-swap here.
SetRunTitle(ctx context.Context, id uuid.UUID, title string) error
}
RunTitler is the run-rename surface (#1197 L2, design.md §3.4). Optional like RunLeaser and for the same reason: the ~30 hand-written test doubles that implement Store directly would otherwise need a mechanical update for a route most of them never exercise. The api layer type-asserts; production is always PG.
type RunWatcherLeaser ¶ added in v0.5.0
type RunWatcherLeaser interface {
ClaimStaleRunWatchers(ctx context.Context, owner string, staleAfter time.Duration) ([]types.AgentRun, error)
HeartbeatRunWatcher(ctx context.Context, id uuid.UUID, owner string) error
// RunWatcherFresh reports whether id's lease heartbeat is younger than
// staleAfter (a live process owns it). The undispatched-run reaper checks
// this so it never false-fails a RUNNING run whose sandbox_ref write was
// lost but whose watcher still holds the lease. Missing row = not fresh (reap it).
RunWatcherFresh(ctx context.Context, id uuid.UUID, staleAfter time.Duration) (bool, error)
}
RunWatcherLeaser is deliberately not part of Store (like Pager): ~30 test doubles embed store.Store overriding only a few methods, so widening Store would route lease writes to the embedded nil interface inside the watcher goroutine, whose recover() would swallow the panic and kill it silently. The api layer type-asserts and skips leasing when a store lacks this; PG always has it.
type RunnerAtCapacityError ¶ added in v0.9.0
RunnerAtCapacityError names the runner and its Runs at once for the sentence; it is ErrRunnerAtCapacity. NeverFits says the run could not go there however empty the runner is: it is past the per-run limit, or the runner declares no limits.
func (*RunnerAtCapacityError) Error ¶ added in v0.9.0
func (e *RunnerAtCapacityError) Error() string
func (*RunnerAtCapacityError) Unwrap ¶ added in v0.9.0
func (e *RunnerAtCapacityError) Unwrap() error
type RunnerContainment ¶ added in v0.9.0
RunnerContainment identifies the exact kept incarnation requiring H3's durable stop_proxy queue. Only an exact action_result may settle that action.
type RunnerContainmentProof ¶ added in v0.9.0
type RunnerContainmentProof struct {
RunnerContainment
ActionID uuid.UUID
ObservedAt time.Time
}
RunnerContainmentProof contains org-persisted action bindings, not values selected by a runner's action_result or inferred from the latest run. H3 stores LostAt/Generation with the queued action and supplies them unchanged. Nil Generation explicitly means no execution had been issued; the committing transaction must still find no execution row, never infer a latest generation.
type RunnerExecution ¶ added in v0.9.0
type RunnerExecution struct {
RunID uuid.UUID
RunnerID uuid.UUID
Generation uuid.UUID
Operation string
ExecID string
}
RunnerExecution is an org-issued execution intent. An empty ExecID requires explicit reconciliation of the ambiguous command result before exit ingestion.
type RunnerExitWork ¶ added in v0.9.0
RunnerExitWork is durable staged or accepted work. Only a bound matching handle can be applied; ambiguous results wait for H3 reconciliation.
type RunnerInventoryResult ¶ added in v0.9.0
type RunnerInventoryResult struct {
Complete bool
NeedsReconciliation bool
// AssertedCapHeld reports a page that met a new asserted subject past
// the runner's cap: nothing was queued and the runner stays not-ready.
AssertedCapHeld bool
}
RunnerInventoryResult describes committed intake, not permission to dispatch. Reconciliation requirements are durable even if the caller loses its reply.
type RunnerInventoryStore ¶ added in v0.9.0
type RunnerInventoryStore interface {
RunnerStore
// ListRunnersPage lists the runners the filter names, newest first, never an unclaimed one that
// has outlived its wait at now (the sweeper may not have deleted the row yet).
ListRunnersPage(ctx context.Context, filter types.RunnerFilter, now time.Time, p Page) ([]types.Runner, error)
// ListUnusedRunnerRegistrationTokensPage lists tokens redeemable at now, newest first, for one
// owner or, with owner "", every owner.
ListUnusedRunnerRegistrationTokensPage(ctx context.Context, now time.Time, owner string, p Page) ([]types.RunnerRegistrationToken, error)
RevokeRunnerRegistrationToken(ctx context.Context, id uuid.UUID, now time.Time) (types.RunnerRegistrationToken, error)
// RunnerSlotHolders counts the runs holding a sandbox on each of ids, the count max_runs bounds.
RunnerSlotHolders(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]int, error)
// RunnerUsage is each named runner's In use, by key (a self-hosted runner's id as text, or a
// remote-hosted runner's id): the figures admission counts, read without a lock.
RunnerUsage(ctx context.Context, runners []uuid.UUID, remotes []string, except uuid.UUID) (map[string]types.RunnerTally, error)
// RunnerPoolsOf names, for each of ids, its owner's live Self-Hosted pools it is a member of, by
// name; a runner in none is absent.
RunnerPoolsOf(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID][]types.RunnerPoolRef, error)
// UpdateRunnerLimits is the owner's declaration of their own live runner's limits.
UpdateRunnerLimits(ctx context.Context, id uuid.UUID, owner string, limits types.RunnerLimits) (before *types.RunnerLimits, after types.Runner, err error)
}
RunnerInventoryStore is the optional capability behind the runners management routes: a page of the inventory, the unused registration tokens and the count of runs on each runner. Revoking a runner is the revoke door's, not this one's.
type RunnerKilledRun ¶ added in v0.9.0
RunnerKilledRun is one run a runner revocation ended KILLED.
type RunnerPoolCatalogueRow ¶ added in v0.9.0
type RunnerPoolCatalogueRow struct {
Pool types.RunnerPool
Policy *types.RunnerPoolUsePolicy
ExecutorIDs []string
OwnRunners int
OwnRunnerIDs []uuid.UUID
}
RunnerPoolCatalogueRow is one live pool with what the API needs to decide who may use it and whether it can take a run right now: its use policy, its remote-hosted members (ExecutorIDs, their ids), how many of the caller's own claimed runners it holds, and which of the caller's own runners (in any state) are its members.
type RunnerPoolDeletion ¶ added in v0.9.0
type RunnerPoolDeletion struct {
Pool types.RunnerPool
ExecutorIDs []string
RunnerCount int
OrgDefaultsBefore *types.RunnerPoolDefaults
OrgDefaultsAfter *types.RunnerPoolDefaults
// CancelledRuns are the runs that were waiting for the pool and were ended KILLED with it.
CancelledRuns []uuid.UUID
}
RunnerPoolDeletion is what a delete removed, for its audit row: the pool as it was, the executors and the count of runners it held, and the organisation defaults before and after when the delete cleared a slot that named it.
type RunnerPoolFullError ¶ added in v0.9.0
RunnerPoolFullError names the pool and its cap for the sentence; it is ErrRunnerPoolFull.
func (*RunnerPoolFullError) Error ¶ added in v0.9.0
func (e *RunnerPoolFullError) Error() string
func (*RunnerPoolFullError) Unwrap ¶ added in v0.9.0
func (e *RunnerPoolFullError) Unwrap() error
type RunnerPoolStore ¶ added in v0.9.0
type RunnerPoolStore interface {
// ListRunnerPoolCatalogue is the live organization pools and owner's own user pools; with all,
// every person's user pools too, for oversight.
ListRunnerPoolCatalogue(ctx context.Context, owner string, all bool) ([]RunnerPoolCatalogueRow, error)
GetRunnerPool(ctx context.Context, id uuid.UUID) (types.RunnerPool, error)
// ListRunnerPoolMembers is every member of a pool: only the admission fold reads it, and only through
// runnerpool.OwnRunnerCandidates.
ListRunnerPoolMembers(ctx context.Context, id uuid.UUID) ([]types.RunnerPoolMember, error)
CreateRunnerPool(ctx context.Context, p types.RunnerPool, by string) (types.RunnerPool, error)
UpdateRunnerPool(ctx context.Context, id uuid.UUID, revision int64, name *string, state *types.RunnerPoolState, limits *types.RunnerPoolLimits) (types.RunnerPool, error)
DeleteRunnerPool(ctx context.Context, id uuid.UUID) (RunnerPoolDeletion, error)
DeleteRunnerPoolsByOwner(ctx context.Context, owner string) ([]RunnerPoolDeletion, error)
AddRunnerPoolExecutor(ctx context.Context, id uuid.UUID, executor string) (m types.RunnerPoolMember, added bool, revision int64, err error)
RemoveRunnerPoolExecutor(ctx context.Context, id uuid.UUID, executor string, refuseGoverned bool) (removed bool, revision int64, err error)
AddOwnRunnerToPool(ctx context.Context, id, runnerID uuid.UUID, owner, orgURLSHA256 string) (m types.RunnerPoolMember, added bool, revision int64, err error)
RemoveOwnRunnerFromPool(ctx context.Context, id, runnerID uuid.UUID, owner string) (removed bool, revision int64, err error)
// AddRemoteRunnerToUserPool puts a remote-hosted runner in owner's own live user pool, only while
// the runner's revision is still peopleRevision, the one whose people policy the caller checked.
AddRemoteRunnerToUserPool(ctx context.Context, id uuid.UUID, remoteRunner, owner string, peopleRevision int64) (m types.RunnerPoolMember, added bool, revision int64, err error)
RemoveRemoteRunnerFromUserPool(ctx context.Context, id uuid.UUID, remoteRunner, owner string) (removed bool, revision int64, err error)
PutRunnerPoolUsePolicy(ctx context.Context, id uuid.UUID, revision *int64, subjects []types.RunnerPoolSubject, by string) (types.RunnerPoolUsePolicy, error)
DeleteRunnerPoolUsePolicy(ctx context.Context, id uuid.UUID) error
GetRunnerPoolOrgDefaults(ctx context.Context) (types.RunnerPoolDefaults, error)
PutRunnerPoolOrgDefaults(ctx context.Context, d types.RunnerPoolDefaults, by string) error
BootstrapRunnerPools(ctx context.Context, executors []string, name string) (*types.RunnerPool, *types.RunnerPoolDefaults, error)
}
RunnerPoolStore is the optional store capability behind the runner pool routes: a store without it answers them 501, as RunnerStore does.
type RunnerRegistrationStore ¶ added in v0.9.0
type RunnerRegistrationStore interface {
RunnerStore
MintRunnerRegistrationToken(context.Context, string, types.RunnerRegistrationToken) (types.RunnerRegistrationToken, error)
ConsumeRunnerRegistrationToken(context.Context, string, string, time.Time) (types.RunnerRegistrationToken, bool, error)
}
RunnerRegistrationStore is the optional capability behind the registration doors. A store without it cannot mint or redeem registration tokens.
type RunnerRevocation ¶ added in v0.9.0
type RunnerRevocation struct {
Runner types.Runner
Killed []RunnerKilledRun
}
RunnerRevocation is what one committed revoke did: the revoked runner and the runs it ended KILLED (RN-Q29), each with the state it was killed from.
type RunnerStore ¶ added in v0.9.0
type RunnerStore interface {
CreateRunner(ctx context.Context, r types.Runner) (types.Runner, error)
GetRunner(ctx context.Context, id uuid.UUID) (types.Runner, error)
ListRunners(ctx context.Context) ([]types.Runner, error)
ListRunnersByOwner(ctx context.Context, owner string) ([]types.Runner, error)
ClaimRunner(ctx context.Context, id uuid.UUID, owner, fingerprint string, now time.Time) (types.Runner, error)
TouchRunner(ctx context.Context, id uuid.UUID, version string, now time.Time) error
RecordRunnerPosture(ctx context.Context, id uuid.UUID, p types.RunnerPosture, now time.Time) (changed bool, err error)
RevokeRunner(ctx context.Context, id uuid.UUID, now time.Time, by, reason string) (RunnerRevocation, error)
ExpireUnclaimedRunners(ctx context.Context, createdBefore time.Time) (int, error)
QueueRunnerAction(ctx context.Context, a types.RunnerPendingAction) (action types.RunnerPendingAction, queued bool, err error)
ListPendingRunnerActions(ctx context.Context, runnerID uuid.UUID) (page []types.RunnerPendingAction, more bool, err error)
RunHasPendingRunnerAction(ctx context.Context, runID uuid.UUID) (bool, error)
RecordRunnerActionResult(ctx context.Context, runnerID, runID, actionID uuid.UUID, outcome, reason string, observedAt time.Time, prepare func(context.Context, types.AuditEvent) (types.AuditEvent, error)) (action types.RunnerPendingAction, first bool, err error)
GetCredentialDeliveryPolicy(ctx context.Context) (types.CredentialDeliveryPolicyDoc, error)
PutCredentialDeliveryPolicy(ctx context.Context, policy json.RawMessage, by string, now time.Time) (types.CredentialDeliveryPolicyDoc, error)
}
RunnerStore is the optional store capability behind client mode, optional like DeviceStore: a fake or a non-Postgres store implements it or the runner routes answer 501.
type RunsByCreatorOrSponsorPager ¶ added in v0.9.0
type RunsByCreatorOrSponsorPager interface {
ListRunsPageByCreatorOrSponsor(ctx context.Context, principal string, p Page) ([]types.AgentRun, error)
}
RunsByCreatorOrSponsorPager is RunsByCreatorPager widened to the runs of the service identities the caller sponsors (#1508): a sponsor reads those runs. Optional; a store without it lists a sponsor's own runs only, never more.
type RunsByCreatorPager ¶ added in v0.5.0
type RunsByCreatorPager interface {
ListRunsPageByCreator(ctx context.Context, createdBy string, p Page) ([]types.AgentRun, error)
}
RunsByCreatorPager is the ownership-scoped analogue of Pager.ListRunsPage: a member's GET /runs is scoped to created_by = the caller. TRUST BOUNDARY: unlike Pager, an absent implementation must fail closed (500), not fall back to the unscoped list — an unscoped list IS the vulnerability here.
type RunsFilteredPager ¶ added in v0.8.0
type RunsFilteredPager interface {
ListRunsFiltered(ctx context.Context, f RunFilter, p Page) ([]types.AgentRun, error)
// CountHiddenRuns answers the X-Wardyn-Hidden-* headers: rows baseWhere
// matches but ended_within excludes (olderHidden), plus rows
// killedVisibleFor additionally excludes (killedHidden) — one query.
CountHiddenRuns(ctx context.Context, f RunFilter) (olderHidden, killedHidden int, err error)
}
RunsFilteredPager is the landing-page scoping surface for GET /runs. Kept out of Pager/Store: widening either would silently route a test double's embedded method to the wrong (unscoped) behaviour. An absent implementation fails CLOSED at the api-layer call site, same as RunsByCreatorPager — a silent unscoped fallback would leak every run to a caller the filter was meant to narrow.
type SSHKeysByPrincipalPager ¶ added in v0.8.0
type SSHKeysByPrincipalPager interface {
ListSSHKeysByPrincipalPage(ctx context.Context, principal string, p Page) ([]types.SSHPublicKey, error)
}
SSHKeysByPrincipalPager is the scoped analogue of Pager for GET /me/ssh-keys, same safe-fallback posture as GrantsByRunPager (ListSSHKeysByPrincipal is already WHERE principal=$1).
type ScimGroup ¶ added in v0.8.6
ScimGroup is a group the identity provider reported. ExternalID is the provider's id for it.
type ScimGroupStore ¶ added in v0.8.6
type ScimGroupStore interface {
CreateScimGroup(ctx context.Context, externalID, displayName string, now time.Time) (ScimGroup, error)
GetScimGroup(ctx context.Context, id uuid.UUID) (ScimGroup, error)
SearchScimGroups(ctx context.Context, attr, value string, limit int) ([]ScimGroup, error)
RenameScimGroup(ctx context.Context, id uuid.UUID, displayName string) error
ScimGroupMembers(ctx context.Context, id uuid.UUID) ([]uuid.UUID, error)
// AddScimGroupMembers records identities as members, skipping any id that names no identity.
AddScimGroupMembers(ctx context.Context, id uuid.UUID, identities []uuid.UUID, now time.Time) error
StartGroupRemoval(ctx context.Context, groupID, identityID uuid.UUID) error
ResumeGroupRemoval(ctx context.Context, groupID, identityID uuid.UUID) (bool, error)
GroupRemovalIdentities(ctx context.Context, groupID uuid.UUID) ([]uuid.UUID, error)
DeleteScimGroup(ctx context.Context, id uuid.UUID) error
PendingGroupRemovals(ctx context.Context, idleFor time.Duration, limit int) ([]PendingGroupRemoval, error)
GroupRemovalFailures(ctx context.Context, limit int) ([]DeprovisionFailure, error)
}
ScimGroupStore is optional, like LeaverStore: callers type-assert it.
type ServiceIdentityChange ¶ added in v0.9.0
ServiceIdentityChange is a PATCH: the fields that are not nil change.
type ServiceIdentityChanged ¶ added in v0.9.0
type ServiceIdentityChanged struct {
Before, After types.ServiceIdentity
TokensRevoked int
}
ServiceIdentityChanged is what a committed change did.
func UpdateServiceIdentityQ ¶ added in v0.9.0
func UpdateServiceIdentityQ(ctx context.Context, tx Querier, name string, ch ServiceIdentityChange) (ServiceIdentityChanged, error)
UpdateServiceIdentityQ is UpdateServiceIdentity's statements on tx (a pgx.Tx), which a held governance change applies inside the decision transaction.
type ServiceIdentityStore ¶ added in v0.9.0
type ServiceIdentityStore interface {
// CreateServiceIdentity inserts si, or refuses with ErrServiceNameTaken or ErrServiceSponsorInvalid.
CreateServiceIdentity(ctx context.Context, si types.ServiceIdentity) (types.ServiceIdentity, error)
// GetServiceIdentity is the row named name, or ErrNotFound.
GetServiceIdentity(ctx context.Context, name string) (types.ServiceIdentity, error)
// ListServiceIdentities returns identities by name, narrowed to sponsor when it is not empty.
ListServiceIdentities(ctx context.Context, sponsor string, p Page) ([]types.ServiceIdentity, error)
// UpdateServiceIdentity applies ch to a non-retired identity. A sponsor change sets sponsor_since and
// revokes every live token of the identity in the same transaction. ErrNotFound, ErrServiceIdentityInactive
// (retired) and ErrServiceSponsorInvalid are the refusals.
UpdateServiceIdentity(ctx context.Context, name string, ch ServiceIdentityChange) (ServiceIdentityChanged, error)
// RetireServiceIdentity retires a non-retired identity and revokes its live tokens in one transaction.
RetireServiceIdentity(ctx context.Context, name, by string) (ServiceIdentityChanged, error)
// CreateServiceToken inserts t, a token of service:<name>, only while the identity is active, its
// sponsor is still sponsor and it holds fewer than maxLive live tokens, counted in the same
// transaction under a row lock that serialises concurrent mints: ErrNotFound for no such identity,
// ErrServiceIdentityInactive, or ErrServiceTokenCap.
CreateServiceToken(ctx context.Context, name, sponsor string, maxLive int, t types.APIToken, raw string) (types.APIToken, error)
// ServiceStillSponsored reports whether name is usable, still sponsored by sponsor, and not re-sponsored
// since openedAt, an application-clock instant that is translated to the database clock sponsor_since
// is written on.
ServiceStillSponsored(ctx context.Context, name, sponsor string, openedAt time.Time) (bool, error)
}
ServiceIdentityStore holds service identities (migration 0157, #1508). Optional, like PersonStore: the API answers 501 on a store without it.
type Store ¶
type Store interface {
// AgentRun.
CreateRun(ctx context.Context, r types.AgentRun) (types.AgentRun, error)
GetRun(ctx context.Context, id uuid.UUID) (types.AgentRun, error)
ListRuns(ctx context.Context) ([]types.AgentRun, error)
// CountActiveRunsBy counts one creator's non-terminal runs — the governance quota's read
// (GovernanceLimits.MaxConcurrentRuns). Called only when an assigned profile sets a cap.
CountActiveRunsBy(ctx context.Context, createdBy string) (int, error)
UpdateRunStateIf(ctx context.Context, id uuid.UUID, fromState, toState types.RunState) (bool, error)
UpdateRunStateIfIdle(ctx context.Context, id uuid.UUID, fromState, toState types.RunState, notAfter time.Time) (bool, error)
SetSandboxRef(ctx context.Context, id uuid.UUID, ref string) error
SetRunImage(ctx context.Context, id uuid.UUID, image string) error
SetRunDiskMiB(ctx context.Context, id uuid.UUID, mib int) error
SetRunAgentExecID(ctx context.Context, id uuid.UUID, execID string) error
TouchRun(ctx context.Context, id uuid.UUID) error
// RunPolicy.
CreatePolicy(ctx context.Context, p types.RunPolicy) (types.RunPolicy, error)
GetPolicy(ctx context.Context, id uuid.UUID) (types.RunPolicy, error)
ListPolicies(ctx context.Context) ([]types.RunPolicy, error)
UpdatePolicy(ctx context.Context, id uuid.UUID, name string, spec types.RunPolicySpec) (types.RunPolicy, error)
DeletePolicy(ctx context.Context, id uuid.UUID) error
// Workspace.
CreateWorkspace(ctx context.Context, ws types.Workspace) (types.Workspace, error)
GetWorkspace(ctx context.Context, id uuid.UUID) (types.Workspace, error)
ListWorkspaces(ctx context.Context) ([]types.Workspace, error)
// UpdateWorkspace writes the full column set, CARRYING ws.EgressEditedAt rather than stamping
// it, or ReconcileWorkspaceEgressDecisions could re-widen a list the operator just cleared.
// stampEgressEdit lets the ONE caller that clears the list say so, stamped by the DATABASE like
// every other writer of that column.
UpdateWorkspace(ctx context.Context, id uuid.UUID, ws types.Workspace, stampEgressEdit bool) (types.Workspace, error)
// SetWorkspaceApprovedEgress replaces the approved-egress list and stamps EgressEditedAt: the
// documented undo for an `always` decision, stopping the boot heal from re-adding a removed host.
SetWorkspaceApprovedEgress(ctx context.Context, id uuid.UUID, domains []string) (types.Workspace, error)
// AddWorkspaceEgressDecision records one `always`-scoped decision: on allow, host moves into
// approved_egress (capped, deduped) and out of denied_egress; on deny the mirror. ErrConflict
// (not ErrNotFound) when the cap refuses the write. Does NOT stamp EgressEditedAt — a decision
// isn't an operator override of itself.
AddWorkspaceEgressDecision(ctx context.Context, id uuid.UUID, host string, allow bool, maxApprovedEgress int) (types.Workspace, error)
// SetWorkspaceDeniedEgress mirrors SetWorkspaceApprovedEgress for denied-egress: pass the FULL
// desired list, replacing rather than merging.
SetWorkspaceDeniedEgress(ctx context.Context, id uuid.UUID, domains []string) (types.Workspace, error)
SetWorkspaceLLMCred(ctx context.Context, id uuid.UUID, cred *types.WorkspaceLLMCred) (types.Workspace, error)
// SetWorkspaceOwner replaces ONLY owned_by (offboarding: reassign a departed member's workspace
// to the operator via owner ""). Scoped and separate from UpdateWorkspace so no ordinary edit
// can move ownership or race a concurrent async scan.
SetWorkspaceOwner(ctx context.Context, id uuid.UUID, owner string) (types.Workspace, error)
SetWorkspaceRequirements(ctx context.Context, id uuid.UUID, reqs map[string]types.WorkspaceRequirement) (types.Workspace, error)
SetWorkspaceRecordResult(ctx context.Context, id uuid.UUID, taskKey string, result json.RawMessage, onlyIfStatus string) (types.Workspace, bool, error)
ClaimWorkspaceActiveRun(ctx context.Context, id, runID uuid.UUID, expected *uuid.UUID) (types.Workspace, bool, error)
ClearWorkspaceActiveRun(ctx context.Context, id, runID uuid.UUID) (bool, error)
// SetWorkspaceBuiltImage writes image_ref, built_profile_hash and the build record by one compare-and-swap
// on observedRef; applied=false means another build moved image_ref first.
SetWorkspaceBuiltImage(ctx context.Context, id uuid.UUID, observedRef, imageRef, builtHash string, rec *types.ImageBuild) (applied bool, err error)
// SetWorkspaceImportState advances the scan pipeline. FENCED: applies only while the import-step
// slot still holds expectedActive; applied=false means the caller must re-read, not retry blindly.
SetWorkspaceImportState(ctx context.Context, id uuid.UUID, status types.WorkspaceStatus, activeRunID *uuid.UUID, expectedActive *uuid.UUID) (types.Workspace, bool, error)
// MergeWorkspaceRequirements ADDS overlay rows atomically (jsonb ||), safe against concurrent
// edits the full-replace SetWorkspaceRequirements would race. ErrConflict at the key cap.
MergeWorkspaceRequirements(ctx context.Context, id uuid.UUID, add map[string]types.WorkspaceRequirement) (types.Workspace, error)
DeleteWorkspace(ctx context.Context, id uuid.UUID) error
// Source library (tier 1) — a repo/dir configured once, attached to many workspaces. Upsert
// dedupes on (kind, locator, ref).
UpsertSource(ctx context.Context, src types.Source) (types.Source, error)
GetSource(ctx context.Context, id uuid.UUID) (types.Source, error)
GetSourcesByIDs(ctx context.Context, ids []uuid.UUID) (map[uuid.UUID]types.Source, error)
ListSources(ctx context.Context) ([]types.Source, error)
UpdateSourceConfig(ctx context.Context, id uuid.UUID, name string, reqs map[string]types.WorkspaceRequirement) (types.Source, error)
WorkspacesAttaching(ctx context.Context, id uuid.UUID) ([]string, error)
DeleteSource(ctx context.Context, id uuid.UUID, detach bool) error
ClaimSourceActiveRun(ctx context.Context, id, runID uuid.UUID) error
ClearSourceActiveRun(ctx context.Context, id, runID uuid.UUID) error
SetSourceScanResult(ctx context.Context, id uuid.UUID, profile []byte, status types.WorkspaceStatus, runID uuid.UUID, seed map[string]types.WorkspaceRequirement) (types.Source, error)
SetSourceScanResultUnfenced(ctx context.Context, id uuid.UUID, profile []byte, status types.WorkspaceStatus, seed map[string]types.WorkspaceRequirement) (types.Source, error)
// Base-image catalog (tier 2). Upsert dedupes on (kind, image, steps); "recommended" is
// structurally excluded (CHECK) — it is a per-workspace derived build, never a catalog row.
UpsertBaseImage(ctx context.Context, b types.BaseImageEntry) (types.BaseImageEntry, error)
// UpdateBaseImageName renames a catalog row — the operator-editable counterpart to
// UpdateSourceConfig above, deliberately NOT folded into UpsertBaseImage's identity-hit dedupe.
UpdateBaseImageName(ctx context.Context, id uuid.UUID, name string) (types.BaseImageEntry, error)
ListBaseImages(ctx context.Context) ([]types.BaseImageEntry, error)
WorkspacesUsingBaseImage(ctx context.Context, id uuid.UUID) ([]string, error)
DeleteBaseImage(ctx context.Context, id uuid.UUID, detach bool) error
// CredentialGrant.
CreateGrant(ctx context.Context, g types.CredentialGrant) (types.CredentialGrant, error)
ListGrantsByRun(ctx context.Context, runID uuid.UUID) ([]types.CredentialGrant, error)
// ApprovalRequest.
CreateApproval(ctx context.Context, a types.ApprovalRequest) (types.ApprovalRequest, error)
GetApproval(ctx context.Context, id uuid.UUID) (types.ApprovalRequest, error)
ListApprovals(ctx context.Context, stateFilter types.ApprovalState) ([]types.ApprovalRequest, error)
// DecideApproval transitions state from PENDING to decision.State; returns
// ErrAlreadyDecided if the approval is not PENDING. See types.ApprovalDecision.
DecideApproval(ctx context.Context, id uuid.UUID, decision types.ApprovalDecision) (types.ApprovalRequest, error)
// AuditEvent.
QueryAuditEvents(ctx context.Context, runID uuid.UUID, limit int) ([]types.AuditEvent, error)
QueryRecentAuditEvents(ctx context.Context, limit int) ([]types.AuditEvent, error)
LatestAuditEventByAction(ctx context.Context, action string) (types.AuditEvent, error)
// SiteConfig.
GetSiteConfig(ctx context.Context) (types.SiteConfig, error)
PutSiteConfig(ctx context.Context, cfg types.SiteConfig) (types.SiteConfig, error)
// Sandbox ref -> substrate routing (the orchestrator's RefStore seam; see
// store_sandbox_ref.go). GetRef reports a missing row as found=false, nil.
PutRef(ctx context.Context, ref, substrateName string) error
GetRef(ctx context.Context, ref string) (substrateName string, found bool, err error)
DeleteRef(ctx context.Context, ref string) error
// Short-lived cross-process handoff row (see store_ephemeral.go): single-use WS attach tickets.
// Consume-once, and the consumer is a single DELETE ... RETURNING, so two racing redemptions —
// on one control plane or two — can only have one win.
MintAttachTicket(ctx context.Context, token string, t AttachTicket, now, expiresAt time.Time) error
ConsumeAttachTicket(ctx context.Context, token string, now time.Time) (AttachTicket, bool, error)
// SSH gateway key registry (migration 0033, self-service via /api/v1/me/ssh-keys). AddSSHKey
// returns ErrConflict on a taken fingerprint (the PK; one key maps to one owner). DeleteSSHKey is
// scoped to principal (someone else's key is ErrNotFound, no existence leak). GetSSHKeyByFingerprint
// is the gateway's unscoped auth-time lookup. RefreshSSHKeyRoles re-stamps role+role_checked_at
// (migration 0046) from the OIDC OnLogin hook, bounding the admin-override stamp's staleness.
AddSSHKey(ctx context.Context, k types.SSHPublicKey) (types.SSHPublicKey, error)
ListSSHKeysByPrincipal(ctx context.Context, principal string) ([]types.SSHPublicKey, error)
GetSSHKeyByFingerprint(ctx context.Context, fingerprint string) (types.SSHPublicKey, error)
DeleteSSHKey(ctx context.Context, fingerprint, principal string) error
// DeleteSSHKeys removes one principal's keys, or all keys when principal is empty.
DeleteSSHKeys(ctx context.Context, principal string) (int, error)
RefreshSSHKeyRoles(ctx context.Context, principal, role string, checkedAt time.Time) error
// RefreshAPITokenIdentity re-stamps role, user type and the group snapshot (plus its completeness
// bit) on every unrevoked api_tokens row a principal holds, from the same OnLogin hook as
// RefreshSSHKeyRoles — neither credential had a way to learn about a demotion or group change.
RefreshAPITokenIdentity(ctx context.Context, principal, role, userType string, groups []string, truncated bool) error
// Per-user API tokens (migration 0045). SECURITY: GetAPITokenByRaw is the
// third auth branch on every authenticated route.
//
// CreateAPIToken/GetAPITokenByRaw hash the plaintext token internally — the raw value never
// reaches SQL. GetAPITokenByRaw returns ErrNotFound for unknown, mismatched, revoked AND expired
// tokens alike, so it's not an existence oracle. RevokeAPIToken is principal-scoped when non-empty
// (self-service; someone else's id is ErrNotFound) and revokes ANY token when empty (admin).
// TouchAPIToken is best effort — its error must never fail a request.
CreateAPIToken(ctx context.Context, t types.APIToken, raw string) (types.APIToken, error)
GetAPITokenByRaw(ctx context.Context, raw string) (types.APIToken, error)
TouchAPIToken(ctx context.Context, id uuid.UUID, now time.Time) error
ListAPITokensByPrincipal(ctx context.Context, principal string) ([]types.APIToken, error)
ListAPITokens(ctx context.Context) ([]types.APIToken, error)
RevokeAPIToken(ctx context.Context, id uuid.UUID, principal string, now time.Time) (types.APIToken, error)
// Capability grants and the per-kind enforcement switch (migration 0042).
// SECURITY: the resolver runs on the request path; the fail mode is a
// fail-open authz gate hiding in an untyped test double.
UpsertCapabilityGrant(ctx context.Context, g types.CapabilityGrant) (types.CapabilityGrant, error)
DeleteCapabilityGrant(ctx context.Context, id uuid.UUID) error
ListCapabilityGrants(ctx context.Context) ([]types.CapabilityGrant, error)
// ListGroupDenyGrants returns the group-subject DENY rows of one kind, the only rows the
// unresolvable-group-deny refusal can match — separate from ListCapabilityGrants so that
// request-path check doesn't cost scale with table size.
ListGroupDenyGrants(ctx context.Context, capability string) ([]types.CapabilityGrant, error)
// ListCapabilityGrantsFor returns the grants that could apply to one caller: `all` rows plus
// `user` rows naming any of users (sub AND email) plus `group` rows naming any of groups plus
// `user_type` rows naming userType. Not filtered by capability — see the implementation.
ListCapabilityGrantsFor(ctx context.Context, users, groups []string, userType string) ([]types.CapabilityGrant, error)
// GetCapabilityEnforcement returns the sparse per-kind switch map; an absent key means NOT
// enforced, the zero-config back-compat default.
GetCapabilityEnforcement(ctx context.Context) (map[string]bool, error)
// PutCapabilityEnforcement replaces the WHOLE map (a capability the caller omits loses its row)
// and returns the stored result.
PutCapabilityEnforcement(ctx context.Context, enabled map[string]bool) (map[string]bool, error)
// ListCapabilityRestrictions returns the restricted values ("Available to: Only...", migration
// 0081) as kind -> set of values; an absent value is not restricted. Never nil.
ListCapabilityRestrictions(ctx context.Context) (map[string]map[string]bool, error)
// SetCapabilityRestriction turns one value's restriction on or off (idempotent either way).
SetCapabilityRestriction(ctx context.Context, capability, value string, restricted bool, by string) error
// Console-managed role mappings (migration 0051): the store half of internal/auth/oidc's
// RoleMappingSource, read once per login and merged with the chart's WARDYN_OIDC_ROLE_MAP.
// SECURITY: on the OIDC login path; the fail mode is silently falling back
// to env-only, WIDENING who derives admin under WARDYN_OIDC_DEFAULT_ROLE=admin.
//
// UpsertRoleMapping keys on the natural UNIQUE (value): re-adding an already-mapped value flips
// its role in place, returning the EXISTING row's id on a conflict (never the candidate's).
UpsertRoleMapping(ctx context.Context, m types.RoleMapping) (types.RoleMapping, error)
DeleteRoleMapping(ctx context.Context, id uuid.UUID) error
// ListRoleMappings returns every row, oldest first — the console's People
// screen and the OIDC login-time merge's whole data need.
ListRoleMappings(ctx context.Context) ([]types.RoleMapping, error)
// User types (migration 0071_user_types). CreateUserType and
// UpdateUserType return ErrConflict on a taken id or name; DeleteUserType
// returns ErrConflict while the type is built in or still named by a
// subject row (UserTypeReferences counts those).
ListUserTypes(ctx context.Context) ([]types.UserType, error)
GetUserType(ctx context.Context, id string) (types.UserType, error)
CreateUserType(ctx context.Context, t types.UserType) (types.UserType, error)
UpdateUserType(ctx context.Context, t types.UserType) (types.UserType, error)
// UpdateUserTypeMetadata is UpdateUserType without the priority column.
UpdateUserTypeMetadata(ctx context.Context, t types.UserType) (types.UserType, error)
UserTypeReferences(ctx context.Context, id string) (int, error)
// UserTypeTokenStamps counts the unrevoked API tokens stamped with the type.
UserTypeTokenStamps(ctx context.Context, id string) (int, error)
DeleteUserType(ctx context.Context, id string) error
// Launch presets (migration 0087, store_launch_presets.go). PutLaunchPreset
// is an upsert by name that moves the version only when the row changes.
ListLaunchPresets(ctx context.Context) ([]types.LaunchPreset, error)
GetLaunchPreset(ctx context.Context, name string) (types.LaunchPreset, error)
PutLaunchPreset(ctx context.Context, p types.LaunchPreset) (types.LaunchPreset, PresetWrite, error)
DeleteLaunchPreset(ctx context.Context, name string) (types.LaunchPreset, error)
// Governance profiles and their subject assignments (migration 0052): the assignable ceiling
// that replaces Config.DefaultPolicy for a principal an admin has named.
// SECURITY: on the run-creation request path; the fail mode is falling
// back to the deployment-wide ceiling, past the floor an admin set.
//
// UpsertGovernanceProfile keys on the PRIMARY KEY (a fresh id inserts, an existing one updates
// in place, rename included) and returns ErrConflict when UNIQUE(name) rejects the write.
// DeleteGovernanceProfile returns ErrConflict when the profile is still ASSIGNED — the ON DELETE
// RESTRICT, so deleting a profile can never silently widen its members.
UpsertGovernanceProfile(ctx context.Context, p types.GovernanceProfile) (types.GovernanceProfile, error)
// WriteGovernanceProfile is the graph-aware write: one transaction under the profile-graph
// lock, where build decides the stored row from every profile as that transaction reads them
// (migration 0125: a profile may be composed on another). DeleteGovernanceProfile also
// returns *ErrProfileHasChildren when another profile composes on the row.
WriteGovernanceProfile(ctx context.Context, id uuid.UUID, build GovernanceProfileBuild) (types.GovernanceProfile, error)
DeleteGovernanceProfile(ctx context.Context, id uuid.UUID) error
// ListGovernanceProfiles and GetGovernanceProfileChain return RAW rows: a composed row
// carries no authority of its own. Only internal/api/governance_compose.go calls them for
// authority (a source guard fails any other caller); GetGovernanceProfileChain is one
// statement, leaf first, bounded at depth 3, and ErrNotFound when the leaf is gone.
ListGovernanceProfiles(ctx context.Context) ([]types.GovernanceProfile, error)
GetGovernanceProfileChain(ctx context.Context, id uuid.UUID) ([]types.GovernanceProfile, error)
// UpsertGovernanceAssignment keys on the natural UNIQUE (subject_type,
// subject): re-assigning a subject REPOINTS its one row, returning the
// EXISTING row's id on a conflict. ErrNotFound when profile_id names no
// profile (the FK rejects it).
UpsertGovernanceAssignment(ctx context.Context, a types.GovernanceAssignment) (types.GovernanceAssignment, error)
DeleteGovernanceAssignment(ctx context.Context, id uuid.UUID) error
ListGovernanceAssignments(ctx context.Context) ([]types.GovernanceAssignment, error)
// Governance changes (migration 0126): a governance write held for a second human. Part of
// this interface, not an optional seam, because a store without them would let a covered write
// through unreviewed. See governance_changes.go for each one's contract.
ProposeGovernanceChange(ctx context.Context, ch types.GovernanceChange, ttl time.Duration) (types.GovernanceChange, []ExpiredGovernanceChange, error)
ListGovernanceChanges(ctx context.Context, state string) ([]types.GovernanceChange, error)
GetGovernanceChange(ctx context.Context, id uuid.UUID) (types.GovernanceChange, error)
DecideGovernanceChange(ctx context.Context, id uuid.UUID, d GovernanceDecision, fn GovernanceDecideFunc) (types.GovernanceChange, error)
// DryRunGovernance runs fn on a transaction that is always rolled back.
DryRunGovernance(ctx context.Context, fn func(q Querier) error) error
// ResolveGovernanceProfile returns THE ONE profile that applies to a caller — user > group >
// user_type > all, sub over email within the user tier, then priority DESC and name ASC — as a
// single indexed read whose ORDER BY is the whole precedence rule. ErrNotFound means "no
// assignment matched", read as the deployment ceiling. userSubjects must arrive in the caller's
// own precedence order since the query matches by POSITION.
//
// Also returns WHICH TIER matched, load-bearing not informational: on a
// stale/truncated group snapshot the caller must tell a user-tier winner
// (serve it) from an all-tier one (refuse), indistinguishable from the
// profile alone. HasGroupTierAssignments below is that separate read.
ResolveGovernanceProfile(ctx context.Context, userSubjects, groups []string, userType string) (*types.GovernanceProfile, types.CapabilitySubjectType, error)
// HasGroupTierAssignments gates the stale/truncated group-snapshot refusal:
// with no group-tier row there is nothing an unknown group could have
// matched, so a nil or truncated snapshot must fall through rather than
// refuse (see the implementation).
HasGroupTierAssignments(ctx context.Context) (bool, error)
// User drives and their subject grants (migration 0054): admin-registered per-user storage a
// member may mount into a run, and the rows allocating one to a user, group, or everyone.
// SECURITY: same reason as the governance resolver above.
//
// UpsertUserDrive keys on the PRIMARY KEY (fresh id inserts, existing updates in place, rename
// included) and returns ErrConflict when UNIQUE(name) rejects the write. DeleteUserDrive returns
// ErrConflict while the drive is still ALLOCATED (ON DELETE RESTRICT).
//
// refuseIfAllocated is a PRECONDITION: the write applies only while the
// drive has no allocations (ErrDriveAllocated otherwise) — the API's
// re-home guard re-asserts, inside the writing statement, the read
// decision that permitted the write.
UpsertUserDrive(ctx context.Context, d types.UserDrive, refuseIfAllocated bool) (types.UserDrive, error)
GetUserDrive(ctx context.Context, id uuid.UUID) (types.UserDrive, error)
DeleteUserDrive(ctx context.Context, id uuid.UUID) error
// ListUserDrives returns every drive by name WITH its grant count — what makes the console's
// delete affordance honest, since a drive with grants answers 409.
ListUserDrives(ctx context.Context) ([]types.UserDriveListItem, error)
// UpsertUserDriveGrant keys on the natural UNIQUE (subject_type, subject, drive_id): writing a
// subject's grant on a drive again updates that row, returning the EXISTING row's id on a
// conflict; another drive is another row. ErrNotFound when
// drive_id names no drive (FK). ErrConflict when ANOTHER subject already holds this drive with
// the same home_override — a directory name is one person's, and on a managed drive an override
// is the last way left to point two people at one object Wardyn creates.
//
// homeOverrideStated is the REQUEST's tri-state, not the row's: false means the caller never
// mentioned home_override, and an update that never mentioned it must not CLEAR one (see the
// guard in PG's statement) — that same ErrConflict, distinguished from the uniqueness one purely
// by this argument (a stated override disables the re-home guard; an unstated one is empty).
UpsertUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, error)
// DeleteUserDriveGrant RETURNS the row it removed (ErrNotFound when none
// matched): the delete's own audit row has to name the subject that was
// de-allocated, and by then it is gone.
DeleteUserDriveGrant(ctx context.Context, id uuid.UUID) (types.UserDriveGrant, error)
ListUserDriveGrants(ctx context.Context) ([]types.UserDriveGrant, error)
// ResolveUserDrive mirrors ResolveGovernanceProfile's precedence and
// stale-snapshot reasoning. DISABLED grants stay IN the query: one that
// wins its tier comes back Enabled false, rendered PAUSED rather than
// falling through (a pause must never widen a member onto an unchosen
// drive). Returns the winning GRANT beside the drive since every override
// lives on the binding row. ErrNotFound means "no drive".
ResolveUserDrive(ctx context.Context, userSubjects, groups []string, userType string) (
*types.UserDrive, *types.UserDriveGrant, types.CapabilitySubjectType, error)
// HasGroupTierDriveGrants gates the stale/truncated group-snapshot refusal:
// with no group-tier row there is nothing an unknown group could have
// matched, so a nil or truncated snapshot must fall through rather than
// refuse (see the implementation).
HasGroupTierDriveGrants(ctx context.Context) (bool, error)
// Ping proves the store is actually reachable, not just constructed — the
// /readyz readiness probe's one call. A live TCP connect with no working
// query would otherwise read as healthy forever.
Ping(ctx context.Context) error
}
Store is the abstract persistence seam the control plane talks to. The default Postgres implementation is PG (query bodies in store.go); a future pure-Go SQLite backend satisfies this same interface unchanged.
Out of scope on purpose: transactional surfaces (broker mint FOR UPDATE, identity revocation) need a real transaction and stay on the pool directly.
SECURITY: several method groups below are deliberately part of this interface, not a type-asserted optional seam, because they run on a request-path authz decision — a test double that doesn't implement them would be a compile error instead of a silent fail-open degrade. Each such group is marked SECURITY below with its specific failure mode.
type SuspendPlan ¶ added in v0.8.6
type SuspendPlan struct {
IdentityID uuid.UUID
// Principal is the principal IdentityID's row bound when the plan was made ("" for none). A row that
// binds another under the suspension's lock is ErrIdentityRebound, and nothing is written.
Principal string
// Principals are the principals whose identity rows are deactivated with IdentityID's and whose
// people rows get deactivated_at.
Principals []string
// CutoffSubs are every sub and email form a session cutoff is written for.
CutoffSubs []string
// PurgeAfter schedules the automatic purge that long after the deactivation. Zero schedules
// none; an earlier schedule is kept.
PurgeAfter time.Duration
// PurgePrincipals are the principals whose identity rows the purge is scheduled for with IdentityID's:
// the person's own. A row of Principals not among them is deactivated and never scheduled.
PurgePrincipals []string
// PendingJobs are added as pending ledger rows in the same transaction, so a crash after the
// commit still leaves the rest of the suspension for the sweeper. Existing rows are kept.
PendingJobs []JobKey
}
SuspendPlan is what step 1 of a suspension writes, all in one transaction.
type SuspendResult ¶ added in v0.8.6
SuspendResult is step 1's outcome. WasActive says the identity was active before it, so this was a new suspension and not the repair of an old one.
type TemplateGrantCheck ¶ added in v0.9.0
TemplateGrantCheck asks a group write to re-read the writer's grant inside its own transaction. Persons are every subject the writer is known by (an administrator may have granted either their sub or their email).
type TemplateLimitError ¶ added in v0.9.0
type TemplateLimitError struct{ Limit int }
TemplateLimitError: the audience already holds Limit templates.
func (*TemplateLimitError) Error ¶ added in v0.9.0
func (e *TemplateLimitError) Error() string
type TemplateRevisionConflictError ¶ added in v0.9.0
type TemplateRevisionConflictError struct{ Current int }
TemplateRevisionConflictError: the template is at Current, not the revision the update expected. Nothing was written.
func (*TemplateRevisionConflictError) Error ¶ added in v0.9.0
func (e *TemplateRevisionConflictError) Error() string
type TemplateStore ¶ added in v0.9.0
type TemplateStore interface {
// ListTemplatesVisible returns the current revision of every organisation
// template, of person's own, and of the groups' templates, by name.
ListTemplatesVisible(ctx context.Context, person string, groups []string) ([]types.RunTemplate, error)
// GetTemplate returns the current revision; ErrNotFound when absent.
GetTemplate(ctx context.Context, id uuid.UUID) (types.RunTemplate, error)
// GetTemplateRevision returns one saved revision, with that revision's own
// saver and time as UpdatedBy and UpdatedAt; ErrNotFound when the template or
// that revision is absent.
GetTemplateRevision(ctx context.Context, id uuid.UUID, revision int) (types.RunTemplate, error)
// CreateTemplate inserts t at revision 1 under the id the caller chose.
// *TemplateLimitError when the audience is full, ErrTemplateNameTaken on a
// name the audience already uses, ErrTemplateGrantGone when grant finds no row.
CreateTemplate(ctx context.Context, t types.RunTemplate, grant *TemplateGrantCheck) (types.RunTemplate, error)
// UpdateTemplate saves t's name, description and document as the next
// revision when the row is at expected; *TemplateRevisionConflictError (and
// nothing written) otherwise. ErrNotFound, ErrTemplateNameTaken and
// ErrTemplateGrantGone as for create.
UpdateTemplate(ctx context.Context, t types.RunTemplate, expected int, grant *TemplateGrantCheck) (types.RunTemplate, error)
// DeleteTemplate removes the template and every revision, and returns the
// row it removed (without a document).
DeleteTemplate(ctx context.Context, id uuid.UUID, grant *TemplateGrantCheck) (types.RunTemplate, error)
// The group-management grants. Put stores the grant as given, which the
// caller has made canonical, and a non-empty Label as the group's label.
ListTemplateGroupAdmins(ctx context.Context) ([]types.TemplateGroupAdmin, error)
PutTemplateGroupAdmin(ctx context.Context, g types.TemplateGroupAdmin) (types.TemplateGroupAdmin, error)
DeleteTemplateGroupAdmin(ctx context.Context, group, person string) (bool, error)
// TemplateGroupAdminGroups lists the groups any of persons holds a grant on.
TemplateGroupAdminGroups(ctx context.Context, persons []string) ([]string, error)
// TemplateGroupLabels returns the labels of those of groups that have one.
TemplateGroupLabels(ctx context.Context, groups []string) (map[string]string, error)
// EraseRunSetupsOf is the run_setups erasure scope: person's own templates
// (with their revisions) and grants go, and their name is blanked wherever
// it is the author of a shared template, a revision or a grant.
EraseRunSetupsOf(ctx context.Context, person string) (RunSetupsErased, error)
}
TemplateStore persists run templates (migration 0165_run_templates); bodies in store_run_templates.go. Optional like ComponentStore: callers type-assert, and a caller that finds it absent answers 501 templates_unavailable rather than pretending to store anything.
The store does not authorise: the API checks types.TemplateAuthorize first. What the store holds for it is what must sit in the write's own transaction: a group write's grant re-read (TemplateGrantCheck, FOR SHARE), the audience limit counted under a named lock, and the revision compare-and-set.
type TokenDispositionFacts ¶ added in v0.9.0
type TokenDispositionFacts struct {
Replacements map[uuid.UUID][]TokenReplacement
Moves map[uuid.UUID]types.TokenMove
}
TokenDispositionFacts is everything a disposition is derived from beside the token row itself.
type TokenMoveStore ¶ added in v0.9.0
type TokenMoveStore interface {
// MoveAPIToken links a live admin-minted token to a non-retired service identity, replacing an earlier
// link. It never revokes. ErrNotFound is no such token; ErrTokenNotMovable, ErrMoveTargetUnknown and
// ErrServiceIdentityInactive (retired) are the refusals.
MoveAPIToken(ctx context.Context, id uuid.UUID, serviceIdentity, by string, now time.Time) (types.TokenMove, error)
// TokenDispositionFacts reads the invitations that replace tokens and the move rows, at now.
TokenDispositionFacts(ctx context.Context, now time.Time) (TokenDispositionFacts, error)
}
TokenMoveStore holds the links between admin-minted tokens and the service identities that replace them (api_token_moves, migration 0157, #1508). Optional, like InvitationStore.
type TokenReplacement ¶ added in v0.9.0
type TokenReplacement struct {
TokenID uuid.UUID
Target string
ClaimedAt *time.Time // nil while pending
}
TokenReplacement is an invitation that names a token as the one its claim replaces, only while pending or once claimed: a revoked or expired one decides nothing about the token.
type UserDriveCatalogueStore ¶ added in v0.9.0
type UserDriveCatalogueStore interface {
// ResolveUserDrives returns, for each drive any of the caller's grants
// names, the grant that wins THAT drive, ranked across drives by the same
// precedence ResolveUserDrive uses, so its first entry is ResolveUserDrive's
// answer. Disabled grants stay in: a disabled winner comes back Enabled
// false and never falls through to a wider grant on the same drive. Empty,
// never ErrNotFound, when nothing matches.
ResolveUserDrives(ctx context.Context, userSubjects, groups []string, userType string) ([]UserDriveWinner, error)
}
UserDriveCatalogueStore resolves every drive a caller reaches. Like PrincipalPrefStore it is not part of Store, so the api test doubles need not grow it; the api type-asserts and treats its absence as "no drives".
type UserDriveGrantTierWriter ¶ added in v0.9.0
type UserDriveGrantTierWriter interface {
UpsertUserDriveGrantWithinTier(ctx context.Context, g types.UserDriveGrant, homeOverrideStated, additional bool) (types.UserDriveGrant, []uuid.UUID, error)
}
UserDriveGrantTierWriter is the allocation write for a caller whose authority stops at the drive's own posture. Optional like PersonStore; a caller without it must refuse the write.
type UserDriveGrantWidensError ¶ added in v0.9.0
type UserDriveGrantWidensError struct{ Field string }
UserDriveGrantWidensError is UpsertUserDriveGrantWithinTier's refusal: Field is what the write would widen (types.DriveGrantWidens). Nothing was written.
func (*UserDriveGrantWidensError) Error ¶ added in v0.9.0
func (e *UserDriveGrantWidensError) Error() string
type UserDriveGrantWriter ¶ added in v0.9.0
type UserDriveGrantWriter interface {
AddUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, error)
ReplaceUserDriveGrant(ctx context.Context, g types.UserDriveGrant, homeOverrideStated bool) (types.UserDriveGrant, []uuid.UUID, error)
}
UserDriveGrantWriter is POST /drives/grants' two verbs: AddUserDriveGrant allocates a drive beside a subject's others (additional), and ReplaceUserDriveGrant is UpsertUserDriveGrant returning the drives the subject lost, for the audit row. Optional like UserDriveCatalogueStore.
type UserDriveWinner ¶ added in v0.9.0
type UserDriveWinner struct {
Drive types.UserDrive
Grant types.UserDriveGrant
}
UserDriveWinner is one drive a caller reaches and the grant that wins it. The tier is Grant.SubjectType.
type WorkspacesByOwnerPager ¶ added in v0.6.0
type WorkspacesByOwnerPager interface {
ListWorkspacesPageForOwner(ctx context.Context, owner string, p Page) ([]types.Workspace, error)
}
WorkspacesByOwnerPager is the ownership-scoped analogue of Pager.ListWorkspacesPage: a member's GET /workspaces sees their own owned rows plus the operator-owned ones (owned_by = ”), never another member's. Unlike RunsByCreatorPager, an absent implementation is not fail-closed: the api-layer fallback applies the same owned_by filter in Go before windowing, so scoping still holds.
Source Files
¶
- audit_delivery.go
- auditchain.go
- auditfilter.go
- auditpartition.go
- auditretention.go
- auditsplit.go
- doc_keys.go
- governance.go
- governance_changes.go
- iface.go
- locker.go
- member_drives.go
- pagination.go
- querier.go
- recorder.go
- revocation_order.go
- store.go
- store_ado_run_pats.go
- store_ado_run_pats_read.go
- store_ado_signin_ends.go
- store_apitokens.go
- store_approval_notify.go
- store_approval_once.go
- store_approval_replay.go
- store_approvals_for_runs.go
- store_attach_leases.go
- store_audit_subject.go
- store_branding.go
- store_capabilities.go
- store_components.go
- store_components_restricted.go
- store_delegates.go
- store_devices.go
- store_ephemeral.go
- store_erasure.go
- store_identity_guard.go
- store_invitations.go
- store_launch_intents.go
- store_launch_presets.go
- store_leaver.go
- store_leaver_purge.go
- store_people.go
- store_people_directory.go
- store_principal_identities.go
- store_principal_prefs.go
- store_push_paths.go
- store_reauth.go
- store_remote_runners.go
- store_role_mappings.go
- store_run_capacity.go
- store_run_harnesses.go
- store_run_lease.go
- store_run_lost.go
- store_run_output_chunks.go
- store_run_output_recording.go
- store_run_outputs.go
- store_run_pause.go
- store_run_proxy_config.go
- store_run_queue.go
- store_run_queue_counts.go
- store_run_queue_promote.go
- store_run_reclamp.go
- store_run_revive.go
- store_run_state_cas.go
- store_run_templates.go
- store_run_title.go
- store_runner_actions.go
- store_runner_activity.go
- store_runner_arch.go
- store_runner_asserted.go
- store_runner_containment.go
- store_runner_execution.go
- store_runner_exit.go
- store_runner_exit_stage.go
- store_runner_inventory.go
- store_runner_limits.go
- store_runner_pools.go
- store_runner_refusal.go
- store_runner_registration.go
- store_runner_spool.go
- store_runner_state.go
- store_runners.go
- store_runs_filtered.go
- store_sandbox_ref.go
- store_scim_groups.go
- store_service_identities.go
- store_sources.go
- store_sshkeys.go
- store_token_moves.go
- store_ui_layout.go
- store_user_types.go
- store_watcher.go
- store_workspaces.go
- subject_tier.go
- user_drives.go
- user_drives_per_drive.go