Mostlylucid.GeoDetection.Contributor 1.0.0

dotnet add package Mostlylucid.GeoDetection.Contributor --version 1.0.0
                    
NuGet\Install-Package Mostlylucid.GeoDetection.Contributor -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mostlylucid.GeoDetection.Contributor" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mostlylucid.GeoDetection.Contributor" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Mostlylucid.GeoDetection.Contributor" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mostlylucid.GeoDetection.Contributor --version 1.0.0
                    
#r "nuget: Mostlylucid.GeoDetection.Contributor, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Mostlylucid.GeoDetection.Contributor@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mostlylucid.GeoDetection.Contributor&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Mostlylucid.GeoDetection.Contributor&version=1.0.0
                    
Install as a Cake Tool

Mostlylucid.GeoDetection.Contributor

Geographic bot detection contributor for Mostlylucid.BotDetection

This package demonstrates the contributor plugin pattern for extending bot detection with domain-specific signals.

What It Does

  • Enriches bot detection with geographic location data
  • Verifies bot origins (e.g., Googlebot should come from US)
  • Detects geo-inconsistencies (e.g., Russian locale from China)
  • Flags hosting/datacenter/VPN IPs
  • Identifies suspicious countries

Installation

dotnet add package Mostlylucid.GeoDetection
dotnet add package Mostlylucid.GeoDetection.Contributor

Usage - It's Really This Simple!

1. Register Services

var builder = WebApplication.CreateBuilder(args);

// Add core geo-location services
builder.Services.AddGeoLocationServices();

// Add bot detection with orchestrator
builder.Services.AddBotDetection();

// Add geo-detection contributor (that's it!)
builder.Services.AddGeoDetectionContributor(options =>
{
    options.EnableBotVerification = true;  // Verify known bots (Googlebot, etc.)
    options.EnableInconsistencyDetection = true;  // Detect locale/geo mismatches
    options.FlagHostingIps = true;  // Flag datacenter IPs
    options.FlagVpnIps = true;  // Flag VPN/proxy IPs
});

2. Use Middleware

app.UseBotDetection();

That's it! The contributor automatically:

  • Runs in the first wave alongside IP detection
  • Contributes geographic signals to the blackboard
  • Integrates with policy evaluation and early-exit logic

Why This Pattern is Powerful

The GeoDetection integration showcases the extensibility of the bot detection system:

✅ Zero Configuration Integration

Once registered, contributors work automatically with:

  • Wave-based parallel execution
  • Quorum-based early exit
  • Circuit breaker (if contributors fail repeatedly)
  • Policy evaluation

✅ Signal-Based Composition

Contributors communicate via typed signals on the blackboard:

// GeoContributor writes
signals.Add(GeoSignalKeys.GeoCountryCode, "US");

// Other contributors/detectors read
var country = state.GetSignal<string>(GeoSignalKeys.GeoCountryCode);

This enables composable detection without tight coupling.

✅ Simple DI Registration

Just one line:

services.TryAddEnumerable(
    ServiceDescriptor.Singleton<IContributingDetector, GeoContributor>());

Creating Your Own Contributor

Want to add custom bot detection logic? Follow this simple pattern:

1. Create Your Contributor

using Mostlylucid.BotDetection.Models;
using Mostlylucid.BotDetection.Orchestration;

public class MyCustomContributor : ContributingDetectorBase
{
    public override string Name => "MyCustom";
    public override int Priority => 150;  // Run order (lower = earlier)

    // Optional: Only run after certain signals are available
    public override IReadOnlyList<TriggerCondition> TriggerConditions =>
        [TriggerCondition.RequireSignal(GeoSignalKeys.GeoCountryCode)];

    public override async Task<IReadOnlyList<DetectionContribution>> ContributeAsync(
        BlackboardState state,
        CancellationToken cancellationToken)
    {
        // Read signals from blackboard
        var country = state.GetSignal<string>(GeoSignalKeys.GeoCountryCode);
        var userAgent = state.UserAgent;

        // Your custom detection logic
        if (IsSuspiciousPattern(country, userAgent))
        {
            return Single(DetectionContribution.Bot(
                Name, "MyCustomCheck",
                confidenceDelta: 0.6,
                reason: "Custom rule triggered",
                botType: BotType.Unknown,
                weight: 1.5
            ));
        }

        return None();
    }

    private bool IsSuspiciousPattern(string country, string userAgent) => false;
}

2. Add Extension Method

public static class MyCustomContributorExtensions
{
    public static IServiceCollection AddMyCustomContributor(
        this IServiceCollection services)
    {
        services.TryAddEnumerable(
            ServiceDescriptor.Singleton<IContributingDetector, MyCustomContributor>());
        return services;
    }
}

3. Register It

builder.Services.AddBotDetection();
builder.Services.AddMyCustomContributor();  // Done!

Your contributor automatically:

  • Runs in the wave-based pipeline
  • Can trigger on signals from other contributors
  • Contributes to the final bot probability
  • Respects early-exit and circuit breaker logic

Signal Keys - Extensible by Design

Signal keys use partial class for extension:

// In Mostlylucid.GeoDetection.Contributor
public static partial class GeoSignalKeys
{
    public const string GeoCountryCode = "geo.country_code";
    public const string GeoIsVpn = "geo.is_vpn";
    // ... more geo signals
}

// In your custom package
public static partial class MySignalKeys
{
    public const string MyCustomSignal = "my.custom_signal";
}

Example: Bot Origin Verification

The GeoContributor verifies known bot origins:

private static readonly Dictionary<string, string[]> KnownBotOrigins = new()
{
    ["googlebot"] = ["US"],
    ["bingbot"] = ["US"],
    ["yandexbot"] = ["RU", "FI", "NL"],
    ["baiduspider"] = ["CN", "HK"]
};

If a User-Agent claims to be "Googlebot" but the IP is from China:

  • Confidence Delta: +0.8 (high probability of bot)
  • Weight: 2.0 (strong signal)
  • Bot Type: Scraper
  • Reason: "FAKE Googlebot from China"

This catches bot impersonation attempts.

Geographic Signals Reference

Signal Key Type Description
geo.country_code string ISO 3166-1 alpha-2 country code
geo.country_name string Full country name
geo.city string City name
geo.timezone string IANA timezone
geo.is_vpn bool IP is from VPN/proxy
geo.is_hosting bool IP is from datacenter/hosting
geo.is_suspicious_country bool Country is in suspicious list
geo.bot_verified bool Known bot verified from expected country
geo.bot_origin_mismatch bool Bot claims identity but wrong country

Configuration

{
  "BotDetection": {
    "Geo": {
      "EnableBotVerification": true,
      "EnableInconsistencyDetection": true,
      "FlagHostingIps": true,
      "FlagVpnIps": true,
      "SuspiciousCountries": ["KP", "CN"],
      "TrustedCountries": ["US", "GB", "DE"],
      "VerifiedBotConfidenceBoost": 0.3,
      "BotOriginMismatchPenalty": 0.8,
      "SignalWeight": 1.0,
      "Priority": 100
    }
  }
}

Why GeoDetection is a Separate Package

The contributor pattern allows:

  • Optional dependencies - Don't need geo if you don't want it
  • Third-party extensions - Anyone can publish contributors
  • Clean separation - Core bot detection has no geo coupling

This is the plugin architecture in action!

License

MIT

A bot detection contributor that provides detailed geographic location analysis for request validation. This package bridges Mostlylucid.GeoDetection with Mostlylucid.BotDetection to enable geo-based bot detection.

Features

  • Geographic Location Signals: Provides country, region, city, and coordinates for requests
  • Geo-Inconsistency Detection: Detects bots claiming to be from one location but IP suggests another
  • Bot Verification: Validates that claimed bots (e.g., Googlebot) originate from expected geographic regions
  • VPN/Proxy Detection: Flags requests from known VPN/proxy/hosting providers
  • Timezone Validation: Detects mismatches between claimed timezone and IP-based location

Installation

dotnet add package Mostlylucid.GeoDetection.Contributor

Usage

// In Program.cs or Startup.cs
services.AddGeoLocationServices(options =>
{
    options.DefaultProvider = GeoProvider.MaxMind;
    options.GeoLite2DatabasePath = "/path/to/GeoLite2-City.mmdb";
});

services.AddBotDetection(options => { /* ... */ });

// Add the geo contributor
services.AddGeoDetectionContributor(options =>
{
    options.EnableBotVerification = true;
    options.EnableInconsistencyDetection = true;
    options.SuspiciousCountries = ["CN", "RU", "KP"]; // Optional
});

Signals Emitted

The contributor emits the following signals to the blackboard:

Signal Key Type Description
geo.country_code string ISO 3166-1 alpha-2 country code
geo.country_name string Full country name
geo.region_code string Region/state code
geo.city string City name
geo.latitude double Latitude coordinate
geo.longitude double Longitude coordinate
geo.timezone string Timezone (e.g., "America/New_York")
geo.is_vpn bool Whether IP is known VPN
geo.is_hosting bool Whether IP is from hosting provider
geo.continent_code string Continent code (e.g., "NA", "EU")

Geo-Inconsistency Detection

The contributor detects several types of geo-based inconsistencies:

Bot Origin Verification

Known search engine bots should originate from specific countries:

Bot Expected Countries
Googlebot US
Bingbot US
Yandex RU
Baidu CN

If a User-Agent claims to be Googlebot but the IP is from China, this is flagged as highly suspicious.

Timezone Mismatches

If the Accept-Language header suggests a specific locale (e.g., "en-US") but the IP originates from a different timezone, this is flagged.

Datacenter + Consumer Locale

Browser User-Agents claiming consumer locales from datacenter IPs are flagged.

Configuration Options

public class GeoContributorOptions
{
    // Enable verification that known bots come from expected countries
    public bool EnableBotVerification { get; set; } = true;

    // Enable geo-inconsistency detection
    public bool EnableInconsistencyDetection { get; set; } = true;

    // Countries to flag as suspicious (higher weight)
    public List<string> SuspiciousCountries { get; set; } = [];

    // Countries to always trust (lower weight)
    public List<string> TrustedCountries { get; set; } = [];

    // Priority for this detector (lower = runs earlier)
    public int Priority { get; set; } = 15;
}

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 90 4/18/2026