agent

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 12, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package agent defines the Agent domain entity for scanner/collector/agent management.

Package agent defines domain errors for agent-related operations.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAgentNotFound is returned when an agent is not found.
	ErrAgentNotFound = fmt.Errorf("%w: agent not found", shared.ErrNotFound)

	// ErrAgentAlreadyExists is returned when an agent with the same name exists.
	ErrAgentAlreadyExists = fmt.Errorf("%w: agent already exists", shared.ErrAlreadyExists)

	// ErrAgentDisabled is returned when trying to use a disabled agent.
	ErrAgentDisabled = fmt.Errorf("%w: agent is disabled", shared.ErrForbidden)

	// ErrAgentRevoked is returned when trying to use a revoked agent.
	ErrAgentRevoked = fmt.Errorf("%w: agent access has been revoked", shared.ErrForbidden)

	// ErrAgentLimitReached is returned when the agent limit for a tenant is reached.
	ErrAgentLimitReached = fmt.Errorf("%w: agent limit reached for this plan", shared.ErrForbidden)

	// ErrAgentNoCapacity is returned when an agent has no capacity for more jobs.
	ErrAgentNoCapacity = fmt.Errorf("%w: agent has no capacity for more jobs", shared.ErrConflict)

	// ErrInvalidAPIKey is returned when an API key is invalid.
	ErrInvalidAPIKey = fmt.Errorf("%w: invalid API key", shared.ErrUnauthorized)
)
View Source
var (
	// ErrPlatformAgentNotFound is returned when a platform agent is not found.
	ErrPlatformAgentNotFound = fmt.Errorf("%w: platform agent not found", shared.ErrNotFound)

	// ErrNoPlatformAgentAvailable is returned when no platform agent is available.
	ErrNoPlatformAgentAvailable = fmt.Errorf("%w: no platform agent available", shared.ErrConflict)

	// ErrAllPlatformAgentsOverloaded is returned when agents exist but all are at capacity.
	ErrAllPlatformAgentsOverloaded = fmt.Errorf("%w: all platform agents are at capacity", shared.ErrConflict)

	// ErrPlatformAgentAccessDenied is returned when tenant doesn't have platform agent access.
	ErrPlatformAgentAccessDenied = fmt.Errorf("%w: platform agent access not included in plan", shared.ErrForbidden)

	// ErrPlatformConcurrentLimitReached is returned when concurrent platform job limit is reached.
	ErrPlatformConcurrentLimitReached = fmt.Errorf("%w: concurrent platform job limit reached", shared.ErrConflict)

	// ErrPlatformQueueLimitReached is returned when queue limit is reached.
	ErrPlatformQueueLimitReached = fmt.Errorf("%w: platform job queue limit reached", shared.ErrConflict)

	// ErrPlatformJobNotFound is returned when a platform job is not found.
	ErrPlatformJobNotFound = fmt.Errorf("%w: platform job not found", shared.ErrNotFound)

	// ErrInvalidAuthToken is returned when the command auth token is invalid.
	ErrInvalidAuthToken = fmt.Errorf("%w: invalid command auth token", shared.ErrUnauthorized)

	// ErrAuthTokenExpired is returned when the command auth token has expired.
	ErrAuthTokenExpired = fmt.Errorf("%w: command auth token has expired", shared.ErrUnauthorized)

	// ErrAgentMismatch is returned when agent ID doesn't match the command's assigned agent.
	ErrAgentMismatch = fmt.Errorf("%w: agent not authorized for this command", shared.ErrForbidden)
)
View Source
var (
	// ErrBootstrapTokenNotFound is returned when a bootstrap token is not found.
	ErrBootstrapTokenNotFound = fmt.Errorf("%w: bootstrap token not found", shared.ErrNotFound)

	// ErrBootstrapTokenExpired is returned when a bootstrap token has expired.
	ErrBootstrapTokenExpired = fmt.Errorf("%w: bootstrap token has expired", shared.ErrForbidden)

	// ErrBootstrapTokenRevoked is returned when a bootstrap token has been revoked.
	ErrBootstrapTokenRevoked = fmt.Errorf("%w: bootstrap token has been revoked", shared.ErrForbidden)

	// ErrBootstrapTokenExhausted is returned when a bootstrap token has reached its usage limit.
	ErrBootstrapTokenExhausted = fmt.Errorf("%w: bootstrap token usage limit reached", shared.ErrForbidden)

	// ErrBootstrapTokenInvalid is returned when a bootstrap token is invalid.
	ErrBootstrapTokenInvalid = fmt.Errorf("%w: invalid bootstrap token", shared.ErrUnauthorized)

	// ErrAgentConstraintViolation is returned when agent doesn't meet token constraints.
	ErrAgentConstraintViolation = fmt.Errorf("%w: agent does not meet token constraints", shared.ErrValidation)
)

Functions

func CollectorScopes

func CollectorScopes() []string

CollectorScopes returns scopes for a collector.

func DefaultAgentScopes

func DefaultAgentScopes() []string

DefaultAgentScopes returns default scopes for an agent.

func IsAgentNotFound

func IsAgentNotFound(err error) bool

IsAgentNotFound checks if the error is an agent not found error.

func IsAllPlatformAgentsOverloaded

func IsAllPlatformAgentsOverloaded(err error) bool

IsAllPlatformAgentsOverloaded checks if all platform agents are at capacity.

func IsAuthTokenError

func IsAuthTokenError(err error) bool

IsAuthTokenError checks if the error is an auth token error.

func IsBootstrapTokenError

func IsBootstrapTokenError(err error) bool

IsBootstrapTokenError checks if the error is a bootstrap token error.

func IsNoPlatformAgentAvailable

func IsNoPlatformAgentAvailable(err error) bool

IsNoPlatformAgentAvailable checks if the error indicates no platform agent is available.

func IsPlatformAgentNotFound

func IsPlatformAgentNotFound(err error) bool

IsPlatformAgentNotFound checks if the error is a platform agent not found error.

func IsPlatformLimitReached

func IsPlatformLimitReached(err error) bool

IsPlatformLimitReached checks if the error is a platform limit error.

func RunnerScopes

func RunnerScopes() []string

RunnerScopes returns scopes for a runner (CI/CD).

func SensorScopes

func SensorScopes() []string

SensorScopes returns scopes for a sensor (EASM).

func WorkerScopes

func WorkerScopes() []string

WorkerScopes returns scopes for a worker (daemon).

Types

type APIKey

type APIKey struct {
	ID        shared.ID
	AgentID   shared.ID
	Name      string
	KeyHash   string
	KeyPrefix string
	Scopes    []string

	// Lifecycle
	ExpiresAt  *time.Time
	LastUsedAt *time.Time
	LastUsedIP string
	UseCount   int64

	// Status
	IsActive      bool
	RevokedAt     *time.Time
	RevokedReason string

	// Timestamps
	CreatedAt time.Time
}

APIKey represents an API key for an agent.

func NewAPIKey

func NewAPIKey(agentID shared.ID, name string, scopes []string) (*APIKey, error)

NewAPIKey creates a new API key entity.

func (*APIKey) HasAnyScope

func (k *APIKey) HasAnyScope(scopes ...APIKeyScope) bool

HasAnyScope checks if the key has any of the specified scopes.

func (*APIKey) HasScope

func (k *APIKey) HasScope(scope APIKeyScope) bool

HasScope checks if the key has a specific scope.

func (*APIKey) IsExpired

func (k *APIKey) IsExpired() bool

IsExpired checks if the key is expired.

func (*APIKey) IsValid

func (k *APIKey) IsValid() bool

IsValid checks if the key is valid (active and not expired).

func (*APIKey) RecordUsage

func (k *APIKey) RecordUsage(ip string)

RecordUsage records a usage of the API key.

func (*APIKey) Revoke

func (k *APIKey) Revoke(reason string)

Revoke revokes the API key.

func (*APIKey) SetExpiration

func (k *APIKey) SetExpiration(expiresAt time.Time)

SetExpiration sets the expiration time.

func (*APIKey) SetKeyHash

func (k *APIKey) SetKeyHash(hash, prefix string)

SetKeyHash sets the key hash and prefix.

type APIKeyFilter

type APIKeyFilter struct {
	AgentID  *shared.ID
	IsActive *bool
}

APIKeyFilter represents filter options for listing API keys.

type APIKeyRepository

type APIKeyRepository interface {
	// Create creates a new API key.
	Create(ctx context.Context, key *APIKey) error

	// GetByID retrieves an API key by ID.
	GetByID(ctx context.Context, id shared.ID) (*APIKey, error)

	// GetByHash retrieves an API key by hash.
	GetByHash(ctx context.Context, hash string) (*APIKey, error)

	// GetByAgentID retrieves all API keys for an agent.
	GetByAgentID(ctx context.Context, agentID shared.ID) ([]*APIKey, error)

	// List lists API keys with filters.
	List(ctx context.Context, filter APIKeyFilter) ([]*APIKey, error)

	// Update updates an API key.
	Update(ctx context.Context, key *APIKey) error

	// Delete deletes an API key.
	Delete(ctx context.Context, id shared.ID) error

	// RecordUsage records API key usage.
	RecordUsage(ctx context.Context, id shared.ID, ip string) error

	// Revoke revokes an API key.
	Revoke(ctx context.Context, id shared.ID, reason string) error

	// CountActiveByAgentID counts active keys for an agent.
	CountActiveByAgentID(ctx context.Context, agentID shared.ID) (int, error)
}

APIKeyRepository defines the interface for API key persistence.

type APIKeyScope

type APIKeyScope string

APIKeyScope represents a permission scope for API keys.

const (
	ScopeIngestWrite    APIKeyScope = "ingest:write"     // Push findings and assets
	ScopeIngestRead     APIKeyScope = "ingest:read"      // Read ingested data
	ScopeCommandsRead   APIKeyScope = "commands:read"    // Poll for pending commands
	ScopeCommandsExec   APIKeyScope = "commands:execute" // Execute commands and report results
	ScopeCommandsWrite  APIKeyScope = "commands:write"   // Create commands (admin only)
	ScopeAgentHeartbeat APIKeyScope = "agent:heartbeat"  // Send heartbeat/status updates
	ScopeAgentRead      APIKeyScope = "agent:read"       // Read own agent config
	ScopeAgentWrite     APIKeyScope = "agent:write"      // Update own agent config
	ScopeAdminAgents    APIKeyScope = "admin:agents"     // Manage other agents
	ScopeAdminKeys      APIKeyScope = "admin:keys"       // Manage API keys
	ScopeAdminTokens    APIKeyScope = "admin:tokens"     // Manage registration tokens
)

type Agent

type Agent struct {
	ID            shared.ID
	TenantID      *shared.ID // nil for platform agents (is_platform_agent = true)
	Name          string
	Type          AgentType
	Description   string
	Capabilities  []string
	Tools         []string // Specific tools: semgrep, trivy, nuclei, nmap, etc.
	ExecutionMode ExecutionMode
	Status        AgentStatus // Admin-controlled: active, disabled, revoked
	Health        AgentHealth // Automatic heartbeat: unknown, online, offline, error
	StatusMessage string

	// Platform agent flag (SaaS model)
	// Platform agents are managed by OpenCTEM and don't count towards tenant's agent limit.
	// Tenants can use platform agents for their scans without provisioning their own.
	IsPlatformAgent bool

	// API key for authentication
	APIKeyHash   string
	APIKeyPrefix string

	// Metadata and configuration
	Labels   map[string]interface{}
	Config   map[string]interface{}
	Metadata map[string]interface{}

	// Runtime info
	Version   string
	Hostname  string
	IPAddress net.IP

	// System metrics (from heartbeat)
	CPUPercent        float64
	MemoryPercent     float64
	DiskReadMBPS      float64 // Disk read throughput in MB/s
	DiskWriteMBPS     float64 // Disk write throughput in MB/s
	NetworkRxMBPS     float64 // Network receive throughput in MB/s
	NetworkTxMBPS     float64 // Network transmit throughput in MB/s
	LoadScore         float64 // Computed weighted load score (lower is better)
	MetricsUpdatedAt  *time.Time
	ActiveJobs        int
	CurrentJobs       int
	MaxConcurrentJobs int
	Region            string

	// Statistics
	LastSeenAt    *time.Time // Last heartbeat timestamp - effectively "last online time"
	LastOfflineAt *time.Time // When agent went offline (heartbeat timeout)
	LastErrorAt   *time.Time
	TotalFindings int64
	TotalScans    int64
	ErrorCount    int64

	// Timestamps
	CreatedAt time.Time
	UpdatedAt time.Time
}

Agent represents a registered agent (runner, worker, collector, or sensor).

func NewAgent

func NewAgent(
	tenantID shared.ID,
	name string,
	agentType AgentType,
	description string,
	capabilities []string,
	tools []string,
	executionMode ExecutionMode,
) (*Agent, error)

NewAgent creates a new tenant-owned Agent entity.

func (*Agent) Activate

func (a *Agent) Activate()

Activate activates the agent.

func (*Agent) AvailableSlots

func (a *Agent) AvailableSlots() int

AvailableSlots returns the number of available job slots.

func (*Agent) CanExecutePlatformJob

func (a *Agent) CanExecutePlatformJob(capabilities []string, tool, preferredRegion string) bool

CanExecutePlatformJob checks if this platform agent can execute a job with the given requirements.

func (*Agent) ComputeLoadScore

func (a *Agent) ComputeLoadScore() float64

ComputeLoadScore calculates the weighted load score for agent selection. Lower score = better candidate for receiving new jobs. Formula: score = (w1 * job_load) + (w2 * cpu) + (w3 * memory) + (w4 * io_score) + (w5 * net_score)

func (*Agent) ComputeLoadScoreWithWeights

func (a *Agent) ComputeLoadScoreWithWeights(weights LoadBalancingWeights) float64

ComputeLoadScoreWithWeights calculates load score with custom weights.

func (*Agent) Disable

func (a *Agent) Disable(reason string)

Disable disables the agent (admin action).

func (*Agent) HasCapability

func (a *Agent) HasCapability(cap string) bool

HasCapability checks if the agent has a specific capability.

func (*Agent) HasCapacity

func (a *Agent) HasCapacity() bool

HasCapacity checks if the agent has capacity for more jobs.

func (*Agent) HasTool

func (a *Agent) HasTool(tool string) bool

HasTool checks if the agent has a specific tool.

func (*Agent) IncrementFindings

func (a *Agent) IncrementFindings(count int64)

IncrementFindings increments the total findings counter.

func (*Agent) IncrementScans

func (a *Agent) IncrementScans()

IncrementScans increments the total scans counter.

func (*Agent) IsAvailable

func (a *Agent) IsAvailable() bool

IsAvailable checks if the agent is available for work.

func (*Agent) IsDaemon

func (a *Agent) IsDaemon() bool

IsDaemon checks if the agent is a daemon (polls for commands).

func (*Agent) IsOneShot

func (a *Agent) IsOneShot() bool

IsOneShot checks if the agent is a one-shot runner (CI/CD).

func (*Agent) LoadFactor

func (a *Agent) LoadFactor() float64

LoadFactor returns the current load factor (0.0 to 1.0).

func (*Agent) MatchesRequirements

func (a *Agent) MatchesRequirements(capabilities []string, tool string) bool

MatchesRequirements checks if the agent matches the given requirements.

func (*Agent) RecordError

func (a *Agent) RecordError(message string)

RecordError records an error and updates error timestamp.

func (*Agent) Revoke

func (a *Agent) Revoke(reason string)

Revoke revokes the agent access.

func (*Agent) ScoreForJob

func (a *Agent) ScoreForJob(capabilities []string, tool, preferredRegion string) int

ScoreForJob calculates a score for job matching (higher is better). Used for selecting the best platform agent for a job.

func (*Agent) SetAPIKey

func (a *Agent) SetAPIKey(hash, prefix string)

SetAPIKey sets the hashed API key and prefix.

func (*Agent) SetMaxConcurrentJobs

func (a *Agent) SetMaxConcurrentJobs(max int)

SetMaxConcurrentJobs sets the maximum number of concurrent jobs.

func (*Agent) SetPlatformAgent

func (a *Agent) SetPlatformAgent(isPlatform bool)

SetPlatformAgent marks this agent as a platform-managed agent. Platform agents don't count towards tenant's agent limit.

func (*Agent) SetStatus

func (a *Agent) SetStatus(status AgentStatus, message string)

SetStatus sets the agent status.

func (*Agent) UpdateExtendedMetrics

func (a *Agent) UpdateExtendedMetrics(metrics ExtendedMetrics)

UpdateExtendedMetrics updates all system metrics from heartbeat including disk I/O and network.

func (*Agent) UpdateLastSeen

func (a *Agent) UpdateLastSeen()

UpdateLastSeen updates the last seen timestamp and sets health to online.

func (*Agent) UpdateMetrics

func (a *Agent) UpdateMetrics(cpuPercent, memoryPercent float64, activeJobs int, region string)

UpdateMetrics updates system metrics from heartbeat.

func (*Agent) UpdateRuntimeInfo

func (a *Agent) UpdateRuntimeInfo(version, hostname string, ip net.IP)

UpdateRuntimeInfo updates runtime information from heartbeat.

type AgentHealth

type AgentHealth string

AgentHealth represents the AUTOMATIC health state based on heartbeat. This is for monitoring only, does NOT affect authentication.

const (
	AgentHealthUnknown AgentHealth = "unknown" // Never seen (just registered)
	AgentHealthOnline  AgentHealth = "online"  // Recently sent heartbeat
	AgentHealthOffline AgentHealth = "offline" // No recent heartbeat
	AgentHealthError   AgentHealth = "error"   // Last operation had errors
)

func (AgentHealth) IsValid

func (h AgentHealth) IsValid() bool

IsValid checks if the agent health is valid.

type AgentStatus

type AgentStatus string

AgentStatus represents the ADMIN-CONTROLLED status of an agent. This determines whether the agent is ALLOWED to authenticate.

const (
	AgentStatusActive   AgentStatus = "active"   // Agent is enabled (can authenticate)
	AgentStatusDisabled AgentStatus = "disabled" // Admin disabled (cannot authenticate)
	AgentStatusRevoked  AgentStatus = "revoked"  // Access permanently revoked
)

func (AgentStatus) CanAuthenticate

func (s AgentStatus) CanAuthenticate() bool

CanAuthenticate checks if the status allows authentication.

func (AgentStatus) IsValid

func (s AgentStatus) IsValid() bool

IsValid checks if the agent status is valid.

type AgentType

type AgentType string

AgentType represents the type of agent. The platform supports 4 main component types:

  • runner: CI/CD one-shot scans (execution_mode: standalone)
  • worker: Server-controlled daemon (execution_mode: daemon)
  • collector: Data collection agent (execution_mode: daemon)
  • sensor: External Attack Surface Monitoring (EASM)
const (
	// Primary types
	AgentTypeRunner    AgentType = "runner"    // CI/CD one-shot scans
	AgentTypeWorker    AgentType = "worker"    // Server-controlled daemon
	AgentTypeCollector AgentType = "collector" // Data collection agent
	AgentTypeSensor    AgentType = "sensor"    // EASM sensor
)

func (AgentType) DefaultExecutionMode

func (t AgentType) DefaultExecutionMode() ExecutionMode

DefaultExecutionMode returns the default execution mode for this agent type.

func (AgentType) IsCollector

func (t AgentType) IsCollector() bool

IsCollector checks if this is a collector type.

func (AgentType) IsRunner

func (t AgentType) IsRunner() bool

IsRunner checks if this is a runner type (one-shot CI/CD).

func (AgentType) IsSensor

func (t AgentType) IsSensor() bool

IsSensor checks if this is a sensor type.

func (AgentType) IsValid

func (t AgentType) IsValid() bool

IsValid checks if the agent type is valid.

func (AgentType) IsWorker

func (t AgentType) IsWorker() bool

IsWorker checks if this is a worker type (server-controlled daemon).

type Capability

type Capability string

Capability represents an agent's capability.

const (
	CapabilitySAST      Capability = "sast"      // Static Application Security Testing
	CapabilitySCA       Capability = "sca"       // Software Composition Analysis
	CapabilitySecrets   Capability = "secrets"   // Secret Detection
	CapabilityIAC       Capability = "iac"       // Infrastructure as Code
	CapabilityDAST      Capability = "dast"      // Dynamic Application Security Testing
	CapabilityInfra     Capability = "infra"     // Infrastructure Scanning
	CapabilityContainer Capability = "container" // Container Scanning
	CapabilityWeb3      Capability = "web3"      // Web3/Blockchain Security
	CapabilityCollector Capability = "collector" // Data Collection
	CapabilityAPI       Capability = "api"       // API Security Testing
)

type ExecutionMode

type ExecutionMode string

ExecutionMode represents how the agent executes tasks.

const (
	ExecutionModeStandalone ExecutionMode = "standalone" // Triggered externally (CI/CD, cron, webhook)
	ExecutionModeDaemon     ExecutionMode = "daemon"     // Long-running, polls for commands
)

func (ExecutionMode) IsValid

func (m ExecutionMode) IsValid() bool

IsValid checks if the execution mode is valid.

type ExtendedMetrics

type ExtendedMetrics struct {
	CPUPercent    float64 `json:"cpu_percent"`
	MemoryPercent float64 `json:"memory_percent"`
	DiskReadMBPS  float64 `json:"disk_read_mbps"`
	DiskWriteMBPS float64 `json:"disk_write_mbps"`
	NetworkRxMBPS float64 `json:"network_rx_mbps"`
	NetworkTxMBPS float64 `json:"network_tx_mbps"`
	ActiveJobs    int     `json:"active_jobs"`
	Region        string  `json:"region,omitempty"`
}

ExtendedMetrics represents all system metrics for load balancing.

type Filter

type Filter struct {
	TenantID      *shared.ID
	Type          *AgentType
	Status        *AgentStatus // Admin-controlled: active, disabled, revoked
	Health        *AgentHealth // Automatic: unknown, online, offline, error
	ExecutionMode *ExecutionMode
	Capabilities  []string
	Tools         []string
	Labels        map[string]string
	Search        string
	HasCapacity   *bool // Filter by agents that have job capacity
}

Filter represents filter options for listing agents.

type LoadBalancingWeights

type LoadBalancingWeights struct {
	JobLoad float64 // Weight for job load factor (default: 0.30)
	CPU     float64 // Weight for CPU usage (default: 0.40)
	Memory  float64 // Weight for memory usage (default: 0.15)
	DiskIO  float64 // Weight for disk I/O (default: 0.10)
	Network float64 // Weight for network I/O (default: 0.05)
}

LoadBalancingWeights defines the weights for load score computation. These weights can be configured via environment variables.

func DefaultLoadBalancingWeights

func DefaultLoadBalancingWeights() LoadBalancingWeights

DefaultLoadBalancingWeights returns the default weights for load score computation.

type RegistrationToken

type RegistrationToken struct {
	ID       shared.ID
	TenantID shared.ID
	Name     string

	// Token identification
	TokenHash   string
	TokenPrefix string

	// Pre-configuration for registered agents
	AgentType           AgentType
	AgentNamePrefix     string
	DefaultScopes       []string
	DefaultCapabilities []string
	DefaultTools        []string
	DefaultLabels       map[string]any

	// Usage limits
	MaxUses   *int // nil = unlimited
	UsesCount int

	// Lifecycle
	ExpiresAt *time.Time
	IsActive  bool

	// Audit
	CreatedBy *shared.ID
	CreatedAt time.Time
}

RegistrationToken represents a token for agent auto-registration.

func NewRegistrationToken

func NewRegistrationToken(
	tenantID shared.ID,
	name string,
	agentType AgentType,
	maxUses *int,
	expiresAt *time.Time,
) (*RegistrationToken, error)

NewRegistrationToken creates a new registration token.

func (*RegistrationToken) CanRegister

func (t *RegistrationToken) CanRegister() error

CanRegister checks if the token can be used and returns an error if not.

func (*RegistrationToken) Deactivate

func (t *RegistrationToken) Deactivate()

Deactivate deactivates the token.

func (*RegistrationToken) IncrementUsage

func (t *RegistrationToken) IncrementUsage()

IncrementUsage increments the usage counter.

func (*RegistrationToken) IsExhausted

func (t *RegistrationToken) IsExhausted() bool

IsExhausted checks if the token has reached its usage limit.

func (*RegistrationToken) IsExpired

func (t *RegistrationToken) IsExpired() bool

IsExpired checks if the token is expired.

func (*RegistrationToken) IsValid

func (t *RegistrationToken) IsValid() bool

IsValid checks if the token can be used for registration.

func (*RegistrationToken) SetCreatedBy

func (t *RegistrationToken) SetCreatedBy(userID shared.ID)

SetCreatedBy sets the user who created the token.

func (*RegistrationToken) SetDefaults

func (t *RegistrationToken) SetDefaults(scopes, capabilities, tools []string, labels map[string]any)

SetDefaults sets default configuration for registered agents.

func (*RegistrationToken) SetTokenHash

func (t *RegistrationToken) SetTokenHash(hash, prefix string)

SetTokenHash sets the token hash and prefix.

type RegistrationTokenFilter

type RegistrationTokenFilter struct {
	TenantID *shared.ID
	IsActive *bool
}

RegistrationTokenFilter represents filter options for listing tokens.

type RegistrationTokenRepository

type RegistrationTokenRepository interface {
	// Create creates a new registration token.
	Create(ctx context.Context, token *RegistrationToken) error

	// GetByID retrieves a token by ID.
	GetByID(ctx context.Context, id shared.ID) (*RegistrationToken, error)

	// GetByTenantAndID retrieves a token by tenant and ID.
	GetByTenantAndID(ctx context.Context, tenantID, id shared.ID) (*RegistrationToken, error)

	// GetByHash retrieves a token by hash.
	GetByHash(ctx context.Context, hash string) (*RegistrationToken, error)

	// List lists tokens with filters and pagination.
	List(ctx context.Context, filter RegistrationTokenFilter, page pagination.Pagination) (pagination.Result[*RegistrationToken], error)

	// Update updates a token.
	Update(ctx context.Context, token *RegistrationToken) error

	// Delete deletes a token.
	Delete(ctx context.Context, id shared.ID) error

	// IncrementUsage increments the usage counter.
	IncrementUsage(ctx context.Context, id shared.ID) error

	// Deactivate deactivates a token.
	Deactivate(ctx context.Context, id shared.ID) error
}

RegistrationTokenRepository defines the interface for registration token persistence.

type Repository

type Repository interface {
	// Create creates a new agent.
	Create(ctx context.Context, agent *Agent) error

	// CountByTenant counts the number of agents for a tenant.
	// Used for enforcing agent limits per plan.
	CountByTenant(ctx context.Context, tenantID shared.ID) (int, error)

	// GetByID retrieves an agent by ID.
	GetByID(ctx context.Context, id shared.ID) (*Agent, error)

	// GetByTenantAndID retrieves an agent by tenant and ID.
	GetByTenantAndID(ctx context.Context, tenantID, id shared.ID) (*Agent, error)

	// GetByAPIKeyHash retrieves an agent by API key hash.
	GetByAPIKeyHash(ctx context.Context, hash string) (*Agent, error)

	// List lists agents with filters and pagination.
	List(ctx context.Context, filter Filter, page pagination.Pagination) (pagination.Result[*Agent], error)

	// Update updates an agent.
	Update(ctx context.Context, agent *Agent) error

	// Delete deletes an agent.
	Delete(ctx context.Context, id shared.ID) error

	// UpdateLastSeen updates the last seen timestamp for an agent.
	UpdateLastSeen(ctx context.Context, id shared.ID) error

	// IncrementStats increments agent statistics.
	IncrementStats(ctx context.Context, id shared.ID, findings, scans, errors int64) error

	// FindByCapabilities finds agents with the given capabilities.
	FindByCapabilities(ctx context.Context, tenantID shared.ID, capabilities []string, tool string) ([]*Agent, error)

	// FindAvailable finds available agents for a step.
	FindAvailable(ctx context.Context, tenantID shared.ID, capabilities []string, tool string) ([]*Agent, error)

	// FindAvailableWithTool finds the best available agent for a tool.
	// Returns the least-loaded agent that has the required tool.
	FindAvailableWithTool(ctx context.Context, tenantID shared.ID, tool string) (*Agent, error)

	// MarkStaleAsOffline marks agents as offline (health) if they haven't sent heartbeat within the timeout.
	// Note: This updates Health (automatic), not Status (admin-controlled).
	// Agents can still authenticate if their Status is 'active', regardless of Health.
	// Returns the number of agents marked as offline.
	MarkStaleAsOffline(ctx context.Context, timeout time.Duration) (int64, error)

	// FindAvailableWithCapacity finds agents that have capacity for new jobs.
	FindAvailableWithCapacity(ctx context.Context, tenantID shared.ID, capabilities []string, tool string) ([]*Agent, error)

	// ClaimJob atomically claims a job slot for an agent.
	ClaimJob(ctx context.Context, agentID shared.ID) error

	// ReleaseJob releases a job slot for an agent.
	ReleaseJob(ctx context.Context, agentID shared.ID) error

	// UpdateOfflineTimestamp marks an agent as offline with the current timestamp.
	// Called when a health monitor detects heartbeat timeout.
	UpdateOfflineTimestamp(ctx context.Context, id shared.ID) error

	// MarkStaleAgentsOffline finds agents that haven't sent heartbeat within timeout and marks them offline.
	// Returns the list of agent IDs that were marked offline (for audit logging).
	MarkStaleAgentsOffline(ctx context.Context, timeout time.Duration) ([]shared.ID, error)

	// GetAgentsOfflineSince returns agents that went offline after the given timestamp.
	// Used for historical queries like "which agents went offline in the last hour?"
	GetAgentsOfflineSince(ctx context.Context, since time.Time) ([]*Agent, error)

	// GetAvailableToolsForTenant returns all unique tool names that have at least one available agent.
	// Used to determine which tools can actually be executed.
	GetAvailableToolsForTenant(ctx context.Context, tenantID shared.ID) ([]string, error)

	// HasAgentForTool checks if there's at least one agent that supports the given tool.
	HasAgentForTool(ctx context.Context, tenantID shared.ID, tool string) (bool, error)

	// GetAvailableCapabilitiesForTenant returns all unique capability names from all agents accessible to the tenant.
	// Used to determine what capabilities a tenant can use based on their available agents.
	GetAvailableCapabilitiesForTenant(ctx context.Context, tenantID shared.ID) ([]string, error)

	// HasAgentForCapability checks if there's at least one agent that supports the given capability.
	HasAgentForCapability(ctx context.Context, tenantID shared.ID, capability string) (bool, error)
}

Repository defines the interface for agent persistence.

Jump to

Keyboard shortcuts

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