app

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: GPL-3.0 Imports: 97 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 (
	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 (
	ErrSSOTenantNotFound      = errors.New("tenant not found")
	ErrSSONoActiveProviders   = errors.New("no active SSO providers for this tenant")
	ErrSSOProviderNotFound    = errors.New("SSO provider not configured for this tenant")
	ErrSSOProviderInactive    = errors.New("SSO provider is not active")
	ErrSSOInvalidState        = errors.New("invalid SSO state token")
	ErrSSOExchangeFailed      = errors.New("failed to exchange authorization code")
	ErrSSOUserInfoFailed      = errors.New("failed to get user info from SSO provider")
	ErrSSODomainNotAllowed    = errors.New("email domain not allowed for this SSO provider")
	ErrSSODecryptionFailed    = errors.New("failed to decrypt client secret")
	ErrSSOProviderUnsupported = errors.New("unsupported SSO provider type")
	ErrSSOInvalidRedirectURI  = errors.New("invalid redirect URI")
	ErrSSOInvalidDefaultRole  = errors.New("invalid default role")
	ErrSSONoEmail             = errors.New("SSO provider did not return an email address")
)

SSO 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 MapTenantToAssetScoringConfig added in v0.1.2

func MapTenantToAssetScoringConfig(s *tenant.RiskScoringSettings) *asset.RiskScoringConfig

MapTenantToAssetScoringConfig maps tenant.RiskScoringSettings to asset.RiskScoringConfig.

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 SMTPConfigFromIntegrationMeta added in v0.1.4

func SMTPConfigFromIntegrationMeta() map[string]string

SMTPConfigFromIntegrationMeta extracts SMTP config fields for creating an email integration. Used by the UI when creating/editing an email notification integration.

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 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(_ context.Context, _ string) (int64, error)

GetPlanTokenLimit returns the monthly token limit for a tenant based on their plan. OSS Edition: Always returns -1 (unlimited).

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) 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 AgentConfigTemplateService added in v0.1.5

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

AgentConfigTemplateService renders agent configuration templates (yaml, env, docker, cli) from filesystem-loaded templates.

Templates live in <templates_dir>/{yaml,env,docker,cli}.tmpl and use Go text/template syntax. Operators can edit the .tmpl files in place without rebuilding the API or frontend — changes are picked up on restart, or live if Reload() is called.

The service caches parsed templates after first load. Call Reload() to pick up file changes without restart.

func NewAgentConfigTemplateService added in v0.1.5

func NewAgentConfigTemplateService(templatesDir string, log *logger.Logger) *AgentConfigTemplateService

NewAgentConfigTemplateService loads templates from the given directory. If the directory doesn't exist or any template fails to parse, the service falls back to built-in defaults so the API never fails to start.

func (*AgentConfigTemplateService) Reload added in v0.1.5

func (s *AgentConfigTemplateService) Reload() error

Reload re-reads all template files from disk. Safe to call at runtime.

func (*AgentConfigTemplateService) Render added in v0.1.5

Render renders all four template formats with the given agent data. Returns user-friendly content (no internal errors leaked).

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) GetPlatformStats added in v0.1.2

func (s *AgentService) GetPlatformStats(ctx context.Context, tenantID shared.ID) (*PlatformStatsOutput, error)

GetPlatformStats returns aggregate statistics for platform agents accessible to the tenant.

func (*AgentService) GetTenantAgentStats added in v0.1.5

func (s *AgentService) GetTenantAgentStats(ctx context.Context, tenantID string) (*agent.TenantAgentStats, error)

GetTenantAgentStats returns aggregate statistics for the tenant's agents. Computed via SQL aggregation in a single round-trip — replaces the previous client-side .filter().length pattern that only saw the current page of results.

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 AgentTemplateData added in v0.1.5

type AgentTemplateData struct {
	Agent       *agent.Agent
	APIKey      string // May be empty if not freshly created/regenerated
	BaseURL     string // Public API URL agents should connect to
	GeneratedAt string // RFC3339 timestamp
}

AgentTemplateData is the data passed to every agent config template.

type ApproveStatusInput added in v0.1.2

type ApproveStatusInput struct {
	TenantID   string `json:"tenant_id" validate:"required,uuid"`
	ApprovalID string `json:"approval_id" validate:"required,uuid"`
	ApprovedBy string `json:"approved_by" validate:"required,uuid"`
}

ApproveStatusInput represents the input for approving a status change.

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, tenantID string, 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, tenantIDStr string, id shared.ID) (*assetgroup.AssetGroup, error)

GetAssetGroup retrieves an asset group by tenant and 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) SetScopeRuleReconciler added in v0.1.2

func (s *AssetGroupService) SetScopeRuleReconciler(fn ScopeRuleGroupReconcilerFunc)

SetScopeRuleReconciler sets the scope rule reconciler callback. Called when asset group membership changes to re-evaluate scope rules.

func (*AssetGroupService) UpdateAssetGroup

func (s *AssetGroupService) UpdateAssetGroup(ctx context.Context, tenantIDStr string, 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) CreateRelationshipBatch added in v0.1.5

func (s *AssetRelationshipService) CreateRelationshipBatch(
	ctx context.Context,
	tenantID, sourceAssetID string,
	items []BatchCreateRelationshipInput,
) (*BatchCreateRelationshipResult, error)

CreateRelationshipBatch creates many relationships from one source asset in a single call. The source asset and tenant are validated ONCE for the whole batch (instead of per-item like the singleton CreateRelationship), and each item's outcome is reported separately so the caller can produce a per-target success/failure UI.

Semantics intentionally match Promise.allSettled on the frontend: a per-item failure does NOT abort the rest of the batch. The whole thing returns 200 with a results array even if every item failed — the caller decides what to do based on the per-item statuses.

This is what the frontend Add Relationship dialog calls when the user multi-selects targets. It replaces the previous N parallel POSTs at the cost of one slightly bigger response.

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) GetRelationshipTypeUsage added in v0.1.5

func (s *AssetRelationshipService) GetRelationshipTypeUsage(
	ctx context.Context,
	tenantID string,
) ([]RelationshipTypeUsage, error)

GetRelationshipTypeUsage returns counts per relationship type for a tenant joined with the metadata from the generated registry. The result includes EVERY registered type (zero-count entries are preserved) so admins can see which types are unused and prune the registry based on real data instead of guessing.

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 atomically updates the status of multiple assets. Security: Requires tenantID to prevent cross-tenant status changes. Uses a single SQL UPDATE with IN clause for atomicity.

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) GetAssetStats added in v0.1.3

func (s *AssetService) GetAssetStats(ctx context.Context, tenantID string, types []string, tags []string) (*asset.AggregateStats, error)

ListTags returns distinct tags across all assets for a tenant. Supports prefix filtering for autocomplete. GetAssetStats returns aggregated asset statistics using SQL aggregation. Filters: types (asset_type ANY), tags (overlap, matches List semantics).

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) GetAssetWithScope added in v0.1.2

func (s *AssetService) GetAssetWithScope(ctx context.Context, tenantID, assetID, actingUserID string, isAdmin bool) (*asset.Asset, error)

GetAssetWithScope retrieves an asset with optional data scope enforcement. Non-admin users with group assignments can only access assets in their groups. Security: fail-closed — any error during scope check denies access. Returns ErrNotFound (not ErrForbidden) to prevent information disclosure.

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) GetRepositoryExtensionsByAssetIDs added in v0.1.2

func (s *AssetService) GetRepositoryExtensionsByAssetIDs(ctx context.Context, assetIDs []shared.ID) (map[shared.ID]*asset.RepositoryExtension, error)

GetRepositoryExtensionsByAssetIDs retrieves repository extensions for multiple assets in a single query. Security: Caller must ensure all assetIDs belong to the specified tenant.

func (*AssetService) HasRepositoryExtensionRepository

func (s *AssetService) HasRepositoryExtensionRepository() bool

HasRepositoryExtensionRepository returns true if the repository extension repository is configured.

func (*AssetService) InvalidateScoringConfigCache added in v0.1.2

func (s *AssetService) InvalidateScoringConfigCache(tenantID shared.ID)

InvalidateScoringConfigCache removes the cached scoring config for a tenant. Call this when scoring settings are updated.

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) ListTags added in v0.1.2

func (s *AssetService) ListTags(ctx context.Context, tenantID string, prefix string, limit int) ([]string, error)

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) PreviewRiskScoreChanges added in v0.1.2

func (s *AssetService) PreviewRiskScoreChanges(ctx context.Context, tenantID shared.ID, newConfig *asset.RiskScoringConfig) ([]RiskScorePreviewItem, int64, error)

PreviewRiskScoreChanges previews how a scoring config change would affect assets. Uses stratified sampling: top 20 + bottom 20 + random 60 assets. Returns preview items and total asset count for context.

func (*AssetService) RecalculateAllRiskScores added in v0.1.2

func (s *AssetService) RecalculateAllRiskScores(ctx context.Context, tenantID shared.ID) (int, error)

RecalculateAllRiskScores recalculates risk scores for all assets in a tenant using the current scoring configuration. Processes assets in batches.

func (*AssetService) RecordRepositoryScan

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

RecordRepositoryScan records a scan completion for a repository.

func (*AssetService) SetAccessControlRepository added in v0.1.2

func (s *AssetService) SetAccessControlRepository(repo accesscontrol.Repository)

SetAccessControlRepository sets the access control repository for Layer 2 data scope checks.

func (*AssetService) SetAssetGroupRepository

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

SetAssetGroupRepository sets the asset group repository for recalculating stats.

func (*AssetService) SetRedisClient added in v0.1.2

func (s *AssetService) SetRedisClient(client *redis.Client)

SetRedisClient sets the Redis client for distributed locking.

func (*AssetService) SetRepositoryExtensionRepository

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

SetRepositoryExtensionRepository sets the repository extension repository.

func (*AssetService) SetScopeRuleEvaluator added in v0.1.2

func (s *AssetService) SetScopeRuleEvaluator(fn ScopeRuleEvaluatorFunc)

SetScopeRuleEvaluator sets the scope rule evaluator callback. When set, asset create/update will trigger async scope rule evaluation.

func (*AssetService) SetScoringConfigProvider added in v0.1.2

func (s *AssetService) SetScoringConfigProvider(provider asset.ScoringConfigProvider)

SetScoringConfigProvider sets the scoring config provider for configurable risk scoring.

func (*AssetService) SetUserMatcher added in v0.1.5

func (s *AssetService) SetUserMatcher(m UserMatcher)

SetUserMatcher sets the user matcher for owner auto-resolution.

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 AssignmentEngine added in v0.1.2

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

AssignmentEngine evaluates assignment rules against findings and returns the list of matching groups with their options.

func NewAssignmentEngine added in v0.1.2

func NewAssignmentEngine(acRepo accesscontrol.Repository, log *logger.Logger) *AssignmentEngine

NewAssignmentEngine creates a new AssignmentEngine.

func (*AssignmentEngine) EvaluateRules added in v0.1.2

func (e *AssignmentEngine) EvaluateRules(ctx context.Context, tenantID shared.ID, finding *vulnerability.Finding) ([]AssignmentResult, error)

EvaluateRules evaluates all active assignment rules for a tenant against a finding. Rules are evaluated in priority order (highest first). All matching rules contribute their target group to the result set (no short-circuiting).

func (*AssignmentEngine) MatchesConditions added in v0.1.2

func (e *AssignmentEngine) MatchesConditions(conds accesscontrol.AssignmentConditions, finding *vulnerability.Finding, assetType ...string) bool

MatchesConditions checks if a finding matches the given conditions. All non-empty condition fields must match (AND logic). Empty conditions = catch-all (always matches). assetType is optional — pass the asset's type when available for AssetTypes condition evaluation.

type AssignmentResult added in v0.1.2

type AssignmentResult struct {
	GroupID shared.ID
	RuleID  shared.ID
	Options accesscontrol.AssignmentOptions
}

AssignmentResult represents a single rule match with its target group and options.

type AssignmentRuleService added in v0.1.2

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

AssignmentRuleService handles assignment rule business operations.

func NewAssignmentRuleService added in v0.1.2

func NewAssignmentRuleService(
	acRepo accesscontrol.Repository,
	groupRepo group.Repository,
	log *logger.Logger,
) *AssignmentRuleService

NewAssignmentRuleService creates a new AssignmentRuleService.

func (*AssignmentRuleService) CreateRule added in v0.1.2

CreateRule creates a new assignment rule.

func (*AssignmentRuleService) DeleteRule added in v0.1.2

func (s *AssignmentRuleService) DeleteRule(ctx context.Context, tenantIDStr, ruleID string) error

DeleteRule deletes an assignment rule.

func (*AssignmentRuleService) GetRule added in v0.1.2

func (s *AssignmentRuleService) GetRule(ctx context.Context, tenantIDStr, ruleID string) (*accesscontrol.AssignmentRule, error)

GetRule retrieves an assignment rule by ID.

func (*AssignmentRuleService) ListRules added in v0.1.2

ListRules lists assignment rules with filtering.

func (*AssignmentRuleService) SetAssignmentEngine added in v0.1.2

func (s *AssignmentRuleService) SetAssignmentEngine(engine *AssignmentEngine)

SetAssignmentEngine sets the assignment engine for TestRule evaluation.

func (*AssignmentRuleService) SetFindingRepository added in v0.1.2

func (s *AssignmentRuleService) SetFindingRepository(repo vulnerability.FindingRepository)

SetFindingRepository sets the finding repository for TestRule evaluation.

func (*AssignmentRuleService) TestRule added in v0.1.2

func (s *AssignmentRuleService) TestRule(ctx context.Context, tenantIDStr, ruleID string) (*TestRuleResult, error)

TestRule evaluates a rule against recent findings (dry run). If assignmentEngine and findingRepo are configured, it fetches recent findings and evaluates the rule conditions against them.

func (*AssignmentRuleService) UpdateRule added in v0.1.2

func (s *AssignmentRuleService) UpdateRule(ctx context.Context, tenantIDStr, ruleID string, input UpdateRuleInput) (*accesscontrol.AssignmentRule, error)

UpdateRule updates an existing assignment rule.

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) SetSMTPChecker added in v0.1.5

func (s *AuthService) SetSMTPChecker(checker SMTPAvailabilityCheck)

SetSMTPChecker injects the SMTP availability checker used for smart email verification (auto mode). If not set, the service falls back to the global RequireEmailVerification flag from config.

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 AutoAssignToOwnersResult added in v0.1.3

type AutoAssignToOwnersResult struct {
	Assigned   int            `json:"assigned"`
	ByOwner    map[string]int `json:"by_owner"`
	Unassigned int            `json:"unassigned"`
}

AutoAssignToOwnersResult is the result of auto-assign operation.

type BatchCreateRelationshipInput added in v0.1.5

type BatchCreateRelationshipInput struct {
	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"`
}

BatchCreateRelationshipInput is the per-item payload for the batch create endpoint. The TenantID and SourceAssetID are NOT here — the service takes them once for the whole batch and reuses for every item, which is the entire point of the batch endpoint.

type BatchCreateRelationshipResult added in v0.1.5

type BatchCreateRelationshipResult struct {
	Results    []BatchCreateRelationshipResultItem `json:"results"`
	CreatedN   int                                 `json:"created"`
	DuplicateN int                                 `json:"duplicates"`
	ErrorN     int                                 `json:"errors"`
	TotalN     int                                 `json:"total"`
}

BatchCreateRelationshipResult is the aggregate response.

type BatchCreateRelationshipResultItem added in v0.1.5

type BatchCreateRelationshipResultItem struct {
	Index          int                                 `json:"index"`
	Status         BatchCreateRelationshipResultStatus `json:"status"`
	TargetAssetID  string                              `json:"target_asset_id"`
	RelationshipID string                              `json:"relationship_id,omitempty"`
	Error          string                              `json:"error,omitempty"`
}

BatchCreateRelationshipResultItem is one slot in the batch response. `Index` matches the position of the corresponding input in the request, so the frontend can map results back to target names without re-fetching anything.

type BatchCreateRelationshipResultStatus added in v0.1.5

type BatchCreateRelationshipResultStatus string

BatchCreateRelationshipResultStatus enumerates the possible outcomes for one item in a batch create call.

const (
	BatchCreateStatusCreated   BatchCreateRelationshipResultStatus = "created"
	BatchCreateStatusDuplicate BatchCreateRelationshipResultStatus = "duplicate"
	BatchCreateStatusError     BatchCreateRelationshipResultStatus = "error"
)

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 BulkAssignAssetsInput added in v0.1.2

type BulkAssignAssetsInput struct {
	GroupID       string   `json:"-"`
	AssetIDs      []string `json:"asset_ids" validate:"required,min=1,max=1000,dive,uuid"`
	OwnershipType string   `json:"ownership_type" validate:"required,oneof=primary secondary stakeholder informed"`
}

BulkAssignAssetsInput represents the input for bulk assigning assets to a group.

type BulkAssignAssetsResult added in v0.1.2

type BulkAssignAssetsResult struct {
	SuccessCount int      `json:"success_count"`
	FailedCount  int      `json:"failed_count"`
	FailedAssets []string `json:"failed_assets,omitempty"`
}

BulkAssignAssetsResult represents the result of bulk asset assignment.

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 BulkFixAppliedInput added in v0.1.3

type BulkFixAppliedInput struct {
	Filter             vulnerability.FindingFilter
	IncludeRelatedCVEs bool
	Note               string // REQUIRED
	Reference          string // optional (commit hash, patch ID)
}

BulkFixAppliedInput is the input for bulk fix-applied operation.

type BulkFixAppliedResult added in v0.1.3

type BulkFixAppliedResult struct {
	Updated        int            `json:"updated"`
	Skipped        int            `json:"skipped"`
	ByCVE          map[string]int `json:"by_cve,omitempty"`
	AssetsAffected int            `json:"assets_affected"`
}

BulkFixAppliedResult is the result of bulk fix-applied operation.

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 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 CampaignAddMemberInput added in v0.1.3

type CampaignAddMemberInput struct {
	TenantID   string
	CampaignID string
	UserID     string
	Role       string
	ActorID    string
}

CampaignAddMemberInput contains input for adding a campaign member.

type CampaignRemoveMemberInput added in v0.1.3

type CampaignRemoveMemberInput struct {
	TenantID   string
	CampaignID string
	UserID     string
	ActorID    string // the user performing the removal (for self-remove check)
}

CampaignRemoveMemberInput contains input for removing a campaign member.

type CampaignUpdateMemberRoleInput added in v0.1.3

type CampaignUpdateMemberRoleInput struct {
	TenantID   string
	CampaignID string
	UserID     string
	NewRole    string
}

CampaignUpdateMemberRoleInput contains input for changing a member's role.

type CancelApprovalInput added in v0.1.2

type CancelApprovalInput struct {
	TenantID   string `json:"tenant_id" validate:"required,uuid"`
	ApprovalID string `json:"approval_id" validate:"required,uuid"`
	CanceledBy string `json:"canceled_by" validate:"required,uuid"`
}

CancelApprovalInput represents the input for cancelling a status change request.

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 ComplianceService added in v0.1.2

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

ComplianceService handles compliance framework business operations.

func NewComplianceService added in v0.1.2

func NewComplianceService(
	frameworkRepo compliance.FrameworkRepository,
	controlRepo compliance.ControlRepository,
	assessmentRepo compliance.AssessmentRepository,
	mappingRepo compliance.MappingRepository,
	log *logger.Logger,
) *ComplianceService

NewComplianceService creates a new ComplianceService.

func (*ComplianceService) GetComplianceStats added in v0.1.2

func (s *ComplianceService) GetComplianceStats(ctx context.Context, tenantID string) (*ComplianceStatsResponse, error)

GetComplianceStats returns overall compliance statistics.

func (*ComplianceService) GetControl added in v0.1.2

func (s *ComplianceService) GetControl(ctx context.Context, tenantID, id string) (*compliance.Control, error)

GetControl retrieves a control by ID and verifies its framework is accessible to the tenant.

func (*ComplianceService) GetControlFindings added in v0.1.2

func (s *ComplianceService) GetControlFindings(ctx context.Context, tenantID, controlID string) ([]*compliance.FindingControlMapping, error)

GetControlFindings lists findings mapped to a control.

func (*ComplianceService) GetFindingControls added in v0.1.2

func (s *ComplianceService) GetFindingControls(ctx context.Context, tenantID, findingID string) ([]*compliance.FindingControlMapping, error)

GetFindingControls lists controls mapped to a finding.

func (*ComplianceService) GetFramework added in v0.1.2

func (s *ComplianceService) GetFramework(ctx context.Context, tenantID, id string) (*compliance.Framework, error)

GetFramework retrieves a framework by ID with tenant isolation.

func (*ComplianceService) GetFrameworkBySlug added in v0.1.2

func (s *ComplianceService) GetFrameworkBySlug(ctx context.Context, slug string) (*compliance.Framework, error)

GetFrameworkBySlug retrieves a system framework by slug.

func (*ComplianceService) GetFrameworkStats added in v0.1.2

func (s *ComplianceService) GetFrameworkStats(ctx context.Context, tenantID, frameworkID string) (*compliance.FrameworkStats, error)

GetFrameworkStats returns compliance statistics for a framework.

func (*ComplianceService) ListAssessments added in v0.1.2

func (s *ComplianceService) ListAssessments(ctx context.Context, tenantID, frameworkID string, page pagination.Pagination) (pagination.Result[*compliance.Assessment], error)

ListAssessments lists assessments for a framework.

func (*ComplianceService) ListControls added in v0.1.2

func (s *ComplianceService) ListControls(ctx context.Context, tenantID, frameworkID string, page pagination.Pagination) (pagination.Result[*compliance.Control], error)

ListControls lists controls for a framework with tenant verification.

func (*ComplianceService) ListFrameworks added in v0.1.2

ListFrameworks lists compliance frameworks.

func (*ComplianceService) MapFindingToControl added in v0.1.2

func (s *ComplianceService) MapFindingToControl(ctx context.Context, tenantID, findingID, controlID, actorID string, impact string) (*compliance.FindingControlMapping, error)

MapFindingToControl maps a finding to a compliance control.

func (*ComplianceService) SetFindingRepository added in v0.1.2

func (s *ComplianceService) SetFindingRepository(repo vulnerability.FindingRepository)

SetFindingRepository sets the finding repository for draft guard on compliance mapping.

func (*ComplianceService) UnmapFindingFromControl added in v0.1.2

func (s *ComplianceService) UnmapFindingFromControl(ctx context.Context, tenantID, mappingID string) error

UnmapFindingFromControl removes a mapping.

func (*ComplianceService) UpdateAssessment added in v0.1.2

UpdateAssessment creates or updates a control assessment.

type ComplianceStatsResponse added in v0.1.2

type ComplianceStatsResponse struct {
	TotalFrameworks int `json:"total_frameworks"`
	TotalControls   int `json:"total_controls"`
	OverdueControls int `json:"overdue_controls"`
}

ComplianceStatsResponse contains overall compliance stats.

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"`
	OwnerRef    string   `validate:"max=500"` // Raw owner from external source
}

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 CreateCampaignInput added in v0.1.2

type CreateCampaignInput struct {
	TenantID          string
	Name              string
	Description       string
	CampaignType      string
	Priority          string
	Methodology       string
	ClientName        string
	ClientContact     string
	StartDate         *string
	EndDate           *string
	Objectives        []string
	ScopeItems        []map[string]any
	RulesOfEngagement map[string]any
	LeadUserID        *string
	TeamUserIDs       []string
	AssetIDs          []string
	AssetGroupIDs     []string
	Tags              []string
	ActorID           string
}

CreateCampaignInput contains the input for creating a campaign.

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"`
	NotificationConfig *group.NotificationConfig `json:"notification_config,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,max=254"`
	Role    string   `json:"-"`                                         // Internal use only - always set to "member" by handler
	RoleIDs []string `json:"role_ids" validate:"required,min=1,max=10"` // RBAC roles to assign (required, max 10)
}

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 CreateProviderInput added in v0.1.2

type CreateProviderInput struct {
	TenantID         string
	Provider         string
	DisplayName      string
	ClientID         string
	ClientSecret     string // Plaintext - will be encrypted
	IssuerURL        string
	TenantIdentifier string
	Scopes           []string
	AllowedDomains   []string
	AutoProvision    bool
	DefaultRole      string
	CreatedBy        string
}

CreateProviderInput is the input for creating an identity provider config.

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 CreateReportInput added in v0.1.2

type CreateReportInput struct {
	TenantID   string
	CampaignID string
	Name       string
	ReportType string
	Format     string
	Options    map[string]any
	ActorID    string
}

CreateReportInput contains input for creating a report.

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 CreateRetestInput added in v0.1.2

type CreateRetestInput struct {
	TenantID          string
	FindingID         string
	Status            string
	Notes             string
	Evidence          []map[string]any
	ActorID           string
	ActorCampaignRole pentest.CampaignRole // role of the actor in the campaign (for auto-status logic)
}

CreateRetestInput contains input for creating a retest.

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 CreateRuleInput added in v0.1.2

type CreateRuleInput struct {
	TenantID      string                             `json:"-"`
	Name          string                             `json:"name" validate:"required,min=2,max=200"`
	Description   string                             `json:"description" validate:"max=1000"`
	Priority      int                                `json:"priority"`
	Conditions    accesscontrol.AssignmentConditions `json:"conditions"`
	TargetGroupID string                             `json:"target_group_id" validate:"required,uuid"`
	Options       accesscontrol.AssignmentOptions    `json:"options"`
}

CreateRuleInput represents the input for creating an assignment rule.

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 CreateScopeRuleInput added in v0.1.2

type CreateScopeRuleInput struct {
	GroupID            string   `json:"-"`
	TenantID           string   `json:"-"`
	Name               string   `json:"name" validate:"required,min=2,max=200"`
	Description        string   `json:"description" validate:"max=1000"`
	RuleType           string   `json:"rule_type" validate:"required,oneof=tag_match asset_group_match"`
	MatchTags          []string `json:"match_tags"`
	MatchLogic         string   `json:"match_logic" validate:"omitempty,oneof=any all"`
	MatchAssetGroupIDs []string `json:"match_asset_group_ids"`
	OwnershipType      string   `json:"ownership_type" validate:"omitempty,oneof=primary secondary stakeholder informed"`
	Priority           int      `json:"priority"`
}

CreateScopeRuleInput represents the input for creating a scope rule.

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 CreateTemplateInput added in v0.1.2

type CreateTemplateInput struct {
	Name             string   `json:"name"`
	Category         string   `json:"category"`
	Severity         string   `json:"severity"`
	OWASPCategory    string   `json:"owasp_category"`
	CWEID            string   `json:"cwe_id"`
	Description      string   `json:"description"`
	StepsToReproduce []string `json:"steps_to_reproduce"`
	BusinessImpact   string   `json:"business_impact"`
	TechnicalImpact  string   `json:"technical_impact"`
	Remediation      string   `json:"remediation"`
	ReferenceURLs    []string `json:"reference_urls"`
	Tags             []string `json:"tags"`
}

CreateTemplateInput contains input for creating a template.

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 DashboardAllStats added in v0.1.2

type DashboardAllStats struct {
	Assets   AssetStatsData
	Findings FindingStatsData
	Repos    RepositoryStatsData
	Activity []ActivityItem
}

DashboardAllStats holds all dashboard stats from the optimized batched query.

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. Uses optimized batched query (2 queries instead of 10+).

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

	// Finding trend (monthly breakdown by severity)
	FindingTrend []FindingTrendPoint
}

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)
	// GetFindingTrend returns monthly finding counts by severity for a tenant
	GetFindingTrend(ctx context.Context, tenantID shared.ID, months int) ([]FindingTrendPoint, error)
	// GetAllStats returns all dashboard stats in 2 optimized queries (replaces 10+ individual calls)
	GetAllStats(ctx context.Context, tenantID shared.ID) (*DashboardAllStats, 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. Supports per-tenant SMTP via TenantSMTPResolver: if a tenant has a custom email integration configured, it uses that SMTP server instead of the system default.

func NewEmailService

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

NewEmailService creates a new EmailService.

func (*EmailService) HasSystemSMTP added in v0.1.5

func (s *EmailService) HasSystemSMTP() bool

HasSystemSMTP implements SMTPAvailabilityCheck. Returns true if the system-wide SMTP sender is configured.

func (*EmailService) HasTenantSMTP added in v0.1.5

func (s *EmailService) HasTenantSMTP(ctx context.Context, tenantID string) bool

HasTenantSMTP implements SMTPAvailabilityCheck. Returns true if the given tenant has a custom SMTP integration configured. tenantID may be empty for self-registration without tenant context.

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, tenantID ...string) error

SendTeamInvitationEmail sends a team invitation email. Uses per-tenant SMTP if configured, otherwise falls back to system SMTP.

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.

func (*EmailService) SetTenantSMTPResolver added in v0.1.4

func (s *EmailService) SetTenantSMTPResolver(resolver TenantSMTPResolver)

SetTenantSMTPResolver sets the per-tenant SMTP resolver.

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) GetExposureSecure added in v0.1.3

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

GetExposureSecure retrieves an exposure event by tenant and ID (tenant-scoped access control).

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) SetOutboxService added in v0.1.2

func (s *ExposureService) SetOutboxService(db *sql.DB, svc *OutboxService)

SetOutboxService 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 FindingActionsService added in v0.1.3

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

FindingActionsService handles the closed-loop finding lifecycle: in_progress → fix_applied → resolved (verified by scan or security).

func NewFindingActionsService added in v0.1.3

func NewFindingActionsService(
	findingRepo vulnerability.FindingRepository,
	accessCtrlRepo accesscontrol.Repository,
	groupRepo group.Repository,
	assetRepo asset.Repository,
	activityService *FindingActivityService,
	db *sql.DB,
	logger *logger.Logger,
) *FindingActionsService

NewFindingActionsService creates a new FindingActionsService.

func (*FindingActionsService) AutoAssignToOwners added in v0.1.3

func (s *FindingActionsService) AutoAssignToOwners(
	ctx context.Context, tenantID string, assignerID string, filter vulnerability.FindingFilter,
) (*AutoAssignToOwnersResult, error)

AutoAssignToOwners assigns findings to their asset owners. Only assigns findings that don't already have an assignee.

func (*FindingActionsService) BulkFixApplied added in v0.1.3

func (s *FindingActionsService) BulkFixApplied(
	ctx context.Context, tenantID string, userID string, input BulkFixAppliedInput,
) (*BulkFixAppliedResult, error)

BulkFixApplied marks findings as fix_applied. Authorization: user must be assignee, group member, or asset owner for each finding.

func (*FindingActionsService) BulkRejectByFilter added in v0.1.3

func (s *FindingActionsService) BulkRejectByFilter(
	ctx context.Context, tenantID string, userID string, input RejectByFilterInput,
) (int64, error)

BulkRejectByFilter reopens all fix_applied findings matching a filter.

func (*FindingActionsService) BulkRejectFix added in v0.1.3

func (s *FindingActionsService) BulkRejectFix(
	ctx context.Context, tenantID string, userID string, findingIDs []string, reason string,
) (*BulkUpdateResult, error)

BulkRejectFix reopens fix_applied findings (fix was incorrect).

func (*FindingActionsService) BulkVerify added in v0.1.3

func (s *FindingActionsService) BulkVerify(
	ctx context.Context, tenantID string, userID string, findingIDs []string, note string,
) (*BulkUpdateResult, error)

BulkVerify resolves fix_applied findings (manual security review).

func (*FindingActionsService) BulkVerifyByFilter added in v0.1.3

func (s *FindingActionsService) BulkVerifyByFilter(
	ctx context.Context, tenantID string, userID string, input VerifyByFilterInput,
) (int64, error)

BulkVerifyByFilter resolves all fix_applied findings matching a filter. Used by Pending Review tab to approve entire groups at once.

func (*FindingActionsService) GetRelatedCVEs added in v0.1.3

func (s *FindingActionsService) GetRelatedCVEs(
	ctx context.Context, tenantID string, cveID string, filter vulnerability.FindingFilter,
) ([]vulnerability.RelatedCVE, error)

GetRelatedCVEs finds CVEs that share the same component as the given CVE.

func (*FindingActionsService) ListFindingGroups added in v0.1.3

ListFindingGroups returns findings grouped by a dimension.

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) DeleteActivityByCommentID added in v0.1.2

func (s *FindingActivityService) DeleteActivityByCommentID(ctx context.Context, tenantID string, commentID string) error

DeleteActivityByCommentID removes the comment_added activity for a given comment ID. This is called when a user deletes their comment to clean up the activity feed.

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) RecordBatchAutoReopened added in v0.1.2

func (s *FindingActivityService) RecordBatchAutoReopened(
	ctx context.Context,
	tenantID shared.ID,
	findingIDs []shared.ID,
) error

RecordBatchAutoReopened creates activity records for findings that were auto-reopened during ingestion (previously auto-resolved findings seen again in a new scan).

func (*FindingActivityService) RecordBatchAutoResolved added in v0.1.2

func (s *FindingActivityService) RecordBatchAutoResolved(
	ctx context.Context,
	tenantID shared.ID,
	findingIDs []shared.ID,
	toolName string,
	scanID string,
) error

RecordBatchAutoResolved creates activity records for findings that were auto-resolved during ingestion. This provides an audit trail for the auto-resolve lifecycle event.

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.

func (*FindingActivityService) UpdateActivityContentByCommentID added in v0.1.2

func (s *FindingActivityService) UpdateActivityContentByCommentID(ctx context.Context, tenantID string, commentID string, content string) error

UpdateActivityContentByCommentID updates the content of a comment_added activity.

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 OutboxService 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 FindingTrendPoint added in v0.1.2

type FindingTrendPoint struct {
	Date     string // "Jan", "Feb", etc.
	Critical int
	High     int
	Medium   int
	Low      int
	Info     int
}

FindingTrendPoint represents one month's finding counts by severity.

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 GetFindingStatsInput added in v0.1.2

type GetFindingStatsInput struct {
	TenantID     string
	ActingUserID string
	IsAdmin      bool
	// AssetID — when non-empty, restrict the stats to findings on this
	// specific asset. Used by /findings?assetId=… so the severity cards
	// match the filtered table.
	AssetID string
}

GetFindingStatsInput represents input for getting finding stats with data scope.

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 GroupCounts added in v0.1.2

type GroupCounts struct {
	MemberCount int
	AssetCount  int
}

GroupCounts holds member and asset counts for a group.

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) BulkAssignAssets added in v0.1.2

func (s *GroupService) BulkAssignAssets(ctx context.Context, input BulkAssignAssetsInput, assignedBy shared.ID, actx AuditContext) (*BulkAssignAssetsResult, error)

BulkAssignAssets assigns multiple assets to a group in bulk.

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) CountUniqueMembers added in v0.1.2

func (s *GroupService) CountUniqueMembers(ctx context.Context, groups []*group.Group) (int, error)

CountUniqueMembers counts the number of distinct users across the given groups.

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) GetGroupCounts added in v0.1.2

func (s *GroupService) GetGroupCounts(ctx context.Context, groups []*group.Group) (map[shared.ID]GroupCounts, error)

GetGroupCounts returns member and asset counts for the given groups.

func (*GroupService) GetGroupSecure added in v0.1.3

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

GetGroupSecure retrieves a group by tenant and ID (tenant-scoped access control).

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, limit, offset int) ([]*accesscontrol.AssetOwnerWithAsset, int64, error)

ListGroupAssets lists assets assigned to a group with asset details, with pagination.

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, limit, offset int) ([]*group.MemberWithUser, int64, error)

ListGroupMembersWithUserInfo lists members with user details, with pagination.

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) SetNotificationService added in v0.1.2

func (s *GroupService) SetNotificationService(ns *NotificationService)

SetNotificationService sets the notification service for GroupService. This is used for late-binding when NotificationService is initialized after GroupService.

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 GroupSyncService added in v0.1.2

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

GroupSyncService handles synchronization of groups from external providers such as GitHub Teams, GitLab Groups, Azure AD, and Okta.

func NewGroupSyncService added in v0.1.2

func NewGroupSyncService(groupRepo group.Repository, log *logger.Logger) *GroupSyncService

NewGroupSyncService creates a new GroupSyncService.

func (*GroupSyncService) SyncAll added in v0.1.2

func (s *GroupSyncService) SyncAll(ctx context.Context, tenantID shared.ID) error

SyncAll synchronizes all configured external providers for a tenant. This is a placeholder implementation that iterates over groups with external sources and triggers sync for each unique provider.

func (*GroupSyncService) SyncFromProvider added in v0.1.2

func (s *GroupSyncService) SyncFromProvider(ctx context.Context, tenantID shared.ID, provider string, config map[string]interface{}) error

SyncFromProvider synchronizes groups from an external provider. This is a placeholder implementation. Actual provider integration (GitHub Teams, GitLab Groups, Azure AD, Okta) will be implemented as separate tasks.

The config parameter would contain provider-specific configuration such as:

  • GitHub: org name, API token
  • GitLab: group ID, API token
  • Azure AD: tenant ID, client credentials
  • Okta: domain, API token

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) AllowLocalhostForTesting added in v0.1.2

func (h *HTTPRequestHandler) AllowLocalhostForTesting()

AllowLocalhostForTesting disables the localhost/loopback SSRF check. This is intended for testing purposes only — never call in production.

func (*HTTPRequestHandler) Execute

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

Execute executes an HTTP request action.

func (*HTTPRequestHandler) SetBlockedCIDRs added in v0.1.2

func (h *HTTPRequestHandler) SetBlockedCIDRs(cidrs []string)

SetBlockedCIDRs overrides the list of blocked CIDR ranges. This is intended for testing purposes only.

func (*HTTPRequestHandler) SetClient added in v0.1.2

func (h *HTTPRequestHandler) SetClient(client *http.Client)

SetClient overrides the default HTTP client used by the handler. This is intended for testing purposes only.

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 IntegrationSMTPResolver added in v0.1.4

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

IntegrationSMTPResolver resolves per-tenant SMTP config from notification integrations. When a tenant creates an email integration (category=notification, provider=email), the SMTP settings are stored encrypted in the integration's config/credentials.

func NewIntegrationSMTPResolver added in v0.1.4

func NewIntegrationSMTPResolver(repo integration.Repository, log *logger.Logger) *IntegrationSMTPResolver

NewIntegrationSMTPResolver creates a new resolver.

func (*IntegrationSMTPResolver) GetTenantSMTPConfig added in v0.1.4

func (r *IntegrationSMTPResolver) GetTenantSMTPConfig(ctx context.Context, tenantID string) (*email.Config, error)

GetTenantSMTPConfig looks up the tenant's email integration and returns SMTP config. Returns nil if no email integration is configured for this tenant.

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) SetNotificationExtensionRepository

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

SetNotificationExtensionRepository sets the notification extension repository.

func (*IntegrationService) SetOutboxEventRepository added in v0.1.2

func (s *IntegrationService) SetOutboxEventRepository(repo outbox.EventRepository)

SetOutboxEventRepository sets the notification event 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"`

	// Layer 2: Data Scope
	ActingUserID string // From JWT context
	IsAdmin      bool   // True for owner/admin (bypasses data scope)
}

ListAssetsInput represents the input for listing assets.

type ListAssignmentRulesInput added in v0.1.2

type ListAssignmentRulesInput struct {
	TenantID      string
	IsActive      *bool
	TargetGroupID *string
	Search        string
	Limit         int
	Offset        int
	OrderBy       string
	OrderDesc     bool
}

ListAssignmentRulesInput represents the input for listing assignment rules.

type ListAssignmentRulesOutput added in v0.1.2

type ListAssignmentRulesOutput struct {
	Rules      []*accesscontrol.AssignmentRule
	TotalCount int64
}

ListAssignmentRulesOutput represents the output for listing assignment rules.

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"`
	ExcludeStatuses []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"`

	// Layer 2: Data Scope
	ActingUserID string // From JWT context
	IsAdmin      bool   // True for owner/admin (bypasses data scope)
}

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 // Active tenants user can access
	// SuspendedTenants lists tenants where this user has a suspended
	// membership. The user has zero access to these tenants — the field
	// exists purely so the UI can show "your access to {name} is
	// suspended" instead of bouncing the user to /onboarding/create-team
	// when they have no active memberships.
	SuspendedTenants []TenantMembershipInfo
}

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 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)
	ListAllSubModules(ctx context.Context) (map[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.

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. Filters by tenant module overrides if configured. Optimized: 2 queries (modules + tenant_modules) instead of 3. Sub-modules are extracted from the same ListActiveModules result.

func (*ModuleService) GetTenantModuleConfig added in v0.1.2

func (s *ModuleService) GetTenantModuleConfig(ctx context.Context, tenantID string) (*TenantModuleConfigOutput, error)

GetTenantModuleConfig returns the full module configuration for a tenant admin. Optimized: 2 queries (modules + tenant_modules) instead of 3.

func (*ModuleService) ListActiveModules

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

ListActiveModules returns all active modules.

func (*ModuleService) ResetTenantModules added in v0.1.2

func (s *ModuleService) ResetTenantModules(ctx context.Context, tenantID string, actx AuditContext) (*TenantModuleConfigOutput, error)

ResetTenantModules resets all module overrides for a tenant (all modules enabled).

func (*ModuleService) SetAuditService added in v0.1.2

func (s *ModuleService) SetAuditService(svc *AuditService)

SetAuditService sets the audit service for logging module changes.

func (*ModuleService) SetTenantModuleRepo added in v0.1.2

func (s *ModuleService) SetTenantModuleRepo(repo TenantModuleRepository)

SetTenantModuleRepo sets the tenant module repository.

func (*ModuleService) UpdateTenantModules added in v0.1.2

func (s *ModuleService) UpdateTenantModules(ctx context.Context, tenantID string, updates []module.TenantModuleUpdate, actx AuditContext) (*TenantModuleConfigOutput, error)

UpdateTenantModules toggles modules for a tenant.

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 NotificationService

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

NotificationService handles user notification operations (inbox).

func NewNotificationService

func NewNotificationService(
	repo notification.Repository,
	wsHub WebSocketBroadcaster,
	log *logger.Logger,
) *NotificationService

NewNotificationService creates a new NotificationService.

func (*NotificationService) CleanupOld added in v0.1.2

func (s *NotificationService) CleanupOld(ctx context.Context, retentionDays int) (int64, error)

CleanupOld removes notifications older than the specified retention period.

func (*NotificationService) GetPreferences added in v0.1.2

func (s *NotificationService) GetPreferences(ctx context.Context, tenantID, userID shared.ID) (*notification.Preferences, error)

GetPreferences returns notification preferences for a user.

func (*NotificationService) GetUnreadCount added in v0.1.2

func (s *NotificationService) GetUnreadCount(ctx context.Context, tenantID, userID shared.ID) (int, error)

GetUnreadCount returns the number of unread notifications for a user. Group membership is resolved via subquery in the repository, eliminating an extra DB roundtrip.

func (*NotificationService) ListNotifications added in v0.1.2

func (s *NotificationService) ListNotifications(
	ctx context.Context,
	tenantID, userID shared.ID,
	filter notification.ListFilter,
	page pagination.Pagination,
) (pagination.Result[*notification.Notification], error)

ListNotifications returns paginated notifications visible to the user. Group membership is resolved via subquery in the repository, eliminating an extra DB roundtrip.

func (*NotificationService) MarkAllAsRead added in v0.1.2

func (s *NotificationService) MarkAllAsRead(ctx context.Context, tenantID, userID shared.ID) error

MarkAllAsRead marks all notifications as read for a user within a tenant.

func (*NotificationService) MarkAsRead added in v0.1.2

func (s *NotificationService) MarkAsRead(ctx context.Context, tenantID shared.ID, notificationID notification.ID, userID shared.ID) error

MarkAsRead marks a single notification as read for a user.

func (*NotificationService) Notify added in v0.1.2

Notify creates a notification and pushes it via WebSocket to appropriate channels.

func (*NotificationService) UpdatePreferences added in v0.1.2

func (s *NotificationService) UpdatePreferences(
	ctx context.Context,
	tenantID, userID shared.ID,
	input UpdatePreferencesInput,
) (*notification.Preferences, error)

UpdatePreferences creates or updates notification preferences for a user.

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 OutboxScheduler added in v0.1.2

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

OutboxScheduler runs periodic notification processing tasks.

func NewOutboxScheduler added in v0.1.2

func NewOutboxScheduler(service *OutboxService, config OutboxSchedulerConfig, log *logger.Logger) *OutboxScheduler

NewOutboxScheduler creates a new notification scheduler.

func (*OutboxScheduler) Start added in v0.1.2

func (s *OutboxScheduler) Start()

Start starts the notification scheduler.

func (*OutboxScheduler) Stop added in v0.1.2

func (s *OutboxScheduler) Stop()

Stop stops the notification scheduler gracefully.

type OutboxSchedulerConfig added in v0.1.2

type OutboxSchedulerConfig 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
}

OutboxSchedulerConfig holds configuration for the notification scheduler.

func DefaultOutboxSchedulerConfig added in v0.1.2

func DefaultOutboxSchedulerConfig() OutboxSchedulerConfig

DefaultOutboxSchedulerConfig returns the default configuration.

type OutboxService added in v0.1.2

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

OutboxService handles notification outbox operations.

func NewOutboxService added in v0.1.2

func NewOutboxService(
	outboxRepo outbox.OutboxRepository,
	eventRepo outbox.EventRepository,
	notificationRepo integration.NotificationExtensionRepository,
	credentialDecrypt func(string) (string, error),
	log *slog.Logger,
) *OutboxService

NewOutboxService creates a new OutboxService.

func (*OutboxService) CleanupOldEntries added in v0.1.2

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

CleanupOldEntries removes old completed and failed entries.

func (*OutboxService) CleanupOldEvents added in v0.1.2

func (s *OutboxService) 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 (*OutboxService) EnqueueNotification added in v0.1.2

func (s *OutboxService) 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 (*OutboxService) EnqueueNotificationInTx added in v0.1.2

func (s *OutboxService) 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 (*OutboxService) ProcessOutboxBatch added in v0.1.2

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

ProcessOutboxBatch processes a batch of pending outbox entries.

func (*OutboxService) UnlockStaleEntries added in v0.1.2

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

UnlockStaleEntries releases locks on stale processing entries.

type PentestFindingInput added in v0.1.2

type PentestFindingInput struct {
	TenantID            string
	CampaignID          string
	AssetID             string // Required for unified findings (CTEM asset linkage)
	Title               string
	Description         string
	Severity            string
	Status              string
	CVSSScore           *float64
	CVSSVector          string
	CWEID               string
	CVEID               string
	OWASPCategory       string
	AffectedAssets      []string // Legacy: for pentest_findings table
	AffectedAssetsText  []string // For unified: free-text asset references
	StepsToReproduce    []string
	PoCCode             string
	Evidence            []map[string]any
	RequestResponses    []map[string]any
	BusinessImpact      string
	TechnicalImpact     string
	RemediationGuidance string
	RemediationDeadline *string
	ReferenceURLs       []string
	AssignedTo          *string
	ReviewedBy          *string
	Tags                []string
	ActorID             string
	TemplateID          *string
}

PentestFindingInput contains the input for creating a pentest finding.

type PentestService added in v0.1.2

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

PentestService handles pentest campaign business operations.

func NewPentestService added in v0.1.2

func NewPentestService(
	campaignRepo pentest.CampaignRepository,
	findingRepo pentest.FindingRepository,
	retestRepo pentest.RetestRepository,
	templateRepo pentest.TemplateRepository,
	reportRepo pentest.ReportRepository,
	log *logger.Logger,
) *PentestService

NewPentestService creates a new PentestService.

func (*PentestService) AddCampaignMember added in v0.1.3

func (s *PentestService) AddCampaignMember(ctx context.Context, input CampaignAddMemberInput) (*pentest.CampaignMember, error)

AddCampaignMember adds a user to a campaign with a specific role.

func (*PentestService) BatchListCampaignMembers added in v0.1.3

func (s *PentestService) BatchListCampaignMembers(ctx context.Context, tenantID string, campaignIDs []string) (map[string][]*pentest.CampaignMember, error)

BatchListCampaignMembers returns members grouped by campaign ID for batch enrichment.

func (*PentestService) CreateCampaign added in v0.1.2

func (s *PentestService) CreateCampaign(ctx context.Context, input CreateCampaignInput) (*pentest.Campaign, error)

CreateCampaign creates a new pentest campaign.

func (*PentestService) CreateFinding added in v0.1.2

func (s *PentestService) CreateFinding(ctx context.Context, input PentestFindingInput) (*pentest.Finding, error)

CreateFinding creates a new pentest finding.

func (*PentestService) CreateReport added in v0.1.2

func (s *PentestService) CreateReport(ctx context.Context, input CreateReportInput) (*pentest.Report, error)

CreateReport creates a report and marks it as generating.

func (*PentestService) CreateRetest added in v0.1.2

func (s *PentestService) CreateRetest(ctx context.Context, input CreateRetestInput) (*pentest.Retest, error)

CreateRetest creates a retest and auto-updates finding status.

func (*PentestService) CreateTemplate added in v0.1.2

func (s *PentestService) CreateTemplate(ctx context.Context, tenantID string, input CreateTemplateInput) (*pentest.Template, error)

CreateTemplate creates a new finding template.

func (*PentestService) CreateUnifiedFinding added in v0.1.2

func (s *PentestService) CreateUnifiedFinding(ctx context.Context, input PentestFindingInput) (*vulnerability.Finding, error)

CreateUnifiedFinding creates a pentest finding in the unified findings table. This is the CTEM-integrated version: finding goes directly into `findings` table with source='pentest', enabling dashboard, SLA, compliance, and risk scoring.

func (*PentestService) DeleteCampaign added in v0.1.2

func (s *PentestService) DeleteCampaign(ctx context.Context, tenantID, campaignID string) error

DeleteCampaign deletes a campaign and cascades to findings, retests, reports.

func (*PentestService) DeleteFinding added in v0.1.2

func (s *PentestService) DeleteFinding(ctx context.Context, tenantID, findingID string) error

DeleteFinding deletes a pentest finding. Uses the unified finding repo when available to delete from the correct table.

func (*PentestService) DeleteReport added in v0.1.2

func (s *PentestService) DeleteReport(ctx context.Context, tenantID, reportID string) error

DeleteReport deletes a report.

func (*PentestService) DeleteTemplate added in v0.1.2

func (s *PentestService) DeleteTemplate(ctx context.Context, tenantID, id string) error

DeleteTemplate deletes a template. System templates cannot be deleted.

func (*PentestService) GetBatchCampaignStats added in v0.1.2

func (s *PentestService) GetBatchCampaignStats(ctx context.Context, tenantID string, campaignIDs []string) (map[string]*pentest.CampaignStats, error)

GetBatchCampaignStats returns finding statistics for multiple campaigns in one query.

func (*PentestService) GetCampaign added in v0.1.2

func (s *PentestService) GetCampaign(ctx context.Context, tenantID, campaignID string) (*pentest.Campaign, error)

GetCampaign retrieves a campaign by ID.

func (*PentestService) GetCampaignStats added in v0.1.2

func (s *PentestService) GetCampaignStats(ctx context.Context, tenantID, campaignID string) (*pentest.CampaignStats, error)

GetCampaignStats returns finding statistics for a campaign.

func (*PentestService) GetFinding added in v0.1.2

func (s *PentestService) GetFinding(ctx context.Context, tenantID, findingID string) (*pentest.Finding, error)

GetFinding retrieves a pentest finding by ID.

func (*PentestService) GetReport added in v0.1.2

func (s *PentestService) GetReport(ctx context.Context, tenantID, reportID string) (*pentest.Report, error)

GetReport retrieves a report by ID.

func (*PentestService) GetTemplate added in v0.1.2

func (s *PentestService) GetTemplate(ctx context.Context, tenantID, id string) (*pentest.Template, error)

GetTemplate retrieves a template by ID with tenant isolation.

func (*PentestService) GetUnifiedFinding added in v0.1.2

func (s *PentestService) GetUnifiedFinding(ctx context.Context, tenantID, findingID string) (*vulnerability.Finding, error)

GetUnifiedFinding retrieves a pentest finding from the unified findings table. Returns ErrNotFound if the finding exists but is not a pentest finding.

func (*PentestService) GetUserCampaignRole added in v0.1.3

func (s *PentestService) GetUserCampaignRole(ctx context.Context, tenantID, campaignID, userID string) (pentest.CampaignRole, error)

GetUserCampaignRole returns the user's role in a campaign.

func (*PentestService) ListAllPentestFindings added in v0.1.2

func (s *PentestService) ListAllPentestFindings(ctx context.Context, tenantID, campaignID string, page pagination.Pagination) (pagination.Result[*vulnerability.Finding], error)

ListAllPentestFindings lists all pentest findings across all campaigns. If campaignID is provided, filters by that campaign.

func (*PentestService) ListCampaignMembers added in v0.1.3

func (s *PentestService) ListCampaignMembers(ctx context.Context, tenantID, campaignID string) ([]*pentest.CampaignMember, error)

ListCampaignMembers returns all members of a campaign.

func (*PentestService) ListCampaigns added in v0.1.2

ListCampaigns lists campaigns with filtering and pagination.

func (*PentestService) ListFindings added in v0.1.2

ListFindings lists findings with filtering and pagination.

func (*PentestService) ListReports added in v0.1.2

ListReports lists reports with filtering.

func (*PentestService) ListRetests added in v0.1.2

func (s *PentestService) ListRetests(ctx context.Context, tenantID, findingID string) ([]*pentest.Retest, error)

ListRetests lists retests for a finding.

func (*PentestService) ListTemplates added in v0.1.2

ListTemplates lists templates with filtering.

func (*PentestService) ListUnifiedCampaignFindings added in v0.1.2

func (s *PentestService) ListUnifiedCampaignFindings(ctx context.Context, tenantID, campaignID string, page pagination.Pagination) (pagination.Result[*vulnerability.Finding], error)

ListUnifiedCampaignFindings lists pentest findings from the unified findings table filtered by campaign.

func (*PentestService) RemoveCampaignMember added in v0.1.3

func (s *PentestService) RemoveCampaignMember(ctx context.Context, input CampaignRemoveMemberInput) error

RemoveCampaignMember removes a user from a campaign. Validates: not removing last lead, not self-removing if lead.

func (*PentestService) ResolveCampaignRoleForFinding added in v0.1.3

func (s *PentestService) ResolveCampaignRoleForFinding(ctx context.Context, tenantID, findingID, userID string, isAdmin bool) (pentest.CampaignRole, *vulnerability.Finding, error)

ResolveCampaignRoleForFinding resolves the caller's campaign role from a unified finding. Used by finding-direct routes where campaign ID is not in the URL. Returns role and the finding. Admin callers get empty role (bypass enforced elsewhere).

func (*PentestService) SetCampaignMemberRepository added in v0.1.3

func (s *PentestService) SetCampaignMemberRepository(repo pentest.CampaignMemberRepository)

SetCampaignMemberRepository sets the campaign member repository.

func (*PentestService) SetTenantMemberChecker added in v0.1.3

func (s *PentestService) SetTenantMemberChecker(checker TenantMemberChecker)

SetTenantMemberChecker sets the tenant membership validator.

func (*PentestService) SetUnifiedFindingRepository added in v0.1.2

func (s *PentestService) SetUnifiedFindingRepository(repo vulnerability.FindingRepository)

SetUnifiedFindingRepository sets the unified finding repository for CTEM integration. When set, pentest findings are created in the findings table (source='pentest').

func (*PentestService) SetUserNotificationService added in v0.1.2

func (s *PentestService) SetUserNotificationService(svc *NotificationService)

SetUserNotificationService sets the in-app notification service.

func (*PentestService) UpdateCampaign added in v0.1.2

func (s *PentestService) UpdateCampaign(ctx context.Context, input UpdateCampaignInput) (*pentest.Campaign, error)

UpdateCampaign updates an existing campaign.

func (*PentestService) UpdateCampaignMemberRole added in v0.1.3

func (s *PentestService) UpdateCampaignMemberRole(ctx context.Context, input CampaignUpdateMemberRoleInput) error

UpdateCampaignMemberRole changes a member's role. Validates: not demoting the last lead.

func (*PentestService) UpdateCampaignStatus added in v0.1.2

func (s *PentestService) UpdateCampaignStatus(ctx context.Context, tenantID, campaignID, newStatus string) (*StatusChangeResult, error)

UpdateCampaignStatus transitions the campaign status. Returns a warning if completing with open findings (does not block).

func (*PentestService) UpdateFinding added in v0.1.2

func (s *PentestService) UpdateFinding(ctx context.Context, tenantID, findingID string, input PentestFindingInput) (*pentest.Finding, error)

UpdateFinding updates a pentest finding.

func (*PentestService) UpdateFindingStatus added in v0.1.2

func (s *PentestService) UpdateFindingStatus(ctx context.Context, tenantID, findingID, newStatus, actorID string) (*pentest.Finding, error)

UpdateFindingStatus transitions the finding status.

func (*PentestService) UpdatePentestFindingStatus added in v0.1.2

func (s *PentestService) UpdatePentestFindingStatus(ctx context.Context, tenantID, findingID, newStatus, actorID string) (*vulnerability.Finding, error)

UpdatePentestFindingStatus transitions a pentest finding's status with validation.

func (*PentestService) UpdateTemplate added in v0.1.2

func (s *PentestService) UpdateTemplate(ctx context.Context, tenantID, id string, input CreateTemplateInput) (*pentest.Template, error)

UpdateTemplate updates a template. Returns error if system template.

func (*PentestService) UpdateUnifiedFinding added in v0.1.2

func (s *PentestService) UpdateUnifiedFinding(ctx context.Context, tenantID, findingID string, input PentestFindingInput) (*vulnerability.Finding, error)

UpdateUnifiedFinding updates a pentest finding in the unified findings table.

type PentestSourceMetadata added in v0.1.2

type PentestSourceMetadata struct {
	StepsToReproduce    []string         `json:"steps_to_reproduce,omitempty"`
	PoCCode             string           `json:"poc_code,omitempty"`
	Evidence            []map[string]any `json:"evidence,omitempty"`
	RequestResponses    []map[string]any `json:"request_responses,omitempty"`
	BusinessImpact      string           `json:"business_impact,omitempty"`
	TechnicalImpact     string           `json:"technical_impact,omitempty"`
	RemediationGuidance string           `json:"remediation_guidance,omitempty"`
	ReviewedBy          string           `json:"reviewed_by,omitempty"`
	OWASPCategory       string           `json:"owasp_category,omitempty"`
	CWEID               string           `json:"cwe_id,omitempty"`
	AffectedAssets      []string         `json:"affected_assets,omitempty"`
	ReferenceURLs       []string         `json:"reference_urls,omitempty"`
}

PentestSourceMetadata holds pentest-specific data stored in findings.source_metadata JSONB.

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 PlatformStatsOutput added in v0.1.2

type PlatformStatsOutput struct {
	Enabled         bool
	MaxTier         string
	AccessibleTiers []string
	MaxConcurrent   int
	MaxQueued       int
	CurrentActive   int
	CurrentQueued   int
	AvailableSlots  int
	TierStats       map[string]PlatformTierStats
}

PlatformStatsOutput represents the output for platform stats.

type PlatformTierStats added in v0.1.2

type PlatformTierStats struct {
	TotalAgents    int
	OnlineAgents   int
	OfflineAgents  int
	TotalCapacity  int
	CurrentLoad    int
	AvailableSlots int
}

PlatformTierStats represents statistics for a single platform agent tier.

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 PreviewScopeRuleResult added in v0.1.2

type PreviewScopeRuleResult struct {
	RuleID          string `json:"rule_id"`
	RuleName        string `json:"rule_name"`
	MatchingAssets  int    `json:"matching_assets"`
	AlreadyAssigned int    `json:"already_assigned"`
	WouldAdd        int    `json:"would_add"`
}

PreviewScopeRuleResult shows what assets would be affected by a rule.

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 ReconcileGroupResult added in v0.1.2

type ReconcileGroupResult struct {
	RulesEvaluated int `json:"rules_evaluated"`
	AssetsAdded    int `json:"assets_added"`
	AssetsRemoved  int `json:"assets_removed"`
}

ReconcileGroupResult shows the result of a reconciliation run.

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 RejectApprovalInput added in v0.1.2

type RejectApprovalInput struct {
	TenantID   string `json:"tenant_id" validate:"required,uuid"`
	ApprovalID string `json:"approval_id" validate:"required,uuid"`
	RejectedBy string `json:"rejected_by" validate:"required,uuid"`
	Reason     string `json:"reason" validate:"required,min=1,max=2000"`
}

RejectApprovalInput represents the input for rejecting a status change.

type RejectByFilterInput added in v0.1.3

type RejectByFilterInput struct {
	Filter vulnerability.FindingFilter
	Reason string
}

RejectByFilterInput is the input for bulk reject by filter.

type RelationshipTypeUsage added in v0.1.5

type RelationshipTypeUsage struct {
	ID          string `json:"id"`
	Direct      string `json:"direct"`
	Inverse     string `json:"inverse"`
	Description string `json:"description"`
	Category    string `json:"category"`
	// Count is the number of relationships of this type that exist
	// for the tenant. 0 means the type is registered but unused —
	// a candidate for removal from the registry.
	Count int64 `json:"count"`
}

RelationshipTypeUsage holds usage stats for a single relationship type.

type RenderedTemplates added in v0.1.5

type RenderedTemplates struct {
	YAML   string `json:"yaml"`
	Env    string `json:"env"`
	Docker string `json:"docker"`
	CLI    string `json:"cli"`
}

RenderedTemplates is the output of rendering all templates for one agent.

type RepositoryStatsData

type RepositoryStatsData struct {
	Total        int
	WithFindings int
}

RepositoryStatsData holds raw repository statistics from repository.

type RequestApprovalInput added in v0.1.2

type RequestApprovalInput struct {
	TenantID        string  `json:"tenant_id" validate:"required,uuid"`
	FindingID       string  `json:"finding_id" validate:"required,uuid"`
	RequestedStatus string  `json:"requested_status" validate:"required"`
	Justification   string  `json:"justification" validate:"required,min=1,max=2000"`
	RequestedBy     string  `json:"requested_by" validate:"required,uuid"`
	ExpiresAt       *string `json:"expires_at"`
}

RequestApprovalInput represents the input for requesting a status approval.

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 RiskScorePreviewItem added in v0.1.2

type RiskScorePreviewItem struct {
	AssetID      string `json:"asset_id"`
	AssetName    string `json:"asset_name"`
	AssetType    string `json:"asset_type"`
	CurrentScore int    `json:"current_score"`
	NewScore     int    `json:"new_score"`
	Delta        int    `json:"delta"`
}

RiskScorePreviewItem represents how an asset's risk score would change.

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 SMTPAvailabilityCheck added in v0.1.5

type SMTPAvailabilityCheck interface {
	// HasSystemSMTP returns true if the platform has system-wide SMTP configured.
	HasSystemSMTP() bool
	// HasTenantSMTP returns true if the given tenant has a custom SMTP integration.
	// tenantID may be empty for self-registration (no tenant context yet).
	HasTenantSMTP(ctx context.Context, tenantID string) bool
}

SMTPAvailabilityCheck reports whether outbound email is available, either via the system SMTP config or for a specific tenant. Used by smart email verification to skip verification when no email channel exists.

type SSOAuthorizeInput added in v0.1.2

type SSOAuthorizeInput struct {
	OrgSlug     string
	Provider    string
	RedirectURI string // Frontend callback URL
}

SSOAuthorizeInput is the input for generating an SSO authorization URL.

type SSOAuthorizeResult added in v0.1.2

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

SSOAuthorizeResult is the result of generating an SSO authorization URL.

type SSOCallbackInput added in v0.1.2

type SSOCallbackInput struct {
	Provider    string
	Code        string
	State       string
	RedirectURI string
}

SSOCallbackInput is the input for handling an SSO callback.

type SSOCallbackResult added in v0.1.2

type SSOCallbackResult 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"`
	TenantID     string     `json:"tenant_id"`
	TenantSlug   string     `json:"tenant_slug"`
}

SSOCallbackResult is the result of a successful SSO callback.

type SSOProviderInfo added in v0.1.2

type SSOProviderInfo struct {
	ID          string `json:"id"`
	Provider    string `json:"provider"`
	DisplayName string `json:"display_name"`
}

SSOProviderInfo represents a public SSO provider for a tenant.

type SSOService added in v0.1.2

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

SSOService handles per-tenant SSO authentication.

func NewSSOService added in v0.1.2

func NewSSOService(
	ipRepo identityprovider.Repository,
	tenantRepo tenant.Repository,
	userRepo user.Repository,
	sessionRepo session.Repository,
	refreshTokenRepo session.RefreshTokenRepository,
	encryptor crypto.Encryptor,
	authCfg config.AuthConfig,
	log *logger.Logger,
) *SSOService

NewSSOService creates a new SSOService.

func (*SSOService) CreateProvider added in v0.1.2

CreateProvider creates a new identity provider configuration for a tenant.

func (*SSOService) DeleteProvider added in v0.1.2

func (s *SSOService) DeleteProvider(ctx context.Context, tenantID, id string) error

DeleteProvider deletes an identity provider configuration.

func (*SSOService) GenerateAuthorizeURL added in v0.1.2

func (s *SSOService) GenerateAuthorizeURL(ctx context.Context, input SSOAuthorizeInput) (*SSOAuthorizeResult, error)

GenerateAuthorizeURL builds the OAuth authorization URL for a tenant's SSO provider.

func (*SSOService) GetProvider added in v0.1.2

func (s *SSOService) GetProvider(ctx context.Context, tenantID, id string) (*identityprovider.IdentityProvider, error)

GetProvider retrieves a provider configuration by ID.

func (*SSOService) GetProvidersForTenant added in v0.1.2

func (s *SSOService) GetProvidersForTenant(ctx context.Context, orgSlug string) ([]SSOProviderInfo, error)

GetProvidersForTenant returns active SSO providers for a tenant identified by slug.

func (*SSOService) HandleCallback added in v0.1.2

func (s *SSOService) HandleCallback(ctx context.Context, input SSOCallbackInput) (*SSOCallbackResult, error)

HandleCallback handles the SSO OAuth callback.

func (*SSOService) ListProviders added in v0.1.2

func (s *SSOService) ListProviders(ctx context.Context, tenantID string) ([]*identityprovider.IdentityProvider, error)

ListProviders lists all identity provider configurations for a tenant.

func (*SSOService) SetTenantMemberRepo added in v0.1.2

func (s *SSOService) SetTenantMemberRepo(repo TenantMemberCreator)

SetTenantMemberRepo sets the tenant membership creator for auto-provisioning.

func (*SSOService) UpdateProvider added in v0.1.2

UpdateProvider updates an identity provider configuration.

type SSOUserInfo added in v0.1.2

type SSOUserInfo struct {
	Email     string
	Name      string
	AvatarURL string
}

SSOUserInfo represents user info from SSO provider.

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 ScopeRuleBroadcaster added in v0.1.2

type ScopeRuleBroadcaster interface {
	BroadcastScopeChange(channel string, data any, tenantID string)
}

ScopeRuleBroadcaster broadcasts scope rule membership change events via WebSocket.

type ScopeRuleEvaluatorFunc added in v0.1.2

type ScopeRuleEvaluatorFunc func(ctx context.Context, tenantID, assetID shared.ID, tags []string, assetGroupIDs []shared.ID) error

ScopeRuleEvaluatorFunc is the callback type for scope rule evaluation. Used by AssetService to trigger evaluation when asset tags change.

type ScopeRuleGroupReconcilerFunc added in v0.1.2

type ScopeRuleGroupReconcilerFunc func(ctx context.Context, assetGroupID shared.ID)

ScopeRuleGroupReconcilerFunc is the callback type for asset group membership changes. Called when assets are added/removed from an asset group.

type ScopeRuleService added in v0.1.2

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

ScopeRuleService handles scope rule business operations.

func NewScopeRuleService added in v0.1.2

func NewScopeRuleService(
	acRepo accesscontrol.Repository,
	groupRepo group.Repository,
	log *logger.Logger,
) *ScopeRuleService

NewScopeRuleService creates a new ScopeRuleService.

func (*ScopeRuleService) CreateScopeRule added in v0.1.2

func (s *ScopeRuleService) CreateScopeRule(ctx context.Context, input CreateScopeRuleInput, createdBy string) (*accesscontrol.ScopeRule, error)

CreateScopeRule creates a new scope rule and runs initial reconciliation.

func (*ScopeRuleService) DeleteScopeRule added in v0.1.2

func (s *ScopeRuleService) DeleteScopeRule(ctx context.Context, tenantID, ruleID string) error

DeleteScopeRule deletes a scope rule and removes its auto-assignments atomically.

func (*ScopeRuleService) EvaluateAsset added in v0.1.2

func (s *ScopeRuleService) EvaluateAsset(ctx context.Context, tenantID shared.ID, assetID shared.ID, tags []string, assetGroupIDs []shared.ID) error

EvaluateAsset evaluates all active scope rules in a tenant against a single asset. Called when an asset is created or its tags change. It both adds new matches and removes stale auto-assignments for groups that no longer match.

func (*ScopeRuleService) GetScopeRule added in v0.1.2

func (s *ScopeRuleService) GetScopeRule(ctx context.Context, tenantID, ruleID string) (*accesscontrol.ScopeRule, error)

GetScopeRule retrieves a scope rule by ID with tenant isolation.

func (*ScopeRuleService) ListScopeRules added in v0.1.2

func (s *ScopeRuleService) ListScopeRules(ctx context.Context, tenantID, groupID string, filter accesscontrol.ScopeRuleFilter) ([]*accesscontrol.ScopeRule, int64, error)

ListScopeRules lists scope rules for a group with tenant isolation.

func (*ScopeRuleService) PreviewScopeRule added in v0.1.2

func (s *ScopeRuleService) PreviewScopeRule(ctx context.Context, tenantID, ruleID string) (*PreviewScopeRuleResult, error)

PreviewScopeRule shows what assets would match a rule without applying changes.

func (*ScopeRuleService) ReconcileByAssetGroup added in v0.1.2

func (s *ScopeRuleService) ReconcileByAssetGroup(ctx context.Context, assetGroupID shared.ID)

ReconcileByAssetGroup finds all access control groups that have scope rules referencing the given asset group, and reconciles each one. Called when asset group membership changes (assets added/removed).

func (*ScopeRuleService) ReconcileGroup added in v0.1.2

func (s *ScopeRuleService) ReconcileGroup(ctx context.Context, tenantID, groupID string) (*ReconcileGroupResult, error)

ReconcileGroup re-evaluates all active scope rules for a group. It adds newly matching assets AND removes stale auto-assigned assets that no longer match.

func (*ScopeRuleService) ReconcileGroupByIDs added in v0.1.2

func (s *ScopeRuleService) ReconcileGroupByIDs(ctx context.Context, tenantID, groupID shared.ID) error

ReconcileGroupByIDs reconciles a group using parsed IDs (for use by background controller).

func (*ScopeRuleService) SetAssetGroupValidator added in v0.1.2

func (s *ScopeRuleService) SetAssetGroupValidator(v assetGroupValidator)

SetAssetGroupValidator sets the validator for cross-tenant asset group validation. The AccessControlRepository implements this interface.

func (*ScopeRuleService) SetBroadcaster added in v0.1.2

func (s *ScopeRuleService) SetBroadcaster(b ScopeRuleBroadcaster)

SetBroadcaster sets the WebSocket broadcaster for real-time UI updates.

func (*ScopeRuleService) UpdateScopeRule added in v0.1.2

func (s *ScopeRuleService) UpdateScopeRule(ctx context.Context, tenantID, ruleID string, input UpdateScopeRuleInput) (*accesscontrol.ScopeRule, error)

UpdateScopeRule updates an existing scope rule.

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, tenantID string) (*scope.Exclusion, error)

ActivateExclusion activates a scope exclusion.

func (*ScopeService) ActivateTarget

func (s *ScopeService) ActivateTarget(ctx context.Context, targetID string, tenantID string) (*scope.Target, error)

ActivateTarget activates a scope target.

func (*ScopeService) ApproveExclusion

func (s *ScopeService) ApproveExclusion(ctx context.Context, exclusionID string, tenantID string, approvedBy string) (*scope.Exclusion, error)

ApproveExclusion approves a scope exclusion.

func (*ScopeService) CheckPatternOverlaps added in v0.1.2

func (s *ScopeService) CheckPatternOverlaps(ctx context.Context, tenantID string, targetType string, pattern string) ([]string, error)

CheckPatternOverlaps checks if a new target pattern overlaps with existing patterns. Returns a list of warning messages describing the overlaps (non-blocking).

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, tenantID string) (*scope.Exclusion, error)

DeactivateExclusion deactivates a scope exclusion.

func (*ScopeService) DeactivateTarget

func (s *ScopeService) DeactivateTarget(ctx context.Context, targetID string, tenantID 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 with atomic tenant verification.

func (*ScopeService) DeleteSchedule

func (s *ScopeService) DeleteSchedule(ctx context.Context, scheduleID string, tenantID string) error

DeleteSchedule deletes a scan schedule by ID with atomic tenant verification.

func (*ScopeService) DeleteTarget

func (s *ScopeService) DeleteTarget(ctx context.Context, targetID string, tenantID string) error

DeleteTarget deletes a scope target by ID with atomic tenant verification.

func (*ScopeService) DisableSchedule

func (s *ScopeService) DisableSchedule(ctx context.Context, scheduleID string, tenantID string) (*scope.Schedule, error)

DisableSchedule disables a scan schedule.

func (*ScopeService) EnableSchedule

func (s *ScopeService) EnableSchedule(ctx context.Context, scheduleID string, tenantID 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, tenantID string, exclusionID string) (*scope.Exclusion, error)

GetExclusion retrieves a scope exclusion by tenant ID and ID.

func (*ScopeService) GetSchedule

func (s *ScopeService) GetSchedule(ctx context.Context, tenantID string, scheduleID string) (*scope.Schedule, error)

GetSchedule retrieves a scan schedule by tenant ID and 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, tenantID string, targetID string) (*scope.Target, error)

GetTarget retrieves a scope target by tenant ID and 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, tenantID string, scheduleID string, status string, nextRunAt *time.Time) (*scope.Schedule, error)

RecordScheduleRun records a scan run for a schedule.

func (*ScopeService) RunScheduleNow added in v0.1.2

func (s *ScopeService) RunScheduleNow(ctx context.Context, scheduleID string, tenantID string) (*scope.Schedule, error)

RunScheduleNow triggers an immediate run of a scan 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 StatusChangeResult added in v0.1.3

type StatusChangeResult struct {
	Campaign *pentest.Campaign
	Warning  string
}

StatusChangeResult wraps campaign + optional warning for status transitions.

type SubModuleInfo added in v0.1.2

type SubModuleInfo struct {
	Module    *module.Module
	IsEnabled bool
}

SubModuleInfo combines sub-module metadata with tenant-specific enabled state.

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 TenantMemberChecker added in v0.1.3

type TenantMemberChecker interface {
	IsTenantMember(ctx context.Context, tenantID, userID string) bool
}

TenantMemberChecker verifies if a user belongs to a tenant.

type TenantMemberCreator added in v0.1.2

type TenantMemberCreator interface {
	CreateMembership(ctx context.Context, m *tenant.Membership) error
}

TenantMemberCreator creates tenant memberships for auto-provisioned users.

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 TenantModuleConfigOutput added in v0.1.2

type TenantModuleConfigOutput struct {
	Modules []*TenantModuleInfo
	Summary TenantModuleSummary
}

TenantModuleConfigOutput represents the full module configuration for a tenant.

type TenantModuleInfo added in v0.1.2

type TenantModuleInfo struct {
	Module     *module.Module
	IsEnabled  bool
	SubModules []*SubModuleInfo
}

TenantModuleInfo combines module metadata with tenant-specific enabled state.

type TenantModuleRepository added in v0.1.2

type TenantModuleRepository interface {
	ListByTenant(ctx context.Context, tenantID shared.ID) ([]*module.TenantModuleOverride, error)
	UpsertBatch(ctx context.Context, tenantID shared.ID, updates []module.TenantModuleUpdate, updatedBy *shared.ID) error
	DeleteByTenant(ctx context.Context, tenantID shared.ID) error
}

TenantModuleRepository interface for per-tenant module configuration.

type TenantModuleSummary added in v0.1.2

type TenantModuleSummary struct {
	Total    int
	Enabled  int
	Disabled int
	Core     int
}

TenantModuleSummary provides counts of module states.

type TenantSMTPResolver added in v0.1.4

type TenantSMTPResolver interface {
	GetTenantSMTPConfig(ctx context.Context, tenantID string) (*email.Config, error)
}

TenantSMTPResolver resolves per-tenant SMTP configuration from integrations. Returns nil if tenant has no custom SMTP config (fallback to system default).

type TenantScoringConfigProvider added in v0.1.2

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

TenantScoringConfigProvider implements asset.ScoringConfigProvider by reading scoring settings from the tenant repository.

func NewTenantScoringConfigProvider added in v0.1.2

func NewTenantScoringConfigProvider(tenantRepo tenant.Repository) *TenantScoringConfigProvider

NewTenantScoringConfigProvider creates a new scoring config provider.

func (*TenantScoringConfigProvider) GetScoringConfig added in v0.1.2

func (p *TenantScoringConfigProvider) GetScoringConfig(ctx context.Context, tenantID shared.ID) (*asset.RiskScoringConfig, error)

GetScoringConfig returns the risk scoring config for a tenant.

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) GetPentestSettings added in v0.1.2

func (s *TenantService) GetPentestSettings(ctx context.Context, tenantID string) (*tenant.PentestSettings, error)

GetPentestSettings returns the current pentest settings for a tenant. Returns system defaults if the tenant has not customized pentest settings.

func (*TenantService) GetRiskScoringSettings added in v0.1.2

func (s *TenantService) GetRiskScoringSettings(ctx context.Context, tenantID string) (*tenant.RiskScoringSettings, error)

GetRiskScoringSettings returns the current risk scoring settings for a tenant.

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) LogAuditEvent added in v0.1.2

func (s *TenantService) LogAuditEvent(ctx context.Context, actx AuditContext, event AuditEvent)

LogAuditEvent logs an audit event via the tenant service's audit service. This is the public variant of logAudit, intended for use by handlers that need to log audit events for operations not managed by the service layer.

func (*TenantService) ReactivateMember added in v0.1.5

func (s *TenantService) ReactivateMember(ctx context.Context, membershipID string, actx AuditContext) error

ReactivateMember restores a suspended member's access.

func (*TenantService) RemoveMember

func (s *TenantService) RemoveMember(ctx context.Context, membershipID string, actx AuditContext) error

RemoveMember removes a member from a tenant.

func (*TenantService) ResendInvitation added in v0.1.5

func (s *TenantService) ResendInvitation(ctx context.Context, tenantID, invitationID string, actx AuditContext) error

ResendInvitation re-enqueues the invitation email for a pending invitation. Does NOT change the token, expiry, or any other fields on the invitation row — just fires the email again. This lets admins recover from lost/spam-filtered invitation emails without having to delete + recreate (which invalidates the old token).

Returns ErrNotFound if the invitation doesn't exist, and ErrValidation if the invitation has already been accepted or has expired.

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) SuspendMember added in v0.1.5

func (s *TenantService) SuspendMember(ctx context.Context, membershipID string, actx AuditContext) error

SuspendMember suspends a member's access to a tenant. The membership row stays in the database (preserving audit trail, ownership attribution, and compliance evidence), but the user's access is immediately revoked: sessions are invalidated, permission cache cleared, and JWT exchange should check membership status.

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) UpdatePentestSettings added in v0.1.2

func (s *TenantService) UpdatePentestSettings(ctx context.Context, tenantID string, input UpdatePentestSettingsInput, actx AuditContext) (*tenant.Settings, error)

UpdatePentestSettings updates only the pentest settings.

func (*TenantService) UpdateRiskScoringSettings added in v0.1.2

func (s *TenantService) UpdateRiskScoringSettings(ctx context.Context, tenantID string, rs tenant.RiskScoringSettings, actx AuditContext) (*tenant.Settings, error)

UpdateRiskScoringSettings updates only the risk scoring settings.

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 TestRuleFindingSummary added in v0.1.2

type TestRuleFindingSummary struct {
	ID       string `json:"id"`
	Severity string `json:"severity"`
	Source   string `json:"source"`
	ToolName string `json:"tool_name"`
	Message  string `json:"message"`
}

TestRuleFindingSummary represents a finding matched during rule testing.

type TestRuleResult added in v0.1.2

type TestRuleResult struct {
	RuleID           string                   `json:"rule_id"`
	RuleName         string                   `json:"rule_name"`
	MatchingFindings int64                    `json:"matching_findings"`
	TargetGroupID    string                   `json:"target_group_id"`
	SampleFindings   []TestRuleFindingSummary `json:"sample_findings,omitempty"`
}

TestRuleResult represents the result of testing a rule against existing findings.

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,
	toolRepo tool.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 UpdateAssessmentInput added in v0.1.2

type UpdateAssessmentInput struct {
	TenantID    string
	FrameworkID string
	ControlID   string
	Status      string
	Priority    string
	Owner       string
	Notes       string
	DueDate     *string
	ActorID     string
}

UpdateAssessmentInput contains input for updating an assessment.

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"`
	OwnerRef    *string  `validate:"omitempty,max=500"` // Free-text owner reference
	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 UpdateCampaignInput added in v0.1.2

type UpdateCampaignInput struct {
	TenantID          string
	CampaignID        string
	Name              string
	Description       string
	CampaignType      string
	Priority          string
	Methodology       string
	ClientName        string
	ClientContact     string
	StartDate         *string
	EndDate           *string
	Objectives        []string
	ScopeItems        []map[string]any
	RulesOfEngagement map[string]any
	LeadUserID        *string
	TeamUserIDs       []string
	AssetIDs          []string
	AssetGroupIDs     []string
	Tags              []string
}

UpdateCampaignInput contains the input for updating a campaign.

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)
	HasVerifyPermission bool   // True if user has findings:verify permission (for direct resolve guard)
}

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"`
	NotificationConfig *group.NotificationConfig `json:"notification_config,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 UpdatePentestSettingsInput added in v0.1.2

type UpdatePentestSettingsInput struct {
	CampaignTypes []tenant.ConfigOption `json:"campaign_types"`
	Methodologies []tenant.ConfigOption `json:"methodologies"`
}

UpdatePentestSettingsInput represents input for updating pentest settings.

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 UpdatePreferencesInput added in v0.1.2

type UpdatePreferencesInput struct {
	InAppEnabled *bool    `json:"in_app_enabled"`
	EmailDigest  *string  `json:"email_digest"` // "none", "daily", "weekly"
	MutedTypes   []string `json:"muted_types"`
	MinSeverity  *string  `json:"min_severity"`
}

UpdatePreferencesInput represents input for updating notification preferences.

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 UpdateProviderInput added in v0.1.2

type UpdateProviderInput struct {
	ID               string
	TenantID         string // For authorization check
	DisplayName      *string
	ClientID         *string
	ClientSecret     *string // Plaintext - will be encrypted if provided
	IssuerURL        *string
	TenantIdentifier *string
	Scopes           []string
	AllowedDomains   []string
	AutoProvision    *bool
	DefaultRole      *string
	IsActive         *bool
}

UpdateProviderInput is the input for updating an identity provider config.

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 UpdateRuleInput added in v0.1.2

type UpdateRuleInput struct {
	Name          *string                             `json:"name" validate:"omitempty,min=2,max=200"`
	Description   *string                             `json:"description" validate:"omitempty,max=1000"`
	Priority      *int                                `json:"priority"`
	IsActive      *bool                               `json:"is_active"`
	Conditions    *accesscontrol.AssignmentConditions `json:"conditions"`
	TargetGroupID *string                             `json:"target_group_id" validate:"omitempty,uuid"`
	Options       *accesscontrol.AssignmentOptions    `json:"options"`
}

UpdateRuleInput represents the input for updating an assignment rule.

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 UpdateScopeRuleInput added in v0.1.2

type UpdateScopeRuleInput struct {
	Name               *string  `json:"name" validate:"omitempty,min=2,max=200"`
	Description        *string  `json:"description" validate:"omitempty,max=1000"`
	MatchTags          []string `json:"match_tags"`
	MatchLogic         *string  `json:"match_logic" validate:"omitempty,oneof=any all"`
	MatchAssetGroupIDs []string `json:"match_asset_group_ids"`
	OwnershipType      *string  `json:"ownership_type" validate:"omitempty,oneof=primary secondary stakeholder informed"`
	Priority           *int     `json:"priority"`
	IsActive           *bool    `json:"is_active"`
}

UpdateScopeRuleInput represents the input for updating a scope rule.

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"`
	EmailVerificationMode string   `json:"email_verification_mode" validate:"omitempty,oneof=auto always never"`
}

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 UserMatcher added in v0.1.5

type UserMatcher interface {
	FindUserIDByEmail(ctx context.Context, tenantID shared.ID, email string) (*shared.ID, error)
}

UserMatcher resolves external references (email, username) to user IDs.

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) 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) 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 VerifyByFilterInput added in v0.1.3

type VerifyByFilterInput struct {
	Filter vulnerability.FindingFilter
	Note   string
}

VerifyByFilterInput is the input for bulk verify by filter.

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) ApproveStatus added in v0.1.2

ApproveStatus approves a pending status change request and applies the status change.

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) BulkUpdateFindingStatus added in v0.1.2

func (s *VulnerabilityService) BulkUpdateFindingStatus(ctx context.Context, tenantID shared.ID, ids []shared.ID, status vulnerability.FindingStatus, resolution string, resolvedBy *shared.ID) error

BulkUpdateFindingStatus updates the status of multiple findings. Pentest findings are excluded — they must be managed via the pentest module.

func (*VulnerabilityService) BulkUpdateFindingsStatus

func (s *VulnerabilityService) BulkUpdateFindingsStatus(ctx context.Context, tenantID string, input BulkUpdateStatusInput) (*BulkUpdateResult, error)

BulkUpdateFindingsStatus updates the status of multiple findings. Optimized: batch-fetches all findings in 1 query, validates transitions in-memory, then batch-updates valid ones in 1 query. Reduces N+1 to 2 queries total.

func (*VulnerabilityService) CancelApproval added in v0.1.2

CancelApproval cancels a pending approval request. Only the requester can cancel.

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) GetFindingStatsWithScope added in v0.1.2

func (s *VulnerabilityService) GetFindingStatsWithScope(ctx context.Context, input GetFindingStatsInput) (*vulnerability.FindingStats, error)

GetFindingStatsWithScope retrieves stats with optional data scope enforcement.

func (*VulnerabilityService) GetFindingWithScope added in v0.1.2

func (s *VulnerabilityService) GetFindingWithScope(ctx context.Context, tenantID, findingID, actingUserID string, isAdmin bool) (*vulnerability.Finding, error)

GetFindingWithScope retrieves a finding with optional data scope enforcement. Non-admin users with group assignments can only access findings for assets in their groups. Security: fail-closed — any error during scope check denies access. Returns ErrNotFound (not ErrForbidden) to prevent information disclosure.

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) ListFindingApprovals added in v0.1.2

func (s *VulnerabilityService) ListFindingApprovals(ctx context.Context, tenantID, findingID string) ([]*vulnerability.Approval, error)

ListFindingApprovals lists all approvals for a finding.

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) ListPendingApprovals added in v0.1.2

func (s *VulnerabilityService) ListPendingApprovals(ctx context.Context, tenantID string, page, perPage int) (pagination.Result[*vulnerability.Approval], error)

ListPendingApprovals lists all pending approvals for a tenant.

func (*VulnerabilityService) ListVulnerabilities

ListVulnerabilities retrieves vulnerabilities with filtering and pagination.

func (*VulnerabilityService) RejectApproval added in v0.1.2

RejectApproval rejects a pending status change request.

func (*VulnerabilityService) RequestApproval added in v0.1.2

RequestApproval creates a new pending approval request for a status change.

func (*VulnerabilityService) SetAITriageService

func (s *VulnerabilityService) SetAITriageService(svc *AITriageService)

SetAITriageService sets the AI triage service for auto-triage on finding creation.

func (*VulnerabilityService) SetAccessControlRepository added in v0.1.2

func (s *VulnerabilityService) SetAccessControlRepository(repo accesscontrol.Repository)

SetAccessControlRepository sets the access control repository for Layer 2 data scope checks.

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) SetApprovalRepository added in v0.1.2

func (s *VulnerabilityService) SetApprovalRepository(repo vulnerability.ApprovalRepository)

SetApprovalRepository sets the approval repository for status approval workflow.

func (*VulnerabilityService) SetAssignmentEngine added in v0.1.2

func (s *VulnerabilityService) SetAssignmentEngine(engine *AssignmentEngine)

SetAssignmentEngine sets the assignment engine for auto-routing findings to groups.

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 SetOutboxService 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) SetOutboxService added in v0.1.2

func (s *VulnerabilityService) SetOutboxService(db *sql.DB, svc *OutboxService)

SetOutboxService 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) SetUserNotificationService added in v0.1.2

func (s *VulnerabilityService) SetUserNotificationService(svc *NotificationService)

SetUserNotificationService sets the in-app notification service for user-facing notifications.

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 WebSocketBroadcaster added in v0.1.2

type WebSocketBroadcaster interface {
	BroadcastEvent(channel string, data any, tenantID string)
}

WebSocketBroadcaster broadcasts messages to WebSocket channels.

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 WithExecutorOutboxService added in v0.1.2

func WithExecutorOutboxService(svc *OutboxService) WorkflowExecutorOption

WithExecutorOutboxService 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.

Source Files

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