Files
nexus/backend/Services/RequestAuthorizationHelper.cs
AzuTear f5552218bc
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s
feat: ship agent-first mission control v0.2.57
2026-07-31 22:39:47 +02:00

77 lines
3.3 KiB
C#

using Microsoft.Extensions.Primitives;
namespace Nexus.Api.Services;
public static class RequestAuthorizationHelper
{
public sealed record AgentHeaderResolution(
string? AgentId,
bool HeaderProvided,
bool IsRecognized,
bool CredentialVerified,
bool IdentityHintAuthorized);
public static bool IsAuthenticatedService(HttpContext httpContext, IConfiguration configuration) =>
(httpContext.User.Identity?.IsAuthenticated == true &&
httpContext.User.IsInRole("Service")) ||
HasValidServiceKey(httpContext, configuration);
public static bool HasVerifiedAuthentication(HttpContext httpContext, IConfiguration configuration) =>
httpContext.User.Identity?.IsAuthenticated == true ||
HasValidServiceKey(httpContext, configuration);
public static bool IsPrivilegedUser(HttpContext httpContext) =>
httpContext.User.Identity?.IsAuthenticated == true &&
(httpContext.User.IsInRole("owner") || httpContext.User.IsInRole("admin"));
public static bool CanUseAgentIdentityHint(HttpContext httpContext, IConfiguration configuration) =>
IsAuthenticatedService(httpContext, configuration) ||
IsPrivilegedUser(httpContext);
public static async Task<string?> ResolveAllowedAgentHeaderAsync(
HttpContext httpContext,
IAgentService agentService,
IConfiguration configuration,
CancellationToken ct)
=> (await ResolveAgentHeaderAsync(httpContext, agentService, configuration, ct)).AgentId;
public static async Task<AgentHeaderResolution> ResolveAgentHeaderAsync(
HttpContext httpContext,
IAgentService agentService,
IConfiguration configuration,
CancellationToken ct)
{
var headerValue = httpContext.Request.Headers["X-Agent-Id"].FirstOrDefault();
if (string.IsNullOrWhiteSpace(headerValue))
return new AgentHeaderResolution(
null,
HeaderProvided: false,
IsRecognized: false,
CredentialVerified: HasVerifiedAuthentication(httpContext, configuration),
IdentityHintAuthorized: CanUseAgentIdentityHint(httpContext, configuration));
var allowed = AgentIdentityCatalog.BuildAllowedActorIds(await agentService.GetAllowedAgentIdsAsync(ct));
var normalized = AgentIdentityCatalog.NormalizeActorId(headerValue, allowed);
var credentialVerified = HasVerifiedAuthentication(httpContext, configuration);
var identityHintAuthorized = CanUseAgentIdentityHint(httpContext, configuration);
return new AgentHeaderResolution(
identityHintAuthorized ? normalized : null,
HeaderProvided: true,
IsRecognized: normalized is not null,
CredentialVerified: credentialVerified,
IdentityHintAuthorized: identityHintAuthorized);
}
public static bool HasValidServiceKey(HttpContext httpContext, IConfiguration configuration)
{
var configuredApiKey = configuration["NexusApiKey"];
if (string.IsNullOrWhiteSpace(configuredApiKey))
return false;
if (!httpContext.Request.Headers.TryGetValue("X-Nexus-Api-Key", out StringValues providedKey))
return false;
return string.Equals(configuredApiKey, providedKey.FirstOrDefault(), StringComparison.Ordinal);
}
}