Documentation
¶
Overview ¶
Package module provides domain models for tenant modules and access control.
Index ¶
- Constants
- Variables
- func BuildSubModuleID(parentModuleID, subModuleName string) string
- func BuildSubModuleSlug(parentModuleID, subModuleName string) string
- func FilterModuleIDsByPermissions(moduleIDs []string, userPermissions []string, isAdmin bool) []string
- func GetCategoryDisplayName(category string) string
- func GetDefaultEventTypeIDs(eventTypes []*EventType) []string
- func GetRequiredPermission(moduleID string) string
- func ValidateSubModuleID(fullSubModuleID string) error
- type BillingCycle
- type EventType
- func (e *EventType) Category() string
- func (e *EventType) Color() string
- func (e *EventType) Description() string
- func (e *EventType) DisplayOrder() int
- func (e *EventType) ID() string
- func (e *EventType) Icon() string
- func (e *EventType) IsActive() bool
- func (e *EventType) IsDefault() bool
- func (e *EventType) Name() string
- func (e *EventType) SeverityApplicable() bool
- func (e *EventType) Slug() string
- type EventTypeCategory
- type EventTypeWithModule
- type ID
- type Module
- func (m *Module) Category() string
- func (m *Module) Description() string
- func (m *Module) DisplayOrder() int
- func (m *Module) EventTypes() []string
- func (m *Module) HasParent(parentID string) bool
- func (m *Module) ID() string
- func (m *Module) Icon() string
- func (m *Module) IsActive() bool
- func (m *Module) IsBeta() bool
- func (m *Module) IsComingSoon() bool
- func (m *Module) IsDeprecated() bool
- func (m *Module) IsReleased() bool
- func (m *Module) IsSubModule() bool
- func (m *Module) Name() string
- func (m *Module) ParentModuleID() *string
- func (m *Module) ReleaseStatus() ReleaseStatus
- func (m *Module) Slug() string
- type ModuleRepository
- type Plan
- func (p *Plan) Badge() string
- func (p *Plan) CreatedAt() time.Time
- func (p *Plan) Currency() string
- func (p *Plan) Description() string
- func (p *Plan) DisplayOrder() int
- func (p *Plan) Features() []string
- func (p *Plan) GetModuleIDs() []string
- func (p *Plan) GetModuleLimit(moduleID, metric string) int64
- func (p *Plan) HasModule(moduleID string) bool
- func (p *Plan) ID() ID
- func (p *Plan) IsActive() bool
- func (p *Plan) IsPopular() bool
- func (p *Plan) IsPublic() bool
- func (p *Plan) MaxAssets() int
- func (p *Plan) MaxUsers() int
- func (p *Plan) Modules() []PlanModule
- func (p *Plan) Name() string
- func (p *Plan) PriceMonthly() *float64
- func (p *Plan) PriceYearly() *float64
- func (p *Plan) Slug() string
- func (p *Plan) StripePriceIDMonthly() string
- func (p *Plan) StripePriceIDYearly() string
- func (p *Plan) StripeProductID() string
- func (p *Plan) SupportLevel() string
- func (p *Plan) TrialDays() int
- func (p *Plan) UpdatedAt() time.Time
- type PlanModule
- type PlanRepository
- type ReleaseStatus
- type SubscriptionRepository
- type SubscriptionStatus
- type TenantSubscription
- func (s *TenantSubscription) BillingCycle() BillingCycle
- func (s *TenantSubscription) BillingEmail() string
- func (s *TenantSubscription) CanceledAt() *time.Time
- func (s *TenantSubscription) ExpiresAt() *time.Time
- func (s *TenantSubscription) GetEnabledModuleIDs() []string
- func (s *TenantSubscription) GetModuleLimit(moduleID, metric string) int64
- func (s *TenantSubscription) HasModule(moduleID string) bool
- func (s *TenantSubscription) IsActive() bool
- func (s *TenantSubscription) LimitsOverride() map[string]any
- func (s *TenantSubscription) Plan() *Plan
- func (s *TenantSubscription) PlanID() uuid.UUID
- func (s *TenantSubscription) StartedAt() time.Time
- func (s *TenantSubscription) Status() SubscriptionStatus
- func (s *TenantSubscription) StripeCustomerID() string
- func (s *TenantSubscription) StripeSubscriptionID() string
- func (s *TenantSubscription) TenantID() uuid.UUID
Constants ¶
const ( EventCategorySystem = "system" EventCategoryAsset = "asset" EventCategoryScan = "scan" EventCategoryFinding = "finding" EventCategoryExposure = "exposure" EventCategoryCredential = "credential" EventCategoryPentest = "pentest" EventCategoryRemediation = "remediation" EventCategoryComponent = "component" EventCategoryThreatIntel = "threat_intel" )
Known event type categories.
const ( ModuleCategoryCore = "core" ModuleCategorySecurity = "security" ModuleCategoryPlatform = "platform" ModuleCategoryCompliance = "compliance" ModuleCategoryEnterprise = "enterprise" )
ModuleCategory constants
const ( // Core ModuleDashboard = "dashboard" ModuleAssets = "assets" ModuleFindings = "findings" ModuleScans = "scans" // Discovery ModuleCredentials = "credentials" ModuleComponents = "components" ModuleBranches = "branches" ModuleVulnerabilities = "vulnerabilities" // Prioritization ModuleThreatIntel = "threat_intel" ModuleExposures = "exposures" ModuleAITriage = "ai_triage" ModuleSLA = "sla" // Validation ModulePentest = "pentest" // Mobilization ModuleRemediation = "remediation" ModuleSuppressions = "suppressions" ModulePolicies = "policies" // Insights ModuleReports = "reports" ModuleAudit = "audit" // Settings ModuleIntegrations = "integrations" ModuleAgents = "agents" ModuleTeam = "team" ModuleGroups = "groups" ModuleRoles = "roles" ModuleSettings = "settings" ModuleAPIKeys = "api_keys" ModuleWebhooks = "webhooks" ModuleNotificationSettings = "notification_settings" // Data ModuleSources = "sources" ModuleSecrets = "secrets" ModuleScope = "scope" // Operations ModulePipelines = "pipelines" ModuleTools = "tools" ModuleCommands = "commands" ModuleScanProfiles = "scan_profiles" ModuleIOCs = "iocs" )
Well-known module IDs (top-level modules)
const ( ModuleIntegrationsSCM = "integrations.scm" ModuleIntegrationsNotifications = "integrations.notifications" ModuleIntegrationsWebhooks = "integrations.webhooks" ModuleIntegrationsAPI = "integrations.api" ModuleIntegrationsPipelines = "integrations.pipelines" ModuleIntegrationsTicketing = "integrations.ticketing" ModuleIntegrationsSIEM = "integrations.siem" )
Integration sub-module IDs (children of ModuleIntegrations)
const ( ModuleAITriageBulk = "ai_triage.bulk" // Bulk triage operations ModuleAITriageAuto = "ai_triage.auto" // Auto-triage on finding creation ModuleAITriageWorkflow = "ai_triage.workflow" // Workflow triggers and actions ModuleAITriageBYOK = "ai_triage.byok" // Bring Your Own Key mode ModuleAITriageAgent = "ai_triage.agent" // Self-hosted Agent mode ModuleAITriageCustomPrompts = "ai_triage.custom_prompts" // Custom prompt templates )
AI Triage sub-module IDs (children of ModuleAITriage)
const (
AITriageLimitMonthlyTokens = "monthly_token_limit" // Monthly token limit (int64, -1 = unlimited)
)
AI Triage limit keys for PlanModule.Limits
const SubModuleSeparator = "."
SubModuleSeparator is the separator used in sub-module IDs (e.g., "integrations.scm").
const SubModuleSlugSeparator = "-"
SubModuleSlugSeparator is the separator used in sub-module slugs (e.g., "integrations-scm").
Variables ¶
var ( ErrPlanNotFound = fmt.Errorf("%w: plan not found", shared.ErrNotFound) ErrPlanSlugExists = fmt.Errorf("%w: plan slug already exists", shared.ErrConflict) ErrModuleNotFound = fmt.Errorf("%w: module not found", shared.ErrNotFound) ErrEventTypeNotFound = fmt.Errorf("%w: event type not found", shared.ErrNotFound) ErrSubscriptionNotFound = fmt.Errorf("%w: subscription not found", shared.ErrNotFound) ErrInvalidPlanID = fmt.Errorf("%w: invalid plan ID format", shared.ErrValidation) ErrInvalidModuleID = fmt.Errorf("%w: invalid module ID format", shared.ErrValidation) ErrInvalidSubModuleID = fmt.Errorf("%w: invalid sub-module ID format", shared.ErrValidation) )
Domain errors.
var CategoryDisplayNames = map[string]string{ EventCategorySystem: "System", EventCategoryAsset: "Assets", EventCategoryScan: "Scans", EventCategoryFinding: "Findings", EventCategoryExposure: "Exposures", EventCategoryCredential: "Credentials", EventCategoryPentest: "Penetration Testing", EventCategoryRemediation: "Remediation", EventCategoryComponent: "Components", EventCategoryThreatIntel: "Threat Intelligence", }
CategoryDisplayNames maps category IDs to display names.
var ModulePermissionMapping = map[string]string{ ModuleDashboard: "dashboard:read", ModuleAssets: "assets:read", ModuleFindings: "findings:read", ModuleScans: "scans:read", ModuleCredentials: "findings:credentials:read", ModuleComponents: "assets:components:read", ModuleBranches: "assets:read", ModuleVulnerabilities: "findings:vulnerabilities:read", ModuleThreatIntel: "threat_intel:read", ModuleExposures: "findings:exposures:read", ModuleAITriage: "ai_triage:read", ModuleSLA: "settings:sla:read", ModulePentest: "validation:read", ModuleRemediation: "findings:remediation:read", ModuleSuppressions: "findings:suppressions:read", ModulePolicies: "findings:policies:read", ModuleReports: "reports:read", ModuleAudit: "audit:read", ModuleIntegrations: "integrations:read", ModuleAgents: "agents:read", ModuleTeam: "team:read", ModuleGroups: "team:groups:read", ModuleRoles: "team:roles:read", ModuleSettings: "settings:read", ModuleAPIKeys: "integrations:api_keys:read", ModuleWebhooks: "integrations:webhooks:read", ModuleNotificationSettings: "integrations:notifications:read", ModuleSources: "scans:sources:read", ModuleSecrets: "scans:secret_store:read", ModuleScope: "attack_surface:scope:read", ModulePipelines: "integrations:pipelines:read", ModuleTools: "scans:tools:read", ModuleScanProfiles: "scans:profiles:read", }
ModulePermissionMapping maps module IDs to their required read permissions. This is used to filter modules based on user's RBAC permissions. A user must have at least the read permission to see the module in sidebar. These permissions MUST match the permission IDs seeded in 000005_permissions.up.sql
Functions ¶
func BuildSubModuleID ¶
BuildSubModuleID constructs a sub-module ID from parent and child. Example: BuildSubModuleID("integrations", "scm") returns "integrations.scm"
func BuildSubModuleSlug ¶
BuildSubModuleSlug constructs a sub-module slug from parent and child. Example: BuildSubModuleSlug("integrations", "scm") returns "integrations-scm"
func FilterModuleIDsByPermissions ¶
func FilterModuleIDsByPermissions(moduleIDs []string, userPermissions []string, isAdmin bool) []string
FilterModuleIDsByPermissions filters module IDs based on user's permissions.
func GetCategoryDisplayName ¶
GetCategoryDisplayName returns the display name for a category.
func GetDefaultEventTypeIDs ¶
GetDefaultEventTypeIDs returns the IDs of event types that are default enabled.
func GetRequiredPermission ¶
GetRequiredPermission returns the required permission for a module. Returns empty string if the module has no permission requirement.
func ValidateSubModuleID ¶
ValidateSubModuleID validates that a sub-module ID follows the correct format. Returns error if the ID is malformed (e.g., double separator, empty parts).
Types ¶
type BillingCycle ¶
type BillingCycle string
BillingCycle represents the billing frequency.
const ( BillingMonthly BillingCycle = "monthly" BillingYearly BillingCycle = "yearly" )
type EventType ¶
type EventType struct {
// contains filtered or unexported fields
}
EventType represents a notification event type stored in the database. This is the single source of truth for all event types in the system.
func ReconstructEventType ¶
func ReconstructEventType( id, slug, name, description, category, icon, color string, severityApplicable, isDefault, isActive bool, displayOrder int, ) *EventType
ReconstructEventType creates an EventType from stored data.
func (*EventType) Description ¶
func (*EventType) DisplayOrder ¶
func (*EventType) SeverityApplicable ¶
type EventTypeCategory ¶
type EventTypeCategory struct {
ID string `json:"id"`
Name string `json:"name"`
EventTypes []*EventType `json:"event_types"`
}
EventTypeCategory represents a category of event types for UI grouping.
func GroupEventTypesByCategory ¶
func GroupEventTypesByCategory(eventTypes []*EventType) []EventTypeCategory
GroupEventTypesByCategory groups event types by their category.
type EventTypeWithModule ¶
EventTypeWithModule represents an event type with its associated module ID.
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module represents a feature module in the system.
func FilterModulesByPermissions ¶
func FilterModulesByPermissions(modules []*Module, userPermissions []string, isAdmin bool) []*Module
FilterModulesByPermissions filters modules based on user's permissions. Returns only modules that the user has at least read permission for. Admin/Owner users should pass isAdmin=true to bypass permission checks.
func ReconstructModule ¶
func ReconstructModule( id, slug, name, description, icon, category string, displayOrder int, isActive bool, releaseStatus string, parentModuleID *string, eventTypes []string, ) *Module
ReconstructModule creates a Module from stored data.
func (*Module) Description ¶
func (*Module) DisplayOrder ¶
func (*Module) EventTypes ¶
func (*Module) IsComingSoon ¶
IsComingSoon returns true if the module is not released yet.
func (*Module) IsDeprecated ¶
IsDeprecated returns true if the module is being phased out.
func (*Module) IsReleased ¶
IsReleased returns true if the module is generally available.
func (*Module) IsSubModule ¶
IsSubModule returns true if this module has a parent module.
func (*Module) ParentModuleID ¶
func (*Module) ReleaseStatus ¶
func (m *Module) ReleaseStatus() ReleaseStatus
type ModuleRepository ¶
type ModuleRepository interface {
// GetByID retrieves a module by its ID.
GetByID(ctx context.Context, id string) (*Module, error)
// GetBySlug retrieves a module by its slug.
GetBySlug(ctx context.Context, slug string) (*Module, error)
// ListAll returns all modules.
ListAll(ctx context.Context) ([]*Module, error)
// ListActive returns all active modules.
ListActive(ctx context.Context) ([]*Module, error)
// ListByCategory returns modules filtered by category.
ListByCategory(ctx context.Context, category string) ([]*Module, error)
// GetModulesForPlan returns all modules included in a plan.
GetModulesForPlan(ctx context.Context, planID ID) ([]*Module, error)
// GetEventTypesForModule returns event types associated with a module.
GetEventTypesForModule(ctx context.Context, moduleID string) ([]string, error)
// GetModuleForEventType returns the module that owns a specific event type.
GetModuleForEventType(ctx context.Context, eventType string) (*Module, error)
}
ModuleRepository defines the interface for module persistence operations.
type Plan ¶
type Plan struct {
// contains filtered or unexported fields
}
Plan represents a tenant's module configuration.
func ReconstructPlan ¶
func ReconstructPlan( id ID, slug, name, description string, priceMonthly, priceYearly *float64, currency string, stripeProductID, stripePriceIDMonthly, stripePriceIDYearly string, isPublic, isPopular, isActive bool, displayOrder int, features []string, badge string, trialDays, maxUsers, maxAssets int, supportLevel string, modules []PlanModule, createdAt, updatedAt time.Time, ) *Plan
ReconstructPlan creates a Plan from stored data.
func (*Plan) Description ¶
func (*Plan) DisplayOrder ¶
func (*Plan) GetModuleIDs ¶
GetModuleIDs returns all module IDs included in this plan.
func (*Plan) GetModuleLimit ¶
GetModuleLimit returns the limit for a specific metric in a module. Returns -1 if no limit is set (unlimited).
func (*Plan) Modules ¶
func (p *Plan) Modules() []PlanModule
func (*Plan) PriceMonthly ¶
func (*Plan) PriceYearly ¶
func (*Plan) StripePriceIDMonthly ¶
func (*Plan) StripePriceIDYearly ¶
func (*Plan) StripeProductID ¶
func (*Plan) SupportLevel ¶
type PlanModule ¶
type PlanModule struct {
// contains filtered or unexported fields
}
PlanModule represents a module included in a plan with optional limits.
func ReconstructPlanModule ¶
func ReconstructPlanModule(moduleID string, module *Module, limits map[string]any) PlanModule
ReconstructPlanModule creates a PlanModule from stored data.
func (*PlanModule) Limits ¶
func (pm *PlanModule) Limits() map[string]any
func (*PlanModule) Module ¶
func (pm *PlanModule) Module() *Module
func (*PlanModule) ModuleID ¶
func (pm *PlanModule) ModuleID() string
type PlanRepository ¶
type PlanRepository interface {
// GetByID retrieves a plan by its ID.
GetByID(ctx context.Context, id ID) (*Plan, error)
// GetBySlug retrieves a plan by its slug.
GetBySlug(ctx context.Context, slug string) (*Plan, error)
// ListPublicPlans returns all public plans.
ListPublicPlans(ctx context.Context) ([]*Plan, error)
// ListAllPlans returns all plans (including non-public).
ListAllPlans(ctx context.Context) ([]*Plan, error)
// GetPlanWithModules retrieves a plan with its modules populated.
GetPlanWithModules(ctx context.Context, id ID) (*Plan, error)
}
PlanRepository defines the interface for plan persistence operations.
type ReleaseStatus ¶
type ReleaseStatus string
ReleaseStatus represents the product lifecycle status of a module.
const ( // ReleaseStatusReleased means the module is generally available. ReleaseStatusReleased ReleaseStatus = "released" // ReleaseStatusComingSoon means the module is not released yet, shown as preview. ReleaseStatusComingSoon ReleaseStatus = "coming_soon" // ReleaseStatusBeta means the module is in beta testing. ReleaseStatusBeta ReleaseStatus = "beta" // ReleaseStatusDeprecated means the module is being phased out. ReleaseStatusDeprecated ReleaseStatus = "deprecated" )
type SubscriptionRepository ¶
type SubscriptionRepository interface {
// GetByTenantID retrieves the subscription for a tenant.
GetByTenantID(ctx context.Context, tenantID uuid.UUID) (*TenantSubscription, error)
// GetEnabledModuleIDs returns the module IDs enabled for a tenant.
GetEnabledModuleIDs(ctx context.Context, tenantID uuid.UUID) ([]string, error)
// HasModule checks if a tenant has access to a specific module.
HasModule(ctx context.Context, tenantID uuid.UUID, moduleID string) (bool, error)
// GetModuleLimit returns the effective limit for a module metric.
GetModuleLimit(ctx context.Context, tenantID uuid.UUID, moduleID, metric string) (int64, error)
// UpdateSubscription updates a tenant's subscription.
UpdateSubscription(ctx context.Context, subscription *TenantSubscription) error
// UpdatePlan changes a tenant's plan.
UpdatePlan(ctx context.Context, tenantID, planID uuid.UUID) error
// UpdateStatus updates the subscription status.
UpdateStatus(ctx context.Context, tenantID uuid.UUID, status SubscriptionStatus) error
// SetLimitsOverride sets custom limits for a tenant.
SetLimitsOverride(ctx context.Context, tenantID uuid.UUID, limits map[string]any) error
}
SubscriptionRepository defines the interface for subscription persistence operations.
type SubscriptionStatus ¶
type SubscriptionStatus string
SubscriptionStatus represents the status of a tenant's subscription.
const ( StatusActive SubscriptionStatus = "active" StatusTrial SubscriptionStatus = "trial" StatusPastDue SubscriptionStatus = "past_due" StatusCanceled SubscriptionStatus = "cancelled" StatusExpired SubscriptionStatus = "expired" )
type TenantSubscription ¶
type TenantSubscription struct {
// contains filtered or unexported fields
}
TenantSubscription represents a tenant's subscription to a plan.
func ReconstructTenantSubscription ¶
func ReconstructTenantSubscription( tenantID, planID uuid.UUID, plan *Plan, status SubscriptionStatus, billingCycle BillingCycle, startedAt time.Time, expiresAt, canceledAt *time.Time, limitsOverride map[string]any, stripeCustomerID, stripeSubscriptionID, billingEmail string, ) *TenantSubscription
ReconstructTenantSubscription creates a TenantSubscription from stored data.
func (*TenantSubscription) BillingCycle ¶
func (s *TenantSubscription) BillingCycle() BillingCycle
func (*TenantSubscription) BillingEmail ¶
func (s *TenantSubscription) BillingEmail() string
func (*TenantSubscription) CanceledAt ¶
func (s *TenantSubscription) CanceledAt() *time.Time
func (*TenantSubscription) ExpiresAt ¶
func (s *TenantSubscription) ExpiresAt() *time.Time
func (*TenantSubscription) GetEnabledModuleIDs ¶
func (s *TenantSubscription) GetEnabledModuleIDs() []string
GetEnabledModuleIDs returns all module IDs available to this subscription.
func (*TenantSubscription) GetModuleLimit ¶
func (s *TenantSubscription) GetModuleLimit(moduleID, metric string) int64
GetModuleLimit returns the effective limit for a module metric. Override limits take precedence over plan limits. Returns -1 if unlimited.
func (*TenantSubscription) HasModule ¶
func (s *TenantSubscription) HasModule(moduleID string) bool
HasModule checks if the tenant has access to a specific module.
func (*TenantSubscription) IsActive ¶
func (s *TenantSubscription) IsActive() bool
IsActive checks if the subscription is currently active.
func (*TenantSubscription) LimitsOverride ¶
func (s *TenantSubscription) LimitsOverride() map[string]any
func (*TenantSubscription) Plan ¶
func (s *TenantSubscription) Plan() *Plan
func (*TenantSubscription) PlanID ¶
func (s *TenantSubscription) PlanID() uuid.UUID
func (*TenantSubscription) StartedAt ¶
func (s *TenantSubscription) StartedAt() time.Time
func (*TenantSubscription) Status ¶
func (s *TenantSubscription) Status() SubscriptionStatus
func (*TenantSubscription) StripeCustomerID ¶
func (s *TenantSubscription) StripeCustomerID() string
func (*TenantSubscription) StripeSubscriptionID ¶
func (s *TenantSubscription) StripeSubscriptionID() string
func (*TenantSubscription) TenantID ¶
func (s *TenantSubscription) TenantID() uuid.UUID