feat: Implement vulnerability token signing and verification utilities
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added VulnTokenSigner for signing JWT tokens with specified algorithms and keys. - Introduced VulnTokenUtilities for resolving tenant and subject claims, and sanitizing context dictionaries. - Created VulnTokenVerificationUtilities for parsing tokens, verifying signatures, and deserializing payloads. - Developed VulnWorkflowAntiForgeryTokenIssuer for issuing anti-forgery tokens with configurable options. - Implemented VulnWorkflowAntiForgeryTokenVerifier for verifying anti-forgery tokens and validating payloads. - Added AuthorityVulnerabilityExplorerOptions to manage configuration for vulnerability explorer features. - Included tests for FilesystemPackRunDispatcher to ensure proper job handling under egress policy restrictions.
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
namespace StellaOps.Scheduler.WebService.Options;
|
||||
|
||||
/// <summary>
|
||||
/// Scheduler WebService event options (outbound + inbound).
|
||||
/// </summary>
|
||||
namespace StellaOps.Scheduler.WebService.Options;
|
||||
|
||||
/// <summary>
|
||||
/// Scheduler WebService event options (outbound + inbound).
|
||||
/// </summary>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public sealed class SchedulerEventsOptions
|
||||
{
|
||||
public GraphJobEventsOptions GraphJobs { get; set; } = new();
|
||||
|
||||
public SchedulerInboundWebhooksOptions Webhooks { get; set; } = new();
|
||||
}
|
||||
|
||||
|
||||
public sealed class SchedulerEventsOptions
|
||||
{
|
||||
public GraphJobEventsOptions GraphJobs { get; set; } = new();
|
||||
|
||||
public SchedulerInboundWebhooksOptions Webhooks { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class GraphJobEventsOptions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -50,91 +50,91 @@ public sealed class GraphJobEventsOptions
|
||||
/// </summary>
|
||||
public IDictionary<string, string> DriverSettings { get; set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public sealed class SchedulerInboundWebhooksOptions
|
||||
{
|
||||
public SchedulerWebhookOptions Feedser { get; set; } = SchedulerWebhookOptions.CreateDefault("feedser");
|
||||
|
||||
public SchedulerWebhookOptions Vexer { get; set; } = SchedulerWebhookOptions.CreateDefault("vexer");
|
||||
}
|
||||
|
||||
public sealed class SchedulerWebhookOptions
|
||||
{
|
||||
private const string DefaultSignatureHeader = "X-Scheduler-Signature";
|
||||
|
||||
public SchedulerWebhookOptions()
|
||||
{
|
||||
SignatureHeader = DefaultSignatureHeader;
|
||||
}
|
||||
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Require a client certificate to be presented (mTLS). Optional when HMAC is configured.
|
||||
/// </summary>
|
||||
public bool RequireClientCertificate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Shared secret (Base64 or raw text) for HMAC-SHA256 signatures. Required if <see cref="RequireClientCertificate"/> is false.
|
||||
/// </summary>
|
||||
public string? HmacSecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header name carrying the webhook signature (defaults to <c>X-Scheduler-Signature</c>).
|
||||
/// </summary>
|
||||
public string SignatureHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of accepted requests per sliding window.
|
||||
/// </summary>
|
||||
public int RateLimitRequests { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Sliding window duration in seconds for the rate limiter.
|
||||
/// </summary>
|
||||
public int RateLimitWindowSeconds { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Optional label used for logging/diagnostics; populated via <see cref="CreateDefault"/>.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public static SchedulerWebhookOptions CreateDefault(string name)
|
||||
=> new()
|
||||
{
|
||||
Name = name,
|
||||
SignatureHeader = DefaultSignatureHeader,
|
||||
RateLimitRequests = 120,
|
||||
RateLimitWindowSeconds = 60
|
||||
};
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (!Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(SignatureHeader))
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must specify a signature header when enabled.");
|
||||
}
|
||||
|
||||
if (!RequireClientCertificate && string.IsNullOrWhiteSpace(HmacSecret))
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must configure either HMAC secret or mTLS enforcement.");
|
||||
}
|
||||
|
||||
if (RateLimitRequests <= 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must configure a positive rate limit.");
|
||||
}
|
||||
|
||||
if (RateLimitWindowSeconds <= 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must configure a rate limit window greater than zero seconds.");
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan GetRateLimitWindow() => TimeSpan.FromSeconds(RateLimitWindowSeconds <= 0 ? 60 : RateLimitWindowSeconds);
|
||||
}
|
||||
|
||||
public sealed class SchedulerInboundWebhooksOptions
|
||||
{
|
||||
public SchedulerWebhookOptions Conselier { get; set; } = SchedulerWebhookOptions.CreateDefault("conselier");
|
||||
|
||||
public SchedulerWebhookOptions Excitor { get; set; } = SchedulerWebhookOptions.CreateDefault("excitor");
|
||||
}
|
||||
|
||||
public sealed class SchedulerWebhookOptions
|
||||
{
|
||||
private const string DefaultSignatureHeader = "X-Scheduler-Signature";
|
||||
|
||||
public SchedulerWebhookOptions()
|
||||
{
|
||||
SignatureHeader = DefaultSignatureHeader;
|
||||
}
|
||||
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Require a client certificate to be presented (mTLS). Optional when HMAC is configured.
|
||||
/// </summary>
|
||||
public bool RequireClientCertificate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Shared secret (Base64 or raw text) for HMAC-SHA256 signatures. Required if <see cref="RequireClientCertificate"/> is false.
|
||||
/// </summary>
|
||||
public string? HmacSecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header name carrying the webhook signature (defaults to <c>X-Scheduler-Signature</c>).
|
||||
/// </summary>
|
||||
public string SignatureHeader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of accepted requests per sliding window.
|
||||
/// </summary>
|
||||
public int RateLimitRequests { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Sliding window duration in seconds for the rate limiter.
|
||||
/// </summary>
|
||||
public int RateLimitWindowSeconds { get; set; } = 60;
|
||||
|
||||
/// <summary>
|
||||
/// Optional label used for logging/diagnostics; populated via <see cref="CreateDefault"/>.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
public static SchedulerWebhookOptions CreateDefault(string name)
|
||||
=> new()
|
||||
{
|
||||
Name = name,
|
||||
SignatureHeader = DefaultSignatureHeader,
|
||||
RateLimitRequests = 120,
|
||||
RateLimitWindowSeconds = 60
|
||||
};
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
if (!Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(SignatureHeader))
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must specify a signature header when enabled.");
|
||||
}
|
||||
|
||||
if (!RequireClientCertificate && string.IsNullOrWhiteSpace(HmacSecret))
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must configure either HMAC secret or mTLS enforcement.");
|
||||
}
|
||||
|
||||
if (RateLimitRequests <= 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must configure a positive rate limit.");
|
||||
}
|
||||
|
||||
if (RateLimitWindowSeconds <= 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Scheduler webhook '{Name}' must configure a rate limit window greater than zero seconds.");
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan GetRateLimitWindow() => TimeSpan.FromSeconds(RateLimitWindowSeconds <= 0 ? 60 : RateLimitWindowSeconds);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user