Help us shape the future of Go! Take the 2026 Go Developer Survey

anomaly

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 19 Imported by: 0

README

anomaly

Watches a user's login history and raises a score when the current sign-in does not look like the ones before it.

Four patterns feed the score: signing in at an hour this account never signs in at, a country it has never been seen from, a burst of attempts well above its normal frequency, and a device type it has never used. None of these is proof of anything on its own. Together they are a decent proxy for "this does not feel like the same person".

The plugin stays quiet until it has enough history to have an opinion, which is ten logins by default.

Use it when

  • You want behavioural detection without writing the baselining yourself
  • Your users have settled habits, so a deviation actually means something
  • You want a risk score that feeds alerting, not a hard block

Skip it when

  • Your accounts are shared or machine-driven, where there is no stable pattern to deviate from
  • Most of your accounts are new. Under MinLoginHistory logins the plugin does nothing
  • You need a hard block. This plugin scores and flags, it does not refuse

Wiring

authsome.WithPlugin(anomaly.New(anomaly.Config{
    MinLoginHistory:   10,
    RiskThreshold:     70,
    EnableTimeAnomaly: true,
    EnableGeoAnomaly:  true,
}))

Geo detection wants geoip registered, otherwise there's no country to compare.

Config

Field Type Default What it does
MinLoginHistory int 10 Logins needed before detection starts
RiskThreshold int 70 Score out of 100 above which an alert is raised
EnableTimeAnomaly bool true Detect logins at unusual hours for this account
EnableGeoAnomaly bool true Detect logins from a country this account has never used

Settings

Key Default
anomaly.min_login_history 10
anomaly.risk_threshold 70
anomaly.enable_time_anomaly true
anomaly.enable_geo_anomaly true

Lifecycle hooks

Hook What happens
AfterSignIn Scores the sign-in against the account's history and raises an alert past the threshold
AfterPrincipalAuth Same scoring for non-user principals

impossibletravel is the sharp version of the geo signal. deviceverify handles the new device case with a challenge, not a score.

Documentation

Overview

contract.go: Wires the anomaly plugin into the forge-dashboard contract surface via plugin.ContractContributor.

Package anomaly provides login anomaly detection by analyzing patterns such as unusual login times, new countries, frequency spikes, and new device types.

Index

Constants

This section is empty.

Variables

View Source
var (
	// SettingMinLoginHistory controls the minimum number of logins before
	// anomaly detection activates.
	SettingMinLoginHistory = settings.Define("anomaly.min_login_history", 10,
		settings.WithDisplayName("Minimum Login History"),
		settings.WithDescription("Minimum number of logins before anomaly detection kicks in"),
		settings.WithCategory("Anomaly Detection"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithHelpText("Minimum number of logins before anomaly detection kicks in"),
		settings.WithOrder(10),
	)

	// SettingRiskThreshold controls the score above which an anomaly alert
	// is raised.
	SettingRiskThreshold = settings.Define("anomaly.risk_threshold", 70,
		settings.WithDisplayName("Risk Threshold"),
		settings.WithDescription("Score above which an anomaly alert is raised (0-100)"),
		settings.WithCategory("Anomaly Detection"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithEnforceable(),
		settings.WithUIValidation(formconfig.Validation{Required: true, Min: intPtr(0), Max: intPtr(100)}),
		settings.WithHelpText("Score above which an anomaly alert is raised (0-100)"),
		settings.WithOrder(20),
	)

	// SettingEnableTimeAnomaly controls whether unusual login time detection
	// is enabled.
	SettingEnableTimeAnomaly = settings.Define("anomaly.enable_time_anomaly", true,
		settings.WithDisplayName("Enable Time Anomaly"),
		settings.WithDescription("Enable detection of unusual login times"),
		settings.WithCategory("Anomaly Detection"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithHelpText("Enable detection of unusual login times"),
		settings.WithOrder(30),
	)

	// SettingEnableGeoAnomaly controls whether new country detection is
	// enabled.
	SettingEnableGeoAnomaly = settings.Define("anomaly.enable_geo_anomaly", true,
		settings.WithDisplayName("Enable Geo Anomaly"),
		settings.WithDescription("Enable detection of logins from new countries"),
		settings.WithCategory("Anomaly Detection"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithHelpText("Enable detection of logins from new countries"),
		settings.WithOrder(40),
	)
)

Functions

This section is empty.

Types

type Alert

type Alert struct {
	Principal principal.Ref
	SessionID id.SessionID
	Type      string // "unusual_time", "unusual_country", "frequency_spike"
	RiskScore int
	Details   map[string]string
}

Alert is emitted when an anomalous login is detected.

type Config

type Config struct {
	// MinLoginHistory is the minimum number of logins before anomaly
	// detection kicks in (default: 10).
	MinLoginHistory int

	// RiskThreshold is the score above which an anomaly alert is raised
	// (default: 70 out of 100).
	RiskThreshold int

	// EnableTimeAnomaly enables unusual login time detection (default: true).
	EnableTimeAnomaly bool

	// EnableGeoAnomaly enables new country detection (default: true).
	EnableGeoAnomaly bool

	// MaxTrackedPrincipals bounds the in-memory pattern table; the least
	// recently seen principal is dropped when it is full (default: 10000).
	// A dropped principal starts a fresh history on its next login.
	MaxTrackedPrincipals int
}

Config configures the anomaly detection plugin.

type LoginPattern

type LoginPattern struct {
	// Principal is the caller this pattern belongs to: a user for sign-in,
	// an agent or workload for machine traffic.
	Principal        principal.Ref
	LoginCount       int
	HourHistogram    [24]int        // login count by hour of day
	DayHistogram     [7]int         // login count by day of week
	CountryHistogram map[string]int // login count by country
	LastLoginAt      time.Time
}

LoginPattern tracks a principal's typical login behavior.

type Plugin

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

Plugin analyzes login patterns and detects anomalies.

func New

func New(cfg ...Config) *Plugin

New creates a new anomaly detection plugin.

func (*Plugin) DeclareSettings

func (p *Plugin) DeclareSettings(m *settings.Manager) error

DeclareSettings implements plugin.SettingsProvider. It registers all anomaly-detection-related configurable settings.

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the plugin name.

func (*Plugin) OnAfterPrincipalAuth

func (p *Plugin) OnAfterPrincipalAuth(ctx context.Context, a *principal.AuthAttempt, s *session.Session) error

OnAfterPrincipalAuth records a machine caller's login and checks for anomalies.

Keyed by principal rather than user. An agent has no user, and two agents sharing one login-pattern history would score each other's normal traffic as anomalous, or mask a real anomaly in one behind the other's volume.

func (*Plugin) OnAfterSignIn

func (p *Plugin) OnAfterSignIn(ctx context.Context, u *user.User, s *session.Session) error

OnAfterSignIn records a person's login and checks for anomalies.

func (*Plugin) OnInit

func (p *Plugin) OnInit(_ context.Context, engine plugin.Engine) error

OnInit discovers engine dependencies.

func (*Plugin) RegisterContract

func (p *Plugin) RegisterContract(
	d *dispatcher.Dispatcher,
	reg contract.Registry,
	wreg contract.WardenRegistry,
	engine plugin.Engine,
) error

Directories

Path Synopsis
Package contract wires the anomaly plugin's deep-link settings page into the forge-dashboard contract registry.
Package contract wires the anomaly plugin's deep-link settings page into the forge-dashboard contract registry.

Jump to

Keyboard shortcuts

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