Portal Community

Minimal Setup

In your application's Program.cs or startup class, call AddGuardRailsExecution():

// Program.cs / Startup.cs
builder.Services.AddGuardRailsExecution();

That's all that's required. Every component below is registered automatically.

What AddGuardRailsExecution() Registers

Service InterfaceImplementationLifetime
INodeGuardExecutorNodeGuardExecutorScoped
IGuardRailsExecutorGuardRailsExecutorScoped
IGuardRailsOrchestratorGuardRailsOrchestratorScoped
IGuardConfigResolverGuardConfigResolverSingleton
IGuardRegistryGuardRegistrySingleton
IGuardCircuitBreakerGuardCircuitBreakerSingleton
IGuardRailsAuditLoggerGuardRailsAuditLoggerSingleton
ITransientFailureWindowTransientFailureWindowSingleton
IPiiDetectorRegexPiiDetectorSingleton
ISecretsRedactorSecretsRedactorSingleton
IGuardRail (×6)All 6 built-in guardsSingleton

Custom Circuit Breaker Policy

To override the default circuit breaker policy, use the overload that accepts a CircuitBreakerPolicy:

builder.Services.AddGuardRailsExecution(new CircuitBreakerPolicy
{
    FailureThreshold          = 3,    // open after 3 failures (default: 5)
    OpenDurationSeconds       = 30,   // stay open for 30s (default: 60)
    SuccessThresholdForHalfOpen = 2,  // 2 successes to close again (default: 3)
    FailSecure                = true, // block on open circuit (default: true)
    ResetOnTransient          = true, // don't count transients (default: true)
    FailureWindowSeconds      = 120   // sliding window (default: 300)
});

Registering the PiiNodeGuard Composite

The PiiNodeGuard is a composite that wires PiiDetectionGuard (Pre) and PiiRedactionGuard (Post) into a single pluggable unit. Register it separately if you want the composite behavior:

builder.Services.AddGuardRailsExecution();

// Register PiiNodeGuard as an additional INodeGuardExecutor
// (complements the built-in guards, or replaces per-node PII config)
builder.Services.AddSingleton<PiiNodeGuard>();

Registering a Custom Guard

Custom guards register through DI as IGuardRail singletons. The GuardRegistry discovers them automatically on startup:

// After AddGuardRailsExecution():
builder.Services.AddSingleton<IGuardRail, ContentModerationGuard>();

// If ContentModerationGuard needs its own dependencies:
builder.Services.AddSingleton<IContentModerationClient, AzureContentModerationClient>();
builder.Services.AddSingleton<IGuardRail, ContentModerationGuard>();

Loading Plugin Assemblies at Startup

For external DLL plugins, call LoadPluginsAsync() from a hosted service or startup hook — after the DI container is built:

// IHostedService or app.Lifetime.ApplicationStarted:
var registry = serviceProvider.GetRequiredService<IGuardRegistry>();
await registry.LoadPluginsAsync(pluginDirectory: "/opt/guardrails/plugins");

// LoadPluginsAsync delegates to IGuardPluginLoader which:
//   1. Scans the directory for guard DLLs
//   2. Validates signatures via IPluginSignatureValidator
//   3. Checks review metadata via IPluginCodeReviewMetadata
//   4. Registers passing assemblies as GuardDefinitions

Guard Group Registration

Guard groups are registered via IGuardRegistry during startup. Groups bundle related guards for node-level reuse:

var registry = serviceProvider.GetRequiredService<IGuardRegistry>();

registry.RegisterGroup("PiiCompliance", new GuardGroupDefinition
{
    Guards = new[]
    {
        new GuardEntry { Name = "PiiDetectionGuard",  Order = 1 },
        new GuardEntry { Name = "PiiRedactionGuard",  Order = 2 }
    }
});

registry.RegisterGroup("Resilience", new GuardGroupDefinition
{
    Guards = new[]
    {
        new GuardEntry { Name = "TimeoutGuard",        Order = 1, Config = new { TimeoutMs = 5000 } },
        new GuardEntry { Name = "CircuitBreakerGuard", Order = 2 }
    }
});

Once registered, these groups can be referenced by name in any node's guardRails.groups configuration.

Backward Compatibility: RateLimitingOrchestrator

Deployments that used the standalone rate limiting subsystem before GuardRails was introduced can continue to use IRateLimitingOrchestrator in parallel. BaseNodeExecutor checks for both:

// BaseNodeExecutor uses pluggable tier: either INodeGuardExecutor
// or IRateLimitingOrchestrator as a fallback, or both simultaneously.

// Both registered → both run (guards take precedence, orchestrator handles rate-limiting checks)
// Only orchestrator registered → legacy rate limiting, no guard pipeline
// Only NodeGuardExecutor registered → full guard pipeline (recommended)

builder.Services.AddGuardRailsExecution();
// Remove IRateLimitingOrchestrator registration to retire the legacy tier

Health Check Integration

GuardRails exposes a health check endpoint via the standard ASP.NET Core health check system. Register it alongside your other health checks:

builder.Services.AddHealthChecks()
    .AddGuardRailsHealthCheck();  // registered by AddGuardRailsExecution()

// The health check reports:
// - Each guard's circuit state (Closed / Open / HalfOpen)
// - Plugin review metadata status
// - Configuration cache freshness
// GET /health/guardrails
{
  "status": "healthy",
  "guards": {
    "TimeoutGuard":        { "circuit": "Closed",   "lastFailure": null },
    "PiiDetectionGuard":   { "circuit": "Closed",   "lastFailure": null },
    "RateLimitingGuard":   { "circuit": "HalfOpen", "lastFailure": "2026-05-25T14:00:00Z" },
    "CircuitBreakerGuard": { "circuit": "Closed",   "lastFailure": null }
  },
  "plugins": {
    "ContentModerationGuard": { "signed": true, "reviewed": true }
  }
}

Full Startup Example

// Program.cs — complete GuardRails wiring
var builder = WebApplication.CreateBuilder(args);

// 1. Core GuardRails stack
builder.Services.AddGuardRailsExecution(new CircuitBreakerPolicy
{
    FailureThreshold    = 5,
    OpenDurationSeconds = 60
});

// 2. Custom guard dependencies
builder.Services.AddHttpClient<IContentModerationClient, AzureContentModerationClient>();
builder.Services.AddSingleton<IGuardRail, ContentModerationGuard>();

// 3. Health checks
builder.Services.AddHealthChecks().AddGuardRailsHealthCheck();

var app = builder.Build();

// 4. Load plugin assemblies after container build
app.Lifetime.ApplicationStarted.Register(async () =>
{
    var registry = app.Services.GetRequiredService<IGuardRegistry>();
    await registry.LoadPluginsAsync("/opt/guardrails/plugins");
});

// 5. Health endpoint
app.MapHealthChecks("/health/guardrails");

app.Run();