app

package
v0.1.1 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: 90 Imported by: 0

Documentation

Overview

Package app provides adapters for connecting services to sub-packages. These adapters implement the interfaces expected by the scan and pipeline sub-packages while delegating to the concrete app-level services.

Package app provides the security validator service for validating pipeline steps, scan configurations, and command payloads to prevent command injection and other security vulnerabilities.

Index

Constants

View Source
const (
	// MaxConcurrentWorkflowRunsPerWorkflow is the maximum concurrent runs per workflow.
	MaxConcurrentWorkflowRunsPerWorkflow = 5

	// MaxConcurrentWorkflowRunsPerTenant is the maximum concurrent workflow runs per tenant.
	MaxConcurrentWorkflowRunsPerTenant = 50
)

Concurrent workflow run limits to prevent resource exhaustion.

View Source
const MaxChangesSize = 15 * 1024

MaxChangesSize is the maximum allowed size for the changes JSONB field (15KB). Increased to support longer comments (up to 10000 chars) for technical discussions.

View Source
const MaxSourcesPerTenant = 50

MaxSourcesPerTenant is the maximum number of template sources a tenant can have.

View Source
const TypeAITriage = "ai:triage"

TypeAITriage is the asynq task type for AI triage jobs.

Variables

View Source
var (
	ErrAITriageNotAvailable      = errors.New("AI triage is not available on your current plan")
	ErrBulkTriageNotAvailable    = errors.New("bulk AI triage is not available on your current plan")
	ErrAutoTriageNotAvailable    = errors.New("auto AI triage is not available on your current plan")
	ErrAITriageBYOKNotAvailable  = errors.New("BYOK mode is not available on your current plan")
	ErrAITriageAgentNotAvailable = errors.New("self-hosted agent mode is not available on your current plan")
)

AI Triage licensing errors

View Source
var (
	ErrInvalidCredentials       = errors.New("invalid email or password")
	ErrAccountLocked            = errors.New("account is locked due to too many failed attempts")
	ErrAccountSuspended         = errors.New("account is suspended")
	ErrEmailNotVerified         = errors.New("email is not verified")
	ErrRegistrationDisabled     = errors.New("registration is disabled")
	ErrEmailAlreadyExists       = errors.New("email already exists")
	ErrInvalidResetToken        = errors.New("invalid or expired reset token")
	ErrInvalidVerificationToken = errors.New("invalid or expired verification token")
	ErrPasswordMismatch         = errors.New("current password is incorrect")
	ErrSessionLimitReached      = errors.New("maximum number of active sessions reached")
	ErrTenantAccessDenied       = errors.New("user does not have access to this tenant")
	ErrTenantRequired           = errors.New("tenant_id is required")
)

AuthService errors.

View Source
var (
	PipelineRunsTotal      = metrics.PipelineRunsTotal
	PipelineRunDuration    = metrics.PipelineRunDuration
	PipelineRunsInProgress = metrics.PipelineRunsInProgress
	StepRunsTotal          = metrics.StepRunsTotal
	StepRunDuration        = metrics.StepRunDuration
	StepRetryTotal         = metrics.StepRetryTotal
)

Pipeline metrics

View Source
var (
	CommandsTotal    = metrics.CommandsTotal
	CommandDuration  = metrics.CommandDuration
	CommandsExpired  = metrics.CommandsExpired
	CommandQueueSize = metrics.CommandQueueSize
)

Command metrics

View Source
var (
	AgentsOnline          = metrics.AgentsOnline
	AgentCommandsExecuted = metrics.AgentCommandsExecuted
	AgentHeartbeatLatency = metrics.AgentHeartbeatLatency
)

Agent metrics

View Source
var (
	ScansTotal              = metrics.ScansTotal
	ScansScheduled          = metrics.ScansScheduled
	ScanFindingsTotal       = metrics.ScanFindingsTotal
	ScanTriggerDuration     = metrics.ScanTriggerDuration
	ScanSchedulerErrors     = metrics.ScanSchedulerErrors
	ScanSchedulerLag        = metrics.ScanSchedulerLag
	ScansConcurrentRuns     = metrics.ScansConcurrentRuns
	ScansQualityGateResults = metrics.ScansQualityGateResults
)

Scan metrics

View Source
var (
	FindingsExpired      = metrics.FindingsExpired
	FindingsAutoResolved = metrics.FindingsAutoResolved
)

Finding lifecycle metrics

View Source
var (
	TemplateSyncsTotal        = metrics.TemplateSyncsTotal
	TemplateSyncsSuccessTotal = metrics.TemplateSyncsSuccessTotal
	TemplateSyncsFailedTotal  = metrics.TemplateSyncsFailedTotal
	TemplateSyncDuration      = metrics.TemplateSyncDuration
)

Template sync metrics

View Source
var (
	ErrOAuthDisabled       = errors.New("OAuth is disabled")
	ErrProviderDisabled    = errors.New("OAuth provider is disabled")
	ErrInvalidProvider     = errors.New("invalid OAuth provider")
	ErrInvalidState        = errors.New("invalid OAuth state")
	ErrOAuthExchangeFailed = errors.New("failed to exchange OAuth code")
	ErrOAuthUserInfoFailed = errors.New("failed to get user info from OAuth provider")
)

OAuth errors.

View Source
var (
	// ErrNoAgentAvailable is returned when no suitable agent is found.
	ErrNoAgentAvailable = errors.New("no suitable agent available")
)
View Source
var ValidTiers = []string{"shared", "dedicated", "premium"}

ValidTiers contains all valid platform agent tiers.

Functions

func CheckTokenLimit

func CheckTokenLimit(usedTokens, limitTokens int) error

CheckTokenLimit checks if a tenant has exceeded their monthly token limit. Returns nil if within limit, TokenLimitError if exceeded.

func ComputeContentHash

func ComputeContentHash(content []byte) string

ComputeContentHash computes a SHA256 hash of the given content.

func GenerateBundleVersion

func GenerateBundleVersion(timestamp time.Time, contentHash string) string

GenerateBundleVersion generates a version string for a bundle.

func MaskAPIKey

func MaskAPIKey(key string) string

MaskAPIKey returns a masked version of an API key for logging/display. Shows first 4 and last 4 characters: "sk-ab...xyz"

func NewPipelineAgentSelectorAdapter

func NewPipelineAgentSelectorAdapter(selector *AgentSelector) pipeline.AgentSelector

NewPipelineAgentSelectorAdapter creates an adapter for the pipeline package's AgentSelector interface.

func NewPipelineAuditServiceAdapter

func NewPipelineAuditServiceAdapter(svc *AuditService) pipeline.AuditService

NewPipelineAuditServiceAdapter creates an adapter for the pipeline package's AuditService interface.

func NewPipelineSecurityValidatorAdapter

func NewPipelineSecurityValidatorAdapter(validator *SecurityValidator) pipeline.SecurityValidator

NewPipelineSecurityValidatorAdapter creates an adapter for the pipeline package's SecurityValidator interface.

func NewScanAgentSelectorAdapter

func NewScanAgentSelectorAdapter(selector *AgentSelector) scan.AgentSelector

NewScanAgentSelectorAdapter creates an adapter for the scan package's AgentSelector interface.

func NewScanAuditServiceAdapter

func NewScanAuditServiceAdapter(svc *AuditService) scan.AuditService

NewScanAuditServiceAdapter creates an adapter for the scan package's AuditService interface.

func NewScanSecurityValidatorAdapter

func NewScanSecurityValidatorAdapter(validator *SecurityValidator) scan.SecurityValidator

NewScanSecurityValidatorAdapter creates an adapter for the scan package's SecurityValidator interface.

func NewScanTemplateSyncerAdapter

func NewScanTemplateSyncerAdapter(syncer *TemplateSyncer) scan.TemplateSyncer

NewScanTemplateSyncerAdapter creates an adapter for the scan package's TemplateSyncer interface.

func RegisterAllActionHandlers

func RegisterAllActionHandlers(
	executor *WorkflowExecutor,
	vulnSvc *VulnerabilityService,
	pipelineSvc *pipeline.Service,
	scanSvc *scansvc.Service,
	integrationSvc *IntegrationService,
	log *logger.Logger,
)

RegisterAllActionHandlers registers all built-in action handlers.

func RegisterAllActionHandlersWithAI

func RegisterAllActionHandlersWithAI(
	executor *WorkflowExecutor,
	vulnSvc *VulnerabilityService,
	pipelineSvc *pipeline.Service,
	scanSvc *scansvc.Service,
	integrationSvc *IntegrationService,
	aiTriageSvc *AITriageService,
	log *logger.Logger,
)

RegisterAllActionHandlersWithAI registers all built-in action handlers including AI triage.

func SanitizeTier

func SanitizeTier(tier string) string

SanitizeTier converts a tier string to a valid tier, defaulting to "shared". This is useful for normalizing user input before processing.

func ValidateSourceFilter

func ValidateSourceFilter(ctx context.Context, config map[string]any, cacheService *FindingSourceCacheService) error

ValidateSourceFilter validates that source codes in the filter are valid. Uses the FindingSourceCacheService to check against active sources.

Types

type AIConfigInfo

type AIConfigInfo struct {
	// Mode is the AI mode: platform, byok, agent, disabled
	Mode string `json:"mode"`
	// Provider is the LLM provider: claude, openai, gemini
	Provider string `json:"provider"`
	// Model is the model being used
	Model string `json:"model"`
	// IsEnabled indicates if AI triage is enabled for this tenant
	IsEnabled bool `json:"is_enabled"`
	// AutoTriageEnabled indicates if auto-triage is enabled
	AutoTriageEnabled bool `json:"auto_triage_enabled"`
	// AutoTriageSeverities is the list of severities for auto-triage
	AutoTriageSeverities []string `json:"auto_triage_severities,omitempty"`
	// MonthlyTokenLimit is the monthly token limit (0 = unlimited)
	MonthlyTokenLimit int `json:"monthly_token_limit"`
	// TokensUsedThisMonth is the number of tokens used this month
	TokensUsedThisMonth int `json:"tokens_used_this_month"`
}

AIConfigInfo represents the AI configuration info returned to the UI.

type AITriageActionHandler

type AITriageActionHandler struct {
	// contains filtered or unexported fields
}

AITriageActionHandler handles AI triage triggering actions.

func NewAITriageActionHandler

func NewAITriageActionHandler(aiTriageSvc *AITriageService, log *logger.Logger) *AITriageActionHandler

NewAITriageActionHandler creates a new AITriageActionHandler.

func (*AITriageActionHandler) Execute

func (h *AITriageActionHandler) Execute(ctx context.Context, input *ActionInput) (map[string]any, error)

Execute executes an AI triage action.

type AITriageEvent

type AITriageEvent struct {
	TenantID   shared.ID
	FindingID  shared.ID
	TriageID   shared.ID
	EventType  workflow.TriggerType // ai_triage_completed or ai_triage_failed
	TriageData map[string]any       // Triage result data
}

AITriageEvent represents an AI triage completion/failure event.

type AITriageJobEnqueuer

type AITriageJobEnqueuer interface {
	EnqueueAITriage(ctx context.Context, resultID, tenantID, findingID string, delay time.Duration) error
}

AITriageJobEnqueuer defines the interface for enqueueing AI triage jobs.

type AITriageModuleChecker

type AITriageModuleChecker interface {
	TenantHasModule(ctx context.Context, tenantID, moduleID string) (bool, error)
	GetTenantModuleLimit(ctx context.Context, tenantID, moduleID, metric string) (*GetModuleLimitOutput, error)
}

AITriageModuleChecker defines the interface for checking AI Triage module. This avoids circular dependency with module package.

type AITriageService

type AITriageService struct {
	// contains filtered or unexported fields
}

AITriageService handles AI-powered vulnerability triage operations.

func NewAITriageService

func NewAITriageService(
	triageRepo aitriage.Repository,
	findingRepo vulnerability.FindingRepository,
	tenantRepo tenant.Repository,
	activitySvc *FindingActivityService,
	llmFactory *llm.Factory,
	platformCfg config.AITriageConfig,
	log *logger.Logger,
) *AITriageService

NewAITriageService creates a new AITriageService.

func (*AITriageService) EnqueueAutoTriage

func (s *AITriageService) EnqueueAutoTriage(ctx context.Context, tenantID, findingID shared.ID) error

EnqueueAutoTriage enqueues an auto-triage job with optional delay.

func (*AITriageService) GetAIConfig

func (s *AITriageService) GetAIConfig(ctx context.Context, tenantID string) (*AIConfigInfo, error)

GetAIConfig returns the AI configuration info for a tenant. This is used by the UI to display which model is being used.

func (*AITriageService) GetLatestTriageByFinding

func (s *AITriageService) GetLatestTriageByFinding(ctx context.Context, tenantID, findingID string) (*TriageResultResponse, error)

GetLatestTriageByFinding retrieves the latest triage result for a finding.

func (*AITriageService) GetPlanTokenLimit

func (s *AITriageService) GetPlanTokenLimit(ctx context.Context, tenantID string) (int64, error)

GetPlanTokenLimit returns the monthly token limit for a tenant based on their plan. Returns -1 if unlimited, 0 if not set.

func (*AITriageService) GetTriageResult

func (s *AITriageService) GetTriageResult(ctx context.Context, tenantID, resultID string) (*TriageResultResponse, error)

GetTriageResult retrieves a triage result by ID.

func (*AITriageService) ListTriageHistory

func (s *AITriageService) ListTriageHistory(ctx context.Context, tenantID, findingID string, limit, offset int) ([]*TriageResultResponse, int, error)

ListTriageHistory retrieves triage history for a finding.

func (*AITriageService) ProcessTriage

func (s *AITriageService) ProcessTriage(ctx context.Context, resultID, tenantID, findingID shared.ID) error

ProcessTriage processes a triage job. Called by the worker. Uses AcquireTriageSlot for atomic token limit check and status update. This prevents race conditions when multiple workers process jobs concurrently.

func (*AITriageService) RecoverStuckJobs

RecoverStuckJobs finds and marks stuck triage jobs as failed. Jobs are considered stuck if they've been in pending/processing state for longer than stuckDuration. This should be called periodically by a background job.

func (*AITriageService) RequestBulkTriage

func (s *AITriageService) RequestBulkTriage(ctx context.Context, req BulkTriageRequest) (*BulkTriageResponse, error)

RequestBulkTriage creates multiple triage jobs for a list of findings.

func (*AITriageService) RequestTriage

func (s *AITriageService) RequestTriage(ctx context.Context, req TriageRequest) (*TriageResponse, error)

RequestTriage creates a triage job and enqueues it for processing.

func (*AITriageService) SetAuditService

func (s *AITriageService) SetAuditService(auditSvc *AuditService)

SetAuditService sets the audit service for logging AI operations.

func (*AITriageService) SetJobEnqueuer

func (s *AITriageService) SetJobEnqueuer(enqueuer AITriageJobEnqueuer)

SetJobEnqueuer sets the job enqueuer for async processing.

func (*AITriageService) SetLicenseChecker

func (s *AITriageService) SetLicenseChecker(checker AITriageModuleChecker)

SetLicenseChecker sets the license checker for AI triage feature gating.

func (*AITriageService) SetTriageBroadcaster

func (s *AITriageService) SetTriageBroadcaster(broadcaster TriageBroadcaster)

SetTriageBroadcaster sets the broadcaster for real-time WebSocket updates.

func (*AITriageService) SetWorkflowDispatcher

func (s *AITriageService) SetWorkflowDispatcher(dispatcher WorkflowEventDispatcherInterface)

SetWorkflowDispatcher sets the workflow event dispatcher for AI triage events.

func (*AITriageService) ShouldAutoTriage

func (s *AITriageService) ShouldAutoTriage(ctx context.Context, tenantID shared.ID, severity string) (bool, error)

ShouldAutoTriage checks if a finding should be auto-triaged based on tenant settings.

type APIKeyEncryptionService

type APIKeyEncryptionService struct {
	// contains filtered or unexported fields
}

APIKeyEncryptionService handles encryption and decryption of tenant API keys.

func NewAPIKeyEncryptionService

func NewAPIKeyEncryptionService(encryptor crypto.Encryptor) *APIKeyEncryptionService

NewAPIKeyEncryptionService creates a new APIKeyEncryptionService. If encryptor is nil, a NoOpEncryptor is used (for development only).

func (*APIKeyEncryptionService) DecryptAPIKey

func (s *APIKeyEncryptionService) DecryptAPIKey(encryptedKey string) (string, error)

DecryptAPIKey decrypts an API key from storage. If the key is not encrypted (no prefix), returns it as-is (backward compatibility).

func (*APIKeyEncryptionService) EncryptAPIKey

func (s *APIKeyEncryptionService) EncryptAPIKey(plainKey string) (string, error)

EncryptAPIKey encrypts an API key for secure storage. Returns a prefixed string to identify encrypted values: "enc:v1:<ciphertext>"

func (*APIKeyEncryptionService) IsEncrypted

func (s *APIKeyEncryptionService) IsEncrypted(key string) bool

IsEncrypted checks if an API key is already encrypted.

type APIKeyService

type APIKeyService struct {
	// contains filtered or unexported fields
}

APIKeyService provides business logic for API key management.

func NewAPIKeyService

func NewAPIKeyService(repo apikey.Repository, log *logger.Logger) *APIKeyService

NewAPIKeyService creates a new APIKeyService.

func (*APIKeyService) CreateAPIKey

func (s *APIKeyService) CreateAPIKey(ctx context.Context, input CreateAPIKeyInput) (*CreateAPIKeyResult, error)

CreateAPIKey generates and stores a new API key.

func (*APIKeyService) DeleteAPIKey

func (s *APIKeyService) DeleteAPIKey(ctx context.Context, id, tenantIDStr string) error

DeleteAPIKey deletes an API key. Tenant isolation enforced at DB level.

func (*APIKeyService) GetAPIKey

func (s *APIKeyService) GetAPIKey(ctx context.Context, id, tenantIDStr string) (*apikey.APIKey, error)

GetAPIKey retrieves an API key by ID within a tenant.

func (*APIKeyService) ListAPIKeys

func (s *APIKeyService) ListAPIKeys(ctx context.Context, input ListAPIKeysInput) (apikey.ListResult, error)

ListAPIKeys retrieves a paginated list of API keys.

func (*APIKeyService) RevokeAPIKey

func (s *APIKeyService) RevokeAPIKey(ctx context.Context, input RevokeAPIKeyInput) (*apikey.APIKey, error)

RevokeAPIKey revokes an API key.

type AcceptInvitationWithRefreshTokenInput

type AcceptInvitationWithRefreshTokenInput struct {
	RefreshToken    string `json:"refresh_token" validate:"required"`
	InvitationToken string `json:"invitation_token" validate:"required"`
}

AcceptInvitationWithRefreshTokenInput represents the input for accepting an invitation.

type AcceptInvitationWithRefreshTokenResult

type AcceptInvitationWithRefreshTokenResult struct {
	AccessToken  string               `json:"access_token"`
	RefreshToken string               `json:"refresh_token"` // Rotated refresh token
	ExpiresAt    time.Time            `json:"expires_at"`
	Tenant       TenantMembershipInfo `json:"tenant"`
	Role         string               `json:"role"`
}

AcceptInvitationWithRefreshTokenResult represents the result of accepting an invitation.

type ActionHandler

type ActionHandler interface {
	// Execute executes the action and returns the output.
	Execute(ctx context.Context, input *ActionInput) (map[string]any, error)
}

ActionHandler defines the interface for workflow action handlers.

type ActionInput

type ActionInput struct {
	TenantID     shared.ID
	WorkflowID   shared.ID
	RunID        shared.ID
	NodeKey      string
	ActionType   workflow.ActionType
	ActionConfig map[string]any
	TriggerData  map[string]any
	Context      map[string]any
}

ActionInput contains the input for an action execution.

type ActivityBroadcaster

type ActivityBroadcaster interface {
	// BroadcastActivity sends an activity event to subscribers.
	// channel: the channel to broadcast to (e.g., "finding:{id}")
	// data: the activity data to broadcast
	// tenantID: tenant isolation for the broadcast
	BroadcastActivity(channel string, data any, tenantID string)
}

ActivityBroadcaster broadcasts activity events for real-time updates. This interface allows decoupling from the WebSocket implementation.

type ActivityItem

type ActivityItem struct {
	Type        string
	Title       string
	Description string
	Timestamp   time.Time
}

ActivityItem represents a recent activity item.

type AddCommentInput

type AddCommentInput struct {
	TenantID  string `validate:"required,uuid"`
	FindingID string `validate:"required,uuid"`
	AuthorID  string `validate:"required,uuid"`
	Content   string `validate:"required,min=1,max=10000"`
}

AddCommentInput represents the input for adding a comment.

type AddEdgeInput

type AddEdgeInput struct {
	TenantID      shared.ID
	UserID        shared.ID
	WorkflowID    shared.ID
	SourceNodeKey string
	TargetNodeKey string
	SourceHandle  string
	Label         string
}

AddEdgeInput represents input for adding an edge.

type AddGroupMemberInput

type AddGroupMemberInput struct {
	GroupID string    `json:"-"`
	UserID  shared.ID `json:"user_id" validate:"required"`
	Role    string    `json:"role" validate:"required,oneof=owner lead member"`
}

AddGroupMemberInput represents the input for adding a member to a group.

type AddMemberInput

type AddMemberInput struct {
	UserID shared.ID `json:"user_id" validate:"required"`
	Role   string    `json:"role" validate:"required,oneof=admin member viewer"`
}

AddMemberInput represents the input for adding a member.

type AddNodeInput

type AddNodeInput struct {
	TenantID    shared.ID
	UserID      shared.ID
	WorkflowID  shared.ID
	NodeKey     string
	NodeType    workflow.NodeType
	Name        string
	Description string
	UIPositionX float64
	UIPositionY float64
	Config      workflow.NodeConfig
}

AddNodeInput represents input for adding a node.

type AddPermissionToSetInput

type AddPermissionToSetInput struct {
	PermissionSetID  string `json:"-"`
	PermissionID     string `json:"permission_id" validate:"required"`
	ModificationType string `json:"modification_type" validate:"omitempty,oneof=add remove"`
}

AddPermissionToSetInput represents the input for adding a permission to a set.

type AddStatusChangeCommentInput

type AddStatusChangeCommentInput struct {
	FindingID string `validate:"required,uuid"`
	AuthorID  string `validate:"required,uuid"`
	Content   string `validate:"max=10000"`
	OldStatus string `validate:"required,finding_status"`
	NewStatus string `validate:"required,finding_status"`
}

AddStatusChangeCommentInput represents the input for adding a status change comment.

type AgentAvailabilityResult

type AgentAvailabilityResult struct {
	HasTenantAgent bool
	Available      bool
	Message        string
}

AgentAvailabilityResult represents agent availability status.

type AgentHeartbeatData

type AgentHeartbeatData struct {
	Version       string
	Hostname      string
	CPUPercent    float64
	MemoryPercent float64
	CurrentJobs   int
	Region        string
}

AgentHeartbeatData represents the data received from agent heartbeat.

type AgentHeartbeatInput

type AgentHeartbeatInput struct {
	AgentID   shared.ID
	Status    string
	Message   string
	Version   string
	Hostname  string
	IPAddress string
}

AgentHeartbeatInput represents the input for agent heartbeat.

type AgentSelectionMode

type AgentSelectionMode string

AgentSelectionMode defines which agents to consider.

const (
	// SelectTenantOnly only considers tenant's own agents.
	SelectTenantOnly AgentSelectionMode = "tenant_only"
	// SelectAny selects from any available agent.
	SelectAny AgentSelectionMode = "any"
)

type AgentSelector

type AgentSelector struct {
	// contains filtered or unexported fields
}

AgentSelector handles intelligent agent selection for job execution.

func NewAgentSelector

func NewAgentSelector(
	agentRepo agent.Repository,
	commandRepo command.Repository,
	agentState *redis.AgentStateStore,
	log *logger.Logger,
) *AgentSelector

NewAgentSelector creates a new AgentSelector.

func (*AgentSelector) CheckAgentAvailability

func (s *AgentSelector) CheckAgentAvailability(ctx context.Context, tenantID shared.ID, toolName string, tenantOnly bool) *AgentAvailabilityResult

CheckAgentAvailability checks if any agent is available for the given scan configuration. This should be called before creating a scan to ensure execution is possible.

func (*AgentSelector) SelectAgent

SelectAgent selects the best agent for a job based on the selection mode.

type AgentService

type AgentService struct {
	// contains filtered or unexported fields
}

AgentService handles agent-related business operations.

func NewAgentService

func NewAgentService(repo agent.Repository, auditService *AuditService, log *logger.Logger) *AgentService

NewAgentService creates a new AgentService.

func (*AgentService) ActivateAgent

func (s *AgentService) ActivateAgent(ctx context.Context, tenantID, agentID string, auditCtx *AuditContext) (*agent.Agent, error)

ActivateAgent activates an agent (admin action).

func (*AgentService) AuthenticateByAPIKey

func (s *AgentService) AuthenticateByAPIKey(ctx context.Context, apiKey string) (*agent.Agent, error)

AuthenticateByAPIKey authenticates an agent by API key. Authentication is based on admin-controlled Status field only: - Active: allowed to authenticate - Disabled: admin has disabled the agent - Revoked: access permanently revoked The Health field (unknown/online/offline/error) is for monitoring only.

func (*AgentService) ClaimJob

func (s *AgentService) ClaimJob(ctx context.Context, agentID shared.ID) error

ClaimJob claims a job slot on an agent for load balancing.

func (*AgentService) CreateAgent

func (s *AgentService) CreateAgent(ctx context.Context, input CreateAgentInput) (*CreateAgentOutput, error)

CreateAgent creates a new agent and generates an API key.

func (*AgentService) DeleteAgent

func (s *AgentService) DeleteAgent(ctx context.Context, tenantID, agentID string, auditCtx *AuditContext) error

DeleteAgent deletes an agent.

func (*AgentService) DisableAgent

func (s *AgentService) DisableAgent(ctx context.Context, tenantID, agentID, reason string, auditCtx *AuditContext) (*agent.Agent, error)

DisableAgent disables an agent (admin action).

func (*AgentService) FindAvailableAgents

func (s *AgentService) FindAvailableAgents(ctx context.Context, tenantID shared.ID, capabilities []string, tool string) ([]*agent.Agent, error)

FindAvailableAgents finds agents that can handle a task.

func (*AgentService) FindAvailableWithCapacity

func (s *AgentService) FindAvailableWithCapacity(ctx context.Context, tenantID shared.ID, capabilities []string, tool string) ([]*agent.Agent, error)

FindAvailableWithCapacity finds agents with available job capacity for load balancing.

func (*AgentService) GetAgent

func (s *AgentService) GetAgent(ctx context.Context, tenantID, agentID string) (*agent.Agent, error)

GetAgent retrieves an agent by ID.

func (*AgentService) GetAvailableCapabilitiesForTenant

func (s *AgentService) GetAvailableCapabilitiesForTenant(ctx context.Context, tenantID shared.ID) (*TenantAvailableCapabilitiesOutput, error)

GetAvailableCapabilitiesForTenant returns all capabilities available to a tenant. This aggregates capabilities from the tenant's own agents (if status=active and health=online).

func (*AgentService) HasCapability

func (s *AgentService) HasCapability(ctx context.Context, tenantID shared.ID, capability string) (bool, error)

HasCapability checks if a tenant has access to a specific capability.

func (*AgentService) Heartbeat

func (s *AgentService) Heartbeat(ctx context.Context, input AgentHeartbeatInput) error

Heartbeat updates agent status from heartbeat.

func (*AgentService) IncrementStats

func (s *AgentService) IncrementStats(ctx context.Context, agentID shared.ID, findings, scans, errors int64) error

IncrementStats increments agent statistics.

func (*AgentService) ListAgents

func (s *AgentService) ListAgents(ctx context.Context, input ListAgentsInput) (pagination.Result[*agent.Agent], error)

ListAgents lists agents with filters.

func (*AgentService) RegenerateAPIKey

func (s *AgentService) RegenerateAPIKey(ctx context.Context, tenantID, agentID string, auditCtx *AuditContext) (string, error)

RegenerateAPIKey generates a new API key for an agent.

func (*AgentService) ReleaseJob

func (s *AgentService) ReleaseJob(ctx context.Context, agentID shared.ID) error

ReleaseJob releases a job slot on an agent.

func (*AgentService) RevokeAgent

func (s *AgentService) RevokeAgent(ctx context.Context, tenantID, agentID, reason string, auditCtx *AuditContext) (*agent.Agent, error)

RevokeAgent permanently revokes an agent's access (admin action).

func (*AgentService) UpdateAgent

func (s *AgentService) UpdateAgent(ctx context.Context, input UpdateAgentInput) (*agent.Agent, error)

UpdateAgent updates an agent.

func (*AgentService) UpdateHeartbeat

func (s *AgentService) UpdateHeartbeat(ctx context.Context, agentID shared.ID, data AgentHeartbeatData) error

UpdateHeartbeat updates agent metrics from heartbeat.

type AssetChange

type AssetChange struct {
	Type      string    `json:"type"` // added, removed, changed
	AssetName string    `json:"asset_name"`
	AssetType string    `json:"asset_type"`
	Timestamp time.Time `json:"timestamp"`
}

AssetChange represents a recent asset change.

type AssetGroupService

type AssetGroupService struct {
	// contains filtered or unexported fields
}

AssetGroupService handles asset group business logic.

func NewAssetGroupService

func NewAssetGroupService(repo assetgroup.Repository, log *logger.Logger) *AssetGroupService

NewAssetGroupService creates a new asset group service.

func (*AssetGroupService) AddAssetsToGroup

func (s *AssetGroupService) AddAssetsToGroup(ctx context.Context, groupID shared.ID, assetIDs []string) error

AddAssetsToGroup adds assets to a group.

func (*AssetGroupService) BulkDeleteAssetGroups

func (s *AssetGroupService) BulkDeleteAssetGroups(ctx context.Context, groupIDs []string) (int, error)

BulkDeleteAssetGroups deletes multiple asset groups.

func (*AssetGroupService) BulkUpdateAssetGroups

func (s *AssetGroupService) BulkUpdateAssetGroups(ctx context.Context, input BulkUpdateInput) (int, error)

BulkUpdateAssetGroups updates multiple asset groups.

func (*AssetGroupService) CreateAssetGroup

CreateAssetGroup creates a new asset group.

func (*AssetGroupService) DeleteAssetGroup

func (s *AssetGroupService) DeleteAssetGroup(ctx context.Context, id shared.ID) error

DeleteAssetGroup deletes an asset group.

func (*AssetGroupService) GetAssetGroup

func (s *AssetGroupService) GetAssetGroup(ctx context.Context, id shared.ID) (*assetgroup.AssetGroup, error)

GetAssetGroup retrieves an asset group by ID.

func (*AssetGroupService) GetAssetGroupStats

func (s *AssetGroupService) GetAssetGroupStats(ctx context.Context, tenantID string) (*assetgroup.Stats, error)

GetAssetGroupStats retrieves aggregated statistics.

func (*AssetGroupService) GetGroupAssets

func (s *AssetGroupService) GetGroupAssets(ctx context.Context, groupID shared.ID, pageNum, perPage int) (pagination.Result[*assetgroup.GroupAsset], error)

GetGroupAssets retrieves assets in a group.

func (*AssetGroupService) GetGroupFindings

func (s *AssetGroupService) GetGroupFindings(ctx context.Context, groupID shared.ID, pageNum, perPage int) (pagination.Result[*assetgroup.GroupFinding], error)

GetGroupFindings retrieves findings for assets in a group.

func (*AssetGroupService) ListAssetGroups

ListAssetGroups lists asset groups with filtering and pagination.

func (*AssetGroupService) RemoveAssetsFromGroup

func (s *AssetGroupService) RemoveAssetsFromGroup(ctx context.Context, groupID shared.ID, assetIDs []string) error

RemoveAssetsFromGroup removes assets from a group.

func (*AssetGroupService) UpdateAssetGroup

func (s *AssetGroupService) UpdateAssetGroup(ctx context.Context, id shared.ID, input UpdateAssetGroupInput) (*assetgroup.AssetGroup, error)

UpdateAssetGroup updates an existing asset group.

type AssetRelationshipService

type AssetRelationshipService struct {
	// contains filtered or unexported fields
}

AssetRelationshipService handles relationship business logic.

func NewAssetRelationshipService

func NewAssetRelationshipService(
	relRepo asset.RelationshipRepository,
	assetRepo asset.Repository,
	log *logger.Logger,
) *AssetRelationshipService

NewAssetRelationshipService creates a new AssetRelationshipService.

func (*AssetRelationshipService) CreateRelationship

CreateRelationship creates a new relationship between two assets.

func (*AssetRelationshipService) DeleteRelationship

func (s *AssetRelationshipService) DeleteRelationship(ctx context.Context, tenantID, relationshipID string) error

DeleteRelationship removes a relationship.

func (*AssetRelationshipService) GetRelationship

func (s *AssetRelationshipService) GetRelationship(ctx context.Context, tenantID, relationshipID string) (*asset.RelationshipWithAssets, error)

GetRelationship retrieves a relationship by ID.

func (*AssetRelationshipService) ListAssetRelationships

func (s *AssetRelationshipService) ListAssetRelationships(
	ctx context.Context,
	tenantID, assetID string,
	filter asset.RelationshipFilter,
) ([]*asset.RelationshipWithAssets, int64, error)

ListAssetRelationships lists all relationships for an asset.

func (*AssetRelationshipService) UpdateRelationship

func (s *AssetRelationshipService) UpdateRelationship(ctx context.Context, tenantID, relationshipID string, input UpdateRelationshipInput) (*asset.RelationshipWithAssets, error)

UpdateRelationship updates a relationship's mutable fields.

type AssetService

type AssetService struct {
	// contains filtered or unexported fields
}

AssetService handles asset-related business operations.

func NewAssetService

func NewAssetService(repo asset.Repository, log *logger.Logger) *AssetService

NewAssetService creates a new AssetService.

func (*AssetService) ActivateAsset

func (s *AssetService) ActivateAsset(ctx context.Context, tenantID, assetID string) (*asset.Asset, error)

ActivateAsset activates an asset. Security: Requires tenantID to prevent cross-tenant activation.

func (*AssetService) ArchiveAsset

func (s *AssetService) ArchiveAsset(ctx context.Context, tenantID, assetID string) (*asset.Asset, error)

ArchiveAsset archives an asset. Security: Requires tenantID to prevent cross-tenant archival.

func (*AssetService) BulkUpdateAssetStatus

func (s *AssetService) BulkUpdateAssetStatus(ctx context.Context, tenantID string, input BulkUpdateAssetStatusInput) (*BulkAssetStatusResult, error)

BulkUpdateAssetStatus updates the status of multiple assets. Security: Requires tenantID to prevent cross-tenant status changes. OPTIMIZED: Reduces N API calls to a single batch operation.

func (*AssetService) CreateAsset

func (s *AssetService) CreateAsset(ctx context.Context, input CreateAssetInput) (*asset.Asset, error)

CreateAsset creates a new asset.

func (*AssetService) CreateRepositoryAsset

CreateRepositoryAsset creates a new repository asset with its extension. If an existing asset matches (by name or fullName), it will be updated with SCM data.

func (*AssetService) DeactivateAsset

func (s *AssetService) DeactivateAsset(ctx context.Context, tenantID, assetID string) (*asset.Asset, error)

DeactivateAsset deactivates an asset. Security: Requires tenantID to prevent cross-tenant deactivation.

func (*AssetService) DeleteAsset

func (s *AssetService) DeleteAsset(ctx context.Context, assetID string, tenantID string) error

DeleteAsset deletes an asset by ID. Security: Requires tenantID to prevent cross-tenant deletion.

func (*AssetService) DisableRepositoryScan

func (s *AssetService) DisableRepositoryScan(ctx context.Context, assetID string) error

DisableRepositoryScan disables scanning for a repository asset.

func (*AssetService) EnableRepositoryScan

func (s *AssetService) EnableRepositoryScan(ctx context.Context, assetID string, schedule string) error

EnableRepositoryScan enables scanning for a repository asset.

func (*AssetService) GetAsset

func (s *AssetService) GetAsset(ctx context.Context, tenantID, assetID string) (*asset.Asset, error)

GetAsset retrieves an asset by ID within a tenant. Security: Requires tenantID to prevent cross-tenant data access.

func (*AssetService) GetAssetByExternalID

func (s *AssetService) GetAssetByExternalID(ctx context.Context, tenantID, provider, externalID string) (*asset.Asset, error)

GetAssetByExternalID retrieves an asset by provider and external ID.

func (*AssetService) GetAssetWithRepository

func (s *AssetService) GetAssetWithRepository(ctx context.Context, tenantID, assetID string) (*asset.Asset, *asset.RepositoryExtension, error)

GetAssetWithRepository retrieves an asset with its repository extension. Security: Requires tenantID to prevent cross-tenant data access.

func (*AssetService) GetRepositoryExtension

func (s *AssetService) GetRepositoryExtension(ctx context.Context, tenantID, assetID string) (*asset.RepositoryExtension, error)

GetRepositoryExtension retrieves the repository extension for an asset. Security: Requires tenantID to prevent cross-tenant data access.

func (*AssetService) HasRepositoryExtensionRepository

func (s *AssetService) HasRepositoryExtensionRepository() bool

HasRepositoryExtensionRepository returns true if the repository extension repository is configured.

func (*AssetService) ListAssets

func (s *AssetService) ListAssets(ctx context.Context, input ListAssetsInput) (pagination.Result[*asset.Asset], error)

ListAssets retrieves assets with filtering, sorting, and pagination.

func (*AssetService) MarkAssetSyncFailed

func (s *AssetService) MarkAssetSyncFailed(ctx context.Context, tenantID, assetID string, syncError string) (*asset.Asset, error)

MarkAssetSyncFailed marks an asset sync as failed with an error message. Security: Requires tenantID to prevent cross-tenant status modification.

func (*AssetService) MarkAssetSynced

func (s *AssetService) MarkAssetSynced(ctx context.Context, tenantID, assetID string) (*asset.Asset, error)

MarkAssetSynced marks an asset as successfully synced. Security: Requires tenantID to prevent cross-tenant status modification.

func (*AssetService) MarkAssetSyncing

func (s *AssetService) MarkAssetSyncing(ctx context.Context, tenantID, assetID string) (*asset.Asset, error)

MarkAssetSyncing marks an asset as currently syncing. Security: Requires tenantID to prevent cross-tenant status modification.

func (*AssetService) RecordRepositoryScan

func (s *AssetService) RecordRepositoryScan(ctx context.Context, assetID string) error

RecordRepositoryScan records a scan completion for a repository.

func (*AssetService) SetAssetGroupRepository

func (s *AssetService) SetAssetGroupRepository(repo assetgroup.Repository)

SetAssetGroupRepository sets the asset group repository for recalculating stats.

func (*AssetService) SetRepositoryExtensionRepository

func (s *AssetService) SetRepositoryExtensionRepository(repo asset.RepositoryExtensionRepository)

SetRepositoryExtensionRepository sets the repository extension repository.

func (*AssetService) UpdateAsset

func (s *AssetService) UpdateAsset(ctx context.Context, assetID string, tenantID string, input UpdateAssetInput) (*asset.Asset, error)

UpdateAsset updates an existing asset. Security: Requires tenantID to prevent cross-tenant data modification.

func (*AssetService) UpdateFindingCount

func (s *AssetService) UpdateFindingCount(ctx context.Context, tenantID, assetID string, count int) error

UpdateFindingCount updates the finding count for an asset. Security: Requires tenantID to prevent cross-tenant data modification.

func (*AssetService) UpdateRepositoryExtension

func (s *AssetService) UpdateRepositoryExtension(ctx context.Context, tenantID, assetID string, input UpdateRepositoryExtensionInput) (*asset.RepositoryExtension, error)

UpdateRepositoryExtension updates the repository extension for an asset. Security: Requires tenantID to prevent cross-tenant data modification.

func (*AssetService) UpdateRepositoryFindingCount

func (s *AssetService) UpdateRepositoryFindingCount(ctx context.Context, assetID string, count int) error

UpdateRepositoryFindingCount updates the finding count for a repository extension.

type AssetStatsData

type AssetStatsData struct {
	Total            int
	ByType           map[string]int
	ByStatus         map[string]int
	AverageRiskScore float64
}

AssetStatsData holds raw asset statistics from repository.

type AssetTypeBreakdown

type AssetTypeBreakdown struct {
	Type    string `json:"type"`
	Total   int    `json:"total"`
	Exposed int    `json:"exposed"`
}

AssetTypeBreakdown represents asset count breakdown by type.

type AssetTypeService

type AssetTypeService struct {
	// contains filtered or unexported fields
}

AssetTypeService handles asset type-related business operations. Asset types are read-only system configuration created via DB seed or by system admin.

func NewAssetTypeService

func NewAssetTypeService(repo assettype.Repository, categoryRepo assettype.CategoryRepository, log *logger.Logger) *AssetTypeService

NewAssetTypeService creates a new AssetTypeService.

func (*AssetTypeService) GetAssetType

func (s *AssetTypeService) GetAssetType(ctx context.Context, assetTypeID string) (*assettype.AssetType, error)

GetAssetType retrieves an asset type by ID.

func (*AssetTypeService) GetAssetTypeByCode

func (s *AssetTypeService) GetAssetTypeByCode(ctx context.Context, code string) (*assettype.AssetType, error)

GetAssetTypeByCode retrieves an asset type by code.

func (*AssetTypeService) GetCategory

func (s *AssetTypeService) GetCategory(ctx context.Context, categoryID string) (*assettype.Category, error)

GetCategory retrieves a category by ID.

func (*AssetTypeService) GetCategoryByCode

func (s *AssetTypeService) GetCategoryByCode(ctx context.Context, code string) (*assettype.Category, error)

GetCategoryByCode retrieves a category by code.

func (*AssetTypeService) ListActiveAssetTypes

func (s *AssetTypeService) ListActiveAssetTypes(ctx context.Context) ([]*assettype.AssetType, error)

ListActiveAssetTypes lists all active asset types.

func (*AssetTypeService) ListActiveAssetTypesByCategory

func (s *AssetTypeService) ListActiveAssetTypesByCategory(ctx context.Context, categoryID string) ([]*assettype.AssetType, error)

ListActiveAssetTypesByCategory lists active asset types by category.

func (*AssetTypeService) ListActiveCategories

func (s *AssetTypeService) ListActiveCategories(ctx context.Context) ([]*assettype.Category, error)

ListActiveCategories lists all active categories.

func (*AssetTypeService) ListAssetTypes

ListAssetTypes lists asset types with filtering and pagination.

func (*AssetTypeService) ListAssetTypesWithCategory

ListAssetTypesWithCategory lists asset types with their categories.

func (*AssetTypeService) ListCategories

ListCategories lists categories with pagination.

type AssignAssetInput

type AssignAssetInput struct {
	GroupID       string `json:"-"`
	AssetID       string `json:"asset_id" validate:"required,uuid"`
	OwnershipType string `json:"ownership_type" validate:"required,oneof=primary secondary stakeholder informed"`
}

AssignAssetInput represents the input for assigning an asset to a group.

type AssignPermissionSetInput

type AssignPermissionSetInput struct {
	GroupID         string `json:"-"`
	PermissionSetID string `json:"permission_set_id" validate:"required"`
}

AssignPermissionSetInput represents the input for assigning a permission set to a group.

type AssignRoleInput

type AssignRoleInput struct {
	TenantID string `json:"-"`
	UserID   string `json:"user_id" validate:"required,uuid"`
	RoleID   string `json:"role_id" validate:"required,uuid"`
}

AssignRoleInput represents the input for assigning a role to a user.

type AttackSurfaceRepository

type AttackSurfaceRepository interface {
	// GetStats returns attack surface statistics for a tenant
	GetStats(ctx context.Context, tenantID shared.ID) (*AttackSurfaceStatsData, error)
	// GetExposedServices returns top exposed services/assets
	GetExposedServices(ctx context.Context, tenantID shared.ID, limit int) ([]ExposedService, error)
	// GetRecentChanges returns recent asset changes
	GetRecentChanges(ctx context.Context, tenantID shared.ID, limit int) ([]AssetChange, error)
	// GetStatsWithTrends returns stats with week-over-week comparison
	GetStatsWithTrends(ctx context.Context, tenantID shared.ID) (*AttackSurfaceStatsData, error)
}

AttackSurfaceRepository defines the interface for attack surface data access.

type AttackSurfaceService

type AttackSurfaceService struct {
	// contains filtered or unexported fields
}

AttackSurfaceService provides attack surface operations.

func NewAttackSurfaceService

func NewAttackSurfaceService(assetRepo asset.Repository, log *logger.Logger) *AttackSurfaceService

NewAttackSurfaceService creates a new AttackSurfaceService.

func (*AttackSurfaceService) GetStats

func (s *AttackSurfaceService) GetStats(ctx context.Context, tenantID shared.ID) (*AttackSurfaceStats, error)

GetStats returns attack surface statistics for a tenant.

type AttackSurfaceStats

type AttackSurfaceStats struct {
	// Summary stats
	TotalAssets       int     `json:"total_assets"`
	ExposedServices   int     `json:"exposed_services"`
	CriticalExposures int     `json:"critical_exposures"`
	RiskScore         float64 `json:"risk_score"`

	// Trends (week-over-week)
	TotalAssetsChange       int `json:"total_assets_change"`
	ExposedServicesChange   int `json:"exposed_services_change"`
	CriticalExposuresChange int `json:"critical_exposures_change"`

	// Asset breakdown by type with exposed count
	AssetBreakdown []AssetTypeBreakdown `json:"asset_breakdown"`

	// Top exposed services
	ExposedServicesList []ExposedService `json:"exposed_services_list"`

	// Recent changes
	RecentChanges []AssetChange `json:"recent_changes"`
}

AttackSurfaceStats represents aggregated attack surface statistics.

type AttackSurfaceStatsData

type AttackSurfaceStatsData struct {
	TotalAssets             int
	ExposedServices         int
	CriticalExposures       int
	AverageRiskScore        float64
	TotalAssetsChange       int
	ExposedServicesChange   int
	CriticalExposuresChange int
	ByType                  map[string]int
	ExposedByType           map[string]int
}

AttackSurfaceStatsData holds raw attack surface statistics.

type AuditContext

type AuditContext struct {
	TenantID   string
	ActorID    string
	ActorEmail string
	ActorIP    string
	UserAgent  string
	RequestID  string
	SessionID  string
}

AuditContext holds contextual information for audit logging.

type AuditEvent

type AuditEvent struct {
	Action       audit.Action
	ResourceType audit.ResourceType
	ResourceID   string
	ResourceName string
	Result       audit.Result
	Severity     audit.Severity
	Changes      *audit.Changes
	Message      string
	Metadata     map[string]any
}

AuditEvent represents an audit event to log.

func NewDeniedEvent

func NewDeniedEvent(action audit.Action, resourceType audit.ResourceType, resourceID string, reason string) AuditEvent

NewDeniedEvent creates a denied audit event.

func NewFailureEvent

func NewFailureEvent(action audit.Action, resourceType audit.ResourceType, resourceID string, err error) AuditEvent

NewFailureEvent creates a failure audit event.

func NewSuccessEvent

func NewSuccessEvent(action audit.Action, resourceType audit.ResourceType, resourceID string) AuditEvent

NewSuccessEvent creates a success audit event.

func (AuditEvent) WithChanges

func (e AuditEvent) WithChanges(changes *audit.Changes) AuditEvent

WithChanges sets the changes.

func (AuditEvent) WithMessage

func (e AuditEvent) WithMessage(message string) AuditEvent

WithMessage sets the message.

func (AuditEvent) WithMetadata

func (e AuditEvent) WithMetadata(key string, value any) AuditEvent

WithMetadata adds metadata.

func (AuditEvent) WithResourceName

func (e AuditEvent) WithResourceName(name string) AuditEvent

WithResourceName sets the resource name.

func (AuditEvent) WithSeverity

func (e AuditEvent) WithSeverity(severity audit.Severity) AuditEvent

WithSeverity sets the severity.

type AuditService

type AuditService struct {
	// contains filtered or unexported fields
}

AuditService handles audit logging operations.

func NewAuditService

func NewAuditService(repo audit.Repository, log *logger.Logger) *AuditService

NewAuditService creates a new AuditService.

func (*AuditService) CleanupOldLogs

func (s *AuditService) CleanupOldLogs(ctx context.Context, retentionDays int) (int64, error)

CleanupOldLogs removes audit logs older than the retention period. Preserves high and critical severity logs.

func (*AuditService) GetActionCount

func (s *AuditService) GetActionCount(ctx context.Context, tenantID string, action audit.Action, since time.Time) (int64, error)

GetActionCount returns the count of a specific action within a time range.

func (*AuditService) GetAuditLog

func (s *AuditService) GetAuditLog(ctx context.Context, auditLogID string) (*audit.AuditLog, error)

GetAuditLog retrieves an audit log by ID.

func (*AuditService) GetResourceHistory

func (s *AuditService) GetResourceHistory(ctx context.Context, resourceType, resourceID string, page, perPage int) (pagination.Result[*audit.AuditLog], error)

GetResourceHistory retrieves audit history for a specific resource.

func (*AuditService) GetUserActivity

func (s *AuditService) GetUserActivity(ctx context.Context, userID string, page, perPage int) (pagination.Result[*audit.AuditLog], error)

GetUserActivity retrieves audit logs for a specific user.

func (*AuditService) ListAuditLogs

ListAuditLogs retrieves audit logs with filtering and pagination.

func (*AuditService) LogAgentActivated

func (s *AuditService) LogAgentActivated(ctx context.Context, actx AuditContext, agentID, agentName string) error

LogAgentActivated logs an agent activation event.

func (*AuditService) LogAgentConnected

func (s *AuditService) LogAgentConnected(ctx context.Context, actx AuditContext, agentID, agentName, ipAddress string) error

LogAgentConnected logs when an agent first connects (comes online).

func (*AuditService) LogAgentCreated

func (s *AuditService) LogAgentCreated(ctx context.Context, actx AuditContext, agentID, agentName, agentType string) error

LogAgentCreated logs an agent creation event.

func (*AuditService) LogAgentDeactivated

func (s *AuditService) LogAgentDeactivated(ctx context.Context, actx AuditContext, agentID, agentName, reason string) error

LogAgentDeactivated logs an agent deactivation event.

func (*AuditService) LogAgentDeleted

func (s *AuditService) LogAgentDeleted(ctx context.Context, actx AuditContext, agentID, agentName string) error

LogAgentDeleted logs an agent deletion event.

func (*AuditService) LogAgentDisconnected

func (s *AuditService) LogAgentDisconnected(ctx context.Context, actx AuditContext, agentID, agentName string) error

LogAgentDisconnected logs when an agent goes offline (timeout).

func (*AuditService) LogAgentKeyRegenerated

func (s *AuditService) LogAgentKeyRegenerated(ctx context.Context, actx AuditContext, agentID, agentName string) error

LogAgentKeyRegenerated logs an agent API key regeneration event.

func (*AuditService) LogAgentRevoked

func (s *AuditService) LogAgentRevoked(ctx context.Context, actx AuditContext, agentID, agentName, reason string) error

LogAgentRevoked logs an agent revocation event.

func (*AuditService) LogAgentUpdated

func (s *AuditService) LogAgentUpdated(ctx context.Context, actx AuditContext, agentID, agentName string, changes *audit.Changes) error

LogAgentUpdated logs an agent update event.

func (*AuditService) LogAuthFailed

func (s *AuditService) LogAuthFailed(ctx context.Context, actx AuditContext, reason string) error

LogAuthFailed logs an authentication failure event.

func (*AuditService) LogCredentialAccessed

func (s *AuditService) LogCredentialAccessed(ctx context.Context, actx AuditContext, credID, name string) error

LogCredentialAccessed logs a credential access (decrypt) event.

func (*AuditService) LogCredentialCreated

func (s *AuditService) LogCredentialCreated(ctx context.Context, actx AuditContext, credID, name, credType string) error

LogCredentialCreated logs a credential creation event.

func (*AuditService) LogCredentialDeleted

func (s *AuditService) LogCredentialDeleted(ctx context.Context, actx AuditContext, credID string) error

LogCredentialDeleted logs a credential deletion event.

func (*AuditService) LogCredentialUpdated

func (s *AuditService) LogCredentialUpdated(ctx context.Context, actx AuditContext, credID, name string) error

LogCredentialUpdated logs a credential update event.

func (*AuditService) LogEvent

func (s *AuditService) LogEvent(ctx context.Context, actx AuditContext, event AuditEvent) error

LogEvent creates and persists an audit log entry.

func (*AuditService) LogInvitationAccepted

func (s *AuditService) LogInvitationAccepted(ctx context.Context, actx AuditContext, invitationID, email string) error

LogInvitationAccepted logs an invitation acceptance event.

func (*AuditService) LogInvitationCreated

func (s *AuditService) LogInvitationCreated(ctx context.Context, actx AuditContext, invitationID, email, role string) error

LogInvitationCreated logs an invitation creation event.

func (*AuditService) LogMemberAdded

func (s *AuditService) LogMemberAdded(ctx context.Context, actx AuditContext, membershipID, email, role string) error

LogMemberAdded logs a member addition event.

func (*AuditService) LogMemberRemoved

func (s *AuditService) LogMemberRemoved(ctx context.Context, actx AuditContext, membershipID, email string) error

LogMemberRemoved logs a member removal event.

func (*AuditService) LogMemberRoleChanged

func (s *AuditService) LogMemberRoleChanged(ctx context.Context, actx AuditContext, membershipID, email, oldRole, newRole string) error

LogMemberRoleChanged logs a member role change event.

func (*AuditService) LogPermissionDenied

func (s *AuditService) LogPermissionDenied(ctx context.Context, actx AuditContext, resourceType audit.ResourceType, resourceID, action, reason string) error

LogPermissionDenied logs a permission denied event.

func (*AuditService) LogRuleOverrideCreated

func (s *AuditService) LogRuleOverrideCreated(ctx context.Context, actx AuditContext, overrideID, pattern string) error

LogRuleOverrideCreated logs a rule override creation event.

func (*AuditService) LogRuleOverrideDeleted

func (s *AuditService) LogRuleOverrideDeleted(ctx context.Context, actx AuditContext, overrideID, pattern string) error

LogRuleOverrideDeleted logs a rule override deletion event.

func (*AuditService) LogRuleOverrideUpdated

func (s *AuditService) LogRuleOverrideUpdated(ctx context.Context, actx AuditContext, overrideID, pattern string) error

LogRuleOverrideUpdated logs a rule override update event.

func (*AuditService) LogRuleSourceCreated

func (s *AuditService) LogRuleSourceCreated(ctx context.Context, actx AuditContext, sourceID, name, sourceType string) error

LogRuleSourceCreated logs a rule source creation event.

func (*AuditService) LogRuleSourceDeleted

func (s *AuditService) LogRuleSourceDeleted(ctx context.Context, actx AuditContext, sourceID, name string) error

LogRuleSourceDeleted logs a rule source deletion event.

func (*AuditService) LogRuleSourceUpdated

func (s *AuditService) LogRuleSourceUpdated(ctx context.Context, actx AuditContext, sourceID, name string) error

LogRuleSourceUpdated logs a rule source update event.

func (*AuditService) LogUserCreated

func (s *AuditService) LogUserCreated(ctx context.Context, actx AuditContext, userID, email string) error

LogUserCreated logs a user creation event.

func (*AuditService) LogUserLogin

func (s *AuditService) LogUserLogin(ctx context.Context, actx AuditContext, userID, email string) error

LogUserLogin logs a user login event.

func (*AuditService) LogUserLogout

func (s *AuditService) LogUserLogout(ctx context.Context, actx AuditContext, userID, email string) error

LogUserLogout logs a user logout event.

func (*AuditService) LogUserRegistered

func (s *AuditService) LogUserRegistered(ctx context.Context, actx AuditContext, userID, email string) error

LogUserRegistered logs a user registration event.

func (*AuditService) LogUserSuspended

func (s *AuditService) LogUserSuspended(ctx context.Context, actx AuditContext, userID, email, reason string) error

LogUserSuspended logs a user suspension event.

func (*AuditService) LogUserUpdated

func (s *AuditService) LogUserUpdated(ctx context.Context, actx AuditContext, userID, email string, changes *audit.Changes) error

LogUserUpdated logs a user update event.

type AuthService

type AuthService struct {
	// contains filtered or unexported fields
}

AuthService handles authentication operations.

func NewAuthService

func NewAuthService(
	userRepo user.Repository,
	sessionRepo session.Repository,
	refreshTokenRepo session.RefreshTokenRepository,
	tenantRepo tenant.Repository,
	auditService *AuditService,
	cfg config.AuthConfig,
	log *logger.Logger,
) *AuthService

NewAuthService creates a new AuthService.

func (*AuthService) AcceptInvitationWithRefreshToken

AcceptInvitationWithRefreshToken accepts an invitation using a refresh token. This endpoint is for users who were invited but don't have a tenant yet, so they only have a refresh token (no access token).

func (*AuthService) ChangePassword

func (s *AuthService) ChangePassword(ctx context.Context, userID string, input ChangePasswordInput) error

ChangePassword changes a user's password (requires authentication).

func (*AuthService) CreateFirstTeam

func (s *AuthService) CreateFirstTeam(ctx context.Context, input CreateFirstTeamInput) (*CreateFirstTeamResult, error)

CreateFirstTeam creates the first team for a user who has no tenants. This endpoint uses refresh_token for authentication since user has no access_token yet.

func (*AuthService) ExchangeToken

func (s *AuthService) ExchangeToken(ctx context.Context, input ExchangeTokenInput) (*ExchangeTokenResult, error)

ExchangeToken exchanges a global refresh token for a tenant-scoped access token. This is the main method for getting access tokens after login.

func (*AuthService) ForgotPassword

func (s *AuthService) ForgotPassword(ctx context.Context, input ForgotPasswordInput) (*ForgotPasswordResult, error)

ForgotPassword initiates a password reset.

func (*AuthService) GenerateWSToken

func (s *AuthService) GenerateWSToken(ctx context.Context, userID, tenantID string) (string, error)

GenerateWSToken generates a short-lived token for WebSocket authentication. This is needed because WebSocket connections cannot use httpOnly cookies when the connection is cross-origin (different port in development). The token is valid for 30 seconds - just enough time to establish the connection.

func (*AuthService) Login

func (s *AuthService) Login(ctx context.Context, input LoginInput) (*LoginResult, error)

Login authenticates a user and creates a session. Returns a global refresh token and list of tenant memberships. Client should call ExchangeToken to get a tenant-scoped access token.

func (*AuthService) Logout

func (s *AuthService) Logout(ctx context.Context, sessionID string) error

Logout revokes a session.

func (*AuthService) RefreshToken

func (s *AuthService) RefreshToken(ctx context.Context, input RefreshTokenInput) (*RefreshTokenResult, error)

RefreshToken rotates the refresh token and issues new tenant-scoped access token. This implements token rotation for security while providing tenant-scoped access.

func (*AuthService) Register

func (s *AuthService) Register(ctx context.Context, input RegisterInput) (*RegisterResult, error)

Register creates a new local user account. Security note: To prevent email enumeration attacks, this method returns a success result even if the email already exists. The caller should always display a generic "check your email" message regardless of the result.

func (*AuthService) ResetPassword

func (s *AuthService) ResetPassword(ctx context.Context, input ResetPasswordInput) error

ResetPassword resets a user's password using the reset token.

func (*AuthService) SetRoleService

func (s *AuthService) SetRoleService(roleService *RoleService)

SetRoleService sets the role service for database-driven permissions. When set, the auth service will fetch permissions from the database instead of using hardcoded role-permission mappings.

func (*AuthService) ValidateAccessToken

func (s *AuthService) ValidateAccessToken(tokenString string) (*jwt.Claims, error)

ValidateAccessToken validates an access token and returns the claims.

func (*AuthService) VerifyEmail

func (s *AuthService) VerifyEmail(ctx context.Context, token string) error

VerifyEmail verifies a user's email with the verification token.

type AuthorizationURLInput

type AuthorizationURLInput struct {
	Provider      OAuthProvider
	RedirectURI   string // Frontend callback URL
	FinalRedirect string // Where to redirect after successful auth
}

AuthorizationURLInput represents input for getting authorization URL.

type AuthorizationURLResult

type AuthorizationURLResult struct {
	AuthorizationURL string `json:"authorization_url"`
	State            string `json:"state"`
}

AuthorizationURLResult represents the result of getting authorization URL.

type BranchService

type BranchService struct {
	// contains filtered or unexported fields
}

BranchService handles branch-related business operations.

func NewBranchService

func NewBranchService(repo branch.Repository, log *logger.Logger) *BranchService

NewBranchService creates a new BranchService.

func (*BranchService) CountRepositoryBranches

func (s *BranchService) CountRepositoryBranches(ctx context.Context, repositoryID string) (int64, error)

CountRepositoryBranches counts branches for a repository.

func (*BranchService) CreateBranch

func (s *BranchService) CreateBranch(ctx context.Context, input CreateBranchInput) (*branch.Branch, error)

CreateBranch creates a new branch.

func (*BranchService) DeleteBranch

func (s *BranchService) DeleteBranch(ctx context.Context, branchID, repositoryID string) error

DeleteBranch deletes a branch by ID.

func (*BranchService) GetBranch

func (s *BranchService) GetBranch(ctx context.Context, branchID string) (*branch.Branch, error)

GetBranch retrieves a branch by ID.

func (*BranchService) GetBranchByName

func (s *BranchService) GetBranchByName(ctx context.Context, repositoryID, name string) (*branch.Branch, error)

GetBranchByName retrieves a branch by repository ID and name.

func (*BranchService) GetDefaultBranch

func (s *BranchService) GetDefaultBranch(ctx context.Context, repositoryID string) (*branch.Branch, error)

GetDefaultBranch retrieves the default branch for a repository.

func (*BranchService) ListBranches

ListBranches retrieves branches with filtering and pagination.

func (*BranchService) ListRepositoryBranches

func (s *BranchService) ListRepositoryBranches(ctx context.Context, repositoryID string) ([]*branch.Branch, error)

ListRepositoryBranches retrieves all branches for a repository.

func (*BranchService) SetDefaultBranch

func (s *BranchService) SetDefaultBranch(ctx context.Context, branchID, repositoryID string) (*branch.Branch, error)

SetDefaultBranch sets a branch as the default for a repository.

func (*BranchService) UpdateBranch

func (s *BranchService) UpdateBranch(ctx context.Context, branchID, repositoryID string, input UpdateBranchInput) (*branch.Branch, error)

UpdateBranch updates an existing branch.

func (*BranchService) UpdateBranchScanStatus

func (s *BranchService) UpdateBranchScanStatus(ctx context.Context, branchID, repositoryID string, input UpdateBranchScanStatusInput) (*branch.Branch, error)

UpdateBranchScanStatus updates scan-related fields for a branch.

type BranchTypeRuleInput

type BranchTypeRuleInput struct {
	Pattern    string `json:"pattern" validate:"required,max=100"`
	MatchType  string `json:"match_type" validate:"required,oneof=exact prefix"`
	BranchType string `json:"branch_type" validate:"required,oneof=main develop feature release hotfix"`
}

BranchTypeRuleInput represents a single branch type mapping rule.

type BroadcastNotificationInput

type BroadcastNotificationInput struct {
	TenantID  string
	EventType integration.EventType // Type of event (findings, exposures, scans, alerts)
	Title     string
	Body      string
	Severity  string
	URL       string
	Fields    map[string]string
}

BroadcastNotificationInput represents the input for broadcasting a notification to all connected integrations.

type BulkAssetStatusResult

type BulkAssetStatusResult struct {
	Updated int      `json:"updated"`
	Failed  int      `json:"failed"`
	Errors  []string `json:"errors,omitempty"`
}

BulkAssetStatusResult represents the result of a bulk asset status operation.

type BulkAssignInput

type BulkAssignInput struct {
	FindingIDs []string
	UserID     string
	AssignerID string
}

BulkAssignInput represents input for bulk assignment.

type BulkAssignRoleToUsersInput

type BulkAssignRoleToUsersInput struct {
	TenantID string   `json:"-"`
	RoleID   string   `json:"role_id" validate:"required,uuid"`
	UserIDs  []string `json:"user_ids" validate:"required,min=1,dive,uuid"`
}

BulkAssignRoleToUsersInput represents the input for bulk role assignment.

type BulkAssignRoleToUsersResult

type BulkAssignRoleToUsersResult struct {
	SuccessCount int      `json:"success_count"`
	FailedCount  int      `json:"failed_count"`
	FailedUsers  []string `json:"failed_users,omitempty"`
}

BulkAssignRoleToUsersResult represents the result of bulk role assignment.

type BulkDisableToolsInput

type BulkDisableToolsInput struct {
	TenantID string   `json:"tenant_id" validate:"required,uuid"`
	ToolIDs  []string `json:"tool_ids" validate:"required,min=1,dive,uuid"`
}

BulkDisableToolsInput represents the input for bulk disabling tools.

type BulkEnableToolsInput

type BulkEnableToolsInput struct {
	TenantID string   `json:"tenant_id" validate:"required,uuid"`
	ToolIDs  []string `json:"tool_ids" validate:"required,min=1,dive,uuid"`
}

BulkEnableToolsInput represents the input for bulk enabling tools.

type BulkTriageJob

type BulkTriageJob struct {
	FindingID string `json:"finding_id"`
	JobID     string `json:"job_id,omitempty"`
	Status    string `json:"status"`
	Error     string `json:"error,omitempty"`
}

BulkTriageJob represents a single job in bulk triage.

type BulkTriageRequest

type BulkTriageRequest struct {
	TenantID   string   `validate:"required,uuid"`
	FindingIDs []string `validate:"required,min=1,max=100,dive,uuid"`
	UserID     *string  `validate:"omitempty,uuid"`
}

BulkTriageRequest represents a request to triage multiple findings.

type BulkTriageResponse

type BulkTriageResponse struct {
	Jobs       []BulkTriageJob `json:"jobs"`
	TotalCount int             `json:"total_count"`
	Queued     int             `json:"queued"`
	Failed     int             `json:"failed"`
}

BulkTriageResponse represents the response from a bulk triage request.

type BulkUpdateAssetStatusInput

type BulkUpdateAssetStatusInput struct {
	AssetIDs []string
	Status   string // "active", "inactive", "archived"
}

BulkUpdateAssetStatusInput represents input for bulk asset status update.

type BulkUpdateInput

type BulkUpdateInput struct {
	GroupIDs    []string
	Environment *string `validate:"omitempty,asset_group_environment"`
	Criticality *string `validate:"omitempty,asset_group_criticality"`
}

BulkUpdateInput represents input for bulk updating asset groups.

type BulkUpdateResult

type BulkUpdateResult struct {
	Updated int
	Failed  int
	Errors  []string
}

BulkUpdateResult represents the result of a bulk operation.

type BulkUpdateStatusInput

type BulkUpdateStatusInput struct {
	FindingIDs []string
	Status     string
	Resolution string
	ActorID    string // User performing the bulk update
}

BulkUpdateStatusInput represents input for bulk status update.

type CachedCategory

type CachedCategory struct {
	ID           string `json:"id"`
	Code         string `json:"code"`
	Name         string `json:"name"`
	Description  string `json:"description,omitempty"`
	Icon         string `json:"icon,omitempty"`
	DisplayOrder int    `json:"display_order"`
}

CachedCategory represents a category in the cache.

type CachedFindingSource

type CachedFindingSource struct {
	ID           string `json:"id"`
	Code         string `json:"code"`
	Name         string `json:"name"`
	Description  string `json:"description,omitempty"`
	CategoryID   string `json:"category_id,omitempty"`
	CategoryCode string `json:"category_code,omitempty"`
	CategoryName string `json:"category_name,omitempty"`
	Icon         string `json:"icon,omitempty"`
	Color        string `json:"color,omitempty"`
	DisplayOrder int    `json:"display_order"`
	IsSystem     bool   `json:"is_system"`
}

CachedFindingSource represents a finding source in the cache.

type CachedFindingSources

type CachedFindingSources struct {
	Sources    []*CachedFindingSource `json:"sources"`
	Categories []*CachedCategory      `json:"categories"`
	ByCode     map[string]int         `json:"by_code"`     // code -> index in Sources for O(1) lookup
	ByCategory map[string][]int       `json:"by_category"` // category_code -> indices in Sources
	CachedAt   time.Time              `json:"cached_at"`
}

CachedFindingSources represents the cached finding source data.

type CachedModule

type CachedModule struct {
	ID             string   `json:"id"`
	Slug           string   `json:"slug"`
	Name           string   `json:"name"`
	Description    string   `json:"description,omitempty"`
	Icon           string   `json:"icon,omitempty"`
	Category       string   `json:"category"`
	DisplayOrder   int      `json:"display_order"`
	IsActive       bool     `json:"is_active"`
	ReleaseStatus  string   `json:"release_status"`
	ParentModuleID *string  `json:"parent_module_id,omitempty"`
	EventTypes     []string `json:"event_types,omitempty"`
}

CachedModule represents a module in the cache.

type CachedTenantModules

type CachedTenantModules struct {
	ModuleIDs  []string                   `json:"module_ids"`
	Modules    []*CachedModule            `json:"modules"`
	SubModules map[string][]*CachedModule `json:"sub_modules,omitempty"`
	EventTypes map[string][]string        `json:"event_types,omitempty"` // module_id -> event_types
	CachedAt   time.Time                  `json:"cached_at"`
}

CachedTenantModules represents the cached module data for a tenant.

func (*CachedTenantModules) ToModules

func (c *CachedTenantModules) ToModules() []*module.Module

ToModules converts cached modules to domain modules.

func (*CachedTenantModules) ToSubModulesMap

func (c *CachedTenantModules) ToSubModulesMap() map[string][]*module.Module

ToSubModules converts cached sub-modules to domain modules map.

type CallbackInput

type CallbackInput struct {
	Provider    OAuthProvider
	Code        string
	State       string
	RedirectURI string
}

CallbackInput represents the OAuth callback input.

type CallbackResult

type CallbackResult struct {
	AccessToken  string     `json:"access_token"`
	RefreshToken string     `json:"refresh_token"`
	ExpiresIn    int64      `json:"expires_in"`
	TokenType    string     `json:"token_type"`
	User         *user.User `json:"user"`
}

CallbackResult represents the OAuth callback result.

type CapabilityService

type CapabilityService struct {
	// contains filtered or unexported fields
}

CapabilityService handles capability business operations.

func NewCapabilityService

func NewCapabilityService(
	repo capability.Repository,
	auditService *AuditService,
	log *logger.Logger,
) *CapabilityService

NewCapabilityService creates a new CapabilityService.

func (*CapabilityService) CreateCapability

CreateCapability creates a new tenant custom capability.

func (*CapabilityService) DeleteCapability

func (s *CapabilityService) DeleteCapability(ctx context.Context, input DeleteCapabilityInput) error

DeleteCapability deletes a tenant custom capability. If capability is in use and Force is false, returns ErrConflict with usage info.

func (*CapabilityService) GetCapabilitiesUsageStatsBatch

func (s *CapabilityService) GetCapabilitiesUsageStatsBatch(ctx context.Context, tenantIDStr string, capabilityIDs []string) (map[string]*CapabilityUsageStatsOutput, error)

GetCapabilitiesUsageStatsBatch returns usage statistics for multiple capabilities. Security: Filters out capabilities the tenant doesn't have access to.

func (*CapabilityService) GetCapability

func (s *CapabilityService) GetCapability(ctx context.Context, id string) (*capability.Capability, error)

GetCapability returns a capability by ID.

func (*CapabilityService) GetCapabilityUsageStats

func (s *CapabilityService) GetCapabilityUsageStats(ctx context.Context, tenantIDStr string, capabilityID string) (*CapabilityUsageStatsOutput, error)

GetCapabilityUsageStats returns usage statistics for a capability. Security: Validates tenant has access to view the capability (platform or owned custom).

func (*CapabilityService) GetCategories

func (s *CapabilityService) GetCategories(ctx context.Context) ([]string, error)

GetCategories returns all unique capability categories.

func (*CapabilityService) ListAllCapabilities

func (s *CapabilityService) ListAllCapabilities(ctx context.Context, tenantID string) ([]*capability.Capability, error)

ListAllCapabilities returns all capabilities for a tenant context (for dropdowns).

func (*CapabilityService) ListCapabilities

ListCapabilities returns capabilities matching the filter. Always includes platform (builtin) capabilities. If TenantID is provided, also includes that tenant's custom capabilities.

func (*CapabilityService) ListCapabilitiesByCategory

func (s *CapabilityService) ListCapabilitiesByCategory(ctx context.Context, tenantID string, category string) ([]*capability.Capability, error)

ListCapabilitiesByCategory returns all capabilities in a category.

func (*CapabilityService) ListCapabilitiesByNames

func (s *CapabilityService) ListCapabilitiesByNames(ctx context.Context, tenantID string, names []string) ([]*capability.Capability, error)

ListCapabilitiesByNames returns capabilities by their names.

func (*CapabilityService) UpdateCapability

UpdateCapability updates an existing tenant custom capability.

type CapabilityUsageStatsOutput

type CapabilityUsageStatsOutput struct {
	ToolCount  int      `json:"tool_count"`
	AgentCount int      `json:"agent_count"`
	ToolNames  []string `json:"tool_names,omitempty"`
	AgentNames []string `json:"agent_names,omitempty"`
}

CapabilityUsageStatsOutput represents usage statistics for a capability.

type ChangePasswordInput

type ChangePasswordInput struct {
	CurrentPassword string `json:"current_password" validate:"required"`
	NewPassword     string `json:"new_password" validate:"required,min=8,max=128"`
}

ChangePasswordInput represents the input for changing password.

type ChangeStateInput

type ChangeStateInput struct {
	ExposureID string `validate:"required,uuid"`
	NewState   string `validate:"required"`
	UserID     string `validate:"required,uuid"`
	Reason     string `validate:"max=500"`
}

ChangeStateInput represents the input for changing exposure state.

type ClassifyFindingInput

type ClassifyFindingInput struct {
	CVEID      string
	CVSSScore  *float64
	CVSSVector string
	CWEIDs     []string
	OWASPIDs   []string
}

ClassifyFindingInput represents input for classification.

type CloneScanProfileInput

type CloneScanProfileInput struct {
	TenantID  string `json:"tenant_id" validate:"required,uuid"`
	ProfileID string `json:"profile_id" validate:"required,uuid"`
	NewName   string `json:"new_name" validate:"required,min=1,max=100"`
	UserID    string `json:"user_id" validate:"omitempty,uuid"`
}

CloneScanProfileInput represents the input for cloning a scan profile.

type CommandExpirationChecker

type CommandExpirationChecker struct {
	// contains filtered or unexported fields
}

CommandExpirationChecker periodically checks for expired commands and handles them.

func NewCommandExpirationChecker

func NewCommandExpirationChecker(
	commandRepo command.Repository,
	pipelineService *pipeline.Service,
	cfg CommandExpirationCheckerConfig,
	log *logger.Logger,
) *CommandExpirationChecker

NewCommandExpirationChecker creates a new CommandExpirationChecker.

func (*CommandExpirationChecker) Start

func (c *CommandExpirationChecker) Start()

Start starts the command expiration checker.

func (*CommandExpirationChecker) Stop

func (c *CommandExpirationChecker) Stop()

Stop stops the command expiration checker gracefully.

type CommandExpirationCheckerConfig

type CommandExpirationCheckerConfig struct {
	// CheckInterval is how often to check for expired commands (default: 1 minute)
	CheckInterval time.Duration
}

CommandExpirationCheckerConfig holds configuration for the command expiration checker.

type CommandService

type CommandService struct {
	// contains filtered or unexported fields
}

CommandService handles command-related business operations.

func NewCommandService

func NewCommandService(repo command.Repository, log *logger.Logger) *CommandService

NewCommandService creates a new CommandService.

func (*CommandService) AcknowledgeCommand

func (s *CommandService) AcknowledgeCommand(ctx context.Context, tenantID, commandID string) (*command.Command, error)

AcknowledgeCommand marks a command as acknowledged.

func (*CommandService) CancelCommand

func (s *CommandService) CancelCommand(ctx context.Context, tenantID, commandID string) (*command.Command, error)

CancelCommand marks a command as canceled.

func (*CommandService) CompleteCommand

func (s *CommandService) CompleteCommand(ctx context.Context, input CompleteCommandInput) (*command.Command, error)

CompleteCommand marks a command as completed.

func (*CommandService) CreateCommand

func (s *CommandService) CreateCommand(ctx context.Context, input CreateCommandInput) (*command.Command, error)

CreateCommand creates a new command.

func (*CommandService) DeleteCommand

func (s *CommandService) DeleteCommand(ctx context.Context, tenantID, commandID string) error

DeleteCommand deletes a command.

func (*CommandService) ExpireOldCommands

func (s *CommandService) ExpireOldCommands(ctx context.Context) (int64, error)

ExpireOldCommands expires old pending commands.

func (*CommandService) FailCommand

func (s *CommandService) FailCommand(ctx context.Context, input FailCommandInput) (*command.Command, error)

FailCommand marks a command as failed.

func (*CommandService) GetCommand

func (s *CommandService) GetCommand(ctx context.Context, tenantID, commandID string) (*command.Command, error)

GetCommand retrieves a command by ID.

func (*CommandService) ListCommands

ListCommands lists commands with filters.

func (*CommandService) PollCommands

func (s *CommandService) PollCommands(ctx context.Context, input PollCommandsInput) ([]*command.Command, error)

PollCommands retrieves pending commands for an agent.

func (*CommandService) StartCommand

func (s *CommandService) StartCommand(ctx context.Context, tenantID, commandID string) (*command.Command, error)

StartCommand marks a command as running.

type CompleteBundleInput

type CompleteBundleInput struct {
	BundleID     string            `json:"bundle_id" validate:"required,uuid"`
	Version      string            `json:"version" validate:"required,max=50"`
	ContentHash  string            `json:"content_hash" validate:"required,max=64"`
	RuleCount    int               `json:"rule_count" validate:"min=0"`
	SourceCount  int               `json:"source_count" validate:"min=0"`
	SizeBytes    int64             `json:"size_bytes" validate:"min=0"`
	SourceHashes map[string]string `json:"source_hashes"`
	ExpiresAt    *string           `json:"expires_at"` // RFC3339 format
}

CompleteBundleInput represents the input for completing a bundle build.

type CompleteCommandInput

type CompleteCommandInput struct {
	TenantID  string          `json:"tenant_id" validate:"required,uuid"`
	CommandID string          `json:"command_id" validate:"required,uuid"`
	Result    json.RawMessage `json:"result,omitempty"`
}

CompleteCommandInput represents the input for completing a command.

type CompleteToolExecutionInput

type CompleteToolExecutionInput struct {
	ExecutionID   string         `json:"execution_id" validate:"required,uuid"`
	FindingsCount int            `json:"findings_count"`
	OutputSummary map[string]any `json:"output_summary"`
}

CompleteToolExecutionInput represents the input for completing a tool execution.

type ComponentService

type ComponentService struct {
	// contains filtered or unexported fields
}

ComponentService handles component-related business operations.

func NewComponentService

func NewComponentService(repo component.Repository, log *logger.Logger) *ComponentService

NewComponentService creates a new ComponentService.

func (*ComponentService) CreateComponent

func (s *ComponentService) CreateComponent(ctx context.Context, input CreateComponentInput) (*component.Component, error)

CreateComponent creates a new component (Global) and links it to an asset.

func (*ComponentService) DeleteAssetComponents

func (s *ComponentService) DeleteAssetComponents(ctx context.Context, assetID string) error

DeleteAssetComponents deletes all components for an asset.

func (*ComponentService) DeleteComponent

func (s *ComponentService) DeleteComponent(ctx context.Context, dependencyID string, tenantID string) error

DeleteComponent deletes a component dependency linkage.

func (*ComponentService) GetComponent

func (s *ComponentService) GetComponent(ctx context.Context, componentID string) (*component.Component, error)

GetComponent retrieves a component by ID.

func (*ComponentService) GetComponentByPURL

func (s *ComponentService) GetComponentByPURL(ctx context.Context, tenantID, purl string) (*component.Component, error)

GetComponentByPURL retrieves a component by Package URL.

func (*ComponentService) GetComponentStats

func (s *ComponentService) GetComponentStats(ctx context.Context, tenantID string) (*component.ComponentStats, error)

GetComponentStats retrieves aggregated component statistics for a tenant.

func (*ComponentService) GetEcosystemStats

func (s *ComponentService) GetEcosystemStats(ctx context.Context, tenantID string) ([]component.EcosystemStats, error)

GetEcosystemStats retrieves per-ecosystem statistics for a tenant.

func (*ComponentService) GetLicenseStats

func (s *ComponentService) GetLicenseStats(ctx context.Context, tenantID string) ([]component.LicenseStats, error)

GetLicenseStats retrieves license statistics for a tenant.

func (*ComponentService) GetVulnerableComponents

func (s *ComponentService) GetVulnerableComponents(ctx context.Context, tenantID string, limit int) ([]component.VulnerableComponent, error)

GetVulnerableComponents retrieves vulnerable components with details for a tenant.

func (*ComponentService) ListAssetComponents

func (s *ComponentService) ListAssetComponents(ctx context.Context, assetID string, page, perPage int) (pagination.Result[*component.AssetDependency], error)

ListAssetComponents retrieves components for a specific asset (Dependencies).

func (*ComponentService) ListComponents

ListComponents retrieves components with filtering and pagination.

func (*ComponentService) UpdateComponent

func (s *ComponentService) UpdateComponent(ctx context.Context, dependencyID string, tenantID string, input UpdateComponentInput) (*component.AssetDependency, error)

UpdateComponent updates a component (specifically an Asset Dependency link). NOTE: For now, we assume edits are focused on the context (path, type). Updating global properties (Version, License) would theoretically require creating a NEW component and re-linking, which is complex. For version bumps, we recommend re-ingestion or Delete+Create. If input.Version is provided, we will return an error or handle it as "not supported via this endpoint" for now, or we implement the re-link logic. DECISION: We will assume `componentID` passed here is the `AssetDependency.ID`.

type ConditionEvaluator

type ConditionEvaluator interface {
	// Evaluate evaluates a condition expression against the given data.
	Evaluate(ctx context.Context, expression string, data map[string]any) (bool, error)
}

ConditionEvaluator defines the interface for condition evaluation.

type CreateAPIKeyInput

type CreateAPIKeyInput struct {
	TenantID      string   `json:"tenant_id" validate:"required,uuid"`
	UserID        string   `json:"user_id" validate:"omitempty,uuid"`
	Name          string   `json:"name" validate:"required,min=1,max=255"`
	Description   string   `json:"description" validate:"max=1000"`
	Scopes        []string `json:"scopes" validate:"max=50"`
	RateLimit     int      `json:"rate_limit"`
	ExpiresInDays int      `json:"expires_in_days"`
	CreatedBy     string   `json:"created_by" validate:"omitempty,uuid"`
}

CreateAPIKeyInput represents input for creating an API key.

type CreateAPIKeyResult

type CreateAPIKeyResult struct {
	Key       *apikey.APIKey
	Plaintext string // Only returned once on creation
}

CreateAPIKeyResult holds the created key and its plaintext (shown only once).

type CreateAgentInput

type CreateAgentInput struct {
	TenantID          string   `json:"tenant_id" validate:"required,uuid"`
	Name              string   `json:"name" validate:"required,min=1,max=255"`
	Type              string   `json:"type" validate:"required,oneof=runner worker collector sensor"`
	Description       string   `json:"description" validate:"max=1000"`
	Capabilities      []string `json:"capabilities" validate:"max=20,dive,max=50"`
	Tools             []string `json:"tools" validate:"max=20,dive,max=50"`
	ExecutionMode     string   `json:"execution_mode" validate:"omitempty,oneof=standalone daemon"`
	MaxConcurrentJobs int      `json:"max_concurrent_jobs" validate:"omitempty,min=1,max=100"`
	// Audit context (optional, for audit logging)
	AuditContext *AuditContext `json:"-"`
}

CreateAgentInput represents the input for creating an agent.

type CreateAgentOutput

type CreateAgentOutput struct {
	Agent  *agent.Agent `json:"agent"`
	APIKey string       `json:"api_key"` // Only returned on creation
}

CreateAgentOutput represents the output after creating an agent.

type CreateAssetGroupInput

type CreateAssetGroupInput struct {
	TenantID     string
	Name         string   `validate:"required,min=1,max=255"`
	Description  string   `validate:"max=1000"`
	Environment  string   `validate:"required,asset_group_environment"`
	Criticality  string   `validate:"required,asset_group_criticality"`
	BusinessUnit string   `validate:"max=255"`
	Owner        string   `validate:"max=255"`
	OwnerEmail   string   `validate:"omitempty,email,max=255"`
	Tags         []string `validate:"max=20,dive,max=50"`
	AssetIDs     []string `validate:"dive,uuid"`
}

CreateAssetGroupInput represents input for creating an asset group.

type CreateAssetInput

type CreateAssetInput struct {
	TenantID    string   `validate:"omitempty,uuid"`
	Name        string   `validate:"required,min=1,max=255"`
	Type        string   `validate:"required,asset_type"`
	Criticality string   `validate:"required,criticality"`
	Scope       string   `validate:"omitempty,scope"`
	Exposure    string   `validate:"omitempty,exposure"`
	Description string   `validate:"max=1000"`
	Tags        []string `validate:"max=20,dive,max=50"`
}

CreateAssetInput represents the input for creating an asset.

type CreateBranchInput

type CreateBranchInput struct {
	RepositoryID  string `validate:"required,uuid"`
	Name          string `validate:"required,min=1,max=255"`
	BranchType    string `validate:"required,branch_type"`
	IsDefault     bool
	IsProtected   bool
	LastCommitSHA string `validate:"max=40"`
}

CreateBranchInput represents the input for creating a branch.

type CreateBundleInput

type CreateBundleInput struct {
	TenantID    string   `json:"tenant_id" validate:"required,uuid"`
	ToolID      string   `json:"tool_id" validate:"required,uuid"`
	SourceIDs   []string `json:"source_ids" validate:"required,min=1,dive,uuid"`
	StoragePath string   `json:"storage_path" validate:"required,max=500"`
}

CreateBundleInput represents the input for creating a rule bundle.

type CreateCapabilityInput

type CreateCapabilityInput struct {
	TenantID    string `json:"-"`
	CreatedBy   string `json:"-"`
	Name        string `json:"name" validate:"required,min=2,max=50"`
	DisplayName string `json:"display_name" validate:"required,max=100"`
	Description string `json:"description" validate:"max=500"`
	Icon        string `json:"icon" validate:"max=50"`
	Color       string `json:"color" validate:"max=20"`
	Category    string `json:"category" validate:"max=50"`

	// Audit context (set by handler)
	AuditContext AuditContext `json:"-"`
}

CreateCapabilityInput represents the input for creating a tenant custom capability.

type CreateCategoryInput

type CreateCategoryInput struct {
	TenantID    string `json:"-"`
	CreatedBy   string `json:"-"`
	Name        string `json:"name" validate:"required,min=2,max=50"`
	DisplayName string `json:"display_name" validate:"required,max=100"`
	Description string `json:"description" validate:"max=500"`
	Icon        string `json:"icon" validate:"max=50"`
	Color       string `json:"color" validate:"max=20"`
}

CreateCategoryInput represents the input for creating a tenant custom category.

type CreateCommandInput

type CreateCommandInput struct {
	TenantID  string          `json:"tenant_id" validate:"required,uuid"`
	AgentID   string          `json:"agent_id,omitempty" validate:"omitempty,uuid"`
	Type      string          `json:"type" validate:"required,oneof=scan collect health_check config_update cancel"`
	Priority  string          `json:"priority" validate:"omitempty,oneof=low normal high critical"`
	Payload   json.RawMessage `json:"payload,omitempty"`
	ExpiresIn int             `json:"expires_in,omitempty"` // Seconds until expiration
}

CreateCommandInput represents the input for creating a command.

type CreateComponentInput

type CreateComponentInput struct {
	TenantID       string `validate:"required,uuid"`
	AssetID        string `validate:"required,uuid"`
	Name           string `validate:"required,min=1,max=255"`
	Version        string `validate:"required,max=100"`
	Ecosystem      string `validate:"required,ecosystem"`
	PackageManager string `validate:"max=50"`
	Namespace      string `validate:"max=255"`
	ManifestFile   string `validate:"max=255"`
	ManifestPath   string `validate:"max=500"`
	DependencyType string `validate:"omitempty,dependency_type"`
	License        string `validate:"max=100"`
}

CreateComponentInput represents the input for creating a component.

type CreateCredentialInput

type CreateCredentialInput struct {
	TenantID       shared.ID
	UserID         shared.ID
	Name           string
	CredentialType secretstore.CredentialType
	Description    string
	Data           any // One of the credential data types
	ExpiresAt      *time.Time
}

CreateCredentialInput contains input for creating a secretstore.

type CreateCustomToolInput

type CreateCustomToolInput struct {
	TenantID         string         `json:"tenant_id" validate:"required,uuid"`
	CreatedBy        string         `json:"created_by" validate:"omitempty,uuid"` // User ID who created the tool
	Name             string         `json:"name" validate:"required,min=1,max=50"`
	DisplayName      string         `json:"display_name" validate:"max=100"`
	Description      string         `json:"description" validate:"max=1000"`
	CategoryID       string         `json:"category_id" validate:"omitempty,uuid"` // UUID of tool_categories
	InstallMethod    string         `json:"install_method" validate:"required,oneof=go pip npm docker binary"`
	InstallCmd       string         `json:"install_cmd" validate:"max=500"`
	UpdateCmd        string         `json:"update_cmd" validate:"max=500"`
	VersionCmd       string         `json:"version_cmd" validate:"max=500"`
	VersionRegex     string         `json:"version_regex" validate:"max=200"`
	ConfigSchema     map[string]any `json:"config_schema"`
	DefaultConfig    map[string]any `json:"default_config"`
	Capabilities     []string       `json:"capabilities" validate:"max=20,dive,max=50"`
	SupportedTargets []string       `json:"supported_targets" validate:"max=10,dive,max=50"`
	OutputFormats    []string       `json:"output_formats" validate:"max=10,dive,max=20"`
	DocsURL          string         `json:"docs_url" validate:"omitempty,url,max=500"`
	GithubURL        string         `json:"github_url" validate:"omitempty,url,max=500"`
	LogoURL          string         `json:"logo_url" validate:"omitempty,url,max=500"`
	Tags             []string       `json:"tags" validate:"max=20,dive,max=50"`
}

CreateCustomToolInput represents the input for creating a tenant custom tool.

type CreateEdgeInput

type CreateEdgeInput struct {
	SourceNodeKey string
	TargetNodeKey string
	SourceHandle  string
	Label         string
}

CreateEdgeInput represents input for creating a workflow edge.

type CreateExclusionInput

type CreateExclusionInput struct {
	TenantID      string     `validate:"required,uuid"`
	ExclusionType string     `validate:"required"`
	Pattern       string     `validate:"required,max=500"`
	Reason        string     `validate:"required,max=1000"`
	ExpiresAt     *time.Time `validate:"omitempty"`
	CreatedBy     string     `validate:"max=200"`
}

CreateExclusionInput represents the input for creating a scope exclusion.

type CreateExposureInput

type CreateExposureInput struct {
	TenantID string `validate:"required,uuid"`

	AssetID     string         `validate:"omitempty,uuid"`
	EventType   string         `validate:"required"`
	Severity    string         `validate:"required"`
	Title       string         `validate:"required,min=1,max=500"`
	Description string         `validate:"max=2000"`
	Source      string         `validate:"required,max=100"`
	Details     map[string]any `validate:"omitempty"`
}

CreateExposureInput represents the input for creating an exposure event.

type CreateFindingInput

type CreateFindingInput struct {
	TenantID        string `validate:"required,uuid"`
	AssetID         string `validate:"required,uuid"`
	BranchID        string `validate:"omitempty,uuid"`
	VulnerabilityID string `validate:"omitempty,uuid"`
	ComponentID     string `validate:"omitempty,uuid"`
	Source          string `validate:"required,finding_source"`
	ToolName        string `validate:"required,max=100"`
	ToolVersion     string `validate:"max=50"`
	RuleID          string `validate:"max=255"`
	FilePath        string `validate:"max=500"`
	StartLine       int    `validate:"min=0"`
	EndLine         int    `validate:"min=0"`
	StartColumn     int    `validate:"min=0"`
	EndColumn       int    `validate:"min=0"`
	Snippet         string `validate:"max=5000"`
	Message         string `validate:"required,max=2000"`
	Severity        string `validate:"required,severity"`
	ScanID          string `validate:"max=100"`
}

CreateFindingInput represents the input for creating a finding.

type CreateFirstTeamInput

type CreateFirstTeamInput struct {
	RefreshToken string `json:"refresh_token" validate:"required"`
	TeamName     string `json:"team_name" validate:"required,min=2,max=100"`
	TeamSlug     string `json:"team_slug" validate:"required,min=3,max=50"`
}

CreateFirstTeamInput represents the input for creating first team.

type CreateFirstTeamResult

type CreateFirstTeamResult struct {
	AccessToken  string               `json:"access_token"`
	RefreshToken string               `json:"refresh_token"` // Rotated refresh token
	ExpiresAt    time.Time            `json:"expires_at"`
	Tenant       TenantMembershipInfo `json:"tenant"`
}

CreateFirstTeamResult represents the result of creating first team.

type CreateGroupInput

type CreateGroupInput struct {
	TenantID    string               `json:"-"`
	Name        string               `json:"name" validate:"required,min=2,max=100"`
	Slug        string               `json:"slug" validate:"required,min=2,max=100,slug"`
	Description string               `json:"description" validate:"max=500"`
	GroupType   string               `json:"group_type" validate:"required,oneof=security_team team department project external"`
	Settings    *group.GroupSettings `json:"settings,omitempty"`
}

CreateGroupInput represents the input for creating a group.

type CreateGroupPermissionInput

type CreateGroupPermissionInput struct {
	GroupID      string `json:"-"`
	PermissionID string `json:"permission_id" validate:"required"`
	Effect       string `json:"effect" validate:"required,oneof=allow deny"`
}

CreateGroupPermissionInput represents the input for creating a custom group permission.

type CreateIntegrationInput

type CreateIntegrationInput struct {
	TenantID    string
	Name        string
	Description string
	Category    string
	Provider    string
	AuthType    string
	BaseURL     string
	Credentials string // Access token, API key, etc.

	// SCM-specific fields
	SCMOrganization string
}

CreateIntegrationInput represents the input for creating an integration.

type CreateInvitationInput

type CreateInvitationInput struct {
	Email   string   `json:"email" validate:"required,email"`
	Role    string   `json:"-"`                                  // Internal use only - always set to "member" by handler
	RoleIDs []string `json:"role_ids" validate:"required,min=1"` // RBAC roles to assign (required)
}

CreateInvitationInput represents the input for creating an invitation. Note: All invited users are "member". Permissions come from RBAC roles (RoleIDs).

type CreateNodeInput

type CreateNodeInput struct {
	NodeKey     string
	NodeType    workflow.NodeType
	Name        string
	Description string
	UIPositionX float64
	UIPositionY float64
	Config      workflow.NodeConfig
}

CreateNodeInput represents input for creating a workflow node.

type CreateNotificationIntegrationInput

type CreateNotificationIntegrationInput struct {
	TenantID    string
	Name        string
	Description string
	Provider    string
	AuthType    string
	Credentials string // Webhook URL, Bot Token, etc.

	// Notification-specific fields
	ChannelID          string
	ChannelName        string
	EnabledSeverities  []string // Severity levels to notify on (critical, high, medium, low, info, none)
	EnabledEventTypes  []string // Event types to receive notifications for (security_alert, new_finding, etc.)
	MessageTemplate    string
	IncludeDetails     bool
	MinIntervalMinutes int
}

CreateNotificationIntegrationInput represents the input for creating a notification integration.

type CreateOverrideInput

type CreateOverrideInput struct {
	TenantID         string  `json:"tenant_id" validate:"required,uuid"`
	ToolID           string  `json:"tool_id" validate:"omitempty,uuid"`
	RulePattern      string  `json:"rule_pattern" validate:"required,min=1,max=500"`
	IsPattern        bool    `json:"is_pattern"`
	Enabled          bool    `json:"enabled"`
	SeverityOverride string  `json:"severity_override" validate:"omitempty,oneof=critical high medium low info"`
	AssetGroupID     string  `json:"asset_group_id" validate:"omitempty,uuid"`
	ScanProfileID    string  `json:"scan_profile_id" validate:"omitempty,uuid"`
	Reason           string  `json:"reason" validate:"max=1000"`
	CreatedBy        string  `json:"created_by" validate:"omitempty,uuid"`
	ExpiresAt        *string `json:"expires_at"` // RFC3339 format
}

CreateOverrideInput represents the input for creating a rule override.

type CreatePermissionSetInput

type CreatePermissionSetInput struct {
	TenantID    string   `json:"-"`
	Name        string   `json:"name" validate:"required,min=2,max=100"`
	Slug        string   `json:"slug" validate:"required,min=2,max=100,slug"`
	Description string   `json:"description" validate:"max=500"`
	SetType     string   `json:"set_type" validate:"required,oneof=custom extended cloned"`
	ParentSetID *string  `json:"parent_set_id,omitempty"`
	Permissions []string `json:"permissions,omitempty"` // List of permission IDs to add
}

CreatePermissionSetInput represents the input for creating a permission set.

type CreateRelationshipInput

type CreateRelationshipInput struct {
	TenantID        string   `validate:"required,uuid"`
	SourceAssetID   string   `validate:"required,uuid"`
	TargetAssetID   string   `validate:"required,uuid"`
	Type            string   `validate:"required"`
	Description     string   `validate:"max=1000"`
	Confidence      string   `validate:"omitempty"`
	DiscoveryMethod string   `validate:"omitempty"`
	ImpactWeight    *int     `validate:"omitempty,min=1,max=10"`
	Tags            []string `validate:"omitempty,max=20,dive,max=50"`
}

CreateRelationshipInput represents the input for creating a relationship.

type CreateRepositoryAssetInput

type CreateRepositoryAssetInput struct {
	// Basic info
	TenantID       string   `validate:"omitempty,uuid"`
	Name           string   `validate:"required,min=1,max=255"`
	Description    string   `validate:"max=1000"`
	Criticality    string   `validate:"required,criticality"`
	Scope          string   `validate:"omitempty,scope"`
	Exposure       string   `validate:"omitempty,exposure"`
	Tags           []string `validate:"max=20,dive,max=50"`
	Provider       string   `validate:"omitempty"`
	ExternalID     string   `validate:"omitempty,max=255"`
	Classification string   `validate:"omitempty"`
	// Repository extension fields
	RepoID          string           `validate:"omitempty,max=255"`
	FullName        string           `validate:"required,max=500"`
	SCMOrganization string           `validate:"omitempty,max=255"`
	CloneURL        string           `validate:"omitempty,url"`
	WebURL          string           `validate:"omitempty,url"`
	SSHURL          string           `validate:"omitempty,max=500"`
	DefaultBranch   string           `validate:"omitempty,max=100"`
	Visibility      string           `validate:"omitempty"`
	Language        string           `validate:"omitempty,max=50"`
	Languages       map[string]int64 `validate:"omitempty"`
	Topics          []string         `validate:"max=50,dive,max=100"`
	// Stats
	Stars      int `validate:"min=0"`
	Forks      int `validate:"min=0"`
	Watchers   int `validate:"min=0"`
	OpenIssues int `validate:"min=0"`
	SizeKB     int `validate:"min=0"`
	// Scan settings
	ScanEnabled  bool   `validate:"omitempty"`
	ScanSchedule string `validate:"omitempty,max=100"`
	// Timestamps from SCM (ISO 8601 format)
	RepoCreatedAt string `validate:"omitempty"`
	RepoUpdatedAt string `validate:"omitempty"`
	RepoPushedAt  string `validate:"omitempty"`
}

CreateRepositoryAssetInput represents the input for creating a repository asset.

type CreateRoleInput

type CreateRoleInput struct {
	TenantID          string   `json:"-"`
	Slug              string   `json:"slug" validate:"required,min=2,max=50,slug"`
	Name              string   `json:"name" validate:"required,min=2,max=100"`
	Description       string   `json:"description" validate:"max=500"`
	HierarchyLevel    int      `json:"hierarchy_level" validate:"min=0,max=100"`
	HasFullDataAccess bool     `json:"has_full_data_access"`
	Permissions       []string `json:"permissions"`
}

CreateRoleInput represents the input for creating a role.

type CreateSLAPolicyInput

type CreateSLAPolicyInput struct {
	TenantID            string `validate:"required,uuid"`
	AssetID             string `validate:"omitempty,uuid"` // Optional, nil for tenant default
	Name                string `validate:"required,min=1,max=100"`
	Description         string `validate:"max=500"`
	IsDefault           bool
	CriticalDays        int `validate:"required,min=1,max=365"`
	HighDays            int `validate:"required,min=1,max=365"`
	MediumDays          int `validate:"required,min=1,max=365"`
	LowDays             int `validate:"required,min=1,max=365"`
	InfoDays            int `validate:"required,min=1,max=365"`
	WarningThresholdPct int `validate:"min=0,max=100"`
	EscalationEnabled   bool
	EscalationConfig    map[string]any
}

CreateSLAPolicyInput represents the input for creating an SLA policy.

type CreateScanProfileInput

type CreateScanProfileInput struct {
	TenantID           string                            `json:"tenant_id" validate:"required,uuid"`
	UserID             string                            `json:"user_id" validate:"omitempty,uuid"`
	Name               string                            `json:"name" validate:"required,min=1,max=100"`
	Description        string                            `json:"description" validate:"max=500"`
	ToolsConfig        map[string]scanprofile.ToolConfig `json:"tools_config"`
	Intensity          string                            `json:"intensity" validate:"omitempty,oneof=low medium high"`
	MaxConcurrentScans int                               `json:"max_concurrent_scans" validate:"omitempty,min=1,max=100"`
	TimeoutSeconds     int                               `json:"timeout_seconds" validate:"omitempty,min=60,max=86400"`
	Tags               []string                          `json:"tags" validate:"max=20,dive,max=50"`
	IsDefault          bool                              `json:"is_default"`
	QualityGate        *scanprofile.QualityGate          `json:"quality_gate"`
}

CreateScanProfileInput represents the input for creating a scan profile.

type CreateScannerTemplateInput

type CreateScannerTemplateInput struct {
	TenantID     string   `json:"tenant_id" validate:"required,uuid"`
	UserID       string   `json:"user_id" validate:"omitempty,uuid"`
	Name         string   `json:"name" validate:"required,min=1,max=255"`
	TemplateType string   `json:"template_type" validate:"required,oneof=nuclei semgrep gitleaks"`
	Description  string   `json:"description" validate:"max=1000"`
	Content      string   `json:"content" validate:"required"` // Base64 encoded
	Tags         []string `json:"tags" validate:"max=20,dive,max=50"`
}

CreateScannerTemplateInput represents the input for creating a scanner template.

type CreateScheduleInput

type CreateScheduleInput struct {
	TenantID             string                 `validate:"required,uuid"`
	Name                 string                 `validate:"required,min=1,max=200"`
	Description          string                 `validate:"max=1000"`
	ScanType             string                 `validate:"required"`
	TargetScope          string                 `validate:"omitempty"`
	TargetIDs            []string               `validate:"max=100"`
	TargetTags           []string               `validate:"max=20,dive,max=50"`
	ScannerConfigs       map[string]interface{} `validate:"omitempty"`
	ScheduleType         string                 `validate:"required"`
	CronExpression       string                 `validate:"max=100"`
	IntervalHours        int                    `validate:"min=0,max=8760"`
	NotifyOnCompletion   bool
	NotifyOnFindings     bool
	NotificationChannels []string `validate:"max=10,dive,max=50"`
	CreatedBy            string   `validate:"max=200"`
}

CreateScheduleInput represents the input for creating a scan schedule.

type CreateSourceInput

type CreateSourceInput struct {
	TenantID            string `json:"tenant_id" validate:"required,uuid"`
	ToolID              string `json:"tool_id" validate:"omitempty,uuid"`
	Name                string `json:"name" validate:"required,min=1,max=255"`
	Description         string `json:"description" validate:"max=1000"`
	SourceType          string `json:"source_type" validate:"required,oneof=git http local"`
	Config              []byte `json:"config" validate:"required"`
	CredentialsID       string `json:"credentials_id" validate:"omitempty,uuid"`
	SyncEnabled         bool   `json:"sync_enabled"`
	SyncIntervalMinutes int    `json:"sync_interval_minutes" validate:"min=5,max=10080"`
	Priority            int    `json:"priority" validate:"min=0,max=1000"`
}

CreateSourceInput represents the input for creating a rule source.

type CreateTargetInput

type CreateTargetInput struct {
	TenantID    string   `validate:"required,uuid"`
	TargetType  string   `validate:"required"`
	Pattern     string   `validate:"required,max=500"`
	Description string   `validate:"max=1000"`
	Priority    int      `validate:"min=0,max=100"`
	Tags        []string `validate:"max=20,dive,max=50"`
	CreatedBy   string   `validate:"max=200"`
}

CreateTargetInput represents the input for creating a scope target.

type CreateTemplateSourceInput

type CreateTemplateSourceInput struct {
	TenantID        string               `json:"tenant_id" validate:"required,uuid"`
	UserID          string               `json:"user_id" validate:"omitempty,uuid"`
	Name            string               `json:"name" validate:"required,min=1,max=255"`
	SourceType      string               `json:"source_type" validate:"required,oneof=git s3 http"`
	TemplateType    string               `json:"template_type" validate:"required,oneof=nuclei semgrep gitleaks"`
	Description     string               `json:"description" validate:"max=1000"`
	Enabled         bool                 `json:"enabled"`
	AutoSyncOnScan  bool                 `json:"auto_sync_on_scan"`
	CacheTTLMinutes int                  `json:"cache_ttl_minutes" validate:"min=0,max=10080"` // Max 1 week
	GitConfig       *ts.GitSourceConfig  `json:"git_config,omitempty"`
	S3Config        *ts.S3SourceConfig   `json:"s3_config,omitempty"`
	HTTPConfig      *ts.HTTPSourceConfig `json:"http_config,omitempty"`
	CredentialID    string               `json:"credential_id" validate:"omitempty,uuid"`
}

CreateTemplateSourceInput represents the input for creating a template source.

type CreateTenantInput

type CreateTenantInput struct {
	Name        string `json:"name" validate:"required,min=2,max=100"`
	Slug        string `json:"slug" validate:"required,min=3,max=100,slug"`
	Description string `json:"description" validate:"max=500"`
}

CreateTenantInput represents the input for creating a tenant.

type CreateTenantToolConfigInput

type CreateTenantToolConfigInput struct {
	TenantID  string         `json:"tenant_id" validate:"required,uuid"`
	ToolID    string         `json:"tool_id" validate:"required,uuid"`
	Config    map[string]any `json:"config"`
	IsEnabled bool           `json:"is_enabled"`
	UpdatedBy string         `json:"updated_by" validate:"omitempty,uuid"`
}

CreateTenantToolConfigInput represents the input for creating a tenant tool config.

type CreateToolInput

type CreateToolInput struct {
	Name             string         `json:"name" validate:"required,min=1,max=50"`
	DisplayName      string         `json:"display_name" validate:"max=100"`
	Description      string         `json:"description" validate:"max=1000"`
	CategoryID       string         `json:"category_id" validate:"omitempty,uuid"` // UUID of tool_categories
	InstallMethod    string         `json:"install_method" validate:"required,oneof=go pip npm docker binary"`
	InstallCmd       string         `json:"install_cmd" validate:"max=500"`
	UpdateCmd        string         `json:"update_cmd" validate:"max=500"`
	VersionCmd       string         `json:"version_cmd" validate:"max=500"`
	VersionRegex     string         `json:"version_regex" validate:"max=200"`
	ConfigSchema     map[string]any `json:"config_schema"`
	DefaultConfig    map[string]any `json:"default_config"`
	Capabilities     []string       `json:"capabilities" validate:"max=20,dive,max=50"`
	SupportedTargets []string       `json:"supported_targets" validate:"max=10,dive,max=50"`
	OutputFormats    []string       `json:"output_formats" validate:"max=10,dive,max=20"`
	DocsURL          string         `json:"docs_url" validate:"omitempty,url,max=500"`
	GithubURL        string         `json:"github_url" validate:"omitempty,url,max=500"`
	LogoURL          string         `json:"logo_url" validate:"omitempty,url,max=500"`
	Tags             []string       `json:"tags" validate:"max=20,dive,max=50"`
}

CreateToolInput represents the input for creating a tool.

type CreateVulnerabilityInput

type CreateVulnerabilityInput struct {
	CVEID            string   `validate:"required,cve_id"`
	Title            string   `validate:"required,min=1,max=500"`
	Description      string   `validate:"max=10000"`
	Severity         string   `validate:"required,severity"`
	CVSSScore        *float64 `validate:"omitempty,min=0,max=10"`
	CVSSVector       string   `validate:"max=100"`
	EPSSScore        *float64 `validate:"omitempty,min=0,max=1"`
	EPSSPercentile   *float64 `validate:"omitempty,min=0,max=1"`
	ExploitAvailable bool
	ExploitMaturity  string   `validate:"omitempty,exploit_maturity"`
	FixedVersions    []string `validate:"max=50,dive,max=100"`
	Remediation      string   `validate:"max=5000"`
}

CreateVulnerabilityInput represents the input for creating a vulnerability.

type CreateWebhookInput

type CreateWebhookInput struct {
	TenantID          string   `json:"tenant_id" validate:"required,uuid"`
	Name              string   `json:"name" validate:"required,min=1,max=255"`
	Description       string   `json:"description" validate:"max=1000"`
	URL               string   `json:"url" validate:"required,url,max=1000"`
	Secret            string   `json:"secret" validate:"max=500"`
	EventTypes        []string `json:"event_types" validate:"required,min=1,max=20"`
	SeverityThreshold string   `json:"severity_threshold" validate:"omitempty,oneof=critical high medium low info"`
	MaxRetries        int      `json:"max_retries" validate:"min=0,max=10"`
	RetryInterval     int      `json:"retry_interval_seconds" validate:"min=0,max=3600"`
	CreatedBy         string   `json:"created_by" validate:"omitempty,uuid"`
}

CreateWebhookInput represents input for creating a webhook.

type CreateWorkflowInput

type CreateWorkflowInput struct {
	TenantID    shared.ID
	UserID      shared.ID
	Name        string
	Description string
	Tags        []string
	Nodes       []CreateNodeInput
	Edges       []CreateEdgeInput
}

CreateWorkflowInput represents input for creating a workflow.

type CredentialImportService

type CredentialImportService struct {
	// contains filtered or unexported fields
}

CredentialImportService handles credential leak import operations.

func NewCredentialImportService

func NewCredentialImportService(
	exposureRepo exposure.Repository,
	historyRepo exposure.StateHistoryRepository,
	log *logger.Logger,
) *CredentialImportService

NewCredentialImportService creates a new CredentialImportService.

func (*CredentialImportService) AcceptCredential

func (s *CredentialImportService) AcceptCredential(ctx context.Context, tenantID, credentialID, userID, notes string) (*CredentialItem, error)

AcceptCredential marks a credential as accepted risk.

func (*CredentialImportService) GetByID

func (s *CredentialImportService) GetByID(ctx context.Context, tenantID, id string) (*CredentialItem, error)

GetByID retrieves a credential leak by its ID.

func (*CredentialImportService) GetCredentialStats

func (s *CredentialImportService) GetCredentialStats(ctx context.Context, tenantID string) (map[string]any, error)

GetCredentialStats returns statistics for credential leaks.

func (*CredentialImportService) GetExposuresForIdentity

func (s *CredentialImportService) GetExposuresForIdentity(
	ctx context.Context,
	tenantID string,
	identity string,
	page, pageSize int,
) (*CredentialListResult, error)

GetExposuresForIdentity gets all credential exposures for a specific identity (lazy loading).

func (*CredentialImportService) GetRelatedCredentials

func (s *CredentialImportService) GetRelatedCredentials(
	ctx context.Context,
	tenantID string,
	credentialID string,
) ([]CredentialItem, error)

GetRelatedCredentials gets all credentials related to a given identifier.

func (*CredentialImportService) Import

Import imports credentials with deduplication support.

func (*CredentialImportService) ImportCSV

func (s *CredentialImportService) ImportCSV(
	ctx context.Context,
	tenantID string,
	records [][]string,
	options credential.ImportOptions,
) (*credential.ImportResult, error)

ImportCSV imports credentials from CSV data.

func (*CredentialImportService) List

func (s *CredentialImportService) List(
	ctx context.Context,
	tenantID string,
	opts CredentialListOptions,
	page, pageSize int,
) (*CredentialListResult, error)

List retrieves credential leaks with filtering and pagination.

func (*CredentialImportService) ListByIdentity

func (s *CredentialImportService) ListByIdentity(
	ctx context.Context,
	tenantID string,
	opts CredentialListOptions,
	page, pageSize int,
) (*IdentityListResult, error)

ListByIdentity lists credential exposures grouped by identity (username/email).

func (*CredentialImportService) MarkCredentialFalsePositive

func (s *CredentialImportService) MarkCredentialFalsePositive(ctx context.Context, tenantID, credentialID, userID, notes string) (*CredentialItem, error)

MarkCredentialFalsePositive marks a credential as a false positive.

func (*CredentialImportService) ReactivateCredential

func (s *CredentialImportService) ReactivateCredential(ctx context.Context, tenantID, credentialID string) (*CredentialItem, error)

ReactivateCredential marks a credential as active again.

func (*CredentialImportService) ResolveCredential

func (s *CredentialImportService) ResolveCredential(ctx context.Context, tenantID, credentialID, userID, notes string) (*CredentialItem, error)

ResolveCredential marks a credential as resolved.

type CredentialItem

type CredentialItem struct {
	ID             string         `json:"id"`
	Identifier     string         `json:"identifier"`
	CredentialType string         `json:"credential_type"`
	SecretValue    string         `json:"secret_value,omitempty"`
	Source         string         `json:"source"`
	Severity       string         `json:"severity"`
	State          string         `json:"state"`
	FirstSeenAt    time.Time      `json:"first_seen_at"`
	LastSeenAt     time.Time      `json:"last_seen_at"`
	IsVerified     bool           `json:"is_verified"`
	IsRevoked      bool           `json:"is_revoked"`
	Details        map[string]any `json:"details,omitempty"`
}

CredentialItem represents a credential leak item.

type CredentialListOptions

type CredentialListOptions struct {
	Severities []string
	States     []string
	Sources    []string
	Search     string
	SortField  string
	SortOrder  string
}

CredentialListOptions contains options for listing credentials.

type CredentialListResult

type CredentialListResult struct {
	Items      []CredentialItem `json:"items"`
	Total      int64            `json:"total"`
	Page       int              `json:"page"`
	PageSize   int              `json:"page_size"`
	TotalPages int              `json:"total_pages"`
}

CredentialListResult represents the result of listing credentials.

type DashboardService

type DashboardService struct {
	// contains filtered or unexported fields
}

DashboardService provides dashboard-related operations.

func NewDashboardService

func NewDashboardService(repo DashboardStatsRepository, log *logger.Logger) *DashboardService

NewDashboardService creates a new DashboardService.

func (*DashboardService) GetGlobalStats

func (s *DashboardService) GetGlobalStats(ctx context.Context) (*DashboardStats, error)

GetGlobalStats returns global dashboard statistics (not tenant-scoped). Deprecated: Use GetStatsForTenants for proper multi-tenant authorization.

func (*DashboardService) GetStats

func (s *DashboardService) GetStats(ctx context.Context, tenantID shared.ID) (*DashboardStats, error)

GetStats returns dashboard statistics for a tenant.

func (*DashboardService) GetStatsForTenants

func (s *DashboardService) GetStatsForTenants(ctx context.Context, tenantIDs []string) (*DashboardStats, error)

GetStatsForTenants returns dashboard statistics filtered by accessible tenant IDs. This should be used for multi-tenant authorization - only shows data from tenants the user has access to.

type DashboardStats

type DashboardStats struct {
	// Asset stats
	AssetCount       int
	AssetsByType     map[string]int
	AssetsByStatus   map[string]int
	AverageRiskScore float64

	// Finding stats
	FindingCount       int
	FindingsBySeverity map[string]int
	FindingsByStatus   map[string]int
	OverdueFindings    int
	AverageCVSS        float64

	// Repository stats (repositories are assets with type 'repository')
	RepositoryCount          int
	RepositoriesWithFindings int

	// Recent activity
	RecentActivity []ActivityItem
}

DashboardStats represents aggregated dashboard statistics.

type DashboardStatsRepository

type DashboardStatsRepository interface {
	// GetAssetStats returns asset statistics for a tenant
	GetAssetStats(ctx context.Context, tenantID shared.ID) (AssetStatsData, error)
	// GetFindingStats returns finding statistics for a tenant
	GetFindingStats(ctx context.Context, tenantID shared.ID) (FindingStatsData, error)
	// GetRepositoryStats returns repository statistics for a tenant
	GetRepositoryStats(ctx context.Context, tenantID shared.ID) (RepositoryStatsData, error)
	// GetRecentActivity returns recent activity for a tenant
	GetRecentActivity(ctx context.Context, tenantID shared.ID, limit int) ([]ActivityItem, error)

	// Global stats (not tenant-scoped) - deprecated, use filtered versions
	GetGlobalAssetStats(ctx context.Context) (AssetStatsData, error)
	GetGlobalFindingStats(ctx context.Context) (FindingStatsData, error)
	GetGlobalRepositoryStats(ctx context.Context) (RepositoryStatsData, error)
	GetGlobalRecentActivity(ctx context.Context, limit int) ([]ActivityItem, error)

	// Filtered stats (by accessible tenant IDs) - for multi-tenant authorization
	GetFilteredAssetStats(ctx context.Context, tenantIDs []string) (AssetStatsData, error)
	GetFilteredFindingStats(ctx context.Context, tenantIDs []string) (FindingStatsData, error)
	GetFilteredRepositoryStats(ctx context.Context, tenantIDs []string) (RepositoryStatsData, error)
	GetFilteredRecentActivity(ctx context.Context, tenantIDs []string, limit int) ([]ActivityItem, error)
}

DashboardStatsRepository defines the interface for dashboard data access.

type DefaultConditionEvaluator

type DefaultConditionEvaluator struct{}

DefaultConditionEvaluator provides a simple condition evaluator. It supports basic expressions like:

  • "trigger.severity == 'critical'"
  • "trigger.asset_type in ['server', 'database']"
  • "upstream.check_status.output.is_valid == true"

SEC-WF11: Includes expression length/complexity limits to prevent ReDoS.

func (*DefaultConditionEvaluator) Evaluate

func (e *DefaultConditionEvaluator) Evaluate(ctx context.Context, expression string, data map[string]any) (bool, error)

Evaluate evaluates a condition expression.

type DefaultNotificationHandler

type DefaultNotificationHandler struct {
	// contains filtered or unexported fields
}

DefaultNotificationHandler handles notification actions using the notification service.

func (*DefaultNotificationHandler) Send

Send sends a notification.

type DeleteCapabilityInput

type DeleteCapabilityInput struct {
	TenantID     string
	CapabilityID string
	Force        bool // Force delete even if capability is in use

	// Audit context (set by handler)
	AuditContext AuditContext
}

DeleteCapabilityInput represents the input for deleting a capability.

type EPSSStats

type EPSSStats struct {
	TotalScores       int `json:"total_scores"`
	HighRiskCount     int `json:"high_risk_count"`     // EPSS > 0.1 (10%)
	CriticalRiskCount int `json:"critical_risk_count"` // EPSS > 0.3 (30%)
}

EPSSStats contains EPSS statistics.

type EmailCredentials

type EmailCredentials struct {
	SMTPHost    string   `json:"smtp_host"`
	SMTPPort    int      `json:"smtp_port"`
	Username    string   `json:"username"`
	Password    string   `json:"password"`
	FromEmail   string   `json:"from_email"`
	FromName    string   `json:"from_name"`
	ToEmails    []string `json:"to_emails"`
	UseTLS      bool     `json:"use_tls"`
	UseSTARTTLS bool     `json:"use_starttls"`
	SkipVerify  bool     `json:"skip_verify"`
	ReplyTo     string   `json:"reply_to,omitempty"`
}

EmailCredentials represents the JSON structure for email SMTP credentials (full input from frontend).

type EmailJobEnqueuer

type EmailJobEnqueuer interface {
	EnqueueTeamInvitation(ctx context.Context, payload TeamInvitationJobPayload) error
}

EmailJobEnqueuer defines the interface for enqueueing email jobs.

type EmailMetadata

type EmailMetadata struct {
	SMTPHost    string   `json:"smtp_host"`
	SMTPPort    int      `json:"smtp_port"`
	FromEmail   string   `json:"from_email"`
	FromName    string   `json:"from_name"`
	ToEmails    []string `json:"to_emails"`
	UseTLS      bool     `json:"use_tls"`
	UseSTARTTLS bool     `json:"use_starttls"`
	SkipVerify  bool     `json:"skip_verify"`
	ReplyTo     string   `json:"reply_to,omitempty"`
}

EmailMetadata represents non-sensitive email config stored in integration.metadata. This allows the frontend to display current config when editing without exposing secrets.

type EmailSensitiveCredentials

type EmailSensitiveCredentials struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

EmailSensitiveCredentials represents sensitive email credentials stored encrypted.

type EmailService

type EmailService struct {
	// contains filtered or unexported fields
}

EmailService handles sending emails for various application events.

func NewEmailService

func NewEmailService(sender email.Sender, cfg config.SMTPConfig, appName string, log *logger.Logger) *EmailService

NewEmailService creates a new EmailService.

func (*EmailService) IsConfigured

func (s *EmailService) IsConfigured() bool

IsConfigured returns true if email service is properly configured.

func (*EmailService) SendPasswordChangedEmail

func (s *EmailService) SendPasswordChangedEmail(ctx context.Context, userEmail, userName, ipAddress string) error

SendPasswordChangedEmail sends a notification that the password was changed.

func (*EmailService) SendPasswordResetEmail

func (s *EmailService) SendPasswordResetEmail(ctx context.Context, userEmail, userName, token string, expiresIn time.Duration, ipAddress string) error

SendPasswordResetEmail sends a password reset link to a user.

func (*EmailService) SendTeamInvitationEmail

func (s *EmailService) SendTeamInvitationEmail(ctx context.Context, recipientEmail, inviterName, teamName, token string, expiresIn time.Duration) error

SendTeamInvitationEmail sends a team invitation email.

func (*EmailService) SendVerificationEmail

func (s *EmailService) SendVerificationEmail(ctx context.Context, userEmail, userName, token string, expiresIn time.Duration) error

SendVerificationEmail sends an email verification link to a user.

func (*EmailService) SendWelcomeEmail

func (s *EmailService) SendWelcomeEmail(ctx context.Context, userEmail, userName string) error

SendWelcomeEmail sends a welcome email to a new user.

type EnqueueNotificationParams

type EnqueueNotificationParams struct {
	TenantID      shared.ID
	EventType     string     // e.g., "new_finding", "scan_completed"
	AggregateType string     // e.g., "finding", "scan"
	AggregateID   *uuid.UUID // ID of the source entity
	Title         string
	Body          string
	Severity      string // critical, high, medium, low, info
	URL           string
	Metadata      map[string]any
}

EnqueueNotificationParams contains parameters for enqueuing a notification.

type EvaluateQualityGateInput

type EvaluateQualityGateInput struct {
	TenantID  string                    `json:"tenant_id" validate:"required,uuid"`
	ProfileID string                    `json:"profile_id" validate:"required,uuid"`
	Counts    scanprofile.FindingCounts `json:"counts" validate:"required"`
}

EvaluateQualityGateInput represents the input for evaluating quality gate.

type ExchangeTokenInput

type ExchangeTokenInput struct {
	RefreshToken string `json:"refresh_token" validate:"required"`
	TenantID     string `json:"tenant_id" validate:"required"`
}

ExchangeTokenInput represents the input for token exchange.

type ExchangeTokenResult

type ExchangeTokenResult struct {
	AccessToken string
	TenantID    string
	TenantSlug  string
	Role        string
	ExpiresAt   time.Time
}

ExchangeTokenResult represents the result of token exchange.

type ExecutionContext

type ExecutionContext struct {
	Run               *workflow.Run
	Workflow          *workflow.Workflow
	TriggerData       map[string]any
	Context           map[string]any // Shared context across nodes
	CompletedNodeKeys map[string]bool
	NodeRunsByKey     map[string]*workflow.NodeRun
	// contains filtered or unexported fields
}

ExecutionContext holds the state during workflow execution.

func (*ExecutionContext) GetContextValue

func (ec *ExecutionContext) GetContextValue(key string) (any, bool)

GetContextValue gets a value from the execution context.

func (*ExecutionContext) IsNodeCompleted

func (ec *ExecutionContext) IsNodeCompleted(nodeKey string) bool

IsNodeCompleted checks if a node is completed.

func (*ExecutionContext) MarkNodeCompleted

func (ec *ExecutionContext) MarkNodeCompleted(nodeKey string)

MarkNodeCompleted marks a node as completed.

func (*ExecutionContext) SetContextValue

func (ec *ExecutionContext) SetContextValue(key string, value any)

SetContextValue sets a value in the execution context.

type ExposedService

type ExposedService struct {
	ID           string    `json:"id"`
	Name         string    `json:"name"`
	Type         string    `json:"type"`
	Port         int       `json:"port,omitempty"`
	Exposure     string    `json:"exposure"`
	Criticality  string    `json:"criticality"`
	FindingCount int       `json:"finding_count"`
	LastSeen     time.Time `json:"last_seen"`
}

ExposedService represents an exposed service/asset.

type ExposureService

type ExposureService struct {
	// contains filtered or unexported fields
}

ExposureService handles exposure event business operations.

func NewExposureService

func NewExposureService(
	repo exposure.Repository,
	historyRepo exposure.StateHistoryRepository,
	log *logger.Logger,
) *ExposureService

NewExposureService creates a new ExposureService.

func (*ExposureService) AcceptExposure

func (s *ExposureService) AcceptExposure(ctx context.Context, exposureID, userID, notes string) (*exposure.ExposureEvent, error)

AcceptExposure marks an exposure event as accepted risk.

func (*ExposureService) BulkIngestExposures

func (s *ExposureService) BulkIngestExposures(ctx context.Context, inputs []CreateExposureInput) ([]*exposure.ExposureEvent, error)

BulkIngestExposures ingests multiple exposure events. OPTIMIZED: Uses batch upsert instead of individual upserts to reduce N+1 queries.

func (*ExposureService) CreateExposure

CreateExposure creates a new exposure event.

func (*ExposureService) DeleteExposure

func (s *ExposureService) DeleteExposure(ctx context.Context, exposureID, tenantID string) error

DeleteExposure deletes an exposure event.

func (*ExposureService) GetExposure

func (s *ExposureService) GetExposure(ctx context.Context, eventID string) (*exposure.ExposureEvent, error)

GetExposure retrieves an exposure event by ID.

func (*ExposureService) GetExposureStats

func (s *ExposureService) GetExposureStats(ctx context.Context, tenantID string) (map[string]any, error)

GetExposureStats returns statistics for a tenant.

func (*ExposureService) GetStateHistory

func (s *ExposureService) GetStateHistory(ctx context.Context, exposureID string) ([]*exposure.StateHistory, error)

GetStateHistory retrieves the state change history for an exposure event.

func (*ExposureService) IngestExposure

IngestExposure creates or updates an exposure event based on fingerprint (deduplication).

func (*ExposureService) ListExposures

ListExposures lists exposure events with filtering and pagination.

func (*ExposureService) MarkFalsePositive

func (s *ExposureService) MarkFalsePositive(ctx context.Context, exposureID, userID, notes string) (*exposure.ExposureEvent, error)

MarkFalsePositive marks an exposure event as a false positive.

func (*ExposureService) ReactivateExposure

func (s *ExposureService) ReactivateExposure(ctx context.Context, exposureID, userID string) (*exposure.ExposureEvent, error)

ReactivateExposure marks an exposure event as active again.

func (*ExposureService) ResolveExposure

func (s *ExposureService) ResolveExposure(ctx context.Context, exposureID, userID, notes string) (*exposure.ExposureEvent, error)

ResolveExposure marks an exposure event as resolved.

func (*ExposureService) SetNotificationService

func (s *ExposureService) SetNotificationService(db *sql.DB, svc *NotificationService)

SetNotificationService sets the notification service for transactional outbox pattern.

type FailCommandInput

type FailCommandInput struct {
	TenantID     string `json:"tenant_id" validate:"required,uuid"`
	CommandID    string `json:"command_id" validate:"required,uuid"`
	ErrorMessage string `json:"error_message"`
}

FailCommandInput represents the input for failing a command.

type FailToolExecutionInput

type FailToolExecutionInput struct {
	ExecutionID  string `json:"execution_id" validate:"required,uuid"`
	ErrorMessage string `json:"error_message" validate:"required,max=2000"`
}

FailToolExecutionInput represents the input for failing a tool execution.

type FindSCMIntegrationInput

type FindSCMIntegrationInput struct {
	TenantID string
	Provider string
	SCMOrg   string
}

FindSCMIntegrationInput represents the input for finding a matching SCM integration.

type FindingActionHandler

type FindingActionHandler struct {
	// contains filtered or unexported fields
}

FindingActionHandler handles actions related to findings.

func NewFindingActionHandler

func NewFindingActionHandler(vulnSvc *VulnerabilityService, log *logger.Logger) *FindingActionHandler

NewFindingActionHandler creates a new FindingActionHandler.

func (*FindingActionHandler) Execute

func (h *FindingActionHandler) Execute(ctx context.Context, input *ActionInput) (map[string]any, error)

Execute executes a finding-related action.

type FindingActivityService

type FindingActivityService struct {
	// contains filtered or unexported fields
}

FindingActivityService handles finding activity operations. Activities are APPEND-ONLY - once created, they should never be modified or deleted.

func NewFindingActivityService

func NewFindingActivityService(
	activityRepo vulnerability.FindingActivityRepository,
	findingRepo vulnerability.FindingRepository,
	log *logger.Logger,
) *FindingActivityService

NewFindingActivityService creates a new FindingActivityService.

func (*FindingActivityService) CountActivities

func (s *FindingActivityService) CountActivities(ctx context.Context, tenantID, findingID string, filter vulnerability.FindingActivityFilter) (int64, error)

CountActivities counts activities for a finding. Security: tenantID is required to ensure tenant isolation.

func (*FindingActivityService) GetActivity

func (s *FindingActivityService) GetActivity(ctx context.Context, activityID string) (*vulnerability.FindingActivity, error)

GetActivity retrieves a single activity by ID.

func (*FindingActivityService) ListActivities

ListActivities retrieves activities for a finding with pagination. Security: TenantID is required to ensure tenant isolation.

func (*FindingActivityService) RecordActivity

RecordActivity creates a new activity record for a finding. This is the primary method for recording any finding lifecycle event. Security: Changes field is limited to MaxChangesSize to prevent DoS attacks.

func (*FindingActivityService) RecordAssignment

func (s *FindingActivityService) RecordAssignment(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	assigneeID, assigneeName, assigneeEmail string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordAssignment is a convenience method for recording assignment changes.

func (*FindingActivityService) RecordCommentAdded

func (s *FindingActivityService) RecordCommentAdded(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	commentID, content string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordCommentAdded is a convenience method for recording comment additions. content is the full comment text, stored for display in activity feed.

func (*FindingActivityService) RecordCommentDeleted

func (s *FindingActivityService) RecordCommentDeleted(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	commentID string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordCommentDeleted is a convenience method for recording comment deletions.

func (*FindingActivityService) RecordCommentUpdated

func (s *FindingActivityService) RecordCommentUpdated(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	commentID string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordCommentUpdated is a convenience method for recording comment updates.

func (*FindingActivityService) RecordCreated

func (s *FindingActivityService) RecordCreated(
	ctx context.Context,
	tenantID, findingID string,
	source string,
	sourceMetadata map[string]interface{},
) (*vulnerability.FindingActivity, error)

RecordCreated records that a finding was created.

func (*FindingActivityService) RecordScanDetected

func (s *FindingActivityService) RecordScanDetected(
	ctx context.Context,
	tenantID, findingID string,
	scanID, scanner, scanType string,
	sourceMetadata map[string]interface{},
) (*vulnerability.FindingActivity, error)

RecordScanDetected is a convenience method for recording scan detections.

func (*FindingActivityService) RecordSeverityChange

func (s *FindingActivityService) RecordSeverityChange(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	oldSeverity, newSeverity string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordSeverityChange is a convenience method for recording severity changes.

func (*FindingActivityService) RecordStatusChange

func (s *FindingActivityService) RecordStatusChange(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	oldStatus, newStatus string,
	reason string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordStatusChange is a convenience method for recording status changes.

func (*FindingActivityService) RecordUnassignment

func (s *FindingActivityService) RecordUnassignment(
	ctx context.Context,
	tenantID, findingID string,
	actorID *string,
	previousAssigneeName string,
	source string,
) (*vulnerability.FindingActivity, error)

RecordUnassignment is a convenience method for recording unassignment.

func (*FindingActivityService) SetBroadcaster

func (s *FindingActivityService) SetBroadcaster(broadcaster ActivityBroadcaster)

SetBroadcaster sets the activity broadcaster for real-time WebSocket updates. This is optional - if not set, real-time updates are disabled.

func (*FindingActivityService) SetUserRepo

func (s *FindingActivityService) SetUserRepo(repo user.Repository)

SetUserRepo sets the user repository for enriching actor info in broadcasts. This is optional - if not set, actor names won't be included in real-time updates.

type FindingCommentService

type FindingCommentService struct {
	// contains filtered or unexported fields
}

FindingCommentService handles finding comment operations.

func NewFindingCommentService

func NewFindingCommentService(
	commentRepo vulnerability.FindingCommentRepository,
	findingRepo vulnerability.FindingRepository,
	log *logger.Logger,
) *FindingCommentService

NewFindingCommentService creates a new FindingCommentService.

func (*FindingCommentService) AddComment

AddComment adds a new comment to a finding.

func (*FindingCommentService) AddStatusChangeComment

AddStatusChangeComment adds a comment recording a status change.

func (*FindingCommentService) CountFindingComments

func (s *FindingCommentService) CountFindingComments(ctx context.Context, findingID string) (int, error)

CountFindingComments counts comments for a finding.

func (*FindingCommentService) DeleteComment

func (s *FindingCommentService) DeleteComment(ctx context.Context, commentID, authorID string) error

DeleteComment deletes a comment.

func (*FindingCommentService) GetComment

func (s *FindingCommentService) GetComment(ctx context.Context, commentID string) (*vulnerability.FindingComment, error)

GetComment retrieves a comment by ID.

func (*FindingCommentService) ListFindingComments

func (s *FindingCommentService) ListFindingComments(ctx context.Context, findingID string) ([]*vulnerability.FindingComment, error)

ListFindingComments retrieves all comments for a finding.

func (*FindingCommentService) UpdateComment

func (s *FindingCommentService) UpdateComment(ctx context.Context, commentID, authorID string, input UpdateCommentInput) (*vulnerability.FindingComment, error)

UpdateComment updates an existing comment.

type FindingEvent

type FindingEvent struct {
	TenantID  shared.ID
	Finding   *vulnerability.Finding
	EventType workflow.TriggerType // finding_created, finding_updated
	Changes   map[string]any       // For finding_updated: which fields changed
}

FindingEvent represents a finding-related event.

type FindingLifecycleScheduler

type FindingLifecycleScheduler struct {
	// contains filtered or unexported fields
}

FindingLifecycleScheduler manages background tasks for finding lifecycle. This includes expiring findings on feature branches that have been inactive.

func NewFindingLifecycleScheduler

func NewFindingLifecycleScheduler(
	findingRepo vulnerability.FindingRepository,
	tenantLister TenantLister,
	cfg FindingLifecycleSchedulerConfig,
	log *logger.Logger,
) *FindingLifecycleScheduler

NewFindingLifecycleScheduler creates a new scheduler.

func (*FindingLifecycleScheduler) Start

func (s *FindingLifecycleScheduler) Start()

Start starts the scheduler.

func (*FindingLifecycleScheduler) Stop

func (s *FindingLifecycleScheduler) Stop()

Stop stops the scheduler gracefully. Safe to call even if Start() was never called (e.g. when Enabled=false).

type FindingLifecycleSchedulerConfig

type FindingLifecycleSchedulerConfig struct {
	// CheckInterval is how often to run lifecycle tasks (default: 1 hour)
	CheckInterval time.Duration

	// DefaultExpiryDays is the default number of days after which
	// feature branch findings are expired if not seen (default: 30)
	// Individual branches can override this via retention_days setting.
	DefaultExpiryDays int

	// Enabled controls whether the scheduler runs (default: true)
	Enabled bool
}

FindingLifecycleSchedulerConfig holds configuration for the scheduler.

func DefaultFindingLifecycleSchedulerConfig

func DefaultFindingLifecycleSchedulerConfig() FindingLifecycleSchedulerConfig

DefaultFindingLifecycleSchedulerConfig returns default configuration.

type FindingNotifier

type FindingNotifier interface {
	// NotifyNewFinding sends a notification for a new finding.
	// This should be called asynchronously to not block finding creation.
	NotifyNewFinding(tenantID, title, body, severity, url string)
}

FindingNotifier is an interface for sending finding notifications asynchronously. Deprecated: Use NotificationService with transactional outbox pattern instead.

type FindingSourceCacheService

type FindingSourceCacheService struct {
	// contains filtered or unexported fields
}

FindingSourceCacheService provides cached access to finding sources. Finding sources are system-level configuration that rarely changes, making them ideal candidates for aggressive caching.

Cache structure: - Key: "finding_sources:all" → CachedFindingSources (all sources with categories) - Key: "finding_sources:code:{code}" → single source (optional, for high-frequency lookups)

Cache invalidation: - Manual via InvalidateAll() when sources are modified (rare) - TTL-based expiration (24 hours)

This cache is GLOBAL (not per-tenant) because finding sources are system configuration.

func NewFindingSourceCacheService

func NewFindingSourceCacheService(
	redisClient *redis.Client,
	repo findingsource.Repository,
	log *logger.Logger,
) (*FindingSourceCacheService, error)

NewFindingSourceCacheService creates a new finding source cache service.

func (*FindingSourceCacheService) GetAll

GetAll returns all active finding sources with their categories (cached). This is the primary method for UI dropdowns and validation.

func (*FindingSourceCacheService) GetByCategory

func (s *FindingSourceCacheService) GetByCategory(ctx context.Context, categoryCode string) ([]*CachedFindingSource, error)

GetByCategory returns finding sources filtered by category code (from cache).

func (*FindingSourceCacheService) GetByCode

GetByCode returns a finding source by code (from cache). Returns nil if not found.

func (*FindingSourceCacheService) GetCategories

func (s *FindingSourceCacheService) GetCategories(ctx context.Context) ([]*CachedCategory, error)

GetCategories returns all active categories (from cache).

func (*FindingSourceCacheService) InvalidateAll

func (s *FindingSourceCacheService) InvalidateAll(ctx context.Context) error

InvalidateAll removes all cached finding source data. Call this when finding sources are modified (rare operation).

func (*FindingSourceCacheService) IsValidCode

func (s *FindingSourceCacheService) IsValidCode(ctx context.Context, code string) (bool, error)

IsValidCode checks if a code is a valid active finding source (from cache).

func (*FindingSourceCacheService) Refresh

Refresh forces a cache refresh by invalidating and reloading.

func (*FindingSourceCacheService) WarmCache

func (s *FindingSourceCacheService) WarmCache(ctx context.Context) error

WarmCache preloads the cache on startup. Call this during application initialization.

type FindingSourceService

type FindingSourceService struct {
	// contains filtered or unexported fields
}

FindingSourceService handles finding source-related business operations. Finding sources are read-only system configuration created via DB seed or by system admin.

func NewFindingSourceService

func NewFindingSourceService(repo findingsource.Repository, categoryRepo findingsource.CategoryRepository, log *logger.Logger) *FindingSourceService

NewFindingSourceService creates a new FindingSourceService.

func (*FindingSourceService) GetCategory

func (s *FindingSourceService) GetCategory(ctx context.Context, categoryID string) (*findingsource.Category, error)

GetCategory retrieves a category by ID.

func (*FindingSourceService) GetCategoryByCode

func (s *FindingSourceService) GetCategoryByCode(ctx context.Context, code string) (*findingsource.Category, error)

GetCategoryByCode retrieves a category by code.

func (*FindingSourceService) GetFindingSource

func (s *FindingSourceService) GetFindingSource(ctx context.Context, findingSourceID string) (*findingsource.FindingSource, error)

GetFindingSource retrieves a finding source by ID.

func (*FindingSourceService) GetFindingSourceByCode

func (s *FindingSourceService) GetFindingSourceByCode(ctx context.Context, code string) (*findingsource.FindingSource, error)

GetFindingSourceByCode retrieves a finding source by code.

func (*FindingSourceService) IsValidSourceCode

func (s *FindingSourceService) IsValidSourceCode(ctx context.Context, code string) (bool, error)

IsValidSourceCode checks if the code is a valid active finding source.

func (*FindingSourceService) ListActiveCategories

func (s *FindingSourceService) ListActiveCategories(ctx context.Context) ([]*findingsource.Category, error)

ListActiveCategories lists all active categories.

func (*FindingSourceService) ListActiveFindingSources

func (s *FindingSourceService) ListActiveFindingSources(ctx context.Context) ([]*findingsource.FindingSource, error)

ListActiveFindingSources lists all active finding sources.

func (*FindingSourceService) ListActiveFindingSourcesByCategory

func (s *FindingSourceService) ListActiveFindingSourcesByCategory(ctx context.Context, categoryID string) ([]*findingsource.FindingSource, error)

ListActiveFindingSourcesByCategory lists active finding sources by category.

func (*FindingSourceService) ListActiveFindingSourcesWithCategory

func (s *FindingSourceService) ListActiveFindingSourcesWithCategory(ctx context.Context) ([]*findingsource.FindingSourceWithCategory, error)

ListActiveFindingSourcesWithCategory lists all active finding sources with their categories.

func (*FindingSourceService) ListCategories

ListCategories lists categories with pagination.

func (*FindingSourceService) ListFindingSources

ListFindingSources lists finding sources with filtering and pagination.

func (*FindingSourceService) ListFindingSourcesWithCategory

ListFindingSourcesWithCategory lists finding sources with their categories.

type FindingStatsData

type FindingStatsData struct {
	Total       int
	BySeverity  map[string]int
	ByStatus    map[string]int
	Overdue     int
	AverageCVSS float64
}

FindingStatsData holds raw finding statistics from repository.

type ForgotPasswordInput

type ForgotPasswordInput struct {
	Email string `json:"email" validate:"required,email"`
}

ForgotPasswordInput represents the input for password reset request.

type ForgotPasswordResult

type ForgotPasswordResult struct {
	Token string // Reset token (should be sent via email in production)
}

ForgotPasswordResult represents the result of password reset request.

type GetModuleLimitOutput

type GetModuleLimitOutput struct {
	Limit     int64
	Unlimited bool
}

GetModuleLimitOutput represents the output for GetTenantModuleLimit.

type GetNotificationEventsInput

type GetNotificationEventsInput struct {
	IntegrationID string
	TenantID      string
	Limit         int
	Offset        int
}

GetNotificationEventsInput represents the input for getting notification events.

type GetNotificationEventsResult

type GetNotificationEventsResult struct {
	Data   []NotificationEventEntry `json:"data"`
	Total  int64                    `json:"total"`
	Limit  int                      `json:"limit"`
	Offset int                      `json:"offset"`
}

GetNotificationEventsResult represents the result of getting notification events.

type GetSCMRepositoryInput

type GetSCMRepositoryInput struct {
	IntegrationID string
	TenantID      string
	FullName      string // owner/repo format
}

GetSCMRepositoryInput represents the input for getting a single repository from SCM.

type GetTenantEnabledModulesOutput

type GetTenantEnabledModulesOutput struct {
	ModuleIDs  []string
	Modules    []*module.Module
	SubModules map[string][]*module.Module
}

GetTenantEnabledModulesOutput represents the output for GetTenantEnabledModules.

type GroupService

type GroupService struct {
	// contains filtered or unexported fields
}

GroupService handles group-related business operations.

func NewGroupService

func NewGroupService(
	repo group.Repository,
	log *logger.Logger,
	opts ...GroupServiceOption,
) *GroupService

NewGroupService creates a new GroupService.

func (*GroupService) AddMember

func (s *GroupService) AddMember(ctx context.Context, input AddGroupMemberInput, actx AuditContext) (*group.Member, error)

AddMember adds a user to a group.

func (*GroupService) AssignAsset

func (s *GroupService) AssignAsset(ctx context.Context, input AssignAssetInput, assignedBy shared.ID, actx AuditContext) error

AssignAsset assigns an asset to a group with the specified ownership type.

func (*GroupService) AssignPermissionSet

func (s *GroupService) AssignPermissionSet(ctx context.Context, input AssignPermissionSetInput, assignedBy shared.ID, actx AuditContext) error

AssignPermissionSet assigns a permission set to a group.

func (*GroupService) CanAccessAsset

func (s *GroupService) CanAccessAsset(ctx context.Context, userID shared.ID, assetID string) (bool, error)

CanAccessAsset checks if a user can access an asset through their group memberships.

func (*GroupService) CreateGroup

func (s *GroupService) CreateGroup(ctx context.Context, input CreateGroupInput, creatorUserID shared.ID, actx AuditContext) (*group.Group, error)

CreateGroup creates a new group.

func (*GroupService) DeleteGroup

func (s *GroupService) DeleteGroup(ctx context.Context, groupID string, actx AuditContext) error

DeleteGroup deletes a group.

func (*GroupService) GetGroup

func (s *GroupService) GetGroup(ctx context.Context, groupID string) (*group.Group, error)

GetGroup retrieves a group by ID.

func (*GroupService) GetGroupBySlug

func (s *GroupService) GetGroupBySlug(ctx context.Context, tenantID, slug string) (*group.Group, error)

GetGroupBySlug retrieves a group by tenant and slug.

func (*GroupService) ListAssetOwners

func (s *GroupService) ListAssetOwners(ctx context.Context, assetID string) ([]*accesscontrol.AssetOwner, error)

ListAssetOwners lists all groups that own an asset.

func (*GroupService) ListGroupAssets

func (s *GroupService) ListGroupAssets(ctx context.Context, groupID string) ([]*accesscontrol.AssetOwner, error)

ListGroupAssets lists all assets assigned to a group.

func (*GroupService) ListGroupMembers

func (s *GroupService) ListGroupMembers(ctx context.Context, groupID string) ([]*group.Member, error)

ListGroupMembers lists all members of a group.

func (*GroupService) ListGroupMembersWithUserInfo

func (s *GroupService) ListGroupMembersWithUserInfo(ctx context.Context, groupID string) ([]*group.MemberWithUser, error)

ListGroupMembersWithUserInfo lists members with user details.

func (*GroupService) ListGroupPermissionSets

func (s *GroupService) ListGroupPermissionSets(ctx context.Context, groupID string) ([]shared.ID, error)

ListGroupPermissionSets lists permission sets assigned to a group.

func (*GroupService) ListGroupPermissionSetsWithDetails

func (s *GroupService) ListGroupPermissionSetsWithDetails(ctx context.Context, groupID string) ([]*permissionset.PermissionSetWithItems, error)

ListGroupPermissionSetsWithDetails lists permission sets assigned to a group with full details.

func (*GroupService) ListGroups

func (s *GroupService) ListGroups(ctx context.Context, input ListGroupsInput) (*ListGroupsOutput, error)

ListGroups lists groups with filtering.

func (*GroupService) ListMyAssets

func (s *GroupService) ListMyAssets(ctx context.Context, tenantID string, userID shared.ID) ([]shared.ID, error)

ListMyAssets lists all assets the user can access through their group memberships.

func (*GroupService) ListUserGroups

func (s *GroupService) ListUserGroups(ctx context.Context, tenantID string, userID shared.ID) ([]*group.GroupWithRole, error)

ListUserGroups lists all groups a user belongs to.

func (*GroupService) RemoveMember

func (s *GroupService) RemoveMember(ctx context.Context, groupID string, userID shared.ID, actx AuditContext) error

RemoveMember removes a member from a group.

func (*GroupService) UnassignAsset

func (s *GroupService) UnassignAsset(ctx context.Context, input UnassignAssetInput, actx AuditContext) error

UnassignAsset removes an asset from a group.

func (*GroupService) UnassignPermissionSet

func (s *GroupService) UnassignPermissionSet(ctx context.Context, groupID, permissionSetID string, actx AuditContext) error

UnassignPermissionSet removes a permission set from a group.

func (*GroupService) UpdateAssetOwnership

func (s *GroupService) UpdateAssetOwnership(ctx context.Context, input UpdateAssetOwnershipInput, actx AuditContext) error

UpdateAssetOwnership updates the ownership type of an asset for a group.

func (*GroupService) UpdateGroup

func (s *GroupService) UpdateGroup(ctx context.Context, groupID string, input UpdateGroupInput, actx AuditContext) (*group.Group, error)

UpdateGroup updates a group.

func (*GroupService) UpdateMemberRole

func (s *GroupService) UpdateMemberRole(ctx context.Context, input UpdateGroupMemberRoleInput, actx AuditContext) (*group.Member, error)

UpdateMemberRole updates a member's role in a group.

type GroupServiceOption

type GroupServiceOption func(*GroupService)

GroupServiceOption is a functional option for GroupService.

func WithAccessControlRepository

func WithAccessControlRepository(repo accesscontrol.Repository) GroupServiceOption

WithAccessControlRepository sets the access control repository.

func WithGroupAuditService

func WithGroupAuditService(auditService *AuditService) GroupServiceOption

WithGroupAuditService sets the audit service for GroupService.

func WithPermissionSetRepository

func WithPermissionSetRepository(repo permissionset.Repository) GroupServiceOption

WithPermissionSetRepository sets the permission set repository.

type HTTPRequestHandler

type HTTPRequestHandler struct {
	// contains filtered or unexported fields
}

HTTPRequestHandler handles HTTP request actions. SECURITY: Includes SSRF protection via URL allowlist/denylist.

func NewHTTPRequestHandler

func NewHTTPRequestHandler(log *logger.Logger) *HTTPRequestHandler

NewHTTPRequestHandler creates a new secure HTTPRequestHandler.

func (*HTTPRequestHandler) Execute

func (h *HTTPRequestHandler) Execute(ctx context.Context, input *ActionInput) (map[string]any, error)

Execute executes an HTTP request action.

type IdentityExposure

type IdentityExposure struct {
	Identity        string         `json:"identity"`      // username or email
	IdentityType    string         `json:"identity_type"` // "username" or "email"
	ExposureCount   int            `json:"exposure_count"`
	Sources         []string       `json:"sources"`
	CredentialTypes []string       `json:"credential_types"`
	HighestSeverity string         `json:"highest_severity"`
	States          map[string]int `json:"states"` // count by state
	FirstSeenAt     time.Time      `json:"first_seen_at"`
	LastSeenAt      time.Time      `json:"last_seen_at"`
}

IdentityExposure represents aggregated exposures for a single identity.

type IdentityListResult

type IdentityListResult struct {
	Items      []IdentityExposure `json:"items"`
	Total      int64              `json:"total"`
	Page       int                `json:"page"`
	PageSize   int                `json:"page_size"`
	TotalPages int                `json:"total_pages"`
}

IdentityListResult represents the result of listing identities.

type IntegrationListReposInput

type IntegrationListReposInput struct {
	IntegrationID string
	TenantID      string
	Search        string
	Page          int
	PerPage       int
}

IntegrationListReposInput represents the input for listing repositories from an SCM integration.

type IntegrationListReposResult

type IntegrationListReposResult struct {
	Repositories []scm.Repository
	Total        int
	HasMore      bool
	NextPage     int
}

IntegrationListReposResult represents the result of listing repositories.

type IntegrationService

type IntegrationService struct {
	// contains filtered or unexported fields
}

IntegrationService provides integration operations.

func NewIntegrationService

func NewIntegrationService(
	repo integration.Repository,
	scmExtRepo integration.SCMExtensionRepository,
	encryptor crypto.Encryptor,
	log *logger.Logger,
) *IntegrationService

NewIntegrationService creates a new IntegrationService. The encryptor is used to encrypt/decrypt integration credentials. If encryptor is nil, a no-op encryptor is used (credentials stored in plaintext).

func (*IntegrationService) BroadcastNotification

BroadcastNotification sends a notification to all connected notification integrations.

func (*IntegrationService) CreateIntegration

CreateIntegration creates a new integration.

func (*IntegrationService) CreateNotificationIntegration

CreateNotificationIntegration creates a new notification integration.

func (*IntegrationService) DeleteIntegration

func (s *IntegrationService) DeleteIntegration(ctx context.Context, id string, tenantID string) error

DeleteIntegration deletes an integration.

func (*IntegrationService) DisableIntegration

func (s *IntegrationService) DisableIntegration(ctx context.Context, id string, tenantID string) (*integration.Integration, error)

DisableIntegration disables an integration.

func (*IntegrationService) EnableIntegration

func (s *IntegrationService) EnableIntegration(ctx context.Context, id string, tenantID string) (*integration.IntegrationWithSCM, error)

EnableIntegration enables an integration.

func (*IntegrationService) FindSCMIntegration

FindSCMIntegration finds a matching SCM integration by provider and organization. Returns the first connected integration that matches.

func (*IntegrationService) GetIntegration

func (s *IntegrationService) GetIntegration(ctx context.Context, id string) (*integration.Integration, error)

GetIntegration retrieves an integration by ID.

func (*IntegrationService) GetIntegrationWithSCM

func (s *IntegrationService) GetIntegrationWithSCM(ctx context.Context, id string) (*integration.IntegrationWithSCM, error)

GetIntegrationWithSCM retrieves an SCM integration with its extension.

func (*IntegrationService) GetNotificationEvents

GetNotificationEvents retrieves notification events for a specific integration. This returns events from the new notification_events audit trail.

func (*IntegrationService) GetNotificationIntegration

func (s *IntegrationService) GetNotificationIntegration(ctx context.Context, id string, tenantID string) (*integration.IntegrationWithNotification, error)

GetNotificationIntegration retrieves a notification integration with its extension.

func (*IntegrationService) GetSCMRepository

func (s *IntegrationService) GetSCMRepository(ctx context.Context, input GetSCMRepositoryInput) (*scm.Repository, error)

GetSCMRepository gets a single repository from an SCM integration (includes languages).

func (*IntegrationService) ListIntegrations

ListIntegrations lists integrations with filtering and pagination.

func (*IntegrationService) ListNotificationIntegrations

func (s *IntegrationService) ListNotificationIntegrations(ctx context.Context, tenantID string) ([]*integration.IntegrationWithNotification, error)

ListNotificationIntegrations lists all notification integrations with their extensions.

func (*IntegrationService) ListSCMIntegrations

func (s *IntegrationService) ListSCMIntegrations(ctx context.Context, tenantID string) ([]*integration.IntegrationWithSCM, error)

ListSCMIntegrations lists all SCM integrations with their extensions.

func (*IntegrationService) ListSCMRepositories

ListSCMRepositories lists repositories from an SCM integration.

func (*IntegrationService) NotifyNewFinding

func (s *IntegrationService) NotifyNewFinding(tenantID, title, body, severity, url string)

NotifyNewFinding sends a notification for a new finding to all connected notification integrations. This implements the FindingNotifier interface and is designed to be called asynchronously. Any errors are logged but not returned since this is a fire-and-forget operation.

func (*IntegrationService) SendNotification

SendNotification sends a notification through a specific integration.

func (*IntegrationService) SetNotificationEventRepository

func (s *IntegrationService) SetNotificationEventRepository(repo notificationdomain.EventRepository)

SetNotificationEventRepository sets the notification event repository.

func (*IntegrationService) SetNotificationExtensionRepository

func (s *IntegrationService) SetNotificationExtensionRepository(repo integration.NotificationExtensionRepository)

SetNotificationExtensionRepository sets the notification extension repository.

func (*IntegrationService) SyncIntegration

func (s *IntegrationService) SyncIntegration(ctx context.Context, id string, tenantID string) (*integration.IntegrationWithSCM, error)

SyncIntegration triggers a sync for an integration (updates stats, repo count, etc.)

func (*IntegrationService) TestIntegration

func (s *IntegrationService) TestIntegration(ctx context.Context, id string, tenantID string) (*integration.IntegrationWithSCM, error)

TestIntegration tests the connection for an integration.

func (*IntegrationService) TestIntegrationCredentials

TestIntegrationCredentials tests credentials without persisting an integration.

func (*IntegrationService) TestNotificationIntegration

func (s *IntegrationService) TestNotificationIntegration(ctx context.Context, id string, tenantID string) (*integration.IntegrationWithNotification, error)

TestNotificationIntegration tests the connection for a notification integration.

func (*IntegrationService) UpdateIntegration

func (s *IntegrationService) UpdateIntegration(ctx context.Context, id string, tenantID string, input UpdateIntegrationInput) (*integration.IntegrationWithSCM, error)

UpdateIntegration updates an existing integration.

func (*IntegrationService) UpdateNotificationIntegration

UpdateNotificationIntegration updates an existing notification integration.

type KEVStats

type KEVStats struct {
	TotalEntries            int `json:"total_entries"`
	PastDueCount            int `json:"past_due_count"`
	RecentlyAddedLast30Days int `json:"recently_added_last_30_days"`
	RansomwareRelatedCount  int `json:"ransomware_related_count"`
}

KEVStats contains KEV catalog statistics.

type ListAPIKeysInput

type ListAPIKeysInput struct {
	TenantID  string `json:"tenant_id" validate:"required,uuid"`
	Status    string `json:"status"`
	Search    string `json:"search"`
	Page      int    `json:"page"`
	PerPage   int    `json:"per_page"`
	SortBy    string `json:"sort_by"`
	SortOrder string `json:"sort_order"`
}

ListAPIKeysInput represents input for listing API keys.

type ListActivitiesInput

type ListActivitiesInput struct {
	TenantID      string   `validate:"required,uuid"` // Security: Required for tenant isolation
	FindingID     string   `validate:"required,uuid"`
	ActivityTypes []string `validate:"omitempty"`
	Page          int      `validate:"gte=0"`
	PageSize      int      `validate:"gte=1,lte=100"`
}

ListActivitiesInput represents the input for listing activities.

type ListAgentsInput

type ListAgentsInput struct {
	TenantID      string   `json:"tenant_id" validate:"required,uuid"`
	Type          string   `json:"type" validate:"omitempty,oneof=runner worker collector sensor"`
	Status        string   `json:"status" validate:"omitempty,oneof=active disabled revoked"`      // Admin-controlled
	Health        string   `json:"health" validate:"omitempty,oneof=unknown online offline error"` // Automatic
	ExecutionMode string   `json:"execution_mode" validate:"omitempty,oneof=standalone daemon"`
	Capabilities  []string `json:"capabilities"`
	Tools         []string `json:"tools"`
	Search        string   `json:"search" validate:"max=255"`
	HasCapacity   *bool    `json:"has_capacity"` // Filter by agents with available capacity
	Page          int      `json:"page"`
	PerPage       int      `json:"per_page"`
}

ListAgentsInput represents the input for listing agents.

type ListAssetGroupsInput

type ListAssetGroupsInput struct {
	TenantID      string
	Search        string
	Environments  []string
	Criticalities []string
	BusinessUnit  string
	Owner         string
	Tags          []string
	HasFindings   *bool
	MinRiskScore  *int
	MaxRiskScore  *int
	Sort          string
	Page          int `validate:"min=1"`
	PerPage       int `validate:"min=1,max=100"`
}

ListAssetGroupsInput represents input for listing asset groups.

type ListAssetGroupsOutput

type ListAssetGroupsOutput struct {
	Groups []*assetgroup.AssetGroup
	Total  int64
	Page   int
	Pages  int
}

ListAssetGroupsOutput represents output from listing asset groups.

type ListAssetsInput

type ListAssetsInput struct {
	TenantID      string   `validate:"omitempty,uuid"`
	Name          string   `validate:"max=255"`
	Types         []string `validate:"max=20,dive,asset_type"`
	Criticalities []string `validate:"max=5,dive,criticality"`
	Statuses      []string `validate:"max=3,dive,status"`
	Scopes        []string `validate:"max=6,dive,scope"`
	Exposures     []string `validate:"max=5,dive,exposure"`
	Tags          []string `validate:"max=20,dive,max=50"`
	Search        string   `validate:"max=255"` // Full-text search across name and description
	MinRiskScore  *int     `validate:"omitempty,min=0,max=100"`
	MaxRiskScore  *int     `validate:"omitempty,min=0,max=100"`
	HasFindings   *bool    // Filter by whether asset has findings
	Sort          string   `validate:"max=100"` // Sort field (e.g., "-created_at", "name")
	Page          int      `validate:"min=0"`
	PerPage       int      `validate:"min=0,max=100"`
}

ListAssetsInput represents the input for listing assets.

type ListAuditLogsInput

type ListAuditLogsInput struct {
	TenantID      string   `validate:"omitempty,uuid"`
	ActorID       string   `validate:"omitempty,uuid"`
	Actions       []string `validate:"max=20"`
	ResourceTypes []string `validate:"max=10"`
	ResourceID    string   `validate:"max=255"`
	Results       []string `validate:"max=3"`
	Severities    []string `validate:"max=4"`
	RequestID     string   `validate:"max=100"`
	Since         *time.Time
	Until         *time.Time
	SearchTerm    string `validate:"max=255"`
	Page          int    `validate:"min=0"`
	PerPage       int    `validate:"min=0,max=100"`
	SortBy        string `validate:"omitempty,oneof=logged_at action resource_type result severity"`
	SortOrder     string `validate:"omitempty,oneof=asc desc"`
	ExcludeSystem bool
}

ListAuditLogsInput represents the input for listing audit logs.

type ListAvailableToolsInput

type ListAvailableToolsInput struct {
	TenantID     string   `json:"tenant_id" validate:"required,uuid"`
	Category     string   `json:"category" validate:"omitempty,max=50"` // Category name (dynamic from tool_categories)
	Capabilities []string `json:"capabilities"`
	IsActive     *bool    `json:"is_active"`
	Search       string   `json:"search" validate:"max=255"`
	Tags         []string `json:"tags"`
	Page         int      `json:"page"`
	PerPage      int      `json:"per_page"`
}

ListAvailableToolsInput represents the input for listing all available tools.

type ListBranchesInput

type ListBranchesInput struct {
	RepositoryID string   `validate:"required,uuid"`
	Name         string   `validate:"max=255"`
	BranchTypes  []string `validate:"max=10,dive,branch_type"`
	IsDefault    *bool
	ScanStatus   string `validate:"omitempty,scan_status"`
	Sort         string `validate:"max=100"`
	Page         int    `validate:"min=0"`
	PerPage      int    `validate:"min=0,max=100"`
}

ListBranchesInput represents the input for listing branches.

type ListBundlesInput

type ListBundlesInput struct {
	TenantID string `json:"tenant_id" validate:"omitempty,uuid"`
	ToolID   string `json:"tool_id" validate:"omitempty,uuid"`
	Status   string `json:"status" validate:"omitempty,oneof=building ready failed expired"`
}

ListBundlesInput represents the input for listing bundles.

type ListCapabilitiesInput

type ListCapabilitiesInput struct {
	TenantID  string
	IsBuiltin *bool
	Category  *string
	Search    string
	Page      int
	PerPage   int
}

ListCapabilitiesInput represents the input for listing capabilities.

type ListCategoriesInput

type ListCategoriesInput struct {
	TenantID  string
	IsBuiltin *bool
	Search    string
	Page      int
	PerPage   int
}

ListCategoriesInput represents the input for listing categories.

type ListCommandsInput

type ListCommandsInput struct {
	TenantID string `json:"tenant_id" validate:"required,uuid"`
	AgentID  string `json:"agent_id,omitempty" validate:"omitempty,uuid"`
	Type     string `json:"type" validate:"omitempty,oneof=scan collect health_check config_update cancel"`
	Status   string `json:"status" validate:"omitempty,oneof=pending acknowledged running completed failed canceled expired"`
	Priority string `json:"priority" validate:"omitempty,oneof=low normal high critical"`
	Page     int    `json:"page"`
	PerPage  int    `json:"per_page"`
}

ListCommandsInput represents the input for listing commands.

type ListComponentsInput

type ListComponentsInput struct {
	TenantID           string   `validate:"required,uuid"`
	AssetID            string   `validate:"omitempty,uuid"`
	Name               string   `validate:"max=255"`
	Ecosystems         []string `validate:"max=10,dive,ecosystem"`
	Statuses           []string `validate:"max=5,dive,component_status"`
	DependencyTypes    []string `validate:"max=5,dive,dependency_type"`
	HasVulnerabilities *bool
	Licenses           []string `validate:"max=20,dive,max=100"`
	Page               int      `validate:"min=0"`
	PerPage            int      `validate:"min=0,max=100"`
}

ListComponentsInput represents the input for listing components.

type ListCredentialsInput

type ListCredentialsInput struct {
	TenantID       shared.ID
	CredentialType *string
	Page           int
	PageSize       int
	SortBy         string
	SortOrder      string
}

ListCredentialsInput contains input for listing credentials.

type ListCredentialsOutput

type ListCredentialsOutput struct {
	Items      []*secretstore.Credential
	TotalCount int
}

ListCredentialsOutput contains the result of listing credentials.

type ListCustomToolsInput

type ListCustomToolsInput struct {
	TenantID     string   `json:"tenant_id" validate:"required,uuid"`
	Category     string   `json:"category" validate:"omitempty,max=50"` // Category name (dynamic from tool_categories)
	Capabilities []string `json:"capabilities"`
	IsActive     *bool    `json:"is_active"`
	Search       string   `json:"search" validate:"max=255"`
	Tags         []string `json:"tags"`
	Page         int      `json:"page"`
	PerPage      int      `json:"per_page"`
}

ListCustomToolsInput represents the input for listing tenant custom tools.

type ListDeliveriesInput

type ListDeliveriesInput struct {
	WebhookID string `json:"webhook_id" validate:"required,uuid"`
	TenantID  string `json:"tenant_id" validate:"required,uuid"`
	Status    string `json:"status"`
	Page      int    `json:"page"`
	PerPage   int    `json:"per_page"`
}

ListDeliveriesInput represents input for listing deliveries.

type ListExclusionsInput

type ListExclusionsInput struct {
	TenantID       string   `validate:"omitempty,uuid"`
	ExclusionTypes []string `validate:"max=20"`
	Statuses       []string `validate:"max=3"`
	IsApproved     *bool
	Search         string `validate:"max=255"`
	Page           int    `validate:"min=0"`
	PerPage        int    `validate:"min=0,max=100"`
}

ListExclusionsInput represents the input for listing scope exclusions.

type ListExposuresInput

type ListExposuresInput struct {
	TenantID string

	AssetID         string
	EventTypes      []string
	Severities      []string
	States          []string
	Sources         []string
	Search          string
	FirstSeenAfter  int64
	FirstSeenBefore int64
	LastSeenAfter   int64
	LastSeenBefore  int64
	Page            int
	PerPage         int
	SortBy          string
	SortOrder       string
}

ListExposuresInput represents the input for listing exposure events.

type ListFindingsInput

type ListFindingsInput struct {
	TenantID        string   `validate:"required,uuid"`
	AssetID         string   `validate:"omitempty,uuid"`
	BranchID        string   `validate:"omitempty,uuid"`
	ComponentID     string   `validate:"omitempty,uuid"`
	VulnerabilityID string   `validate:"omitempty,uuid"`
	Severities      []string `validate:"max=5,dive,severity"`
	Statuses        []string `validate:"max=10,dive,finding_status"`
	Sources         []string `validate:"max=5,dive,finding_source"`
	ToolName        string   `validate:"max=100"`
	RuleID          string   `validate:"max=255"`
	ScanID          string   `validate:"max=100"`
	FilePath        string   `validate:"max=500"`
	Search          string   `validate:"max=255"` // Full-text search across title, description, and file path
	Sort            string   `validate:"max=100"` // Sort field (e.g., "-severity", "created_at")
	Page            int      `validate:"min=0"`
	PerPage         int      `validate:"min=0,max=100"`
}

ListFindingsInput represents the input for listing findings.

type ListGroupsInput

type ListGroupsInput struct {
	TenantID  string
	GroupType *string
	IsActive  *bool
	Search    string
	Limit     int
	Offset    int
}

ListGroupsInput represents the input for listing groups.

type ListGroupsOutput

type ListGroupsOutput struct {
	Groups     []*group.Group
	TotalCount int64
}

ListGroupsOutput represents the output for listing groups.

type ListIntegrationsInput

type ListIntegrationsInput struct {
	TenantID  string
	Category  string
	Provider  string
	Status    string
	Search    string
	Page      int
	PerPage   int
	SortBy    string
	SortOrder string
}

ListIntegrationsInput represents the input for listing integrations.

type ListOverridesInput

type ListOverridesInput struct {
	TenantID      string `json:"tenant_id" validate:"omitempty,uuid"`
	ToolID        string `json:"tool_id" validate:"omitempty,uuid"`
	AssetGroupID  string `json:"asset_group_id" validate:"omitempty,uuid"`
	ScanProfileID string `json:"scan_profile_id" validate:"omitempty,uuid"`
	Enabled       *bool  `json:"enabled"`
	Page          int    `json:"page"`
	PerPage       int    `json:"per_page"`
}

ListOverridesInput represents the input for listing rule overrides.

type ListPermissionSetsInput

type ListPermissionSetsInput struct {
	TenantID      string
	IncludeSystem bool    // Include system permission sets
	SetType       *string // Filter by type
	IsActive      *bool
	Search        string
	Limit         int
	Offset        int
}

ListPermissionSetsInput represents the input for listing permission sets.

type ListPermissionSetsOutput

type ListPermissionSetsOutput struct {
	PermissionSets []*permissionset.PermissionSet
	TotalCount     int64
}

ListPermissionSetsOutput represents the output for listing permission sets.

type ListPlatformToolsInput

type ListPlatformToolsInput struct {
	Category     string   `json:"category" validate:"omitempty,max=50"` // Category name (dynamic from tool_categories)
	Capabilities []string `json:"capabilities"`
	IsActive     *bool    `json:"is_active"`
	Search       string   `json:"search" validate:"max=255"`
	Tags         []string `json:"tags"`
	Page         int      `json:"page"`
	PerPage      int      `json:"per_page"`
}

ListPlatformToolsInput represents the input for listing platform tools.

type ListRulesInput

type ListRulesInput struct {
	TenantID string   `json:"tenant_id" validate:"omitempty,uuid"`
	ToolID   string   `json:"tool_id" validate:"omitempty,uuid"`
	SourceID string   `json:"source_id" validate:"omitempty,uuid"`
	Severity string   `json:"severity" validate:"omitempty,oneof=critical high medium low info unknown"`
	Category string   `json:"category" validate:"max=100"`
	Tags     []string `json:"tags"`
	RuleIDs  []string `json:"rule_ids"`
	Search   string   `json:"search" validate:"max=255"`
	Page     int      `json:"page"`
	PerPage  int      `json:"per_page"`
}

ListRulesInput represents the input for listing rules.

type ListScanProfilesInput

type ListScanProfilesInput struct {
	TenantID      string   `json:"tenant_id" validate:"required,uuid"`
	IsDefault     *bool    `json:"is_default"`
	IsSystem      *bool    `json:"is_system"`
	Tags          []string `json:"tags"`
	Search        string   `json:"search" validate:"max=255"`
	Page          int      `json:"page"`
	PerPage       int      `json:"per_page"`
	IncludeSystem bool     `json:"include_system"` // Include system profiles in results
}

ListScanProfilesInput represents the input for listing scan profiles.

type ListScanSessionsInput

type ListScanSessionsInput struct {
	ScannerName string
	AssetType   string
	AssetValue  string
	Branch      string
	Status      string
	Since       *time.Time
	Until       *time.Time
}

ListScanSessionsInput represents the input for listing scan sessions.

type ListScannerTemplatesInput

type ListScannerTemplatesInput struct {
	TenantID     string   `json:"tenant_id" validate:"required,uuid"`
	TemplateType *string  `json:"template_type" validate:"omitempty,oneof=nuclei semgrep gitleaks"`
	Status       *string  `json:"status" validate:"omitempty,oneof=active pending_review deprecated revoked"`
	Tags         []string `json:"tags"`
	Search       string   `json:"search" validate:"max=255"`
	Page         int      `json:"page"`
	PerPage      int      `json:"per_page"`
}

ListScannerTemplatesInput represents the input for listing scanner templates.

type ListSchedulesInput

type ListSchedulesInput struct {
	TenantID      string   `validate:"omitempty,uuid"`
	ScanTypes     []string `validate:"max=20"`
	ScheduleTypes []string `validate:"max=3"`
	Enabled       *bool
	Search        string `validate:"max=255"`
	Page          int    `validate:"min=0"`
	PerPage       int    `validate:"min=0,max=100"`
}

ListSchedulesInput represents the input for listing scan schedules.

type ListSourcesInput

type ListSourcesInput struct {
	TenantID          string `json:"tenant_id" validate:"omitempty,uuid"`
	ToolID            string `json:"tool_id" validate:"omitempty,uuid"`
	SourceType        string `json:"source_type" validate:"omitempty,oneof=git http local"`
	Enabled           *bool  `json:"enabled"`
	IsPlatformDefault *bool  `json:"is_platform_default"`
	SyncStatus        string `json:"sync_status" validate:"omitempty,oneof=pending syncing success failed"`
	Search            string `json:"search" validate:"max=255"`
	Page              int    `json:"page"`
	PerPage           int    `json:"per_page"`
}

ListSourcesInput represents the input for listing rule sources.

type ListTargetsInput

type ListTargetsInput struct {
	TenantID    string   `validate:"omitempty,uuid"`
	TargetTypes []string `validate:"max=20"`
	Statuses    []string `validate:"max=3"`
	Tags        []string `validate:"max=20,dive,max=50"`
	Search      string   `validate:"max=255"`
	Page        int      `validate:"min=0"`
	PerPage     int      `validate:"min=0,max=100"`
}

ListTargetsInput represents the input for listing scope targets.

type ListTemplateSourcesInput

type ListTemplateSourcesInput struct {
	TenantID     string  `json:"tenant_id" validate:"required,uuid"`
	SourceType   *string `json:"source_type" validate:"omitempty,oneof=git s3 http"`
	TemplateType *string `json:"template_type" validate:"omitempty,oneof=nuclei semgrep gitleaks"`
	Enabled      *bool   `json:"enabled"`
	Page         int     `json:"page"`
	PageSize     int     `json:"page_size"`
	SortBy       string  `json:"sort_by"`
	SortOrder    string  `json:"sort_order"`
}

ListTemplateSourcesInput represents the input for listing template sources.

type ListTenantToolConfigsInput

type ListTenantToolConfigsInput struct {
	TenantID  string `json:"tenant_id" validate:"required,uuid"`
	ToolID    string `json:"tool_id" validate:"omitempty,uuid"`
	IsEnabled *bool  `json:"is_enabled"`
	Page      int    `json:"page"`
	PerPage   int    `json:"per_page"`
}

ListTenantToolConfigsInput represents the input for listing tenant tool configs.

type ListToolExecutionsInput

type ListToolExecutionsInput struct {
	TenantID      string `json:"tenant_id" validate:"required,uuid"`
	ToolID        string `json:"tool_id" validate:"omitempty,uuid"`
	AgentID       string `json:"agent_id" validate:"omitempty,uuid"`
	PipelineRunID string `json:"pipeline_run_id" validate:"omitempty,uuid"`
	Status        string `json:"status" validate:"omitempty,oneof=running completed failed timeout"`
	Page          int    `json:"page"`
	PerPage       int    `json:"per_page"`
}

ListToolExecutionsInput represents the input for listing tool executions.

type ListToolsInput

type ListToolsInput struct {
	Category     string   `json:"category" validate:"omitempty,max=50"` // Category name (dynamic from tool_categories)
	Capabilities []string `json:"capabilities"`
	IsActive     *bool    `json:"is_active"`
	IsBuiltin    *bool    `json:"is_builtin"`
	Search       string   `json:"search" validate:"max=255"`
	Tags         []string `json:"tags"`
	Page         int      `json:"page"`
	PerPage      int      `json:"per_page"`
}

ListToolsInput represents the input for listing tools.

type ListToolsWithConfigInput

type ListToolsWithConfigInput struct {
	TenantID  string   `json:"tenant_id" validate:"required,uuid"`
	Category  string   `json:"category" validate:"omitempty,max=50"` // Category name (dynamic from tool_categories)
	IsActive  *bool    `json:"is_active"`
	IsBuiltin *bool    `json:"is_builtin"`
	Search    string   `json:"search" validate:"max=255"`
	Tags      []string `json:"tags"`
	Page      int      `json:"page"`
	PerPage   int      `json:"per_page"`
}

ListToolsWithConfigInput represents the input for listing tools with config.

type ListVulnerabilitiesInput

type ListVulnerabilitiesInput struct {
	CVEIDs           []string `validate:"max=50,dive,max=20"`
	Severities       []string `validate:"max=5,dive,severity"`
	MinCVSS          *float64 `validate:"omitempty,min=0,max=10"`
	MaxCVSS          *float64 `validate:"omitempty,min=0,max=10"`
	MinEPSS          *float64 `validate:"omitempty,min=0,max=1"`
	ExploitAvailable *bool
	CISAKEVOnly      *bool
	Statuses         []string `validate:"max=5,dive,vulnerability_status"`
	Search           string   `validate:"max=255"` // Full-text search across CVE ID and description
	Sort             string   `validate:"max=100"` // Sort field (e.g., "-cvss_score", "cve_id")
	Page             int      `validate:"min=0"`
	PerPage          int      `validate:"min=0,max=100"`
}

ListVulnerabilitiesInput represents the input for listing vulnerabilities.

type ListWebhooksInput

type ListWebhooksInput struct {
	TenantID  string `json:"tenant_id" validate:"required,uuid"`
	Status    string `json:"status"`
	EventType string `json:"event_type"`
	Search    string `json:"search"`
	Page      int    `json:"page"`
	PerPage   int    `json:"per_page"`
	SortBy    string `json:"sort_by"`
	SortOrder string `json:"sort_order"`
}

ListWebhooksInput represents input for listing webhooks.

type ListWorkflowRunsInput

type ListWorkflowRunsInput struct {
	TenantID   shared.ID
	WorkflowID *shared.ID
	Status     *workflow.RunStatus
	Page       int
	PerPage    int
}

ListWorkflowRunsInput represents input for listing workflow runs.

type ListWorkflowsInput

type ListWorkflowsInput struct {
	TenantID shared.ID
	IsActive *bool
	Tags     []string
	Search   string
	Page     int
	PerPage  int
}

ListWorkflowsInput represents input for listing workflows.

type LoginInput

type LoginInput struct {
	Email     string `json:"email" validate:"required,email"`
	Password  string `json:"password" validate:"required"`
	IPAddress string `json:"-"`
	UserAgent string `json:"-"`
}

LoginInput represents the input for login.

type LoginResult

type LoginResult struct {
	User         *user.User
	RefreshToken string // Global refresh token (no tenant context)
	ExpiresAt    time.Time
	SessionID    string
	Tenants      []TenantMembershipInfo // List of tenants user belongs to
}

LoginResult represents the result of login. Returns a global refresh token and list of tenant memberships. Client must call ExchangeToken to get a tenant-scoped access token.

type ModuleCacheRepository

type ModuleCacheRepository interface {
	GetPlanModulesByTenantID(ctx context.Context, tenantID uuid.UUID) ([]string, error)
	GetModulesByIDs(ctx context.Context, ids []string) ([]*module.Module, error)
	GetEventTypesForModulesBatch(ctx context.Context, moduleIDs []string) (map[string][]string, error)
	GetSubModulesForParents(ctx context.Context, parentModuleIDs []string) (map[string][]*module.Module, error)
}

ModuleCacheRepository defines the repository methods needed by ModuleCacheService.

type ModuleCacheService

type ModuleCacheService struct {
	// contains filtered or unexported fields
}

ModuleCacheService provides cached access to tenant modules. Modules are cached in Redis with a short TTL for performance. On cache miss, modules are fetched from the database.

Key format: tenant_modules:{tenant_id} → JSON array of module data Cache is invalidated when tenant's module configuration changes.

func NewModuleCacheService

func NewModuleCacheService(
	redisClient *redis.Client,
	repo ModuleCacheRepository,
	log *logger.Logger,
) (*ModuleCacheService, error)

NewModuleCacheService creates a new module cache service.

func (*ModuleCacheService) GetTenantModules

func (s *ModuleCacheService) GetTenantModules(ctx context.Context, tenantID string) (*CachedTenantModules, error)

GetTenantModules returns the cached modules for a tenant. Uses TTL-based caching (5 min) + explicit invalidation on plan changes. No extra DB queries on cache hit - relies on: 1. TTL expiration for natural refresh 2. Explicit Invalidate() call when module configuration changes (see ModuleService.UpdateTenantModules)

func (*ModuleCacheService) HasModule

func (s *ModuleCacheService) HasModule(ctx context.Context, tenantID, moduleID string) (bool, error)

HasModule checks if a tenant has access to a specific module (using cache).

func (*ModuleCacheService) HasSubModule

func (s *ModuleCacheService) HasSubModule(ctx context.Context, tenantID, parentModuleID, fullSubModuleID string) (bool, error)

HasSubModule checks if a tenant has access to a specific sub-module (using cache).

func (*ModuleCacheService) Invalidate

func (s *ModuleCacheService) Invalidate(ctx context.Context, tenantID string) error

Invalidate removes the cached modules for a tenant. Called when tenant's module configuration changes. Returns error if cache invalidation fails after retries. Callers should log errors but typically should not fail the operation since DB transaction has already committed.

func (*ModuleCacheService) InvalidateAll

func (s *ModuleCacheService) InvalidateAll(ctx context.Context)

InvalidateAll removes cached modules for all tenants. Called when global module configuration changes.

func (*ModuleCacheService) Refresh

func (s *ModuleCacheService) Refresh(ctx context.Context, tenantID string) (*CachedTenantModules, error)

Refresh refreshes the cached modules for a tenant. Forces a database fetch and updates the cache.

type ModuleRepository

type ModuleRepository interface {
	ListAllModules(ctx context.Context) ([]*module.Module, error)
	ListActiveModules(ctx context.Context) ([]*module.Module, error)
	GetModuleByID(ctx context.Context, id string) (*module.Module, error)
	GetSubModules(ctx context.Context, parentModuleID string) ([]*module.Module, error)
}

ModuleRepository interface for module operations.

type ModuleService

type ModuleService struct {
	// contains filtered or unexported fields
}

ModuleService handles module-related business operations. OSS Edition: All modules are always enabled, no subscription/licensing checks.

func NewModuleService

func NewModuleService(moduleRepo ModuleRepository, log *logger.Logger) *ModuleService

NewModuleService creates a new ModuleService.

func (*ModuleService) GetModule

func (s *ModuleService) GetModule(ctx context.Context, moduleID string) (*module.Module, error)

GetModule retrieves a module by ID.

func (*ModuleService) GetTenantEnabledModules

func (s *ModuleService) GetTenantEnabledModules(ctx context.Context, tenantID string) (*GetTenantEnabledModulesOutput, error)

GetTenantEnabledModules returns all enabled modules for a tenant. OSS Edition: Returns all active modules from the database.

func (*ModuleService) GetTenantModuleLimit

func (s *ModuleService) GetTenantModuleLimit(ctx context.Context, tenantID, moduleID, metric string) (*GetModuleLimitOutput, error)

GetTenantModuleLimit returns the limit for a specific module metric. OSS Edition: Always returns unlimited.

func (*ModuleService) ListActiveModules

func (s *ModuleService) ListActiveModules(ctx context.Context) ([]*module.Module, error)

ListActiveModules returns all active modules.

func (*ModuleService) TenantHasModule

func (s *ModuleService) TenantHasModule(ctx context.Context, tenantID, moduleID string) (bool, error)

TenantHasModule checks if a tenant has access to a specific module. OSS Edition: Always returns true (all modules enabled).

func (*ModuleService) TenantHasSubModule

func (s *ModuleService) TenantHasSubModule(ctx context.Context, tenantID, parentModuleID, subModuleID string) (bool, error)

TenantHasSubModule checks if a tenant has access to a specific sub-module. OSS Edition: Always returns true (all modules enabled).

type NotificationEventEntry

type NotificationEventEntry struct {
	ID                    string                        `json:"id"`
	EventType             string                        `json:"event_type"`
	AggregateType         string                        `json:"aggregate_type,omitempty"`
	AggregateID           string                        `json:"aggregate_id,omitempty"`
	Title                 string                        `json:"title"`
	Body                  string                        `json:"body,omitempty"`
	Severity              string                        `json:"severity"`
	URL                   string                        `json:"url,omitempty"`
	Status                string                        `json:"status"`
	IntegrationsTotal     int                           `json:"integrations_total"`
	IntegrationsMatched   int                           `json:"integrations_matched"`
	IntegrationsSucceeded int                           `json:"integrations_succeeded"`
	IntegrationsFailed    int                           `json:"integrations_failed"`
	SendResults           []NotificationEventSendResult `json:"send_results"`
	LastError             string                        `json:"last_error,omitempty"`
	RetryCount            int                           `json:"retry_count"`
	CreatedAt             time.Time                     `json:"created_at"`
	ProcessedAt           time.Time                     `json:"processed_at"`
}

NotificationEventEntry represents a notification event entry in API responses.

type NotificationEventSendResult

type NotificationEventSendResult struct {
	IntegrationID   string    `json:"integration_id"`
	IntegrationName string    `json:"name"`
	Provider        string    `json:"provider"`
	Status          string    `json:"status"`
	MessageID       string    `json:"message_id,omitempty"`
	Error           string    `json:"error,omitempty"`
	SentAt          time.Time `json:"sent_at"`
}

NotificationEventSendResult represents a single send result to an integration.

type NotificationHandler

type NotificationHandler interface {
	// Send sends a notification and returns the result.
	Send(ctx context.Context, input *NotificationInput) (map[string]any, error)
}

NotificationHandler defines the interface for notification handlers.

type NotificationInput

type NotificationInput struct {
	TenantID           shared.ID
	WorkflowID         shared.ID
	RunID              shared.ID
	NodeKey            string
	NotificationType   workflow.NotificationType
	NotificationConfig map[string]any
	TriggerData        map[string]any
	Context            map[string]any
}

NotificationInput contains the input for a notification.

type NotificationScheduler

type NotificationScheduler struct {
	// contains filtered or unexported fields
}

NotificationScheduler runs periodic notification processing tasks.

func NewNotificationScheduler

func NewNotificationScheduler(service *NotificationService, config NotificationSchedulerConfig, log *logger.Logger) *NotificationScheduler

NewNotificationScheduler creates a new notification scheduler.

func (*NotificationScheduler) Start

func (s *NotificationScheduler) Start()

Start starts the notification scheduler.

func (*NotificationScheduler) Stop

func (s *NotificationScheduler) Stop()

Stop stops the notification scheduler gracefully.

type NotificationSchedulerConfig

type NotificationSchedulerConfig struct {
	// ProcessInterval is how often to process outbox entries (default: 5 seconds).
	ProcessInterval time.Duration
	// CleanupInterval is how often to cleanup old entries (default: 24 hours).
	CleanupInterval time.Duration
	// UnlockInterval is how often to unlock stale entries (default: 1 minute).
	UnlockInterval time.Duration
	// BatchSize is the number of entries to process per batch (default: 50).
	BatchSize int
	// CompletedRetentionDays is how long to keep completed outbox entries (default: 7).
	// Note: With the new architecture, completed entries are deleted immediately after archiving.
	// This is kept for backward compatibility and for entries that failed to archive.
	CompletedRetentionDays int
	// FailedRetentionDays is how long to keep failed outbox entries (default: 30).
	FailedRetentionDays int
	// EventRetentionDays is how long to keep archived notification events (default: 90).
	// Set to 0 for unlimited retention.
	EventRetentionDays int
	// StaleMinutes is how long before a locked entry is considered stale (default: 10).
	StaleMinutes int
}

NotificationSchedulerConfig holds configuration for the notification scheduler.

func DefaultNotificationSchedulerConfig

func DefaultNotificationSchedulerConfig() NotificationSchedulerConfig

DefaultNotificationSchedulerConfig returns the default configuration.

type NotificationService

type NotificationService struct {
	// contains filtered or unexported fields
}

NotificationService handles notification outbox operations.

func NewNotificationService

func NewNotificationService(
	outboxRepo notification.OutboxRepository,
	eventRepo notification.EventRepository,
	notificationRepo integration.NotificationExtensionRepository,
	credentialDecrypt func(string) (string, error),
	log *slog.Logger,
) *NotificationService

NewNotificationService creates a new NotificationService.

func (*NotificationService) CleanupOldEntries

func (s *NotificationService) CleanupOldEntries(ctx context.Context, completedDays, failedDays int) (deletedCompleted, deletedFailed int64, err error)

CleanupOldEntries removes old completed and failed entries.

func (*NotificationService) CleanupOldEvents

func (s *NotificationService) CleanupOldEvents(ctx context.Context, retentionDays int) (deleted int64, err error)

CleanupOldEvents removes notification events older than the specified retention days. If retentionDays <= 0, no deletion is performed (unlimited retention).

func (*NotificationService) EnqueueNotification

func (s *NotificationService) EnqueueNotification(ctx context.Context, params EnqueueNotificationParams) error

EnqueueNotification creates an outbox entry for a notification. This should be called within the same transaction as the business event.

func (*NotificationService) EnqueueNotificationInTx

func (s *NotificationService) EnqueueNotificationInTx(ctx context.Context, tx *sql.Tx, params EnqueueNotificationParams) error

EnqueueNotificationInTx creates an outbox entry within an existing transaction. This is the preferred method for the transactional outbox pattern.

func (*NotificationService) ProcessOutboxBatch

func (s *NotificationService) ProcessOutboxBatch(ctx context.Context, workerID string, batchSize int) (processed, failed int, err error)

ProcessOutboxBatch processes a batch of pending outbox entries.

func (*NotificationService) UnlockStaleEntries

func (s *NotificationService) UnlockStaleEntries(ctx context.Context, olderThanMinutes int) (unlocked int64, err error)

UnlockStaleEntries releases locks on stale processing entries.

type OAuthProvider

type OAuthProvider string

OAuthProvider represents a supported OAuth provider.

const (
	OAuthProviderGoogle    OAuthProvider = "google"
	OAuthProviderGitHub    OAuthProvider = "github"
	OAuthProviderMicrosoft OAuthProvider = "microsoft"
)

func (OAuthProvider) IsValid

func (p OAuthProvider) IsValid() bool

IsValid checks if the provider is valid.

func (OAuthProvider) ToAuthProvider

func (p OAuthProvider) ToAuthProvider() user.AuthProvider

ToAuthProvider converts OAuthProvider to user.AuthProvider.

type OAuthService

type OAuthService struct {
	// contains filtered or unexported fields
}

OAuthService handles OAuth authentication.

func NewOAuthService

func NewOAuthService(
	userRepo user.Repository,
	sessionRepo session.Repository,
	refreshTokenRepo session.RefreshTokenRepository,
	oauthCfg config.OAuthConfig,
	authCfg config.AuthConfig,
	log *logger.Logger,
) *OAuthService

NewOAuthService creates a new OAuthService.

func (*OAuthService) GetAuthorizationURL

func (s *OAuthService) GetAuthorizationURL(ctx context.Context, input AuthorizationURLInput) (*AuthorizationURLResult, error)

GetAuthorizationURL returns the OAuth authorization URL for the specified provider.

func (*OAuthService) GetAvailableProviders

func (s *OAuthService) GetAvailableProviders() []ProviderInfo

GetAvailableProviders returns a list of available OAuth providers.

func (*OAuthService) HandleCallback

func (s *OAuthService) HandleCallback(ctx context.Context, input CallbackInput) (*CallbackResult, error)

HandleCallback handles the OAuth callback.

type OAuthUserInfo

type OAuthUserInfo struct {
	ID        string
	Email     string
	Name      string
	AvatarURL string
}

OAuthUserInfo represents user information from OAuth provider.

type PermissionCacheService

type PermissionCacheService struct {
	// contains filtered or unexported fields
}

PermissionCacheService provides cached access to user permissions. Permissions are cached in Redis with a short TTL for performance. On cache miss, permissions are fetched from the database.

Key format: user_perms:{tenant_id}:{user_id} → JSON array of permission strings Cache is invalidated when user's roles change.

func NewPermissionCacheService

func NewPermissionCacheService(
	redisClient *redis.Client,
	roleRepo role.Repository,
	versionSvc *PermissionVersionService,
	log *logger.Logger,
) (*PermissionCacheService, error)

NewPermissionCacheService creates a new permission cache service.

func (*PermissionCacheService) GetPermissions

func (s *PermissionCacheService) GetPermissions(ctx context.Context, tenantID, userID string) ([]string, error)

GetPermissions returns the permissions for a user. First checks Redis cache, then falls back to database.

func (*PermissionCacheService) GetPermissionsWithFallback

func (s *PermissionCacheService) GetPermissionsWithFallback(ctx context.Context, tenantID, userID string) ([]string, error)

GetPermissionsWithFallback returns permissions, falling back to database on any cache error. Use this when availability is more important than protecting the database.

func (*PermissionCacheService) HasAllPermissions

func (s *PermissionCacheService) HasAllPermissions(ctx context.Context, tenantID, userID string, permissions ...string) (bool, error)

HasAllPermissions checks if a user has all of the specified permissions.

func (*PermissionCacheService) HasAnyPermission

func (s *PermissionCacheService) HasAnyPermission(ctx context.Context, tenantID, userID string, permissions ...string) (bool, error)

HasAnyPermission checks if a user has any of the specified permissions.

func (*PermissionCacheService) HasPermission

func (s *PermissionCacheService) HasPermission(ctx context.Context, tenantID, userID, permission string) (bool, error)

HasPermission checks if a user has a specific permission.

func (*PermissionCacheService) Invalidate

func (s *PermissionCacheService) Invalidate(ctx context.Context, tenantID, userID string)

Invalidate removes the cached permissions for a user. Called when roles are changed.

func (*PermissionCacheService) InvalidateForTenant

func (s *PermissionCacheService) InvalidateForTenant(ctx context.Context, tenantID string)

InvalidateForTenant removes cached permissions for all users in a tenant. Called when a role definition is updated and affects potentially all users.

func (*PermissionCacheService) InvalidateForUsers

func (s *PermissionCacheService) InvalidateForUsers(ctx context.Context, tenantID string, userIDs []string)

InvalidateForUsers removes cached permissions for multiple users. Called when a role definition is updated.

func (*PermissionCacheService) Refresh

func (s *PermissionCacheService) Refresh(ctx context.Context, tenantID, userID string) ([]string, error)

Refresh refreshes the cached permissions for a user. Forces a database fetch and updates the cache.

type PermissionService

type PermissionService struct {
	// contains filtered or unexported fields
}

PermissionService handles permission-related business operations.

func NewPermissionService

func NewPermissionService(
	permissionSetRepo permissionset.Repository,
	log *logger.Logger,
	opts ...PermissionServiceOption,
) *PermissionService

NewPermissionService creates a new PermissionService.

func (*PermissionService) AddPermissionToSet

func (s *PermissionService) AddPermissionToSet(ctx context.Context, input AddPermissionToSetInput, actx AuditContext) error

AddPermissionToSet adds a permission to a permission set.

func (*PermissionService) CreateGroupPermission

func (s *PermissionService) CreateGroupPermission(ctx context.Context, input CreateGroupPermissionInput, createdBy shared.ID, actx AuditContext) (*accesscontrol.GroupPermission, error)

CreateGroupPermission creates a custom permission override for a group.

func (*PermissionService) CreatePermissionSet

CreatePermissionSet creates a new permission set.

func (*PermissionService) DeleteGroupPermission

func (s *PermissionService) DeleteGroupPermission(ctx context.Context, groupID, permissionID string, actx AuditContext) error

DeleteGroupPermission removes a custom permission override from a group.

func (*PermissionService) DeletePermissionSet

func (s *PermissionService) DeletePermissionSet(ctx context.Context, permissionSetID string, actx AuditContext) error

DeletePermissionSet deletes a permission set.

func (*PermissionService) GetPermissionSet

func (s *PermissionService) GetPermissionSet(ctx context.Context, permissionSetID string) (*permissionset.PermissionSet, error)

GetPermissionSet retrieves a permission set by ID.

func (*PermissionService) GetPermissionSetWithItems

func (s *PermissionService) GetPermissionSetWithItems(ctx context.Context, permissionSetID string) (*permissionset.PermissionSetWithItems, error)

GetPermissionSetWithItems retrieves a permission set with its items.

func (*PermissionService) HasAllPermissions

func (s *PermissionService) HasAllPermissions(ctx context.Context, tenantID string, userID shared.ID, perms ...permission.Permission) (bool, error)

HasAllPermissions checks if a user has all of the specified permissions.

func (*PermissionService) HasAnyPermission

func (s *PermissionService) HasAnyPermission(ctx context.Context, tenantID string, userID shared.ID, perms ...permission.Permission) (bool, error)

HasAnyPermission checks if a user has any of the specified permissions.

func (*PermissionService) HasPermission

func (s *PermissionService) HasPermission(ctx context.Context, tenantID string, userID shared.ID, perm permission.Permission) (bool, error)

HasPermission checks if a user has a specific permission.

func (*PermissionService) ListGroupCustomPermissions

func (s *PermissionService) ListGroupCustomPermissions(ctx context.Context, groupID string) ([]*accesscontrol.GroupPermission, error)

ListGroupCustomPermissions lists custom permissions for a group.

func (*PermissionService) ListPermissionSets

ListPermissionSets lists permission sets with filtering.

func (*PermissionService) RemovePermissionFromSet

func (s *PermissionService) RemovePermissionFromSet(ctx context.Context, permissionSetID, permissionID string, actx AuditContext) error

RemovePermissionFromSet removes a permission from a permission set.

func (*PermissionService) ResolveGroupPermissions

func (s *PermissionService) ResolveGroupPermissions(ctx context.Context, groupID string) ([]permission.Permission, error)

ResolveGroupPermissions resolves all effective permissions for a group.

func (*PermissionService) ResolveUserPermissions

func (s *PermissionService) ResolveUserPermissions(ctx context.Context, tenantID string, userID shared.ID) ([]permission.Permission, error)

ResolveUserPermissions resolves all effective permissions for a user.

func (*PermissionService) ResolveUserPermissionsWithCount

func (s *PermissionService) ResolveUserPermissionsWithCount(ctx context.Context, tenantID string, userID shared.ID) ([]permission.Permission, int, error)

ResolveUserPermissionsWithCount resolves all effective permissions for a user and returns the group count.

func (*PermissionService) UpdatePermissionSet

func (s *PermissionService) UpdatePermissionSet(ctx context.Context, permissionSetID string, input UpdatePermissionSetInput, actx AuditContext) (*permissionset.PermissionSet, error)

UpdatePermissionSet updates a permission set.

type PermissionServiceOption

type PermissionServiceOption func(*PermissionService)

PermissionServiceOption is a functional option for PermissionService.

func WithPermissionAccessControlRepository

func WithPermissionAccessControlRepository(repo accesscontrol.Repository) PermissionServiceOption

WithPermissionAccessControlRepository sets the access control repository.

func WithPermissionAuditService

func WithPermissionAuditService(auditService *AuditService) PermissionServiceOption

WithPermissionAuditService sets the audit service for PermissionService.

func WithPermissionGroupRepository

func WithPermissionGroupRepository(repo group.Repository) PermissionServiceOption

WithPermissionGroupRepository sets the group repository.

type PermissionVersionService

type PermissionVersionService struct {
	// contains filtered or unexported fields
}

PermissionVersionService manages permission version tracking in Redis. Version is incremented whenever a user's permissions change (role assigned/removed). This enables real-time permission synchronization without embedding permissions in JWT.

Key format: perm_ver:{tenant_id}:{user_id} → integer version When admin changes user's roles, the version is incremented. JWT contains the version at token generation time. If JWT version != Redis version, permissions are stale.

func NewPermissionVersionService

func NewPermissionVersionService(redisClient *redis.Client, log *logger.Logger) *PermissionVersionService

NewPermissionVersionService creates a new permission version service.

func (*PermissionVersionService) Delete

func (s *PermissionVersionService) Delete(ctx context.Context, tenantID, userID string) error

Delete removes the permission version for a user. Called when user is removed from tenant.

func (*PermissionVersionService) EnsureVersion

func (s *PermissionVersionService) EnsureVersion(ctx context.Context, tenantID, userID string) int

EnsureVersion ensures a version exists for the user, initializing to 1 if not. Returns the current version (either existing or newly initialized).

func (*PermissionVersionService) Get

func (s *PermissionVersionService) Get(ctx context.Context, tenantID, userID string) int

Get returns the current permission version for a user. Returns 1 if no version is set (new user).

func (*PermissionVersionService) Increment

func (s *PermissionVersionService) Increment(ctx context.Context, tenantID, userID string) int

Increment atomically increments the permission version for a user. Called when roles are assigned, removed, or modified. Returns the new version number.

func (*PermissionVersionService) IncrementForUsers

func (s *PermissionVersionService) IncrementForUsers(ctx context.Context, tenantID string, userIDs []string)

IncrementForUsers increments permission version for multiple users. Used when a role definition is updated (affects all users with that role).

func (*PermissionVersionService) Set

func (s *PermissionVersionService) Set(ctx context.Context, tenantID, userID string, version int) error

Set sets the permission version for a user to a specific value. Used during token generation to include current version in JWT.

type PipelineDeactivator

type PipelineDeactivator interface {
	// DeactivatePipelinesByTool deactivates all active pipelines using the specified tool.
	// Returns the count of deactivated pipelines and their IDs.
	DeactivatePipelinesByTool(ctx context.Context, toolName string) (int, []shared.ID, error)

	// GetPipelinesUsingTool returns all active pipeline IDs that use a specific tool.
	GetPipelinesUsingTool(ctx context.Context, toolName string) ([]shared.ID, error)
}

PipelineDeactivator interface for cascade deactivation when tools are disabled/deleted. This decouples ToolService from PipelineService while allowing the cascade behavior.

type PipelineTriggerHandler

type PipelineTriggerHandler struct {
	// contains filtered or unexported fields
}

PipelineTriggerHandler handles pipeline and scan triggering actions.

func NewPipelineTriggerHandler

func NewPipelineTriggerHandler(pipelineSvc *pipeline.Service, scanSvc *scansvc.Service, log *logger.Logger) *PipelineTriggerHandler

NewPipelineTriggerHandler creates a new PipelineTriggerHandler.

func (*PipelineTriggerHandler) Execute

func (h *PipelineTriggerHandler) Execute(ctx context.Context, input *ActionInput) (map[string]any, error)

Execute executes a pipeline/scan trigger action.

type PollCommandsInput

type PollCommandsInput struct {
	TenantID string `json:"tenant_id" validate:"required,uuid"`
	AgentID  string `json:"agent_id,omitempty" validate:"omitempty,uuid"`
	Limit    int    `json:"limit" validate:"min=1,max=100"`
}

PollCommandsInput represents the input for polling commands.

type PromptSanitizer

type PromptSanitizer struct {
	// contains filtered or unexported fields
}

PromptSanitizer sanitizes user-provided data before including in prompts.

func NewPromptSanitizer

func NewPromptSanitizer() *PromptSanitizer

NewPromptSanitizer creates a new prompt sanitizer.

func (*PromptSanitizer) SanitizeCodeSnippet

func (s *PromptSanitizer) SanitizeCodeSnippet(code string) string

SanitizeCodeSnippet sanitizes a code snippet for inclusion in prompts.

func (*PromptSanitizer) SanitizeForPrompt

func (s *PromptSanitizer) SanitizeForPrompt(text string) string

SanitizeForPrompt sanitizes a string for inclusion in an LLM prompt. Applies unicode normalization to prevent bypass via homoglyphs and special characters.

type ProviderInfo

type ProviderInfo struct {
	ID      string `json:"id"`
	Name    string `json:"name"`
	Enabled bool   `json:"enabled"`
}

ProviderInfo represents information about an OAuth provider.

type RecordActivityInput

type RecordActivityInput struct {
	TenantID       string                 `validate:"required,uuid"`
	FindingID      string                 `validate:"required,uuid"`
	ActivityType   string                 `validate:"required"`
	ActorID        *string                `validate:"omitempty,uuid"`
	ActorType      string                 `validate:"required"`
	Changes        map[string]interface{} `validate:"required"`
	Source         string
	SourceMetadata map[string]interface{}
}

RecordActivityInput represents the input for recording an activity.

type RecordToolExecutionInput

type RecordToolExecutionInput struct {
	TenantID      string         `json:"tenant_id" validate:"required,uuid"`
	ToolID        string         `json:"tool_id" validate:"required,uuid"`
	AgentID       string         `json:"agent_id" validate:"omitempty,uuid"`
	PipelineRunID string         `json:"pipeline_run_id" validate:"omitempty,uuid"`
	StepRunID     string         `json:"step_run_id" validate:"omitempty,uuid"`
	InputConfig   map[string]any `json:"input_config"`
	TargetsCount  int            `json:"targets_count"`
}

RecordToolExecutionInput represents the input for recording a tool execution.

type RecoverStuckJobsInput

type RecoverStuckJobsInput struct {
	// StuckDuration is how long a job must be stuck before being recovered.
	// Default: 15 minutes
	StuckDuration time.Duration
	// Limit is the maximum number of stuck jobs to recover in one batch.
	// Default: 50
	Limit int
}

RecoverStuckJobsInput contains parameters for stuck job recovery.

type RecoverStuckJobsOutput

type RecoverStuckJobsOutput struct {
	// Total is the number of stuck jobs found.
	Total int `json:"total"`
	// Recovered is the number of jobs successfully marked as failed.
	Recovered int `json:"recovered"`
	// Skipped is the number of jobs that were already in a terminal state.
	Skipped int `json:"skipped"`
	// Errors is the number of jobs that failed to update.
	Errors int `json:"errors"`
}

RecoverStuckJobsOutput contains the results of stuck job recovery.

type RefreshTokenInput

type RefreshTokenInput struct {
	RefreshToken string `json:"refresh_token" validate:"required"`
	TenantID     string `json:"tenant_id" validate:"required"`
	IPAddress    string `json:"-"`
	UserAgent    string `json:"-"`
}

RefreshTokenInput represents the input for token refresh. Requires tenant_id to generate tenant-scoped access token.

type RefreshTokenResult

type RefreshTokenResult struct {
	AccessToken      string    // Tenant-scoped access token
	RefreshToken     string    // New global refresh token (rotated)
	TenantID         string    // Tenant ID the access token is scoped to
	TenantSlug       string    // Tenant slug
	Role             string    // User's role in this tenant
	ExpiresAt        time.Time // Access token expiration
	RefreshExpiresAt time.Time // Refresh token expiration (for cookie)
}

RefreshTokenResult represents the result of token refresh. Returns a new global refresh token and tenant-scoped access token.

type RegisterInput

type RegisterInput struct {
	Email    string `json:"email" validate:"required,email,max=255"`
	Password string `json:"password" validate:"required,min=8,max=128"`
	Name     string `json:"name" validate:"required,max=255"`
}

RegisterInput represents the input for user registration.

type RegisterResult

type RegisterResult struct {
	User                 *user.User
	VerificationToken    string // Only returned if email verification is required
	RequiresVerification bool
	EmailExisted         bool // Set to true if email already exists (for anti-enumeration)
}

RegisterResult represents the result of registration.

type RegisterScanInput

type RegisterScanInput struct {
	ScannerName    string `json:"scanner_name" validate:"required"`
	ScannerVersion string `json:"scanner_version"`
	ScannerType    string `json:"scanner_type"`
	AssetType      string `json:"asset_type" validate:"required"`
	AssetValue     string `json:"asset_value" validate:"required"`
	CommitSha      string `json:"commit_sha"`
	Branch         string `json:"branch"`
}

RegisterScanInput represents the input to register a new scan.

type RegisterScanOutput

type RegisterScanOutput struct {
	ScanID        string `json:"scan_id"`
	BaseCommitSha string `json:"base_commit_sha"` // For incremental scanning
	ScanURL       string `json:"scan_url"`
}

RegisterScanOutput represents the output from registering a scan.

type RepositoryStatsData

type RepositoryStatsData struct {
	Total        int
	WithFindings int
}

RepositoryStatsData holds raw repository statistics from repository.

type ResetPasswordInput

type ResetPasswordInput struct {
	Token       string `json:"token" validate:"required"`
	NewPassword string `json:"new_password" validate:"required,min=8,max=128"`
}

ResetPasswordInput represents the input for password reset.

type RevokeAPIKeyInput

type RevokeAPIKeyInput struct {
	ID        string `json:"id" validate:"required,uuid"`
	TenantID  string `json:"tenant_id" validate:"required,uuid"`
	RevokedBy string `json:"revoked_by" validate:"required,uuid"`
}

RevokeAPIKeyInput represents input for revoking an API key.

type RoleService

type RoleService struct {
	// contains filtered or unexported fields
}

RoleService handles role-related business operations.

func NewRoleService

func NewRoleService(
	roleRepo role.Repository,
	permissionRepo role.PermissionRepository,
	log *logger.Logger,
	opts ...RoleServiceOption,
) *RoleService

NewRoleService creates a new RoleService.

func (*RoleService) AssignRole

func (s *RoleService) AssignRole(ctx context.Context, input AssignRoleInput, assignedBy string, actx AuditContext) error

AssignRole assigns a role to a user.

func (*RoleService) BulkAssignRoleToUsers

func (s *RoleService) BulkAssignRoleToUsers(ctx context.Context, input BulkAssignRoleToUsersInput, assignedBy string, actx AuditContext) (*BulkAssignRoleToUsersResult, error)

BulkAssignRoleToUsers assigns a role to multiple users at once.

func (*RoleService) CountUsersWithRole

func (s *RoleService) CountUsersWithRole(ctx context.Context, roleID string) (int, error)

CountUsersWithRole returns the count of users with a specific role.

func (*RoleService) CreateRole

func (s *RoleService) CreateRole(ctx context.Context, input CreateRoleInput, createdBy string, actx AuditContext) (*role.Role, error)

CreateRole creates a new custom role for a tenant.

func (*RoleService) DeleteRole

func (s *RoleService) DeleteRole(ctx context.Context, roleID string, actx AuditContext) error

DeleteRole deletes a role.

func (*RoleService) GetRole

func (s *RoleService) GetRole(ctx context.Context, roleID string) (*role.Role, error)

GetRole retrieves a role by ID.

func (*RoleService) GetRoleBySlug

func (s *RoleService) GetRoleBySlug(ctx context.Context, tenantID *string, slug string) (*role.Role, error)

GetRoleBySlug retrieves a role by slug.

func (*RoleService) GetUserPermissions

func (s *RoleService) GetUserPermissions(ctx context.Context, tenantID, userID string) ([]string, error)

GetUserPermissions returns all permissions for a user (UNION of all roles).

func (*RoleService) GetUserRoles

func (s *RoleService) GetUserRoles(ctx context.Context, tenantID, userID string) ([]*role.Role, error)

GetUserRoles returns all roles for a user in a tenant.

func (*RoleService) HasFullDataAccess

func (s *RoleService) HasFullDataAccess(ctx context.Context, tenantID, userID string) (bool, error)

HasFullDataAccess checks if user has full data access.

func (*RoleService) HasPermission

func (s *RoleService) HasPermission(ctx context.Context, tenantID, userID, permission string) (bool, error)

HasPermission checks if a user has a specific permission.

func (*RoleService) ListModulesWithPermissions

func (s *RoleService) ListModulesWithPermissions(ctx context.Context) ([]*role.Module, error)

ListModulesWithPermissions returns all modules with their permissions.

func (*RoleService) ListPermissions

func (s *RoleService) ListPermissions(ctx context.Context) ([]*role.Permission, error)

ListPermissions returns all permissions.

func (*RoleService) ListRoleMembers

func (s *RoleService) ListRoleMembers(ctx context.Context, tenantID, roleID string) ([]*role.UserRole, error)

ListRoleMembers returns all users who have a specific role.

func (*RoleService) ListRolesForTenant

func (s *RoleService) ListRolesForTenant(ctx context.Context, tenantID string) ([]*role.Role, error)

ListRolesForTenant returns all roles available for a tenant.

func (*RoleService) ListSystemRoles

func (s *RoleService) ListSystemRoles(ctx context.Context) ([]*role.Role, error)

ListSystemRoles returns only system roles.

func (*RoleService) RemoveRole

func (s *RoleService) RemoveRole(ctx context.Context, tenantID, userID, roleID string, actx AuditContext) error

RemoveRole removes a role from a user.

func (*RoleService) SetUserRoles

func (s *RoleService) SetUserRoles(ctx context.Context, input SetUserRolesInput, assignedBy string, actx AuditContext) error

SetUserRoles replaces all roles for a user.

func (*RoleService) UpdateRole

func (s *RoleService) UpdateRole(ctx context.Context, roleID string, input UpdateRoleInput, actx AuditContext) (*role.Role, error)

UpdateRole updates a role.

type RoleServiceOption

type RoleServiceOption func(*RoleService)

RoleServiceOption is a functional option for RoleService.

func WithRoleAuditService

func WithRoleAuditService(auditService *AuditService) RoleServiceOption

WithRoleAuditService sets the audit service for RoleService.

func WithRolePermissionCacheService

func WithRolePermissionCacheService(svc *PermissionCacheService) RoleServiceOption

WithRolePermissionCacheService sets the permission cache service. This enables permission cache invalidation when roles change.

func WithRolePermissionVersionService

func WithRolePermissionVersionService(svc *PermissionVersionService) RoleServiceOption

WithRolePermissionVersionService sets the permission version service. This enables real-time permission synchronization when roles change.

type RuleService

type RuleService struct {
	// contains filtered or unexported fields
}

RuleService handles rule management business operations.

func NewRuleService

func NewRuleService(
	sourceRepo rule.SourceRepository,
	ruleRepo rule.RuleRepository,
	bundleRepo rule.BundleRepository,
	overrideRepo rule.OverrideRepository,
	syncHistoryRepo rule.SyncHistoryRepository,
	auditService *AuditService,
	log *logger.Logger,
) *RuleService

NewRuleService creates a new RuleService.

func (*RuleService) CleanupExpiredBundles

func (s *RuleService) CleanupExpiredBundles(ctx context.Context) (int64, error)

CleanupExpiredBundles deletes all expired bundles.

func (*RuleService) CompleteBundle

func (s *RuleService) CompleteBundle(ctx context.Context, input CompleteBundleInput) (*rule.Bundle, error)

CompleteBundle marks a bundle build as completed successfully.

func (*RuleService) CountRulesBySource

func (s *RuleService) CountRulesBySource(ctx context.Context, sourceID string) (int, error)

CountRulesBySource counts rules for a source.

func (*RuleService) CreateBundle

func (s *RuleService) CreateBundle(ctx context.Context, input CreateBundleInput) (*rule.Bundle, error)

CreateBundle creates a new rule bundle (starts building).

func (*RuleService) CreateOverride

func (s *RuleService) CreateOverride(ctx context.Context, input CreateOverrideInput) (*rule.Override, error)

CreateOverride creates a new rule override.

func (*RuleService) CreateSource

func (s *RuleService) CreateSource(ctx context.Context, input CreateSourceInput) (*rule.Source, error)

CreateSource creates a new rule source.

func (*RuleService) DeleteBundle

func (s *RuleService) DeleteBundle(ctx context.Context, bundleID string) error

DeleteBundle deletes a bundle.

func (*RuleService) DeleteOverride

func (s *RuleService) DeleteOverride(ctx context.Context, tenantID, overrideID string) error

DeleteOverride deletes a rule override.

func (*RuleService) DeleteSource

func (s *RuleService) DeleteSource(ctx context.Context, tenantID, sourceID string) error

DeleteSource deletes a rule source and its associated rules.

func (*RuleService) DisableSource

func (s *RuleService) DisableSource(ctx context.Context, tenantID, sourceID string) (*rule.Source, error)

DisableSource disables a rule source.

func (*RuleService) EnableSource

func (s *RuleService) EnableSource(ctx context.Context, tenantID, sourceID string) (*rule.Source, error)

EnableSource enables a rule source.

func (*RuleService) FailBundle

func (s *RuleService) FailBundle(ctx context.Context, bundleID, errorMessage string) (*rule.Bundle, error)

FailBundle marks a bundle build as failed.

func (*RuleService) GetBundleByID

func (s *RuleService) GetBundleByID(ctx context.Context, bundleID string) (*rule.Bundle, error)

GetBundleByID retrieves a bundle by ID.

func (*RuleService) GetLatestBundle

func (s *RuleService) GetLatestBundle(ctx context.Context, tenantID, toolID string) (*rule.Bundle, error)

GetLatestBundle retrieves the latest ready bundle for a tenant and tool.

func (*RuleService) GetOverride

func (s *RuleService) GetOverride(ctx context.Context, overrideID string) (*rule.Override, error)

GetOverride retrieves an override by ID.

func (*RuleService) GetOverrideByTenantAndID

func (s *RuleService) GetOverrideByTenantAndID(ctx context.Context, tenantID, overrideID string) (*rule.Override, error)

GetOverrideByTenantAndID retrieves an override by tenant and ID.

func (*RuleService) GetRule

func (s *RuleService) GetRule(ctx context.Context, ruleID string) (*rule.Rule, error)

GetRule retrieves a rule by ID.

func (*RuleService) GetSource

func (s *RuleService) GetSource(ctx context.Context, sourceID string) (*rule.Source, error)

GetSource retrieves a rule source by ID.

func (*RuleService) GetSourceByTenantAndID

func (s *RuleService) GetSourceByTenantAndID(ctx context.Context, tenantID, sourceID string) (*rule.Source, error)

GetSourceByTenantAndID retrieves a rule source by tenant and ID.

func (*RuleService) GetSyncHistory

func (s *RuleService) GetSyncHistory(ctx context.Context, sourceID string, limit int) ([]*rule.SyncHistory, error)

GetSyncHistory lists sync history for a source.

func (*RuleService) ListActiveOverridesForTool

func (s *RuleService) ListActiveOverridesForTool(ctx context.Context, tenantID string, toolID *string) ([]*rule.Override, error)

ListActiveOverridesForTool lists all active (non-expired) overrides for a tenant and tool.

func (*RuleService) ListBundles

func (s *RuleService) ListBundles(ctx context.Context, input ListBundlesInput) ([]*rule.Bundle, error)

ListBundles lists bundles with filters.

func (*RuleService) ListOverrides

func (s *RuleService) ListOverrides(ctx context.Context, input ListOverridesInput) (pagination.Result[*rule.Override], error)

ListOverrides lists rule overrides with filters.

func (*RuleService) ListRules

func (s *RuleService) ListRules(ctx context.Context, input ListRulesInput) (pagination.Result[*rule.Rule], error)

ListRules lists rules with filters.

func (*RuleService) ListRulesBySource

func (s *RuleService) ListRulesBySource(ctx context.Context, sourceID string) ([]*rule.Rule, error)

ListRulesBySource lists all rules for a source.

func (*RuleService) ListSources

func (s *RuleService) ListSources(ctx context.Context, input ListSourcesInput) (pagination.Result[*rule.Source], error)

ListSources lists rule sources with filters.

func (*RuleService) ListSourcesNeedingSync

func (s *RuleService) ListSourcesNeedingSync(ctx context.Context, limit int) ([]*rule.Source, error)

ListSourcesNeedingSync lists sources that need synchronization.

func (*RuleService) RecordSyncResult

func (s *RuleService) RecordSyncResult(ctx context.Context, sourceID string, result *SyncResult) error

RecordSyncResult records the result of a source sync operation.

func (*RuleService) UpdateOverride

func (s *RuleService) UpdateOverride(ctx context.Context, input UpdateOverrideInput) (*rule.Override, error)

UpdateOverride updates a rule override.

func (*RuleService) UpdateSource

func (s *RuleService) UpdateSource(ctx context.Context, input UpdateSourceInput) (*rule.Source, error)

UpdateSource updates a rule source.

func (*RuleService) UpsertRulesFromSync

func (s *RuleService) UpsertRulesFromSync(ctx context.Context, rules []*rule.Rule) error

UpsertRulesFromSync upserts rules from a sync operation.

type SLAComplianceResult

type SLAComplianceResult struct {
	IsCompliant      bool
	Status           string // on_track, warning, overdue, exceeded
	DeadlineAt       time.Time
	DaysRemaining    int
	PercentElapsed   float64
	EscalationNeeded bool
}

CheckSLACompliance checks if a finding is within SLA compliance.

type SLAService

type SLAService struct {
	// contains filtered or unexported fields
}

SLAService handles SLA policy-related business operations.

func NewSLAService

func NewSLAService(repo sla.Repository, log *logger.Logger) *SLAService

NewSLAService creates a new SLAService.

func (*SLAService) CalculateSLADeadline

func (s *SLAService) CalculateSLADeadline(ctx context.Context, tenantID, assetID string, severity vulnerability.Severity, detectedAt time.Time) (time.Time, error)

CalculateSLADeadline calculates the SLA deadline for a finding based on its severity.

func (*SLAService) CheckSLACompliance

func (s *SLAService) CheckSLACompliance(
	ctx context.Context,
	tenantID, assetID string,
	severity vulnerability.Severity,
	detectedAt time.Time,
	resolvedAt *time.Time,
) (*SLAComplianceResult, error)

CheckSLACompliance checks the SLA status of a finding.

func (*SLAService) CreateDefaultTenantPolicy

func (s *SLAService) CreateDefaultTenantPolicy(ctx context.Context, tenantID string) (*sla.Policy, error)

CreateDefaultTenantPolicy creates a default SLA policy for a new tenant.

func (*SLAService) CreateSLAPolicy

func (s *SLAService) CreateSLAPolicy(ctx context.Context, input CreateSLAPolicyInput) (*sla.Policy, error)

CreateSLAPolicy creates a new SLA policy.

func (*SLAService) DeleteSLAPolicy

func (s *SLAService) DeleteSLAPolicy(ctx context.Context, policyID, tenantID string) error

DeleteSLAPolicy deletes an SLA policy by ID.

func (*SLAService) GetAssetSLAPolicy

func (s *SLAService) GetAssetSLAPolicy(ctx context.Context, tenantID, assetID string) (*sla.Policy, error)

GetAssetSLAPolicy retrieves the effective SLA policy for an asset. Returns asset-specific policy if exists, otherwise tenant default.

func (*SLAService) GetSLAPolicy

func (s *SLAService) GetSLAPolicy(ctx context.Context, policyID string) (*sla.Policy, error)

GetSLAPolicy retrieves an SLA policy by ID.

func (*SLAService) GetTenantDefaultPolicy

func (s *SLAService) GetTenantDefaultPolicy(ctx context.Context, tenantID string) (*sla.Policy, error)

GetTenantDefaultPolicy retrieves the default SLA policy for a tenant.

func (*SLAService) ListTenantPolicies

func (s *SLAService) ListTenantPolicies(ctx context.Context, tenantID string) ([]*sla.Policy, error)

ListTenantPolicies retrieves all SLA policies for a tenant.

func (*SLAService) UpdateSLAPolicy

func (s *SLAService) UpdateSLAPolicy(ctx context.Context, policyID, tenantID string, input UpdateSLAPolicyInput) (*sla.Policy, error)

UpdateSLAPolicy updates an existing SLA policy.

type ScanProfileService

type ScanProfileService struct {
	// contains filtered or unexported fields
}

ScanProfileService handles scan profile business operations.

func NewScanProfileService

func NewScanProfileService(repo scanprofile.Repository, log *logger.Logger) *ScanProfileService

NewScanProfileService creates a new ScanProfileService.

func (*ScanProfileService) CloneScanProfile

CloneScanProfile creates a copy of an existing scan profile.

func (*ScanProfileService) CreateScanProfile

CreateScanProfile creates a new scan profile.

func (*ScanProfileService) DeleteScanProfile

func (s *ScanProfileService) DeleteScanProfile(ctx context.Context, tenantID, profileID string) error

DeleteScanProfile deletes a scan profile.

func (*ScanProfileService) EvaluateQualityGate

EvaluateQualityGate evaluates finding counts against a scan profile's quality gate. Returns the quality gate result indicating pass/fail and any breaches.

func (*ScanProfileService) EvaluateQualityGateByProfile

func (s *ScanProfileService) EvaluateQualityGateByProfile(profile *scanprofile.ScanProfile, counts scanprofile.FindingCounts) *scanprofile.QualityGateResult

EvaluateQualityGateByProfile evaluates finding counts against a given quality gate. This can be used when the profile is already loaded.

func (*ScanProfileService) GetDefaultScanProfile

func (s *ScanProfileService) GetDefaultScanProfile(ctx context.Context, tenantID string) (*scanprofile.ScanProfile, error)

GetDefaultScanProfile retrieves the default scan profile for a tenant.

func (*ScanProfileService) GetScanProfile

func (s *ScanProfileService) GetScanProfile(ctx context.Context, tenantID, profileID string) (*scanprofile.ScanProfile, error)

GetScanProfile retrieves a scan profile by ID.

func (*ScanProfileService) GetScanProfileForUse

func (s *ScanProfileService) GetScanProfileForUse(ctx context.Context, tenantID, profileID string) (*scanprofile.ScanProfile, error)

GetScanProfileForUse retrieves a scan profile by ID for use in scans. This method allows tenants to use both their own profiles and system profiles.

func (*ScanProfileService) ListScanProfiles

ListScanProfiles lists scan profiles with filters. If IncludeSystem is true, system profiles will be included alongside tenant profiles.

func (*ScanProfileService) SetDefaultScanProfile

func (s *ScanProfileService) SetDefaultScanProfile(ctx context.Context, tenantID, profileID string) (*scanprofile.ScanProfile, error)

SetDefaultScanProfile sets a scan profile as the default for a tenant.

func (*ScanProfileService) UpdateQualityGate

UpdateQualityGate updates the quality gate configuration for a scan profile.

func (*ScanProfileService) UpdateScanProfile

UpdateScanProfile updates an existing scan profile.

type ScanScheduler

type ScanScheduler struct {
	// contains filtered or unexported fields
}

ScanScheduler periodically checks for due scans and triggers them.

func NewScanScheduler

func NewScanScheduler(
	scanRepo scan.Repository,
	scanService *scansvc.Service,
	cfg ScanSchedulerConfig,
	log *logger.Logger,
) *ScanScheduler

NewScanScheduler creates a new ScanScheduler.

func (*ScanScheduler) Start

func (s *ScanScheduler) Start()

Start starts the scan scheduler.

func (*ScanScheduler) Stop

func (s *ScanScheduler) Stop()

Stop stops the scan scheduler gracefully.

type ScanSchedulerConfig

type ScanSchedulerConfig struct {
	// CheckInterval is how often to check for due scans (default: 1 minute)
	CheckInterval time.Duration
	// BatchSize is the max number of scans to process per cycle (default: 50)
	BatchSize int
}

ScanSchedulerConfig holds configuration for the scan scheduler.

type ScanSessionService

type ScanSessionService struct {
	// contains filtered or unexported fields
}

ScanSessionService handles scan session lifecycle management.

func NewScanSessionService

func NewScanSessionService(
	sessionRepo scansession.Repository,
	agentRepo agent.Repository,
	log *logger.Logger,
) *ScanSessionService

NewScanSessionService creates a new ScanSessionService.

func (*ScanSessionService) DeleteScan

func (s *ScanSessionService) DeleteScan(ctx context.Context, tenantID shared.ID, scanID string) error

DeleteScan deletes a scan session.

func (*ScanSessionService) GetScan

func (s *ScanSessionService) GetScan(ctx context.Context, tenantID shared.ID, scanID string) (*scansession.ScanSession, error)

GetScan retrieves a scan session by ID.

func (*ScanSessionService) GetStats

func (s *ScanSessionService) GetStats(ctx context.Context, tenantID shared.ID, since time.Time) (*scansession.Stats, error)

GetStats retrieves scan session statistics.

func (*ScanSessionService) ListRunning

func (s *ScanSessionService) ListRunning(ctx context.Context, tenantID shared.ID) ([]*scansession.ScanSession, error)

ListRunning lists all currently running scans for a tenant.

func (*ScanSessionService) ListScanSessions

ListScanSessions lists scan sessions for a tenant.

func (*ScanSessionService) RegisterScan

RegisterScan registers a new scan session and returns baseline info.

func (*ScanSessionService) UpdateScanSession

func (s *ScanSessionService) UpdateScanSession(ctx context.Context, agt *agent.Agent, scanID string, input UpdateScanSessionInput) error

UpdateScanSession updates a scan session status.

type ScannerTemplateService

type ScannerTemplateService struct {
	// contains filtered or unexported fields
}

ScannerTemplateService handles scanner template business operations.

func NewScannerTemplateService

func NewScannerTemplateService(repo scannertemplate.Repository, signingSecret string, log *logger.Logger) *ScannerTemplateService

NewScannerTemplateService creates a new ScannerTemplateService.

func (*ScannerTemplateService) CreateTemplate

CreateTemplate creates a new scanner template.

func (*ScannerTemplateService) DeleteTemplate

func (s *ScannerTemplateService) DeleteTemplate(ctx context.Context, tenantID, templateID string) error

DeleteTemplate deletes a scanner template.

func (*ScannerTemplateService) DeprecateTemplate

func (s *ScannerTemplateService) DeprecateTemplate(ctx context.Context, tenantID, templateID string) (*scannertemplate.ScannerTemplate, error)

DeprecateTemplate marks a template as deprecated.

func (*ScannerTemplateService) DownloadTemplate

func (s *ScannerTemplateService) DownloadTemplate(ctx context.Context, tenantID, templateID string) ([]byte, string, error)

DownloadTemplate returns the template content for download.

func (*ScannerTemplateService) GetQuota

GetQuota returns the current quota configuration.

func (*ScannerTemplateService) GetTemplate

func (s *ScannerTemplateService) GetTemplate(ctx context.Context, tenantID, templateID string) (*scannertemplate.ScannerTemplate, error)

GetTemplate retrieves a scanner template by ID.

func (*ScannerTemplateService) GetTemplatesByIDs

func (s *ScannerTemplateService) GetTemplatesByIDs(ctx context.Context, tenantID string, templateIDs []string) ([]*scannertemplate.ScannerTemplate, error)

GetTemplatesByIDs retrieves multiple templates by their IDs.

func (*ScannerTemplateService) GetUsage

func (s *ScannerTemplateService) GetUsage(ctx context.Context, tenantID string) (*TemplateUsageResult, error)

GetUsage returns the current template usage for a tenant.

func (*ScannerTemplateService) ListTemplates

ListTemplates lists scanner templates with filters.

func (*ScannerTemplateService) SetQuota

SetQuota sets custom quota limits for the service.

func (*ScannerTemplateService) UpdateTemplate

UpdateTemplate updates an existing scanner template.

func (*ScannerTemplateService) ValidateTemplate

ValidateTemplate validates template content without saving.

func (*ScannerTemplateService) VerifyTemplateSignature

func (s *ScannerTemplateService) VerifyTemplateSignature(template *scannertemplate.ScannerTemplate) bool

VerifyTemplateSignature verifies the signature of a template.

type ScopeService

type ScopeService struct {
	// contains filtered or unexported fields
}

ScopeService handles scope configuration business operations.

func NewScopeService

func NewScopeService(
	targetRepo scope.TargetRepository,
	exclusionRepo scope.ExclusionRepository,
	scheduleRepo scope.ScheduleRepository,
	assetRepo asset.Repository,
	log *logger.Logger,
) *ScopeService

NewScopeService creates a new ScopeService.

func (*ScopeService) ActivateExclusion

func (s *ScopeService) ActivateExclusion(ctx context.Context, exclusionID string) (*scope.Exclusion, error)

ActivateExclusion activates a scope exclusion.

func (*ScopeService) ActivateTarget

func (s *ScopeService) ActivateTarget(ctx context.Context, targetID string) (*scope.Target, error)

ActivateTarget activates a scope target.

func (*ScopeService) ApproveExclusion

func (s *ScopeService) ApproveExclusion(ctx context.Context, exclusionID string, approvedBy string) (*scope.Exclusion, error)

ApproveExclusion approves a scope exclusion.

func (*ScopeService) CheckScope

func (s *ScopeService) CheckScope(ctx context.Context, tenantID string, assetType string, value string) (*scope.MatchResult, error)

CheckScope checks if an asset value is in scope.

func (*ScopeService) CreateExclusion

func (s *ScopeService) CreateExclusion(ctx context.Context, input CreateExclusionInput) (*scope.Exclusion, error)

CreateExclusion creates a new scope exclusion.

func (*ScopeService) CreateSchedule

func (s *ScopeService) CreateSchedule(ctx context.Context, input CreateScheduleInput) (*scope.Schedule, error)

CreateSchedule creates a new scan schedule.

func (*ScopeService) CreateTarget

func (s *ScopeService) CreateTarget(ctx context.Context, input CreateTargetInput) (*scope.Target, error)

CreateTarget creates a new scope target.

func (*ScopeService) DeactivateExclusion

func (s *ScopeService) DeactivateExclusion(ctx context.Context, exclusionID string) (*scope.Exclusion, error)

DeactivateExclusion deactivates a scope exclusion.

func (*ScopeService) DeactivateTarget

func (s *ScopeService) DeactivateTarget(ctx context.Context, targetID string) (*scope.Target, error)

DeactivateTarget deactivates a scope target.

func (*ScopeService) DeleteExclusion

func (s *ScopeService) DeleteExclusion(ctx context.Context, exclusionID string, tenantID string) error

DeleteExclusion deletes a scope exclusion by ID.

func (*ScopeService) DeleteSchedule

func (s *ScopeService) DeleteSchedule(ctx context.Context, scheduleID string, tenantID string) error

DeleteSchedule deletes a scan schedule by ID.

func (*ScopeService) DeleteTarget

func (s *ScopeService) DeleteTarget(ctx context.Context, targetID string, tenantID string) error

DeleteTarget deletes a scope target by ID.

func (*ScopeService) DisableSchedule

func (s *ScopeService) DisableSchedule(ctx context.Context, scheduleID string) (*scope.Schedule, error)

DisableSchedule disables a scan schedule.

func (*ScopeService) EnableSchedule

func (s *ScopeService) EnableSchedule(ctx context.Context, scheduleID string) (*scope.Schedule, error)

EnableSchedule enables a scan schedule.

func (*ScopeService) ExpireOldExclusions

func (s *ScopeService) ExpireOldExclusions(ctx context.Context) error

ExpireOldExclusions marks expired exclusions as expired.

func (*ScopeService) GetExclusion

func (s *ScopeService) GetExclusion(ctx context.Context, exclusionID string) (*scope.Exclusion, error)

GetExclusion retrieves a scope exclusion by ID.

func (*ScopeService) GetSchedule

func (s *ScopeService) GetSchedule(ctx context.Context, scheduleID string) (*scope.Schedule, error)

GetSchedule retrieves a scan schedule by ID.

func (*ScopeService) GetStats

func (s *ScopeService) GetStats(ctx context.Context, tenantID string) (*scope.Stats, error)

GetStats retrieves scope configuration statistics for a tenant.

func (*ScopeService) GetTarget

func (s *ScopeService) GetTarget(ctx context.Context, targetID string) (*scope.Target, error)

GetTarget retrieves a scope target by ID.

func (*ScopeService) ListActiveExclusions

func (s *ScopeService) ListActiveExclusions(ctx context.Context, tenantID string) ([]*scope.Exclusion, error)

ListActiveExclusions retrieves all active scope exclusions for a tenant.

func (*ScopeService) ListActiveTargets

func (s *ScopeService) ListActiveTargets(ctx context.Context, tenantID string) ([]*scope.Target, error)

ListActiveTargets retrieves all active scope targets for a tenant.

func (*ScopeService) ListDueSchedules

func (s *ScopeService) ListDueSchedules(ctx context.Context) ([]*scope.Schedule, error)

ListDueSchedules retrieves all enabled schedules that are due to run.

func (*ScopeService) ListExclusions

ListExclusions retrieves scope exclusions with filtering and pagination.

func (*ScopeService) ListSchedules

ListSchedules retrieves scan schedules with filtering and pagination.

func (*ScopeService) ListTargets

ListTargets retrieves scope targets with filtering and pagination.

func (*ScopeService) RecordScheduleRun

func (s *ScopeService) RecordScheduleRun(ctx context.Context, scheduleID string, status string, nextRunAt *time.Time) (*scope.Schedule, error)

RecordScheduleRun records a scan run for a schedule.

func (*ScopeService) UpdateExclusion

func (s *ScopeService) UpdateExclusion(ctx context.Context, exclusionID string, tenantID string, input UpdateExclusionInput) (*scope.Exclusion, error)

UpdateExclusion updates an existing scope exclusion.

func (*ScopeService) UpdateSchedule

func (s *ScopeService) UpdateSchedule(ctx context.Context, scheduleID string, tenantID string, input UpdateScheduleInput) (*scope.Schedule, error)

UpdateSchedule updates an existing scan schedule.

func (*ScopeService) UpdateTarget

func (s *ScopeService) UpdateTarget(ctx context.Context, targetID string, tenantID string, input UpdateTargetInput) (*scope.Target, error)

UpdateTarget updates an existing scope target.

type ScriptRunnerHandler

type ScriptRunnerHandler struct {
	// contains filtered or unexported fields
}

ScriptRunnerHandler handles script execution actions. NOTE: This is a placeholder. In production, script execution would need proper sandboxing, resource limits, and security controls.

func NewScriptRunnerHandler

func NewScriptRunnerHandler(log *logger.Logger) *ScriptRunnerHandler

NewScriptRunnerHandler creates a new ScriptRunnerHandler.

func (*ScriptRunnerHandler) Execute

func (h *ScriptRunnerHandler) Execute(ctx context.Context, input *ActionInput) (map[string]any, error)

Execute executes a script action.

type SecretStoreService

type SecretStoreService struct {
	// contains filtered or unexported fields
}

SecretStoreService handles credential storage business logic.

func NewSecretStoreService

func NewSecretStoreService(
	repo secretstore.Repository,
	encryptionKey []byte,
	auditService *AuditService,
	log *logger.Logger,
) (*SecretStoreService, error)

NewSecretStoreService creates a new SecretStoreService.

func (*SecretStoreService) CreateCredential

CreateCredential creates a new credential in the secret store.

func (*SecretStoreService) DecryptCredentialData

func (s *SecretStoreService) DecryptCredentialData(ctx context.Context, tenantID shared.ID, credentialID string) (any, error)

DecryptCredentialData decrypts and returns the credential data. This also updates the last_used_at timestamp.

func (*SecretStoreService) DeleteCredential

func (s *SecretStoreService) DeleteCredential(ctx context.Context, tenantID shared.ID, credentialID string) error

DeleteCredential deletes a credential from the secret store.

func (*SecretStoreService) GetCredential

func (s *SecretStoreService) GetCredential(ctx context.Context, tenantID shared.ID, credentialID string) (*secretstore.Credential, error)

GetCredential retrieves a credential by ID.

func (*SecretStoreService) ListCredentials

ListCredentials lists credentials with filtering and pagination.

func (*SecretStoreService) RotateCredential

func (s *SecretStoreService) RotateCredential(ctx context.Context, tenantID shared.ID, credentialID string, newData any) (*secretstore.Credential, error)

RotateCredential rotates a credential with new data.

func (*SecretStoreService) UpdateCredential

UpdateCredential updates a credential in the secret store.

type SecurityValidator

type SecurityValidator struct {
	// contains filtered or unexported fields
}

SecurityValidator provides validation for security-sensitive operations. It validates tool names, capabilities, and configurations against registered tools to prevent command injection and unauthorized access.

func NewSecurityValidator

func NewSecurityValidator(toolRepo tool.Repository, log *logger.Logger) *SecurityValidator

NewSecurityValidator creates a new SecurityValidator.

func (*SecurityValidator) GetAllowedCapabilities

func (v *SecurityValidator) GetAllowedCapabilities() []string

GetAllowedCapabilities returns the list of allowed capabilities. This can be used by the UI to show valid options. Capabilities are loaded from the database with caching.

func (*SecurityValidator) ValidateCommandPayload

func (v *SecurityValidator) ValidateCommandPayload(ctx context.Context, tenantID shared.ID, payload map[string]any) *ValidationResult

ValidateCommandPayload validates a command payload before sending to an agent. This is the last line of defense before a command is executed.

func (*SecurityValidator) ValidateCronExpression

func (v *SecurityValidator) ValidateCronExpression(expr string) error

ValidateCronExpression validates a cron expression format. This prevents cron injection attacks.

func (*SecurityValidator) ValidateIdentifier

func (v *SecurityValidator) ValidateIdentifier(name string, maxLen int, fieldName string) *ValidationResult

ValidateIdentifier validates an identifier string against safe character patterns. Identifiers can only contain alphanumeric characters, dashes, and underscores. This should be used for StepKey, Tags, and similar user-provided identifiers.

func (*SecurityValidator) ValidateIdentifiers

func (v *SecurityValidator) ValidateIdentifiers(names []string, maxLen int, fieldName string) *ValidationResult

ValidateIdentifiers validates a slice of identifiers.

func (*SecurityValidator) ValidateScannerConfig

func (v *SecurityValidator) ValidateScannerConfig(ctx context.Context, tenantID shared.ID, scannerConfig map[string]any) *ValidationResult

ValidateScannerConfig validates a scan configuration's scanner settings.

func (*SecurityValidator) ValidateStepConfig

func (v *SecurityValidator) ValidateStepConfig(ctx context.Context, tenantID shared.ID, toolName string, capabilities []string, config map[string]any) *ValidationResult

ValidateStepConfig validates a pipeline step's tool name and configuration. This is called before creating a pipeline step to ensure the tool is registered and the configuration matches the tool's schema.

func (*SecurityValidator) ValidateTier

func (v *SecurityValidator) ValidateTier(tier string) error

ValidateTier validates a tier value against the allowed tier list. This should be called at application boundaries before database operations. Returns nil if the tier is valid or empty (empty defaults to 'shared').

func (*SecurityValidator) ValidateTierWithResult

func (v *SecurityValidator) ValidateTierWithResult(tier string, fieldName string) *ValidationResult

ValidateTierWithResult validates a tier and returns a ValidationResult.

type SelectAgentRequest

type SelectAgentRequest struct {
	TenantID     shared.ID
	Capabilities []string
	Tool         string
	Region       string // Preferred region
	Mode         AgentSelectionMode
	AllowQueue   bool // If true, return queue info instead of error when no agent available
}

SelectAgentRequest represents a request to select an agent for a job.

type SelectAgentResult

type SelectAgentResult struct {
	Agent   *agent.Agent
	Queued  bool
	Message string
}

SelectAgentResult represents the result of agent selection.

type SendNotificationInput

type SendNotificationInput struct {
	IntegrationID string
	TenantID      string
	Title         string
	Body          string
	Severity      string // critical, high, medium, low
	URL           string
	Fields        map[string]string
}

SendNotificationInput represents the input for sending a notification.

type SendNotificationResult

type SendNotificationResult struct {
	Success   bool
	MessageID string
	Error     string
}

SendNotificationResult represents the result of sending a notification.

type SessionInfo

type SessionInfo struct {
	ID             string `json:"id"`
	IPAddress      string `json:"ip_address,omitempty"`
	UserAgent      string `json:"user_agent,omitempty"`
	LastActivityAt string `json:"last_activity_at"`
	CreatedAt      string `json:"created_at"`
	IsCurrent      bool   `json:"is_current"`
}

SessionInfo represents session information returned to the user.

type SessionResult

type SessionResult struct {
	AccessToken  string
	RefreshToken string
}

SessionResult represents session creation result.

type SessionService

type SessionService struct {
	// contains filtered or unexported fields
}

SessionService handles session management operations.

func NewSessionService

func NewSessionService(
	sessionRepo session.Repository,
	refreshTokenRepo session.RefreshTokenRepository,
	log *logger.Logger,
) *SessionService

NewSessionService creates a new SessionService.

func (*SessionService) CleanupExpiredSessions

func (s *SessionService) CleanupExpiredSessions(ctx context.Context) (int64, int64, error)

CleanupExpiredSessions removes expired sessions and tokens. This should be called periodically (e.g., by a cron job).

func (*SessionService) CountActiveSessions

func (s *SessionService) CountActiveSessions(ctx context.Context, userID string) (int, error)

CountActiveSessions returns the count of active sessions for a user.

func (*SessionService) GetSessionByAccessToken

func (s *SessionService) GetSessionByAccessToken(ctx context.Context, accessToken string) (*session.Session, error)

GetSessionByAccessToken retrieves a session by its access token.

func (*SessionService) ListUserSessions

func (s *SessionService) ListUserSessions(ctx context.Context, userID string, currentSessionID string) ([]SessionInfo, error)

ListUserSessions returns all active sessions for a user.

func (*SessionService) RevokeAllSessions

func (s *SessionService) RevokeAllSessions(ctx context.Context, userID, exceptSessionID string) error

RevokeAllSessions revokes all sessions for a user except the current one.

func (*SessionService) RevokeSession

func (s *SessionService) RevokeSession(ctx context.Context, userID, sessionID string) error

RevokeSession revokes a specific session for a user.

func (*SessionService) SetPermissionServices

func (s *SessionService) SetPermissionServices(
	cacheSvc *PermissionCacheService,
	versionSvc *PermissionVersionService,
	tenantRepo TenantMembershipProvider,
)

SetPermissionServices sets the permission cache and version services. This enables cache invalidation when sessions are revoked.

func (*SessionService) UpdateSessionActivity

func (s *SessionService) UpdateSessionActivity(ctx context.Context, sessionID string) error

UpdateSessionActivity updates the last activity time for a session.

func (*SessionService) ValidateSession

func (s *SessionService) ValidateSession(ctx context.Context, sessionID string) (*session.Session, error)

ValidateSession checks if a session is valid.

type SetUserRolesInput

type SetUserRolesInput struct {
	TenantID string   `json:"-"`
	UserID   string   `json:"user_id" validate:"required,uuid"`
	RoleIDs  []string `json:"role_ids" validate:"required,min=1"`
}

SetUserRolesInput represents the input for setting user roles.

type SyncResult

type SyncResult struct {
	Status         rule.SyncStatus
	RulesAdded     int
	RulesUpdated   int
	RulesRemoved   int
	Duration       time.Duration
	ErrorMessage   string
	ErrorDetails   map[string]any
	PreviousHash   string
	NewContentHash string
}

SyncResult represents the result of a sync operation.

type SyncSourceInput

type SyncSourceInput struct {
	TenantID string `json:"tenant_id" validate:"required,uuid"`
	SourceID string `json:"source_id" validate:"required,uuid"`
}

SyncSourceInput represents the input for syncing a rule source.

type TeamInvitationJobPayload

type TeamInvitationJobPayload struct {
	RecipientEmail string
	InviterName    string
	TeamName       string
	Token          string
	ExpiresIn      time.Duration
	InvitationID   string
	TenantID       string
}

TeamInvitationJobPayload contains data for team invitation email jobs.

type TelegramCredentials

type TelegramCredentials struct {
	BotToken string `json:"bot_token"`
	ChatID   string `json:"chat_id"`
}

TelegramCredentials represents the JSON structure for Telegram credentials (full input from frontend).

type TemplateSourceService

type TemplateSourceService struct {
	// contains filtered or unexported fields
}

TemplateSourceService handles template source business operations.

func NewTemplateSourceService

func NewTemplateSourceService(repo ts.Repository, log *logger.Logger) *TemplateSourceService

NewTemplateSourceService creates a new TemplateSourceService.

func (*TemplateSourceService) CreateSource

CreateSource creates a new template source.

func (*TemplateSourceService) DeleteSource

func (s *TemplateSourceService) DeleteSource(ctx context.Context, tenantID, sourceID string) error

DeleteSource deletes a template source.

func (*TemplateSourceService) DisableSource

func (s *TemplateSourceService) DisableSource(ctx context.Context, tenantID, sourceID string) (*ts.TemplateSource, error)

DisableSource disables a template source.

func (*TemplateSourceService) EnableSource

func (s *TemplateSourceService) EnableSource(ctx context.Context, tenantID, sourceID string) (*ts.TemplateSource, error)

EnableSource enables a template source.

func (*TemplateSourceService) ForceSync

func (s *TemplateSourceService) ForceSync(ctx context.Context, tenantID, sourceID string) (*TemplateSyncResult, error)

ForceSync triggers an immediate sync for a specific source. This is used for manual "force sync" requests from the API.

func (*TemplateSourceService) GetSource

func (s *TemplateSourceService) GetSource(ctx context.Context, tenantID, sourceID string) (*ts.TemplateSource, error)

GetSource retrieves a template source by ID.

func (*TemplateSourceService) GetSourcesForScan

func (s *TemplateSourceService) GetSourcesForScan(ctx context.Context, tenantID string, templateTypes []scannertemplate.TemplateType) ([]*ts.TemplateSource, error)

GetSourcesForScan retrieves enabled template sources linked to a scan profile.

func (*TemplateSourceService) GetSourcesNeedingSync

func (s *TemplateSourceService) GetSourcesNeedingSync(ctx context.Context, tenantID string) ([]*ts.TemplateSource, error)

GetSourcesNeedingSync returns sources that need to be synced (cache expired).

func (*TemplateSourceService) ListSources

ListSources lists template sources with filters.

func (*TemplateSourceService) SetTemplateSyncer

func (s *TemplateSourceService) SetTemplateSyncer(syncer *TemplateSyncer)

SetTemplateSyncer sets the template syncer for force sync operations.

func (*TemplateSourceService) UpdateSource

UpdateSource updates an existing template source.

func (*TemplateSourceService) UpdateSyncStatus

func (s *TemplateSourceService) UpdateSyncStatus(ctx context.Context, source *ts.TemplateSource) error

UpdateSyncStatus updates the sync status of a template source.

type TemplateSyncResult

type TemplateSyncResult struct {
	SourceID       shared.ID
	Success        bool
	Hash           string
	TemplatesFound int
	TemplatesAdded int
	Error          string
	Duration       time.Duration
}

SyncResult contains the result of a sync operation.

type TemplateSyncer

type TemplateSyncer struct {
	// contains filtered or unexported fields
}

TemplateSyncer handles syncing templates from external sources.

func NewTemplateSyncer

func NewTemplateSyncer(
	sourceRepo templatesource.Repository,
	templateRepo scannertemplate.Repository,
	secretStoreSvc *SecretStoreService,
	signingKey []byte,
	log *logger.Logger,
) *TemplateSyncer

NewTemplateSyncer creates a new TemplateSyncer.

func (*TemplateSyncer) SyncSource

SyncSource syncs templates from a single source.

func (*TemplateSyncer) SyncSourcesForScan

func (s *TemplateSyncer) SyncSourcesForScan(ctx context.Context, tenantID shared.ID) ([]*TemplateSyncResult, error)

SyncSourcesForScan syncs all sources that need updating for a scan.

type TemplateUsageResult

type TemplateUsageResult struct {
	Usage scannertemplate.TemplateUsage `json:"usage"`
	Quota scannertemplate.TemplateQuota `json:"quota"`
}

TemplateUsageResult combines usage and quota information.

type TenantAvailableCapabilitiesOutput

type TenantAvailableCapabilitiesOutput struct {
	Capabilities []string `json:"capabilities"` // Unique capability names available to tenant
	TotalAgents  int      `json:"total_agents"` // Total number of online agents
}

TenantAvailableCapabilitiesOutput represents the output for available capabilities.

type TenantLister

type TenantLister interface {
	// ListActiveTenantIDs returns all active tenant IDs for batch processing.
	ListActiveTenantIDs(ctx context.Context) ([]shared.ID, error)
}

TenantLister provides a list of active tenant IDs.

type TenantMembershipAdapter

type TenantMembershipAdapter struct {
	// contains filtered or unexported fields
}

TenantMembershipAdapter adapts the tenant.Repository to the TenantMembershipProvider interface. This allows SessionService to get all tenant IDs a user belongs to for cache invalidation.

func NewTenantMembershipAdapter

func NewTenantMembershipAdapter(repo tenant.Repository) *TenantMembershipAdapter

NewTenantMembershipAdapter creates a new TenantMembershipAdapter.

func (*TenantMembershipAdapter) GetUserTenantIDs

func (a *TenantMembershipAdapter) GetUserTenantIDs(ctx context.Context, userID shared.ID) ([]string, error)

GetUserTenantIDs returns all tenant IDs that a user belongs to. This is used by SessionService to invalidate permission cache across all tenants when a user's session is revoked.

type TenantMembershipInfo

type TenantMembershipInfo struct {
	TenantID   string `json:"tenant_id"`
	TenantSlug string `json:"tenant_slug"`
	TenantName string `json:"tenant_name"`
	Role       string `json:"role"`
}

TenantMembershipInfo represents a tenant membership for API responses.

type TenantMembershipProvider

type TenantMembershipProvider interface {
	GetUserTenantIDs(ctx context.Context, userID shared.ID) ([]string, error)
}

TenantMembershipProvider provides tenant membership information. Used to get all tenants a user belongs to for cache invalidation.

type TenantService

type TenantService struct {
	// contains filtered or unexported fields
}

TenantService handles tenant-related business operations. Note: Tenants are displayed as "Teams" in the UI.

func NewTenantService

func NewTenantService(repo tenant.Repository, log *logger.Logger, opts ...TenantServiceOption) *TenantService

NewTenantService creates a new TenantService.

func (*TenantService) AcceptInvitation

func (s *TenantService) AcceptInvitation(ctx context.Context, token string, userID shared.ID, userEmail string, actx AuditContext) (*tenant.Membership, error)

AcceptInvitation accepts an invitation and creates a membership. userID is the local user ID (from users table) of the person accepting the invitation. userEmail is used to verify the invitation is intended for this user.

func (*TenantService) AddMember

func (s *TenantService) AddMember(ctx context.Context, tenantID string, input AddMemberInput, inviterUserID shared.ID, actx AuditContext) (*tenant.Membership, error)

AddMember adds a user to a tenant. inviterUserID is the local user ID of the person inviting.

func (*TenantService) CleanupExpiredInvitations

func (s *TenantService) CleanupExpiredInvitations(ctx context.Context) (int64, error)

CleanupExpiredInvitations removes all expired invitations.

func (*TenantService) CreateInvitation

func (s *TenantService) CreateInvitation(ctx context.Context, tenantID string, input CreateInvitationInput, inviterUserID shared.ID, actx AuditContext) (*tenant.Invitation, error)

CreateInvitation creates an invitation to join a tenant. inviterUserID is the local user ID (from users table) of the person sending the invitation.

func (*TenantService) CreateTenant

func (s *TenantService) CreateTenant(ctx context.Context, input CreateTenantInput, creatorUserID shared.ID, actx AuditContext) (*tenant.Tenant, error)

CreateTenant creates a new tenant and adds the creator as owner. creatorUserID is the local user ID (from users table).

func (*TenantService) DeleteInvitation

func (s *TenantService) DeleteInvitation(ctx context.Context, invitationID string) error

DeleteInvitation cancels an invitation.

func (*TenantService) DeleteTenant

func (s *TenantService) DeleteTenant(ctx context.Context, tenantID string) error

DeleteTenant deletes a tenant.

func (*TenantService) GetInvitationByToken

func (s *TenantService) GetInvitationByToken(ctx context.Context, token string) (*tenant.Invitation, error)

GetInvitationByToken retrieves an invitation by its token.

func (*TenantService) GetMemberStats

func (s *TenantService) GetMemberStats(ctx context.Context, tenantID string) (*tenant.MemberStats, error)

GetMemberStats retrieves member statistics for a tenant.

func (*TenantService) GetMembership

func (s *TenantService) GetMembership(ctx context.Context, userID shared.ID, tenantID string) (*tenant.Membership, error)

GetMembership retrieves a user's membership in a tenant. userID is the local user ID (from users table).

func (*TenantService) GetTenant

func (s *TenantService) GetTenant(ctx context.Context, tenantID string) (*tenant.Tenant, error)

GetTenant retrieves a tenant by ID.

func (*TenantService) GetTenantBySlug

func (s *TenantService) GetTenantBySlug(ctx context.Context, slug string) (*tenant.Tenant, error)

GetTenantBySlug retrieves a tenant by slug.

func (*TenantService) GetTenantSettings

func (s *TenantService) GetTenantSettings(ctx context.Context, tenantID string) (*tenant.Settings, error)

GetTenantSettings retrieves the typed settings for a tenant.

func (*TenantService) GetUserDisplayName

func (s *TenantService) GetUserDisplayName(ctx context.Context, userID shared.ID) string

GetUserDisplayName returns the display name for a user by their ID. Returns empty string if user not found or no userInfoProvider is configured.

func (*TenantService) ListMembers

func (s *TenantService) ListMembers(ctx context.Context, tenantID string) ([]*tenant.Membership, error)

ListMembers lists all members of a tenant.

func (*TenantService) ListMembersWithUserInfo

func (s *TenantService) ListMembersWithUserInfo(ctx context.Context, tenantID string) ([]*tenant.MemberWithUser, error)

ListMembersWithUserInfo lists all members of a tenant with user details.

func (*TenantService) ListPendingInvitations

func (s *TenantService) ListPendingInvitations(ctx context.Context, tenantID string) ([]*tenant.Invitation, error)

ListPendingInvitations lists pending invitations for a tenant.

func (*TenantService) ListUserTenants

func (s *TenantService) ListUserTenants(ctx context.Context, userID shared.ID) ([]*tenant.TenantWithRole, error)

ListUserTenants lists all tenants a user belongs to. userID is the local user ID (from users table).

func (*TenantService) RemoveMember

func (s *TenantService) RemoveMember(ctx context.Context, membershipID string, actx AuditContext) error

RemoveMember removes a member from a tenant.

func (*TenantService) SearchMembersWithUserInfo

func (s *TenantService) SearchMembersWithUserInfo(ctx context.Context, tenantID string, filters tenant.MemberSearchFilters) (*tenant.MemberSearchResult, error)

SearchMembersWithUserInfo searches members with filtering and pagination.

func (*TenantService) SetPermissionServices

func (s *TenantService) SetPermissionServices(cacheSvc *PermissionCacheService, versionSvc *PermissionVersionService)

SetPermissionServices sets the permission cache and version services. This is used when services are initialized after TenantService.

func (*TenantService) UpdateAPISettings

func (s *TenantService) UpdateAPISettings(ctx context.Context, tenantID string, input UpdateAPISettingsInput, actx AuditContext) (*tenant.Settings, error)

UpdateAPISettings updates only the API settings.

func (*TenantService) UpdateBranchSettings

func (s *TenantService) UpdateBranchSettings(ctx context.Context, tenantID string, input UpdateBranchSettingsInput, actx AuditContext) (*tenant.Settings, error)

UpdateBranchSettings updates only the branch naming convention settings.

func (*TenantService) UpdateBrandingSettings

func (s *TenantService) UpdateBrandingSettings(ctx context.Context, tenantID string, input UpdateBrandingSettingsInput, actx AuditContext) (*tenant.Settings, error)

UpdateBrandingSettings updates only the branding settings.

func (*TenantService) UpdateGeneralSettings

func (s *TenantService) UpdateGeneralSettings(ctx context.Context, tenantID string, input UpdateGeneralSettingsInput, actx AuditContext) (*tenant.Settings, error)

UpdateGeneralSettings updates only the general settings.

func (*TenantService) UpdateMemberRole

func (s *TenantService) UpdateMemberRole(ctx context.Context, membershipID string, input UpdateMemberRoleInput, actx AuditContext) (*tenant.Membership, error)

UpdateMemberRole updates a member's role.

func (*TenantService) UpdateSecuritySettings

func (s *TenantService) UpdateSecuritySettings(ctx context.Context, tenantID string, input UpdateSecuritySettingsInput, actx AuditContext) (*tenant.Settings, error)

UpdateSecuritySettings updates only the security settings.

func (*TenantService) UpdateTenant

func (s *TenantService) UpdateTenant(ctx context.Context, tenantID string, input UpdateTenantInput) (*tenant.Tenant, error)

UpdateTenant updates a tenant's information.

func (*TenantService) UpdateTenantSettings

func (s *TenantService) UpdateTenantSettings(ctx context.Context, tenantID string, settings tenant.Settings, actx AuditContext) (*tenant.Settings, error)

UpdateTenantSettings updates all tenant settings.

type TenantServiceOption

type TenantServiceOption func(*TenantService)

TenantServiceOption is a functional option for TenantService.

func WithEmailEnqueuer

func WithEmailEnqueuer(enqueuer EmailJobEnqueuer) TenantServiceOption

WithEmailEnqueuer sets the email job enqueuer for TenantService.

func WithTenantAuditService

func WithTenantAuditService(auditService *AuditService) TenantServiceOption

WithTenantAuditService sets the audit service for TenantService.

func WithTenantPermissionCacheService

func WithTenantPermissionCacheService(svc *PermissionCacheService) TenantServiceOption

WithTenantPermissionCacheService sets the permission cache service for TenantService. This enables immediate cache invalidation when members are removed.

func WithTenantPermissionVersionService

func WithTenantPermissionVersionService(svc *PermissionVersionService) TenantServiceOption

WithTenantPermissionVersionService sets the permission version service for TenantService. This enables version cleanup when members are removed.

func WithUserInfoProvider

func WithUserInfoProvider(provider UserInfoProvider) TenantServiceOption

WithUserInfoProvider sets the user info provider for TenantService.

type TestIntegrationCredentialsInput

type TestIntegrationCredentialsInput struct {
	Category        string
	Provider        string
	BaseURL         string
	AuthType        string
	Credentials     string
	SCMOrganization string
}

TestCredentialsInput represents the input for testing credentials without creating.

type TestIntegrationCredentialsResult

type TestIntegrationCredentialsResult struct {
	Success      bool
	Message      string
	RepoCount    int
	Organization string
	Username     string
}

TestIntegrationCredentialsResult represents the result of testing credentials.

type ThreatIntelService

type ThreatIntelService struct {
	// contains filtered or unexported fields
}

ThreatIntelService handles threat intelligence operations.

func NewThreatIntelService

func NewThreatIntelService(
	repo threatintel.ThreatIntelRepository,
	log *logger.Logger,
) *ThreatIntelService

NewThreatIntelService creates a new ThreatIntelService.

func (*ThreatIntelService) EnrichCVE

EnrichCVE enriches a single CVE with threat intel data.

func (*ThreatIntelService) EnrichCVEs

EnrichCVEs enriches multiple CVEs with threat intel data.

func (*ThreatIntelService) GetEPSSScore

func (s *ThreatIntelService) GetEPSSScore(ctx context.Context, cveID string) (*threatintel.EPSSScore, error)

GetEPSSScore retrieves an EPSS score by CVE ID.

func (*ThreatIntelService) GetEPSSScores

func (s *ThreatIntelService) GetEPSSScores(ctx context.Context, cveIDs []string) ([]*threatintel.EPSSScore, error)

GetEPSSScores retrieves EPSS scores for multiple CVE IDs.

func (*ThreatIntelService) GetEPSSStats

func (s *ThreatIntelService) GetEPSSStats(ctx context.Context) (*EPSSStats, error)

GetEPSSStats returns EPSS statistics.

func (*ThreatIntelService) GetHighRiskEPSS

func (s *ThreatIntelService) GetHighRiskEPSS(ctx context.Context, threshold float64, limit int) ([]*threatintel.EPSSScore, error)

GetHighRiskEPSS retrieves high-risk EPSS scores.

func (*ThreatIntelService) GetKEVEntry

func (s *ThreatIntelService) GetKEVEntry(ctx context.Context, cveID string) (*threatintel.KEVEntry, error)

GetKEVEntry retrieves a KEV entry by CVE ID.

func (*ThreatIntelService) GetKEVStats

func (s *ThreatIntelService) GetKEVStats(ctx context.Context) (*KEVStats, error)

GetKEVStats returns KEV statistics.

func (*ThreatIntelService) GetSyncStatus

func (s *ThreatIntelService) GetSyncStatus(ctx context.Context, source string) (*threatintel.SyncStatus, error)

GetSyncStatus returns sync status for a specific source.

func (*ThreatIntelService) GetSyncStatuses

func (s *ThreatIntelService) GetSyncStatuses(ctx context.Context) ([]*threatintel.SyncStatus, error)

GetSyncStatuses returns all sync statuses.

func (*ThreatIntelService) GetThreatIntelStats

func (s *ThreatIntelService) GetThreatIntelStats(ctx context.Context) (*ThreatIntelStats, error)

GetThreatIntelStats returns unified threat intelligence statistics. This combines EPSS stats, KEV stats, and sync statuses in a single call.

func (*ThreatIntelService) IsInKEV

func (s *ThreatIntelService) IsInKEV(ctx context.Context, cveID string) (bool, error)

IsInKEV checks if a CVE is in the KEV catalog.

func (*ThreatIntelService) SetSyncEnabled

func (s *ThreatIntelService) SetSyncEnabled(ctx context.Context, source string, enabled bool) error

SetSyncEnabled enables or disables sync for a source.

func (*ThreatIntelService) SyncAll

SyncAll syncs all enabled threat intel sources.

func (*ThreatIntelService) SyncEPSS

SyncEPSS syncs EPSS scores from FIRST.org.

func (*ThreatIntelService) SyncKEV

SyncKEV syncs KEV catalog from CISA.

type ThreatIntelStats

type ThreatIntelStats struct {
	EPSS         *EPSSStats            `json:"epss"`
	KEV          *KEVStats             `json:"kev"`
	SyncStatuses []*ThreatIntelSyncDTO `json:"sync_statuses"`
}

ThreatIntelStats contains unified threat intelligence statistics.

type ThreatIntelSyncDTO

type ThreatIntelSyncDTO struct {
	Source         string  `json:"source"`
	Enabled        bool    `json:"enabled"`
	LastSyncAt     *string `json:"last_sync_at,omitempty"`
	LastSyncStatus string  `json:"last_sync_status"`
	RecordsSynced  int     `json:"records_synced"`
	LastError      *string `json:"last_error,omitempty"`
	NextSyncAt     *string `json:"next_sync_at,omitempty"`
}

ThreatIntelSyncDTO is a data transfer object for sync status.

type ThreatIntelSyncResult

type ThreatIntelSyncResult struct {
	Source        string
	RecordsSynced int
	DurationMs    int64
	Error         error
}

ThreatIntelSyncResult contains the result of a sync operation.

type TicketActionHandler

type TicketActionHandler struct {
	// contains filtered or unexported fields
}

TicketActionHandler handles ticket creation and update actions.

func NewTicketActionHandler

func NewTicketActionHandler(intSvc *IntegrationService, log *logger.Logger) *TicketActionHandler

NewTicketActionHandler creates a new TicketActionHandler.

func (*TicketActionHandler) Execute

func (h *TicketActionHandler) Execute(ctx context.Context, input *ActionInput) (map[string]any, error)

Execute executes a ticket-related action.

type TokenLimitError

type TokenLimitError struct {
	Used  int
	Limit int
}

TokenLimitError is returned when token limit is exceeded.

func (*TokenLimitError) Error

func (e *TokenLimitError) Error() string

type ToolCategoryService

type ToolCategoryService struct {
	// contains filtered or unexported fields
}

ToolCategoryService handles tool category business operations.

func NewToolCategoryService

func NewToolCategoryService(
	repo toolcategory.Repository,
	log *logger.Logger,
) *ToolCategoryService

NewToolCategoryService creates a new ToolCategoryService.

func (*ToolCategoryService) CreateCategory

CreateCategory creates a new tenant custom category.

func (*ToolCategoryService) DeleteCategory

func (s *ToolCategoryService) DeleteCategory(ctx context.Context, tenantID, categoryID string) error

DeleteCategory deletes a tenant custom category.

func (*ToolCategoryService) GetCategory

GetCategory returns a category by ID.

func (*ToolCategoryService) ListAllCategories

func (s *ToolCategoryService) ListAllCategories(ctx context.Context, tenantID string) ([]*toolcategory.ToolCategory, error)

ListAllCategories returns all categories for a tenant context (for dropdowns).

func (*ToolCategoryService) ListCategories

ListCategories returns categories matching the filter. Always includes platform (builtin) categories. If TenantID is provided, also includes that tenant's custom categories.

func (*ToolCategoryService) UpdateCategory

UpdateCategory updates an existing tenant custom category.

type ToolService

type ToolService struct {
	// contains filtered or unexported fields
}

ToolService handles tool registry business operations.

func NewToolService

func NewToolService(
	toolRepo tool.Repository,
	configRepo tool.TenantToolConfigRepository,
	executionRepo tool.ToolExecutionRepository,
	log *logger.Logger,
) *ToolService

NewToolService creates a new ToolService.

func (*ToolService) ActivateCustomTool

func (s *ToolService) ActivateCustomTool(ctx context.Context, tenantID, toolID string) (*tool.Tool, error)

ActivateCustomTool activates a tenant custom tool.

func (*ToolService) ActivateTool

func (s *ToolService) ActivateTool(ctx context.Context, toolID string) (*tool.Tool, error)

ActivateTool activates a tool.

func (*ToolService) BulkDisableTools

func (s *ToolService) BulkDisableTools(ctx context.Context, input BulkDisableToolsInput) error

BulkDisableTools disables multiple tools for a tenant.

func (*ToolService) BulkEnableTools

func (s *ToolService) BulkEnableTools(ctx context.Context, input BulkEnableToolsInput) error

BulkEnableTools enables multiple tools for a tenant.

func (*ToolService) CompleteToolExecution

func (s *ToolService) CompleteToolExecution(ctx context.Context, input CompleteToolExecutionInput) (*tool.ToolExecution, error)

CompleteToolExecution marks a tool execution as completed.

func (*ToolService) CreateCustomTool

func (s *ToolService) CreateCustomTool(ctx context.Context, input CreateCustomToolInput) (*tool.Tool, error)

CreateCustomTool creates a new tenant custom tool.

func (*ToolService) CreateTenantToolConfig

func (s *ToolService) CreateTenantToolConfig(ctx context.Context, input CreateTenantToolConfigInput) (*tool.TenantToolConfig, error)

CreateTenantToolConfig creates a new tenant tool configuration.

func (*ToolService) CreateTool

func (s *ToolService) CreateTool(ctx context.Context, input CreateToolInput) (*tool.Tool, error)

CreateTool creates a new tool in the registry.

func (*ToolService) DeactivateCustomTool

func (s *ToolService) DeactivateCustomTool(ctx context.Context, tenantID, toolID string) (*tool.Tool, error)

DeactivateCustomTool deactivates a tenant custom tool. Also cascade deactivates any active pipelines that use this tool.

func (*ToolService) DeactivateTool

func (s *ToolService) DeactivateTool(ctx context.Context, toolID string) (*tool.Tool, error)

DeactivateTool deactivates a tool. Also cascade deactivates any active pipelines that use this tool.

func (*ToolService) DeleteCustomTool

func (s *ToolService) DeleteCustomTool(ctx context.Context, tenantID, toolID string) error

DeleteCustomTool deletes a tenant custom tool. Before deleting, cascade deactivates any active pipelines that use this tool.

func (*ToolService) DeleteTenantToolConfig

func (s *ToolService) DeleteTenantToolConfig(ctx context.Context, tenantID, toolID string) error

DeleteTenantToolConfig deletes a tenant tool configuration.

func (*ToolService) DeleteTool

func (s *ToolService) DeleteTool(ctx context.Context, toolID string) error

DeleteTool deletes a tool from the registry. Before deleting, cascade deactivates any active pipelines that use this tool.

func (*ToolService) DisableToolForTenant

func (s *ToolService) DisableToolForTenant(ctx context.Context, tenantID, toolID string) error

DisableToolForTenant disables a tool for a tenant.

func (*ToolService) EnableToolForTenant

func (s *ToolService) EnableToolForTenant(ctx context.Context, tenantID, toolID string) error

EnableToolForTenant enables a tool for a tenant.

func (*ToolService) FailToolExecution

func (s *ToolService) FailToolExecution(ctx context.Context, input FailToolExecutionInput) (*tool.ToolExecution, error)

FailToolExecution marks a tool execution as failed.

func (*ToolService) GetCustomTool

func (s *ToolService) GetCustomTool(ctx context.Context, tenantID, toolID string) (*tool.Tool, error)

GetCustomTool retrieves a tenant custom tool.

func (*ToolService) GetEffectiveToolConfig

func (s *ToolService) GetEffectiveToolConfig(ctx context.Context, tenantID, toolID string) (map[string]any, error)

GetEffectiveToolConfig retrieves the effective (merged) configuration for a tool.

func (*ToolService) GetTenantToolConfig

func (s *ToolService) GetTenantToolConfig(ctx context.Context, tenantID, toolID string) (*tool.TenantToolConfig, error)

GetTenantToolConfig retrieves a tenant tool configuration.

func (*ToolService) GetTenantToolStats

func (s *ToolService) GetTenantToolStats(ctx context.Context, tenantID string, days int) (*tool.TenantToolStats, error)

GetTenantToolStats retrieves aggregated tool statistics for a tenant.

func (*ToolService) GetTool

func (s *ToolService) GetTool(ctx context.Context, toolID string) (*tool.Tool, error)

GetTool retrieves a tool by ID.

func (*ToolService) GetToolByName

func (s *ToolService) GetToolByName(ctx context.Context, name string) (*tool.Tool, error)

GetToolByName retrieves a tool by name.

func (*ToolService) GetToolStats

func (s *ToolService) GetToolStats(ctx context.Context, tenantID, toolID string, days int) (*tool.ToolStats, error)

GetToolStats retrieves statistics for a specific tool.

func (*ToolService) GetToolWithConfig

func (s *ToolService) GetToolWithConfig(ctx context.Context, tenantID, toolID string) (*tool.ToolWithConfig, error)

GetToolWithConfig retrieves a tool with its tenant-specific configuration.

func (*ToolService) ListAvailableTools

func (s *ToolService) ListAvailableTools(ctx context.Context, input ListAvailableToolsInput) (pagination.Result[*tool.Tool], error)

ListAvailableTools lists all tools available to a tenant (platform + custom).

func (*ToolService) ListCustomTools

func (s *ToolService) ListCustomTools(ctx context.Context, input ListCustomToolsInput) (pagination.Result[*tool.Tool], error)

ListCustomTools lists tenant's custom tools.

func (*ToolService) ListEnabledToolsForTenant

func (s *ToolService) ListEnabledToolsForTenant(ctx context.Context, tenantID string) ([]*tool.TenantToolConfig, error)

ListEnabledToolsForTenant lists all enabled tools for a tenant.

func (*ToolService) ListPlatformTools

func (s *ToolService) ListPlatformTools(ctx context.Context, input ListPlatformToolsInput) (pagination.Result[*tool.Tool], error)

ListPlatformTools lists platform tools (system-provided, available to all tenants).

func (*ToolService) ListTenantToolConfigs

ListTenantToolConfigs lists tenant tool configurations.

func (*ToolService) ListToolExecutions

ListToolExecutions lists tool executions with filters.

func (*ToolService) ListTools

func (s *ToolService) ListTools(ctx context.Context, input ListToolsInput) (pagination.Result[*tool.Tool], error)

ListTools lists tools with filters.

func (*ToolService) ListToolsByCapability

func (s *ToolService) ListToolsByCapability(ctx context.Context, capability string) ([]*tool.Tool, error)

ListToolsByCapability lists tools by capability.

func (*ToolService) ListToolsByCategory

func (s *ToolService) ListToolsByCategory(ctx context.Context, category string) ([]*tool.Tool, error)

ListToolsByCategory lists tools by category name.

func (*ToolService) ListToolsWithConfig

ListToolsWithConfig lists tools with their tenant-specific config.

func (*ToolService) RecordToolExecution

func (s *ToolService) RecordToolExecution(ctx context.Context, input RecordToolExecutionInput) (*tool.ToolExecution, error)

RecordToolExecution records a new tool execution.

func (*ToolService) SetAgentRepo

func (s *ToolService) SetAgentRepo(repo agent.Repository)

SetAgentRepo sets the agent repository for tool availability checks. This is optional - if not set, IsAvailable will always be true.

func (*ToolService) SetCategoryRepo

func (s *ToolService) SetCategoryRepo(repo toolcategory.Repository)

SetCategoryRepo sets the category repository for fetching category info. This is optional - if not set, Category will be nil in responses.

func (*ToolService) SetPipelineDeactivator

func (s *ToolService) SetPipelineDeactivator(deactivator PipelineDeactivator)

SetPipelineDeactivator sets the pipeline deactivator for cascade deactivation. This is optional - if not set, pipelines will not be auto-deactivated when tools are disabled.

func (*ToolService) TimeoutToolExecution

func (s *ToolService) TimeoutToolExecution(ctx context.Context, executionID string) (*tool.ToolExecution, error)

TimeoutToolExecution marks a tool execution as timed out.

func (*ToolService) UpdateCustomTool

func (s *ToolService) UpdateCustomTool(ctx context.Context, input UpdateCustomToolInput) (*tool.Tool, error)

UpdateCustomTool updates a tenant custom tool.

func (*ToolService) UpdateTenantToolConfig

func (s *ToolService) UpdateTenantToolConfig(ctx context.Context, input UpdateTenantToolConfigInput) (*tool.TenantToolConfig, error)

UpdateTenantToolConfig updates a tenant tool configuration (upsert).

func (*ToolService) UpdateTool

func (s *ToolService) UpdateTool(ctx context.Context, input UpdateToolInput) (*tool.Tool, error)

UpdateTool updates an existing tool.

func (*ToolService) UpdateToolVersion

func (s *ToolService) UpdateToolVersion(ctx context.Context, input UpdateToolVersionInput) (*tool.Tool, error)

UpdateToolVersion updates the version information of a tool.

type TriageBroadcaster

type TriageBroadcaster interface {
	// BroadcastTriage sends a triage event to subscribers.
	// channel: the channel to broadcast to (e.g., "triage:{finding_id}")
	// data: the triage event data
	// tenantID: tenant isolation for the broadcast
	BroadcastTriage(channel string, data any, tenantID string)
}

TriageBroadcaster broadcasts triage events for real-time WebSocket updates.

type TriageOutputValidator

type TriageOutputValidator struct {
	// contains filtered or unexported fields
}

TriageOutputValidator validates LLM triage output for security and correctness.

func NewTriageOutputValidator

func NewTriageOutputValidator() *TriageOutputValidator

NewTriageOutputValidator creates a new validator with default settings.

func (*TriageOutputValidator) ValidateAndSanitize

func (v *TriageOutputValidator) ValidateAndSanitize(content string) (*aitriage.TriageAnalysis, error)

ValidateAndSanitize validates and sanitizes the LLM output. Returns a sanitized analysis or an error if validation fails.

type TriageRequest

type TriageRequest struct {
	TenantID   string  `validate:"required,uuid"`
	FindingID  string  `validate:"required,uuid"`
	TriageType string  `validate:"required,oneof=auto manual bulk"`
	UserID     *string `validate:"omitempty,uuid"` // For manual requests
}

TriageRequest represents a request to triage a finding.

type TriageResponse

type TriageResponse struct {
	JobID  string `json:"job_id"`
	Status string `json:"status"`
}

TriageResponse represents the response from a triage request.

type TriageResultResponse

type TriageResultResponse struct {
	ID                      string     `json:"id"`
	Status                  string     `json:"status"`
	SeverityAssessment      string     `json:"severity_assessment,omitempty"`
	SeverityJustification   string     `json:"severity_justification,omitempty"`
	RiskScore               float64    `json:"risk_score,omitempty"`
	Exploitability          string     `json:"exploitability,omitempty"`
	ExploitabilityDetails   string     `json:"exploitability_details,omitempty"`
	BusinessImpact          string     `json:"business_impact,omitempty"`
	PriorityRank            int        `json:"priority_rank,omitempty"`
	FalsePositiveLikelihood float64    `json:"false_positive_likelihood,omitempty"`
	FalsePositiveReason     string     `json:"false_positive_reason,omitempty"`
	Summary                 string     `json:"summary,omitempty"`
	CreatedAt               time.Time  `json:"created_at"`
	CompletedAt             *time.Time `json:"completed_at,omitempty"`
	ErrorMessage            string     `json:"error_message,omitempty"`
}

TriageResultResponse represents the detailed triage result.

type TriggerWorkflowInput

type TriggerWorkflowInput struct {
	TenantID    shared.ID
	UserID      shared.ID
	WorkflowID  shared.ID
	TriggerType workflow.TriggerType
	TriggerData map[string]any
}

TriggerWorkflowInput represents input for triggering a workflow.

type UnassignAssetInput

type UnassignAssetInput struct {
	GroupID string `json:"-"`
	AssetID string `json:"-"`
}

UnassignAssetInput represents the input for removing an asset from a group.

type UpdateAPISettingsInput

type UpdateAPISettingsInput struct {
	APIKeyEnabled bool     `json:"api_key_enabled"`
	WebhookURL    string   `json:"webhook_url" validate:"omitempty,url"`
	WebhookSecret string   `json:"webhook_secret"`
	WebhookEvents []string `json:"webhook_events"`
}

UpdateAPISettingsInput represents input for updating API settings.

type UpdateAgentInput

type UpdateAgentInput struct {
	TenantID          string   `json:"tenant_id" validate:"required,uuid"`
	AgentID           string   `json:"agent_id" validate:"required,uuid"`
	Name              string   `json:"name" validate:"omitempty,min=1,max=255"`
	Description       string   `json:"description" validate:"max=1000"`
	Capabilities      []string `json:"capabilities" validate:"max=20,dive,max=50"`
	Tools             []string `json:"tools" validate:"max=20,dive,max=50"`
	Status            string   `json:"status" validate:"omitempty,oneof=active disabled revoked"` // Admin-controlled
	MaxConcurrentJobs *int     `json:"max_concurrent_jobs" validate:"omitempty,min=1,max=100"`
	// Audit context (optional, for audit logging)
	AuditContext *AuditContext `json:"-"`
}

UpdateAgentInput represents the input for updating an agent.

type UpdateAssetGroupInput

type UpdateAssetGroupInput struct {
	Name         *string  `validate:"omitempty,min=1,max=255"`
	Description  *string  `validate:"omitempty,max=1000"`
	Environment  *string  `validate:"omitempty,asset_group_environment"`
	Criticality  *string  `validate:"omitempty,asset_group_criticality"`
	BusinessUnit *string  `validate:"omitempty,max=255"`
	Owner        *string  `validate:"omitempty,max=255"`
	OwnerEmail   *string  `validate:"omitempty,email,max=255"`
	Tags         []string `validate:"omitempty,max=20,dive,max=50"`
}

UpdateAssetGroupInput represents input for updating an asset group.

type UpdateAssetInput

type UpdateAssetInput struct {
	Name        *string  `validate:"omitempty,min=1,max=255"`
	Criticality *string  `validate:"omitempty,criticality"`
	Scope       *string  `validate:"omitempty,scope"`
	Exposure    *string  `validate:"omitempty,exposure"`
	Description *string  `validate:"omitempty,max=1000"`
	Tags        []string `validate:"omitempty,max=20,dive,max=50"`
}

UpdateAssetInput represents the input for updating an asset.

type UpdateAssetOwnershipInput

type UpdateAssetOwnershipInput struct {
	GroupID       string `json:"-"`
	AssetID       string `json:"-"`
	OwnershipType string `json:"ownership_type" validate:"required,oneof=primary secondary stakeholder informed"`
}

UpdateAssetOwnershipInput represents the input for updating asset ownership type.

type UpdateBranchInput

type UpdateBranchInput struct {
	IsProtected            *bool
	LastCommitSHA          *string `validate:"omitempty,max=40"`
	LastCommitMessage      *string `validate:"omitempty,max=1000"`
	LastCommitAuthor       *string `validate:"omitempty,max=100"`
	LastCommitAuthorAvatar *string `validate:"omitempty,max=500"`
	ScanOnPush             *bool
	ScanOnPR               *bool
	KeepWhenInactive       *bool
	RetentionDays          *int `validate:"omitempty,min=0,max=365"`
}

UpdateBranchInput represents the input for updating a branch.

type UpdateBranchScanStatusInput

type UpdateBranchScanStatusInput struct {
	ScanID           string `validate:"required,uuid"`
	ScanStatus       string `validate:"required,scan_status"`
	QualityGate      string `validate:"omitempty,quality_gate_status"`
	TotalFindings    *int   `validate:"omitempty,min=0"`
	CriticalFindings *int   `validate:"omitempty,min=0"`
	HighFindings     *int   `validate:"omitempty,min=0"`
	MediumFindings   *int   `validate:"omitempty,min=0"`
	LowFindings      *int   `validate:"omitempty,min=0"`
}

UpdateBranchScanStatusInput represents the input for updating scan status.

type UpdateBranchSettingsInput

type UpdateBranchSettingsInput struct {
	TypeRules []BranchTypeRuleInput `json:"type_rules" validate:"dive"`
}

UpdateBranchSettingsInput represents input for updating branch naming convention settings.

type UpdateBrandingSettingsInput

type UpdateBrandingSettingsInput struct {
	PrimaryColor string `json:"primary_color" validate:"omitempty"`
	LogoDarkURL  string `json:"logo_dark_url" validate:"omitempty,url"`
	LogoData     string `json:"logo_data" validate:"omitempty"` // Base64 encoded logo (max 150KB)
}

UpdateBrandingSettingsInput represents input for updating branding settings.

type UpdateCapabilityInput

type UpdateCapabilityInput struct {
	TenantID    string `json:"-"`
	ID          string `json:"-"`
	DisplayName string `json:"display_name" validate:"required,max=100"`
	Description string `json:"description" validate:"max=500"`
	Icon        string `json:"icon" validate:"max=50"`
	Color       string `json:"color" validate:"max=20"`
	Category    string `json:"category" validate:"max=50"`

	// Audit context (set by handler)
	AuditContext AuditContext `json:"-"`
}

UpdateCapabilityInput represents the input for updating a capability.

type UpdateCategoryInput

type UpdateCategoryInput struct {
	TenantID    string `json:"-"`
	ID          string `json:"-"`
	DisplayName string `json:"display_name" validate:"required,max=100"`
	Description string `json:"description" validate:"max=500"`
	Icon        string `json:"icon" validate:"max=50"`
	Color       string `json:"color" validate:"max=20"`
}

UpdateCategoryInput represents the input for updating a category.

type UpdateCommentInput

type UpdateCommentInput struct {
	Content string `validate:"required,min=1,max=10000"`
}

UpdateCommentInput represents the input for updating a comment.

type UpdateComponentInput

type UpdateComponentInput struct {
	Version            *string `validate:"omitempty,max=100"`
	PackageManager     *string `validate:"omitempty,max=50"`
	Namespace          *string `validate:"omitempty,max=255"`
	ManifestFile       *string `validate:"omitempty,max=255"`
	ManifestPath       *string `validate:"omitempty,max=500"`
	DependencyType     *string `validate:"omitempty,dependency_type"`
	License            *string `validate:"omitempty,max=100"`
	Status             *string `validate:"omitempty,component_status"`
	VulnerabilityCount *int    `validate:"omitempty,min=0"`
}

UpdateComponentInput represents the input for updating a component.

type UpdateCredentialInput

type UpdateCredentialInput struct {
	TenantID     shared.ID
	CredentialID string
	Name         string
	Description  string
	Data         any // One of the credential data types (nil to keep existing)
	ExpiresAt    *time.Time
}

UpdateCredentialInput contains input for updating a secretstore.

type UpdateCustomToolInput

type UpdateCustomToolInput struct {
	TenantID         string         `json:"tenant_id" validate:"required,uuid"`
	ToolID           string         `json:"tool_id" validate:"required,uuid"`
	DisplayName      string         `json:"display_name" validate:"max=100"`
	Description      string         `json:"description" validate:"max=1000"`
	InstallCmd       string         `json:"install_cmd" validate:"max=500"`
	UpdateCmd        string         `json:"update_cmd" validate:"max=500"`
	VersionCmd       string         `json:"version_cmd" validate:"max=500"`
	VersionRegex     string         `json:"version_regex" validate:"max=200"`
	ConfigSchema     map[string]any `json:"config_schema"`
	DefaultConfig    map[string]any `json:"default_config"`
	Capabilities     []string       `json:"capabilities" validate:"max=20,dive,max=50"`
	SupportedTargets []string       `json:"supported_targets" validate:"max=10,dive,max=50"`
	OutputFormats    []string       `json:"output_formats" validate:"max=10,dive,max=20"`
	DocsURL          string         `json:"docs_url" validate:"omitempty,url,max=500"`
	GithubURL        string         `json:"github_url" validate:"omitempty,url,max=500"`
	LogoURL          string         `json:"logo_url" validate:"omitempty,url,max=500"`
	Tags             []string       `json:"tags" validate:"max=20,dive,max=50"`
}

UpdateCustomToolInput represents the input for updating a tenant custom tool.

type UpdateExclusionInput

type UpdateExclusionInput struct {
	Reason    *string    `validate:"omitempty,max=1000"`
	ExpiresAt *time.Time `validate:"omitempty"`
}

UpdateExclusionInput represents the input for updating a scope exclusion.

type UpdateFindingStatusInput

type UpdateFindingStatusInput struct {
	Status     string `validate:"required,finding_status"`
	Resolution string `validate:"max=1000"`
	ActorID    string // Authenticated user ID from middleware (required for audit trail and resolved_by)
}

UpdateFindingStatusInput represents the input for updating a finding's status.

type UpdateGeneralSettingsInput

type UpdateGeneralSettingsInput struct {
	Timezone string `json:"timezone" validate:"omitempty"`
	Language string `json:"language" validate:"omitempty,oneof=en vi ja ko zh"`
	Industry string `json:"industry" validate:"omitempty,max=100"`
	Website  string `json:"website" validate:"omitempty,url,max=500"`
}

UpdateGeneralSettingsInput represents input for updating general settings.

type UpdateGroupInput

type UpdateGroupInput struct {
	Name        *string              `json:"name" validate:"omitempty,min=2,max=100"`
	Slug        *string              `json:"slug" validate:"omitempty,min=2,max=100,slug"`
	Description *string              `json:"description" validate:"omitempty,max=500"`
	Settings    *group.GroupSettings `json:"settings,omitempty"`
	IsActive    *bool                `json:"is_active,omitempty"`
}

UpdateGroupInput represents the input for updating a group.

type UpdateGroupMemberRoleInput

type UpdateGroupMemberRoleInput struct {
	GroupID string    `json:"-"`
	UserID  shared.ID `json:"-"`
	Role    string    `json:"role" validate:"required,oneof=owner lead member"`
}

UpdateMemberRoleInput represents the input for updating a member's role.

type UpdateIntegrationInput

type UpdateIntegrationInput struct {
	Name        *string
	Description *string
	Credentials *string
	BaseURL     *string

	// SCM-specific fields
	SCMOrganization *string
}

UpdateIntegrationInput represents the input for updating an integration.

type UpdateMemberRoleInput

type UpdateMemberRoleInput struct {
	Role string `json:"role" validate:"required,oneof=admin member viewer"`
}

UpdateMemberRoleInput represents the input for updating a member's role.

type UpdateNodeInput

type UpdateNodeInput struct {
	TenantID    shared.ID
	UserID      shared.ID
	WorkflowID  shared.ID
	NodeID      shared.ID
	Name        *string
	Description *string
	UIPositionX *float64
	UIPositionY *float64
	Config      *workflow.NodeConfig
}

UpdateNodeInput represents input for updating a node.

type UpdateNotificationIntegrationInput

type UpdateNotificationIntegrationInput struct {
	Name        *string
	Description *string
	Credentials *string // Webhook URL, Bot Token, etc.

	// Notification-specific fields
	ChannelID          *string
	ChannelName        *string
	EnabledSeverities  []string // Severity levels to notify on (nil = no change)
	EnabledEventTypes  []string // Event types to receive notifications for (nil = no change)
	MessageTemplate    *string
	IncludeDetails     *bool
	MinIntervalMinutes *int
}

UpdateNotificationIntegrationInput represents the input for updating a notification integration.

type UpdateOverrideInput

type UpdateOverrideInput struct {
	TenantID         string  `json:"tenant_id" validate:"required,uuid"`
	OverrideID       string  `json:"override_id" validate:"required,uuid"`
	RulePattern      string  `json:"rule_pattern" validate:"omitempty,min=1,max=500"`
	IsPattern        *bool   `json:"is_pattern"`
	Enabled          *bool   `json:"enabled"`
	SeverityOverride string  `json:"severity_override" validate:"omitempty,oneof=critical high medium low info"`
	AssetGroupID     string  `json:"asset_group_id" validate:"omitempty,uuid"`
	ScanProfileID    string  `json:"scan_profile_id" validate:"omitempty,uuid"`
	Reason           string  `json:"reason" validate:"max=1000"`
	ExpiresAt        *string `json:"expires_at"` // RFC3339 format, null to remove
}

UpdateOverrideInput represents the input for updating a rule override.

type UpdatePermissionSetInput

type UpdatePermissionSetInput struct {
	Name        *string `json:"name" validate:"omitempty,min=2,max=100"`
	Description *string `json:"description" validate:"omitempty,max=500"`
	IsActive    *bool   `json:"is_active,omitempty"`
}

UpdatePermissionSetInput represents the input for updating a permission set.

type UpdateProfileInput

type UpdateProfileInput struct {
	Name      *string `validate:"omitempty,max=255"`
	Phone     *string `validate:"omitempty,max=50"`
	AvatarURL *string `validate:"omitempty,max=500,url"`
}

UpdateProfileInput represents the input for updating a user profile.

type UpdateQualityGateInput

type UpdateQualityGateInput struct {
	TenantID    string                  `json:"tenant_id" validate:"required,uuid"`
	ProfileID   string                  `json:"profile_id" validate:"required,uuid"`
	QualityGate scanprofile.QualityGate `json:"quality_gate" validate:"required"`
}

UpdateQualityGateInput represents the input for updating a quality gate.

type UpdateRelationshipInput

type UpdateRelationshipInput struct {
	Description  *string  `json:"description" validate:"omitempty,max=1000"`
	Confidence   *string  `json:"confidence" validate:"omitempty"`
	ImpactWeight *int     `json:"impact_weight" validate:"omitempty,min=1,max=10"`
	Tags         []string `json:"tags" validate:"omitempty,max=20,dive,max=50"`
	MarkVerified bool     `json:"mark_verified"`
}

UpdateRelationshipInput represents the input for updating a relationship.

type UpdateRepositoryExtensionInput

type UpdateRepositoryExtensionInput struct {
	RepoID               *string          `validate:"omitempty,max=255"`
	FullName             *string          `validate:"omitempty,max=500"`
	SCMOrganization      *string          `validate:"omitempty,max=255"`
	CloneURL             *string          `validate:"omitempty,url"`
	WebURL               *string          `validate:"omitempty,url"`
	SSHURL               *string          `validate:"omitempty,max=500"`
	DefaultBranch        *string          `validate:"omitempty,max=100"`
	Visibility           *string          `validate:"omitempty"`
	Language             *string          `validate:"omitempty,max=50"`
	Languages            map[string]int64 `validate:"omitempty"`
	Topics               []string         `validate:"omitempty,max=50,dive,max=100"`
	Stars                *int             `validate:"omitempty,min=0"`
	Forks                *int             `validate:"omitempty,min=0"`
	Watchers             *int             `validate:"omitempty,min=0"`
	OpenIssues           *int             `validate:"omitempty,min=0"`
	ContributorsCount    *int             `validate:"omitempty,min=0"`
	SizeKB               *int             `validate:"omitempty,min=0"`
	BranchCount          *int             `validate:"omitempty,min=0"`
	ProtectedBranchCount *int             `validate:"omitempty,min=0"`
	ComponentCount       *int             `validate:"omitempty,min=0"`
}

UpdateRepositoryExtensionInput represents the input for updating a repository extension.

type UpdateRoleInput

type UpdateRoleInput struct {
	Name              *string  `json:"name" validate:"omitempty,min=2,max=100"`
	Description       *string  `json:"description" validate:"omitempty,max=500"`
	HierarchyLevel    *int     `json:"hierarchy_level" validate:"omitempty,min=0,max=100"`
	HasFullDataAccess *bool    `json:"has_full_data_access"`
	Permissions       []string `json:"permissions,omitempty"`
}

UpdateRoleInput represents the input for updating a role.

type UpdateSLAPolicyInput

type UpdateSLAPolicyInput struct {
	Name                *string `validate:"omitempty,min=1,max=100"`
	Description         *string `validate:"omitempty,max=500"`
	IsDefault           *bool
	CriticalDays        *int `validate:"omitempty,min=1,max=365"`
	HighDays            *int `validate:"omitempty,min=1,max=365"`
	MediumDays          *int `validate:"omitempty,min=1,max=365"`
	LowDays             *int `validate:"omitempty,min=1,max=365"`
	InfoDays            *int `validate:"omitempty,min=1,max=365"`
	WarningThresholdPct *int `validate:"omitempty,min=0,max=100"`
	EscalationEnabled   *bool
	EscalationConfig    map[string]any
	IsActive            *bool
}

UpdateSLAPolicyInput represents the input for updating an SLA policy.

type UpdateScanProfileInput

type UpdateScanProfileInput struct {
	TenantID           string                            `json:"tenant_id" validate:"required,uuid"`
	ProfileID          string                            `json:"profile_id" validate:"required,uuid"`
	Name               string                            `json:"name" validate:"omitempty,min=1,max=100"`
	Description        string                            `json:"description" validate:"max=500"`
	ToolsConfig        map[string]scanprofile.ToolConfig `json:"tools_config"`
	Intensity          string                            `json:"intensity" validate:"omitempty,oneof=low medium high"`
	MaxConcurrentScans int                               `json:"max_concurrent_scans" validate:"omitempty,min=1,max=100"`
	TimeoutSeconds     int                               `json:"timeout_seconds" validate:"omitempty,min=60,max=86400"`
	Tags               []string                          `json:"tags" validate:"max=20,dive,max=50"`
	QualityGate        *scanprofile.QualityGate          `json:"quality_gate"`
}

UpdateScanProfileInput represents the input for updating a scan profile.

type UpdateScanSessionInput

type UpdateScanSessionInput struct {
	Status             string         `json:"status" validate:"required,oneof=completed failed canceled"`
	ErrorMessage       string         `json:"error_message"`
	FindingsTotal      int            `json:"findings_total"`
	FindingsNew        int            `json:"findings_new"`
	FindingsFixed      int            `json:"findings_fixed"`
	FindingsBySeverity map[string]int `json:"findings_by_severity"`
}

UpdateScanSessionInput represents the input to update scan session status.

type UpdateScannerTemplateInput

type UpdateScannerTemplateInput struct {
	TenantID    string   `json:"tenant_id" validate:"required,uuid"`
	TemplateID  string   `json:"template_id" validate:"required,uuid"`
	Name        string   `json:"name" validate:"omitempty,min=1,max=255"`
	Description string   `json:"description" validate:"max=1000"`
	Content     string   `json:"content"` // Base64 encoded, optional
	Tags        []string `json:"tags" validate:"max=20,dive,max=50"`
}

UpdateScannerTemplateInput represents the input for updating a scanner template.

type UpdateScheduleInput

type UpdateScheduleInput struct {
	Name                 *string                `validate:"omitempty,min=1,max=200"`
	Description          *string                `validate:"omitempty,max=1000"`
	TargetScope          *string                `validate:"omitempty"`
	TargetIDs            []string               `validate:"omitempty,max=100"`
	TargetTags           []string               `validate:"omitempty,max=20,dive,max=50"`
	ScannerConfigs       map[string]interface{} `validate:"omitempty"`
	ScheduleType         *string                `validate:"omitempty"`
	CronExpression       *string                `validate:"omitempty,max=100"`
	IntervalHours        *int                   `validate:"omitempty,min=0,max=8760"`
	NotifyOnCompletion   *bool
	NotifyOnFindings     *bool
	NotificationChannels []string `validate:"omitempty,max=10,dive,max=50"`
}

UpdateScheduleInput represents the input for updating a scan schedule.

type UpdateSecuritySettingsInput

type UpdateSecuritySettingsInput struct {
	SSOEnabled        bool     `json:"sso_enabled"`
	SSOProvider       string   `json:"sso_provider" validate:"omitempty,oneof=saml oidc"`
	SSOConfigURL      string   `json:"sso_config_url" validate:"omitempty,url"`
	MFARequired       bool     `json:"mfa_required"`
	SessionTimeoutMin int      `json:"session_timeout_min" validate:"omitempty,min=15,max=480"`
	IPWhitelist       []string `json:"ip_whitelist"`
	AllowedDomains    []string `json:"allowed_domains"`
}

UpdateSecuritySettingsInput represents input for updating security settings.

type UpdateSourceInput

type UpdateSourceInput struct {
	TenantID            string `json:"tenant_id" validate:"required,uuid"`
	SourceID            string `json:"source_id" validate:"required,uuid"`
	Name                string `json:"name" validate:"min=1,max=255"`
	Description         string `json:"description" validate:"max=1000"`
	Config              []byte `json:"config"`
	CredentialsID       string `json:"credentials_id" validate:"omitempty,uuid"`
	SyncEnabled         *bool  `json:"sync_enabled"`
	SyncIntervalMinutes int    `json:"sync_interval_minutes" validate:"omitempty,min=5,max=10080"`
	Priority            int    `json:"priority" validate:"omitempty,min=0,max=1000"`
	Enabled             *bool  `json:"enabled"`
}

UpdateSourceInput represents the input for updating a rule source.

type UpdateTargetInput

type UpdateTargetInput struct {
	Description *string  `validate:"omitempty,max=1000"`
	Priority    *int     `validate:"omitempty,min=0,max=100"`
	Tags        []string `validate:"omitempty,max=20,dive,max=50"`
}

UpdateTargetInput represents the input for updating a scope target.

type UpdateTemplateSourceInput

type UpdateTemplateSourceInput struct {
	TenantID        string               `json:"tenant_id" validate:"required,uuid"`
	SourceID        string               `json:"source_id" validate:"required,uuid"`
	Name            string               `json:"name" validate:"omitempty,min=1,max=255"`
	Description     string               `json:"description" validate:"max=1000"`
	Enabled         *bool                `json:"enabled"`
	AutoSyncOnScan  *bool                `json:"auto_sync_on_scan"`
	CacheTTLMinutes *int                 `json:"cache_ttl_minutes" validate:"omitempty,min=0,max=10080"`
	GitConfig       *ts.GitSourceConfig  `json:"git_config,omitempty"`
	S3Config        *ts.S3SourceConfig   `json:"s3_config,omitempty"`
	HTTPConfig      *ts.HTTPSourceConfig `json:"http_config,omitempty"`
	CredentialID    *string              `json:"credential_id" validate:"omitempty,uuid"`
}

UpdateTemplateSourceInput represents the input for updating a template source.

type UpdateTenantInput

type UpdateTenantInput struct {
	Name        *string `json:"name" validate:"omitempty,min=2,max=100"`
	Slug        *string `json:"slug" validate:"omitempty,min=3,max=100,slug"`
	Description *string `json:"description" validate:"omitempty,max=500"`
	LogoURL     *string `json:"logo_url" validate:"omitempty,url,max=500"`
}

UpdateTenantInput represents the input for updating a tenant.

type UpdateTenantToolConfigInput

type UpdateTenantToolConfigInput struct {
	TenantID  string         `json:"tenant_id" validate:"required,uuid"`
	ToolID    string         `json:"tool_id" validate:"required,uuid"`
	Config    map[string]any `json:"config"`
	IsEnabled bool           `json:"is_enabled"`
	UpdatedBy string         `json:"updated_by" validate:"omitempty,uuid"`
}

UpdateTenantToolConfigInput represents the input for updating a tenant tool config.

type UpdateToolInput

type UpdateToolInput struct {
	ToolID           string         `json:"tool_id" validate:"required,uuid"`
	DisplayName      string         `json:"display_name" validate:"max=100"`
	Description      string         `json:"description" validate:"max=1000"`
	InstallCmd       string         `json:"install_cmd" validate:"max=500"`
	UpdateCmd        string         `json:"update_cmd" validate:"max=500"`
	VersionCmd       string         `json:"version_cmd" validate:"max=500"`
	VersionRegex     string         `json:"version_regex" validate:"max=200"`
	ConfigSchema     map[string]any `json:"config_schema"`
	DefaultConfig    map[string]any `json:"default_config"`
	Capabilities     []string       `json:"capabilities" validate:"max=20,dive,max=50"`
	SupportedTargets []string       `json:"supported_targets" validate:"max=10,dive,max=50"`
	OutputFormats    []string       `json:"output_formats" validate:"max=10,dive,max=20"`
	DocsURL          string         `json:"docs_url" validate:"omitempty,url,max=500"`
	GithubURL        string         `json:"github_url" validate:"omitempty,url,max=500"`
	LogoURL          string         `json:"logo_url" validate:"omitempty,url,max=500"`
	Tags             []string       `json:"tags" validate:"max=20,dive,max=50"`
}

UpdateToolInput represents the input for updating a tool.

type UpdateToolVersionInput

type UpdateToolVersionInput struct {
	ToolID         string `json:"tool_id" validate:"required,uuid"`
	CurrentVersion string `json:"current_version" validate:"max=50"`
	LatestVersion  string `json:"latest_version" validate:"max=50"`
}

UpdateToolVersionInput represents the input for updating tool version.

type UpdateVulnerabilityInput

type UpdateVulnerabilityInput struct {
	Title            *string  `validate:"omitempty,min=1,max=500"`
	Description      *string  `validate:"omitempty,max=10000"`
	Severity         *string  `validate:"omitempty,severity"`
	CVSSScore        *float64 `validate:"omitempty,min=0,max=10"`
	CVSSVector       *string  `validate:"omitempty,max=100"`
	EPSSScore        *float64 `validate:"omitempty,min=0,max=1"`
	EPSSPercentile   *float64 `validate:"omitempty,min=0,max=1"`
	ExploitAvailable *bool
	ExploitMaturity  *string  `validate:"omitempty,exploit_maturity"`
	FixedVersions    []string `validate:"omitempty,max=50,dive,max=100"`
	Remediation      *string  `validate:"omitempty,max=5000"`
	Status           *string  `validate:"omitempty,vulnerability_status"`
}

UpdateVulnerabilityInput represents the input for updating a vulnerability.

type UpdateWebhookInput

type UpdateWebhookInput struct {
	Name              *string  `json:"name" validate:"omitempty,min=1,max=255"`
	Description       *string  `json:"description" validate:"omitempty,max=1000"`
	URL               *string  `json:"url" validate:"omitempty,url,max=1000"`
	Secret            *string  `json:"secret" validate:"omitempty,max=500"`
	EventTypes        []string `json:"event_types" validate:"omitempty,min=1,max=20"`
	SeverityThreshold *string  `json:"severity_threshold" validate:"omitempty,oneof=critical high medium low info"`
	MaxRetries        *int     `json:"max_retries" validate:"omitempty,min=0,max=10"`
	RetryInterval     *int     `json:"retry_interval_seconds" validate:"omitempty,min=0,max=3600"`
}

UpdateWebhookInput represents input for updating a webhook.

type UpdateWorkflowGraphInput

type UpdateWorkflowGraphInput struct {
	TenantID    shared.ID
	UserID      shared.ID
	WorkflowID  shared.ID
	Name        *string           // Optional: update name
	Description *string           // Optional: update description
	Tags        []string          // Optional: update tags (nil = no change)
	Nodes       []CreateNodeInput // Required: new nodes (replaces all existing)
	Edges       []CreateEdgeInput // Required: new edges (replaces all existing)
}

UpdateWorkflowGraphInput represents input for updating a workflow's graph (nodes and edges).

type UpdateWorkflowInput

type UpdateWorkflowInput struct {
	TenantID    shared.ID
	UserID      shared.ID
	WorkflowID  shared.ID
	Name        *string
	Description *string
	Tags        []string
	IsActive    *bool
}

UpdateWorkflowInput represents input for updating a workflow.

type UserInfoProvider

type UserInfoProvider interface {
	GetUserNameByID(ctx context.Context, id shared.ID) (string, error)
}

UserInfoProvider defines methods to fetch user information for emails.

type UserService

type UserService struct {
	// contains filtered or unexported fields
}

UserService handles user-related business operations.

func NewUserService

func NewUserService(repo user.Repository, log *logger.Logger) *UserService

NewUserService creates a new UserService.

func (*UserService) ActivateUser

func (s *UserService) ActivateUser(ctx context.Context, userID string) (*user.User, error)

ActivateUser activates a user account.

func (*UserService) GetByEmail

func (s *UserService) GetByEmail(ctx context.Context, email string) (*user.User, error)

GetByEmail retrieves a user by their email.

func (*UserService) GetByIDs

func (s *UserService) GetByIDs(ctx context.Context, ids []shared.ID) ([]*user.User, error)

GetByIDs retrieves multiple users by their IDs (shared.ID format).

func (*UserService) GetByKeycloakID

func (s *UserService) GetByKeycloakID(ctx context.Context, keycloakID string) (*user.User, error)

GetByKeycloakID retrieves a user by their Keycloak ID.

func (*UserService) GetOrCreateFromLocalToken

func (s *UserService) GetOrCreateFromLocalToken(ctx context.Context, userID, email, name string) (*user.User, error)

GetOrCreateFromLocalToken gets an existing user by ID from local JWT claims. This is used by the UserSync middleware for local auth.

IMPORTANT: For OSS/local auth, we do NOT auto-create users from JWT tokens. Users MUST register through the /api/v1/auth/register endpoint first. This prevents creating passwordless users that cannot login.

func (*UserService) GetProfile

func (s *UserService) GetProfile(ctx context.Context, userID string) (*user.User, error)

GetProfile retrieves a user's profile by ID.

func (*UserService) GetUsersByIDs

func (s *UserService) GetUsersByIDs(ctx context.Context, userIDs []string) ([]*user.User, error)

GetUsersByIDs retrieves multiple users by their IDs (string format).

func (*UserService) SetSessionService

func (s *UserService) SetSessionService(sessionService *SessionService)

SetSessionService sets the session service for revoking sessions. This enables immediate session revocation when user is suspended.

func (*UserService) SuspendUser

func (s *UserService) SuspendUser(ctx context.Context, userID string) (*user.User, error)

SuspendUser suspends a user account. This also revokes all active sessions to immediately block access.

func (*UserService) SyncFromKeycloak

func (s *UserService) SyncFromKeycloak(ctx context.Context, claims *keycloak.Claims) (*user.User, error)

SyncFromKeycloak syncs a user from Keycloak claims. This is called by middleware on each authenticated request. It creates the user if not exists, or updates their info if exists.

func (*UserService) UpdatePreferences

func (s *UserService) UpdatePreferences(ctx context.Context, userID string, prefs user.Preferences) (*user.User, error)

UpdatePreferences updates a user's preferences.

func (*UserService) UpdateProfile

func (s *UserService) UpdateProfile(ctx context.Context, userID string, input UpdateProfileInput) (*user.User, error)

UpdateProfile updates a user's profile.

type ValidateTemplateInput

type ValidateTemplateInput struct {
	TemplateType string `json:"template_type" validate:"required,oneof=nuclei semgrep gitleaks"`
	Content      string `json:"content" validate:"required"` // Base64 encoded
}

ValidateTemplateInput represents the input for validating template content.

type ValidationError

type ValidationError struct {
	Field   string
	Message string
	Code    string
}

ValidationError represents a validation error.

type ValidationResult

type ValidationResult struct {
	Valid  bool
	Errors []ValidationError
}

ValidationResult represents the result of a validation.

type VulnerabilityService

type VulnerabilityService struct {
	// contains filtered or unexported fields
}

VulnerabilityService handles vulnerability-related business operations.

func NewVulnerabilityService

func NewVulnerabilityService(
	vulnRepo vulnerability.VulnerabilityRepository,
	findingRepo vulnerability.FindingRepository,
	log *logger.Logger,
) *VulnerabilityService

NewVulnerabilityService creates a new VulnerabilityService.

func (*VulnerabilityService) AddFindingComment

func (s *VulnerabilityService) AddFindingComment(ctx context.Context, tenantID, findingID, authorID, content string) (*vulnerability.FindingComment, error)

AddFindingComment adds a comment to a finding. tenantID is used for IDOR prevention and activity logging.

func (*VulnerabilityService) AssignFinding

func (s *VulnerabilityService) AssignFinding(ctx context.Context, findingID, tenantID, userID, assignerID string) (*vulnerability.Finding, error)

AssignFinding assigns a finding to a user.

func (*VulnerabilityService) BulkAssignFindings

func (s *VulnerabilityService) BulkAssignFindings(ctx context.Context, tenantID string, input BulkAssignInput) (*BulkUpdateResult, error)

BulkAssignFindings assigns multiple findings to a user.

func (*VulnerabilityService) BulkUpdateFindingsStatus

func (s *VulnerabilityService) BulkUpdateFindingsStatus(ctx context.Context, tenantID string, input BulkUpdateStatusInput) (*BulkUpdateResult, error)

BulkUpdateFindingsStatus updates the status of multiple findings.

func (*VulnerabilityService) ClassifyFinding

func (s *VulnerabilityService) ClassifyFinding(ctx context.Context, findingID, tenantID string, input ClassifyFindingInput) (*vulnerability.Finding, error)

ClassifyFinding sets classification data on a finding.

func (*VulnerabilityService) CountAssetFindings

func (s *VulnerabilityService) CountAssetFindings(
	ctx context.Context,
	tenantID string,
	assetID string,
) (int64, error)

CountAssetFindings counts findings for an asset. tenantID is used for IDOR prevention - ensures the findings belong to the caller's tenant.

func (*VulnerabilityService) CountOpenAssetFindings

func (s *VulnerabilityService) CountOpenAssetFindings(
	ctx context.Context,
	tenantID string,
	assetID string,
) (int64, error)

CountOpenAssetFindings counts open findings for an asset. tenantID is used for IDOR prevention - ensures the findings belong to the caller's tenant.

func (*VulnerabilityService) CreateFinding

CreateFinding creates a new finding.

func (*VulnerabilityService) CreateVulnerability

CreateVulnerability creates a new vulnerability.

func (*VulnerabilityService) DeleteAssetFindings

func (s *VulnerabilityService) DeleteAssetFindings(
	ctx context.Context,
	tenantID string,
	assetID string,
) error

DeleteAssetFindings deletes all findings for an asset. tenantID is used for IDOR prevention - ensures the findings belong to the caller's tenant.

func (*VulnerabilityService) DeleteFinding

func (s *VulnerabilityService) DeleteFinding(ctx context.Context, findingID string, tenantID string) error

DeleteFinding deletes a finding by ID. tenantID is used for IDOR prevention - ensures the finding belongs to the caller's tenant.

func (*VulnerabilityService) DeleteFindingComment

func (s *VulnerabilityService) DeleteFindingComment(ctx context.Context, tenantID, commentID, authorID string) error

DeleteFindingComment deletes a comment. tenantID is used for activity logging.

func (*VulnerabilityService) DeleteVulnerability

func (s *VulnerabilityService) DeleteVulnerability(ctx context.Context, vulnID string) error

DeleteVulnerability deletes a vulnerability by ID.

func (*VulnerabilityService) GetFinding

func (s *VulnerabilityService) GetFinding(ctx context.Context, tenantID, findingID string) (*vulnerability.Finding, error)

GetFinding retrieves a finding by ID. tenantID is used for IDOR prevention - ensures the finding belongs to the caller's tenant.

func (*VulnerabilityService) GetFindingCountsByScanID

func (s *VulnerabilityService) GetFindingCountsByScanID(ctx context.Context, tenantID, scanID string) (vulnerability.SeverityCounts, error)

GetFindingCountsByScanID returns the count of findings by severity for a scan. Used for quality gate evaluation.

func (*VulnerabilityService) GetFindingStats

func (s *VulnerabilityService) GetFindingStats(ctx context.Context, tenantID string) (*vulnerability.FindingStats, error)

GetFindingStats retrieves aggregated statistics for findings of a tenant.

func (*VulnerabilityService) GetVulnerability

func (s *VulnerabilityService) GetVulnerability(ctx context.Context, vulnID string) (*vulnerability.Vulnerability, error)

GetVulnerability retrieves a vulnerability by ID.

func (*VulnerabilityService) GetVulnerabilityByCVE

func (s *VulnerabilityService) GetVulnerabilityByCVE(ctx context.Context, cveID string) (*vulnerability.Vulnerability, error)

GetVulnerabilityByCVE retrieves a vulnerability by CVE ID.

func (*VulnerabilityService) ListAssetFindings

func (s *VulnerabilityService) ListAssetFindings(
	ctx context.Context,
	tenantID string,
	assetID string,
	sort string,
	page,
	perPage int,
) (pagination.Result[*vulnerability.Finding], error)

ListAssetFindings retrieves findings for a specific asset. tenantID is used for IDOR prevention - ensures the findings belong to the caller's tenant.

func (*VulnerabilityService) ListFindingComments

func (s *VulnerabilityService) ListFindingComments(ctx context.Context, findingID string) ([]*vulnerability.FindingComment, error)

ListFindingComments retrieves all comments for a finding.

func (*VulnerabilityService) ListFindings

ListFindings retrieves findings with filtering and pagination.

func (*VulnerabilityService) ListVulnerabilities

ListVulnerabilities retrieves vulnerabilities with filtering and pagination.

func (*VulnerabilityService) SetAITriageService

func (s *VulnerabilityService) SetAITriageService(svc *AITriageService)

SetAITriageService sets the AI triage service for auto-triage on finding creation.

func (*VulnerabilityService) SetActivityService

func (s *VulnerabilityService) SetActivityService(svc *FindingActivityService)

SetActivityService sets the activity service for audit trail tracking. When set, the service will automatically record activities for finding changes.

func (*VulnerabilityService) SetCommentRepository

func (s *VulnerabilityService) SetCommentRepository(repo vulnerability.FindingCommentRepository)

SetCommentRepository sets the comment repository for comment operations. This is optional and can be called after service creation.

func (*VulnerabilityService) SetDataFlowRepository

func (s *VulnerabilityService) SetDataFlowRepository(repo vulnerability.DataFlowRepository)

SetDataFlowRepository sets the data flow repository for loading data flow traces.

func (*VulnerabilityService) SetFindingNotifier

func (s *VulnerabilityService) SetFindingNotifier(notifier FindingNotifier)

SetFindingNotifier sets the notifier for new findings. Deprecated: Use SetNotificationService for reliable transactional notifications.

func (*VulnerabilityService) SetFindingTags

func (s *VulnerabilityService) SetFindingTags(ctx context.Context, findingID, tenantID string, tags []string) (*vulnerability.Finding, error)

SetFindingTags sets tags on a finding.

func (*VulnerabilityService) SetNotificationService

func (s *VulnerabilityService) SetNotificationService(db *sql.DB, svc *NotificationService)

SetNotificationService sets the notification service for transactional outbox pattern. When set, notifications are enqueued in the same transaction as finding creation, ensuring reliable delivery even if the server crashes.

func (*VulnerabilityService) SetUserRepository

func (s *VulnerabilityService) SetUserRepository(repo user.Repository)

SetUserRepository sets the user repository for user lookup (e.g., for activity recording).

func (*VulnerabilityService) TriageFinding

func (s *VulnerabilityService) TriageFinding(ctx context.Context, findingID, tenantID, userID, reason string) (*vulnerability.Finding, error)

TriageFinding confirms a finding (triage = confirm the finding is real). This is a convenience method that transitions status from "new" to "confirmed". For other status changes, use UpdateFindingStatus.

func (*VulnerabilityService) UnassignFinding

func (s *VulnerabilityService) UnassignFinding(ctx context.Context, findingID, tenantID, actorID string) (*vulnerability.Finding, error)

UnassignFinding removes the assignment from a finding.

func (*VulnerabilityService) UpdateFindingComment

func (s *VulnerabilityService) UpdateFindingComment(ctx context.Context, tenantID, commentID, authorID, content string) (*vulnerability.FindingComment, error)

UpdateFindingComment updates a comment's content. tenantID is used for activity logging.

func (*VulnerabilityService) UpdateFindingSeverity

func (s *VulnerabilityService) UpdateFindingSeverity(ctx context.Context, findingID, tenantID, severityStr, actorID string) (*vulnerability.Finding, error)

UpdateFindingSeverity updates a finding's severity.

func (*VulnerabilityService) UpdateFindingStatus

func (s *VulnerabilityService) UpdateFindingStatus(ctx context.Context, findingID string, tenantID string, input UpdateFindingStatusInput) (*vulnerability.Finding, error)

UpdateFindingStatus updates a finding's status. tenantID is used for IDOR prevention - ensures the finding belongs to the caller's tenant.

func (*VulnerabilityService) UpdateVulnerability

UpdateVulnerability updates an existing vulnerability.

func (*VulnerabilityService) VerifyFinding

func (s *VulnerabilityService) VerifyFinding(ctx context.Context, findingID, tenantID, userID string) (*vulnerability.Finding, error)

VerifyFinding marks a resolved finding as verified.

type WebhookService

type WebhookService struct {
	// contains filtered or unexported fields
}

WebhookService provides business logic for webhook management.

func NewWebhookService

func NewWebhookService(repo webhook.Repository, encryptor crypto.Encryptor, log *logger.Logger) *WebhookService

NewWebhookService creates a new WebhookService.

func (*WebhookService) CreateWebhook

func (s *WebhookService) CreateWebhook(ctx context.Context, input CreateWebhookInput) (*webhook.Webhook, error)

CreateWebhook creates a new webhook.

func (*WebhookService) DeleteWebhook

func (s *WebhookService) DeleteWebhook(ctx context.Context, id, tenantIDStr string) error

DeleteWebhook deletes a webhook. Tenant isolation enforced at DB level.

func (*WebhookService) DisableWebhook

func (s *WebhookService) DisableWebhook(ctx context.Context, id, tenantIDStr string) (*webhook.Webhook, error)

DisableWebhook disables a webhook.

func (*WebhookService) EnableWebhook

func (s *WebhookService) EnableWebhook(ctx context.Context, id, tenantIDStr string) (*webhook.Webhook, error)

EnableWebhook enables a webhook.

func (*WebhookService) GetWebhook

func (s *WebhookService) GetWebhook(ctx context.Context, id, tenantIDStr string) (*webhook.Webhook, error)

GetWebhook retrieves a webhook by ID within a tenant.

func (*WebhookService) ListDeliveries

ListDeliveries retrieves delivery history for a webhook.

func (*WebhookService) ListWebhooks

func (s *WebhookService) ListWebhooks(ctx context.Context, input ListWebhooksInput) (webhook.ListResult, error)

ListWebhooks retrieves a paginated list of webhooks.

func (*WebhookService) UpdateWebhook

func (s *WebhookService) UpdateWebhook(ctx context.Context, id, tenantIDStr string, input UpdateWebhookInput) (*webhook.Webhook, error)

UpdateWebhook updates a webhook.

type WorkflowEventDispatcher

type WorkflowEventDispatcher struct {
	// contains filtered or unexported fields
}

WorkflowEventDispatcher dispatches events to matching workflows. It evaluates trigger configurations to determine which workflows should run.

func NewWorkflowEventDispatcher

func NewWorkflowEventDispatcher(
	workflowRepo workflow.WorkflowRepository,
	nodeRepo workflow.NodeRepository,
	service *WorkflowService,
	log *logger.Logger,
) *WorkflowEventDispatcher

NewWorkflowEventDispatcher creates a new workflow event dispatcher.

func (*WorkflowEventDispatcher) DispatchAITriageCompleted

func (d *WorkflowEventDispatcher) DispatchAITriageCompleted(
	ctx context.Context,
	tenantID, findingID, triageID shared.ID,
	triageData map[string]any,
)

DispatchAITriageCompleted is a convenience method for dispatching ai_triage_completed events.

func (*WorkflowEventDispatcher) DispatchAITriageEvent

func (d *WorkflowEventDispatcher) DispatchAITriageEvent(ctx context.Context, event AITriageEvent) error

DispatchAITriageEvent dispatches an AI triage event to matching workflows.

func (*WorkflowEventDispatcher) DispatchAITriageFailed

func (d *WorkflowEventDispatcher) DispatchAITriageFailed(
	ctx context.Context,
	tenantID, findingID, triageID shared.ID,
	errorMessage string,
)

DispatchAITriageFailed is a convenience method for dispatching ai_triage_failed events.

func (*WorkflowEventDispatcher) DispatchFindingEvent

func (d *WorkflowEventDispatcher) DispatchFindingEvent(ctx context.Context, event FindingEvent) error

DispatchFindingEvent dispatches a finding event to matching workflows. It evaluates all active workflows with matching trigger types and filters.

func (*WorkflowEventDispatcher) DispatchFindingsCreated

func (d *WorkflowEventDispatcher) DispatchFindingsCreated(ctx context.Context, tenantID shared.ID, findings []*vulnerability.Finding)

DispatchFindingsCreated dispatches finding_created events for a batch of newly created findings. This is called by the ingest service when findings are created during ingestion. Events are dispatched asynchronously to avoid blocking the ingestion pipeline.

Optimizations applied: - Batch workflow matching: finds workflows once for all findings instead of per-finding - Limits findings per dispatch to prevent memory exhaustion - Proper goroutine recovery to prevent panics from crashing the service - Deduplication: each workflow is triggered once per batch (not per finding)

type WorkflowEventDispatcherInterface

type WorkflowEventDispatcherInterface interface {
	DispatchAITriageCompleted(ctx context.Context, tenantID, findingID, triageID shared.ID, triageData map[string]any)
	DispatchAITriageFailed(ctx context.Context, tenantID, findingID, triageID shared.ID, errorMessage string)
}

WorkflowEventDispatcherInterface defines the interface for dispatching workflow events. This avoids circular dependency with workflow package.

type WorkflowExecutor

type WorkflowExecutor struct {
	// contains filtered or unexported fields
}

WorkflowExecutor handles the execution of workflow runs. It processes nodes in topological order, handling conditions, actions, and notifications.

SECURITY: Includes tenant isolation, execution timeout, and rate limiting.

func NewWorkflowExecutor

func NewWorkflowExecutor(
	workflowRepo workflow.WorkflowRepository,
	runRepo workflow.RunRepository,
	nodeRunRepo workflow.NodeRunRepository,
	log *logger.Logger,
	opts ...WorkflowExecutorOption,
) *WorkflowExecutor

NewWorkflowExecutor creates a new WorkflowExecutor.

func (*WorkflowExecutor) Execute

func (e *WorkflowExecutor) Execute(ctx context.Context, runID shared.ID) error

Execute executes a workflow run. This is the main entry point for workflow execution. SEC-WF05: Includes tenant isolation check.

func (*WorkflowExecutor) ExecuteAsync

func (e *WorkflowExecutor) ExecuteAsync(runID shared.ID)

ExecuteAsync executes a workflow run asynchronously with rate limiting. SEC-WF07: Uses semaphore to limit concurrent executions.

func (*WorkflowExecutor) ExecuteAsyncWithTenant

func (e *WorkflowExecutor) ExecuteAsyncWithTenant(runID shared.ID, tenantID shared.ID)

ExecuteAsyncWithTenant executes a workflow run asynchronously with tenant context. SEC-WF07: Uses semaphore to limit concurrent executions and passes tenant for isolation. SEC-WF10: Also enforces per-tenant rate limiting. SEC-WF12: Includes panic recovery to prevent resource leaks.

func (*WorkflowExecutor) ExecuteWithTenant

func (e *WorkflowExecutor) ExecuteWithTenant(ctx context.Context, runID shared.ID, expectedTenantID shared.ID) error

ExecuteWithTenant executes a workflow run with explicit tenant verification. SEC-WF05: If expectedTenantID is provided, verifies the run belongs to that tenant.

func (*WorkflowExecutor) RegisterActionHandler

func (e *WorkflowExecutor) RegisterActionHandler(actionType workflow.ActionType, handler ActionHandler)

RegisterActionHandler registers a custom action handler.

type WorkflowExecutorConfig

type WorkflowExecutorConfig struct {
	// MaxNodeExecutionTime is the maximum time allowed for a single node execution.
	MaxNodeExecutionTime time.Duration

	// MaxConcurrentNodes is the maximum nodes that can execute concurrently.
	MaxConcurrentNodes int
}

WorkflowExecutorConfig holds configuration for the executor.

func DefaultWorkflowExecutorConfig

func DefaultWorkflowExecutorConfig() WorkflowExecutorConfig

DefaultWorkflowExecutorConfig returns default configuration.

type WorkflowExecutorOption

type WorkflowExecutorOption func(*WorkflowExecutor)

WorkflowExecutorOption is a functional option for WorkflowExecutor.

func WithExecutorAuditService

func WithExecutorAuditService(svc *AuditService) WorkflowExecutorOption

WithExecutorAuditService sets the audit service.

func WithExecutorDB

func WithExecutorDB(db *sql.DB) WorkflowExecutorOption

WithExecutorDB sets the database connection for transactions.

func WithExecutorIntegrationService

func WithExecutorIntegrationService(svc *IntegrationService) WorkflowExecutorOption

WithExecutorIntegrationService sets the integration service.

func WithExecutorNotificationService

func WithExecutorNotificationService(svc *NotificationService) WorkflowExecutorOption

WithExecutorNotificationService sets the notification service.

type WorkflowService

type WorkflowService struct {
	// contains filtered or unexported fields
}

WorkflowService handles workflow-related business operations.

func NewWorkflowService

func NewWorkflowService(
	workflowRepo workflow.WorkflowRepository,
	nodeRepo workflow.NodeRepository,
	edgeRepo workflow.EdgeRepository,
	runRepo workflow.RunRepository,
	nodeRunRepo workflow.NodeRunRepository,
	log *logger.Logger,
	opts ...WorkflowServiceOption,
) *WorkflowService

NewWorkflowService creates a new WorkflowService.

func (*WorkflowService) AddEdge

func (s *WorkflowService) AddEdge(ctx context.Context, input AddEdgeInput) (*workflow.Edge, error)

AddEdge adds an edge to a workflow.

func (*WorkflowService) AddNode

func (s *WorkflowService) AddNode(ctx context.Context, input AddNodeInput) (*workflow.Node, error)

AddNode adds a node to a workflow.

func (*WorkflowService) CancelRun

func (s *WorkflowService) CancelRun(ctx context.Context, tenantID, userID, runID shared.ID) error

CancelRun cancels a running workflow.

func (*WorkflowService) CreateWorkflow

func (s *WorkflowService) CreateWorkflow(ctx context.Context, input CreateWorkflowInput) (*workflow.Workflow, error)

CreateWorkflow creates a new workflow with its nodes and edges.

func (*WorkflowService) DeleteEdge

func (s *WorkflowService) DeleteEdge(ctx context.Context, tenantID, workflowID, edgeID shared.ID) error

DeleteEdge deletes an edge from a workflow.

func (*WorkflowService) DeleteNode

func (s *WorkflowService) DeleteNode(ctx context.Context, tenantID, workflowID, nodeID shared.ID) error

DeleteNode deletes a node from a workflow.

func (*WorkflowService) DeleteWorkflow

func (s *WorkflowService) DeleteWorkflow(ctx context.Context, tenantID, userID, workflowID shared.ID) error

DeleteWorkflow deletes a workflow and all its nodes/edges.

func (*WorkflowService) GetRun

func (s *WorkflowService) GetRun(ctx context.Context, tenantID, runID shared.ID) (*workflow.Run, error)

GetRun retrieves a workflow run with its node runs.

func (*WorkflowService) GetWorkflow

func (s *WorkflowService) GetWorkflow(ctx context.Context, tenantID, workflowID shared.ID) (*workflow.Workflow, error)

GetWorkflow retrieves a workflow by ID with its graph.

func (*WorkflowService) ListRuns

ListRuns lists workflow runs.

func (*WorkflowService) ListWorkflows

ListWorkflows lists workflows with filters.

func (*WorkflowService) TriggerWorkflow

func (s *WorkflowService) TriggerWorkflow(ctx context.Context, input TriggerWorkflowInput) (*workflow.Run, error)

TriggerWorkflow triggers a workflow execution.

func (*WorkflowService) UpdateNode

func (s *WorkflowService) UpdateNode(ctx context.Context, input UpdateNodeInput) (*workflow.Node, error)

UpdateNode updates a workflow node.

func (*WorkflowService) UpdateWorkflow

func (s *WorkflowService) UpdateWorkflow(ctx context.Context, input UpdateWorkflowInput) (*workflow.Workflow, error)

UpdateWorkflow updates a workflow.

func (*WorkflowService) UpdateWorkflowGraph

func (s *WorkflowService) UpdateWorkflowGraph(ctx context.Context, input UpdateWorkflowGraphInput) (*workflow.Workflow, error)

UpdateWorkflowGraph atomically replaces a workflow's graph (nodes and edges). This is a complete replacement operation - all existing nodes/edges are deleted and new ones are created in a single atomic operation.

type WorkflowServiceOption

type WorkflowServiceOption func(*WorkflowService)

WorkflowServiceOption is a functional option for WorkflowService.

func WithWorkflowAuditService

func WithWorkflowAuditService(auditService *AuditService) WorkflowServiceOption

WithWorkflowAuditService sets the audit service for WorkflowService.

func WithWorkflowExecutor

func WithWorkflowExecutor(executor *WorkflowExecutor) WorkflowServiceOption

WithWorkflowExecutor sets the workflow executor for WorkflowService.

Directories

Path Synopsis
Package ingest provides unified ingestion of assets and findings from various formats.
Package ingest provides unified ingestion of assets and findings from various formats.
Package pipeline provides adapters to bridge app types with pipeline interfaces.
Package pipeline provides adapters to bridge app types with pipeline interfaces.
Package validators provides template validation for different scanner types.
Package validators provides template validation for different scanner types.

Jump to

Keyboard shortcuts

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