module

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package module provides domain models for tenant modules and access control.

Index

Constants

View Source
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.

View Source
const (
	ModuleCategoryCore       = "core"
	ModuleCategorySecurity   = "security"
	ModuleCategoryPlatform   = "platform"
	ModuleCategoryCompliance = "compliance"
	ModuleCategoryEnterprise = "enterprise"
)

ModuleCategory constants

View Source
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)

View Source
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)

View Source
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)

View Source
const (
	AITriageLimitMonthlyTokens = "monthly_token_limit" // Monthly token limit (int64, -1 = unlimited)
)

AI Triage limit keys for PlanModule.Limits

View Source
const SubModuleSeparator = "."

SubModuleSeparator is the separator used in sub-module IDs (e.g., "integrations.scm").

View Source
const SubModuleSlugSeparator = "-"

SubModuleSlugSeparator is the separator used in sub-module slugs (e.g., "integrations-scm").

Variables

View Source
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.

View Source
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.

View Source
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

func BuildSubModuleID(parentModuleID, subModuleName string) string

BuildSubModuleID constructs a sub-module ID from parent and child. Example: BuildSubModuleID("integrations", "scm") returns "integrations.scm"

func BuildSubModuleSlug

func BuildSubModuleSlug(parentModuleID, subModuleName string) string

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

func GetCategoryDisplayName(category string) string

GetCategoryDisplayName returns the display name for a category.

func GetDefaultEventTypeIDs

func GetDefaultEventTypeIDs(eventTypes []*EventType) []string

GetDefaultEventTypeIDs returns the IDs of event types that are default enabled.

func GetRequiredPermission

func GetRequiredPermission(moduleID string) string

GetRequiredPermission returns the required permission for a module. Returns empty string if the module has no permission requirement.

func ValidateSubModuleID

func ValidateSubModuleID(fullSubModuleID string) error

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

func (e *EventType) Category() string

func (*EventType) Color

func (e *EventType) Color() string

func (*EventType) Description

func (e *EventType) Description() string

func (*EventType) DisplayOrder

func (e *EventType) DisplayOrder() int

func (*EventType) ID

func (e *EventType) ID() string

func (*EventType) Icon

func (e *EventType) Icon() string

func (*EventType) IsActive

func (e *EventType) IsActive() bool

func (*EventType) IsDefault

func (e *EventType) IsDefault() bool

func (*EventType) Name

func (e *EventType) Name() string

func (*EventType) SeverityApplicable

func (e *EventType) SeverityApplicable() bool

func (*EventType) Slug

func (e *EventType) Slug() string

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

type EventTypeWithModule struct {
	*EventType
	ModuleID string
}

EventTypeWithModule represents an event type with its associated module ID.

type ID

type ID = uuid.UUID

ID represents a unique identifier for licensing entities.

func NewID

func NewID() ID

NewID generates a new licensing ID.

func ParseID

func ParseID(s string) (ID, error)

ParseID parses a string into a licensing 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) Category

func (m *Module) Category() string

func (*Module) Description

func (m *Module) Description() string

func (*Module) DisplayOrder

func (m *Module) DisplayOrder() int

func (*Module) EventTypes

func (m *Module) EventTypes() []string

func (*Module) HasParent

func (m *Module) HasParent(parentID string) bool

HasParent returns true if this module's parent is the given ID.

func (*Module) ID

func (m *Module) ID() string

func (*Module) Icon

func (m *Module) Icon() string

func (*Module) IsActive

func (m *Module) IsActive() bool

func (*Module) IsBeta

func (m *Module) IsBeta() bool

IsBeta returns true if the module is in beta testing.

func (*Module) IsComingSoon

func (m *Module) IsComingSoon() bool

IsComingSoon returns true if the module is not released yet.

func (*Module) IsDeprecated

func (m *Module) IsDeprecated() bool

IsDeprecated returns true if the module is being phased out.

func (*Module) IsReleased

func (m *Module) IsReleased() bool

IsReleased returns true if the module is generally available.

func (*Module) IsSubModule

func (m *Module) IsSubModule() bool

IsSubModule returns true if this module has a parent module.

func (*Module) Name

func (m *Module) Name() string

func (*Module) ParentModuleID

func (m *Module) ParentModuleID() *string

func (*Module) ReleaseStatus

func (m *Module) ReleaseStatus() ReleaseStatus

func (*Module) Slug

func (m *Module) Slug() string

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

func (p *Plan) Badge() string

func (*Plan) CreatedAt

func (p *Plan) CreatedAt() time.Time

func (*Plan) Currency

func (p *Plan) Currency() string

func (*Plan) Description

func (p *Plan) Description() string

func (*Plan) DisplayOrder

func (p *Plan) DisplayOrder() int

func (*Plan) Features

func (p *Plan) Features() []string

func (*Plan) GetModuleIDs

func (p *Plan) GetModuleIDs() []string

GetModuleIDs returns all module IDs included in this plan.

func (*Plan) GetModuleLimit

func (p *Plan) GetModuleLimit(moduleID, metric string) int64

GetModuleLimit returns the limit for a specific metric in a module. Returns -1 if no limit is set (unlimited).

func (*Plan) HasModule

func (p *Plan) HasModule(moduleID string) bool

HasModule checks if the plan includes a specific module.

func (*Plan) ID

func (p *Plan) ID() ID

func (*Plan) IsActive

func (p *Plan) IsActive() bool

func (*Plan) IsPopular

func (p *Plan) IsPopular() bool

func (*Plan) IsPublic

func (p *Plan) IsPublic() bool

func (*Plan) MaxAssets

func (p *Plan) MaxAssets() int

func (*Plan) MaxUsers

func (p *Plan) MaxUsers() int

func (*Plan) Modules

func (p *Plan) Modules() []PlanModule

func (*Plan) Name

func (p *Plan) Name() string

func (*Plan) PriceMonthly

func (p *Plan) PriceMonthly() *float64

func (*Plan) PriceYearly

func (p *Plan) PriceYearly() *float64

func (*Plan) Slug

func (p *Plan) Slug() string

func (*Plan) StripePriceIDMonthly

func (p *Plan) StripePriceIDMonthly() string

func (*Plan) StripePriceIDYearly

func (p *Plan) StripePriceIDYearly() string

func (*Plan) StripeProductID

func (p *Plan) StripeProductID() string

func (*Plan) SupportLevel

func (p *Plan) SupportLevel() string

func (*Plan) TrialDays

func (p *Plan) TrialDays() int

func (*Plan) UpdatedAt

func (p *Plan) UpdatedAt() time.Time

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 (*TenantSubscription) StripeCustomerID

func (s *TenantSubscription) StripeCustomerID() string

func (*TenantSubscription) StripeSubscriptionID

func (s *TenantSubscription) StripeSubscriptionID() string

func (*TenantSubscription) TenantID

func (s *TenantSubscription) TenantID() uuid.UUID

Jump to

Keyboard shortcuts

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