using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Options; using StellaOps.Auth.Abstractions; using StellaOps.Auth.ServerIntegration; using StellaOps.Auth.ServerIntegration.Tenancy; using StellaOps.Scanner.Cartographer.Options; using StellaOps.Router.AspNet; var builder = WebApplication.CreateBuilder(args); builder.Configuration .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables("CARTOGRAPHER_"); builder.Services.AddOptions(); builder.Services.AddLogging(); var authoritySection = builder.Configuration.GetSection("Cartographer:Authority"); builder.Services.AddOptions() .Bind(authoritySection) .PostConfigure(CartographerAuthorityOptionsConfigurator.ApplyDefaults) .ValidateOnStart(); builder.Services.AddSingleton, CartographerAuthorityOptionsValidator>(); var authorityOptions = authoritySection.Get() ?? new CartographerAuthorityOptions(); CartographerAuthorityOptionsConfigurator.ApplyDefaults(authorityOptions); authorityOptions.Validate(); if (authorityOptions.Enabled) { builder.Services.AddStellaOpsResourceServerAuthentication( builder.Configuration, configurationSection: null, configure: resourceOptions => { resourceOptions.Authority = authorityOptions.Issuer; resourceOptions.RequireHttpsMetadata = authorityOptions.RequireHttpsMetadata; resourceOptions.MetadataAddress = authorityOptions.MetadataAddress; resourceOptions.BackchannelTimeout = TimeSpan.FromSeconds(authorityOptions.BackchannelTimeoutSeconds); resourceOptions.TokenClockSkew = TimeSpan.FromSeconds(authorityOptions.TokenClockSkewSeconds); resourceOptions.Audiences.Clear(); foreach (var audience in authorityOptions.Audiences) { resourceOptions.Audiences.Add(audience); } resourceOptions.RequiredScopes.Clear(); foreach (var scope in authorityOptions.RequiredScopes) { resourceOptions.RequiredScopes.Add(scope); } }); builder.Services.AddAuthorization(options => { if (authorityOptions.AllowAnonymousFallback) { return; } options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .AddAuthenticationSchemes(StellaOpsAuthenticationDefaults.AuthenticationScheme) .AddRequirements(new StellaOpsScopeRequirement(authorityOptions.RequiredScopes.ToArray())) .Build(); }); } // TODO: register Cartographer graph builders, overlay workers, and Authority client once implementations land. builder.Services.AddHealthChecks() .AddCheck("cartographer_ready", () => HealthCheckResult.Healthy(), tags: new[] { "ready" }); builder.Services.AddStellaOpsTenantServices(); builder.Services.AddStellaOpsCors(builder.Environment, builder.Configuration); // Stella Router integration var routerEnabled = builder.Services.AddRouterMicroservice( builder.Configuration, serviceName: "cartographer", version: System.Reflection.CustomAttributeExtensions.GetCustomAttribute(System.Reflection.Assembly.GetExecutingAssembly())?.InformationalVersion ?? "1.0.0", routerOptionsSection: "Router"); builder.TryAddStellaOpsLocalBinding("cartographer"); var app = builder.Build(); app.LogStellaOpsLocalHostname("cartographer"); if (!authorityOptions.Enabled) { app.Logger.LogWarning("Cartographer Authority authentication is disabled; enable it before production deployments."); } else if (authorityOptions.AllowAnonymousFallback) { app.Logger.LogWarning("Cartographer Authority allows anonymous fallback; disable fallback before production rollout."); } app.UseStellaOpsCors(); if (authorityOptions.Enabled) { app.UseAuthentication(); app.UseAuthorization(); app.TryUseStellaRouter(routerEnabled); } app.UseStellaOpsTenantMiddleware(); app.MapHealthChecks("/healthz").AllowAnonymous(); app.MapHealthChecks("/readyz", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions { Predicate = check => check.Tags.Contains("ready") }).AllowAnonymous(); app.TryRefreshStellaRouterEndpoints(routerEnabled); app.Run(); public partial class Program;