Centinel AnalyticaCentinel Analytica
PlatformsApplication

ASP.NET Core

Add Centinel Analytica to your ASP.NET Core application.

Overview

The Centinel middleware runs before your endpoints, sending request metadata to the validator API. The validator decides if the request should be allowed, blocked, redirected, or didn't match any protected path. Blocked and challenged responses are rendered from HTML the validator returns, so that traffic never reaches your endpoints. Two cases do fall through to your app: a challenge that arrives without HTML, and a misconfigured CentinelConfiguration section.

Prerequisites

  • .NET 9.0 SDK or later (the package targets net9.0)
  • NuGet package access
  • Centinel secret key (from the Dashboard)

Install

In your ASP.NET Core project:

dotnet add package Centinel.AspNetCore

Configure

Configuration

Add your Centinel settings to appsettings.json (or any other configuration provider):

{
  "CentinelConfiguration": {
    "SecretKey": "YOUR_SECRET_KEY",
    "ValidatorApiUrl": "https://validator.centinelanalytica.com/validate",
    "ProtectedPaths": ["/api", "/dashboard"],
    "ExcludedPaths": ["/health", "/static"],
    "FailOpen": true
  }
}
PropertyTypeRequiredDefaultDescription
SecretKeystringYesSecret key for the validator API.
ValidatorApiUrlstringNohttps://validator.centinelanalytica.com/validateValidator endpoint URL.
ProtectedPathsstring[]NoRoutes to validate. If empty, all routes are protected.
ExcludedPathsstring[]NoRoutes to skip validation on.
FailOpenbooleanNotrueIf false, return 503 with Service temporarily unavailable when the Centinel API is unreachable.
RequestTimeoutTimeSpanNo00:00:05Validator request timeout.
EnableLoggingbooleanNotrueEmit validator request and response logs.
CookieNamestringNo_centinelSession cookie the middleware reads.

ProtectedPaths and ExcludedPaths are case-insensitive prefix matches with no wildcards, and exclusions always win. A prefix of /api therefore also matches /apiary, so add a trailing slash (/api/) when you mean a path segment.

Register services

Register Centinel in Program.cs:

using Centinel.AspNetCore.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCentinel(builder.Configuration);
// Or configure manually:
// builder.Services.AddCentinel(options =>
// {
//     options.SecretKey = Environment.GetEnvironmentVariable("CENTINEL_SECRET_KEY")!;
//     options.ProtectedPaths = new() { "/api", "/admin" };
// });

var app = builder.Build();
Add middleware

Put the Centinel middleware in your request pipeline before endpoint execution:

using Centinel.AspNetCore.Extensions;

app.UseCentinel();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

Put UseCentinel() first. The middleware reads context.Request.Path directly and needs no routing data, so placing it ahead of routing and auth keeps unwanted traffic away from that work entirely.

Confirm the config actually bound

If the CentinelConfiguration section is missing or misspelled, the middleware allows every request and logs Centinel configuration is invalid. Requests will be allowed through. The check runs per request, not at startup, so send a request first and then read the logs. Nothing appears in your startup output either way, and under production traffic this line repeats on every request.

The NuGet package does not inject the browser script. Add the script tag to _Layout.cshtml yourself if you want browser-side signals.

Middleware

With app.UseCentinel(), every matching request is validated automatically. Use ProtectedPaths and ExcludedPaths in your configuration to control which routes get checked.

Inject ICentinelValidator to apply Centinel only where you need it (e.g. sensitive APIs) without middleware-wide protection.

Custom validator endpoint

Override the validator URL or request timeout if you're using a self-hosted validator:

builder.Services.AddCentinel(options =>
{
    options.SecretKey = Environment.GetEnvironmentVariable("CENTINEL_SECRET_KEY")!;
    options.ValidatorApiUrl = "https://validator.yourdomain.com/validate";
    options.RequestTimeout = TimeSpan.FromSeconds(10);
});

Deployment notes

Make sure your production configuration or environment variables include the CentinelConfiguration values (especially SecretKey and any custom validator URL). Restart your app after updating keys so the middleware picks up the new settings.

Verify

With EnableLogging on and the log level at Debug, curl an excluded path and then a protected one. A protected request logs Sending validation request to Centinel API for URL: {Url} followed by Received validation response: {Decision}.

curl -s -o /dev/null -w '%{http_code}\n' http://localhost:5000/health
curl -s -o /dev/null -w '%{http_code}\n' -A 'python-requests/2.31' http://localhost:5000/api/items

Four log lines tell you what went wrong when it doesn't work:

Log lineMeaning
Centinel configuration is invalidThe config section did not bind. Everything is allowed.
Centinel API returned status {StatusCode}Usually a wrong secret key.
Centinel API request timed out for URLRaise RequestTimeout, or check egress.
Centinel API unavailable, allowing request throughFail-open engaged.

The repo ships a runnable demo under demo/ with public and protected routes if you want to see all of this without touching your own app.

Changelog

  • v1.0.1 — Response header passthrough

On this page