feat(graph-api): Add schema review notes for upcoming Graph API changes
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

feat(sbomservice): Add placeholder for SHA256SUMS in LNM v1 fixtures

docs(devportal): Create README for SDK archives in public directory

build(devportal): Implement offline bundle build script

test(devportal): Add link checker script for validating links in documentation

test(devportal): Create performance check script for dist folder size

test(devportal): Implement accessibility check script using Playwright and Axe

docs(devportal): Add SDK quickstart guide with examples for Node.js, Python, and cURL

feat(excititor): Implement MongoDB storage for airgap import records

test(findings): Add unit tests for export filters hash determinism

feat(findings): Define attestation contracts for ledger web service

feat(graph): Add MongoDB options and service collection extensions for graph indexing

test(graph): Implement integration tests for MongoDB provider and service collection extensions

feat(zastava): Define configuration options for Zastava surface secrets

build(tests): Create script to run Concelier linkset tests with TRX output
This commit is contained in:
StellaOps Bot
2025-11-22 19:22:30 +02:00
parent ca09400069
commit 48702191be
76 changed files with 3878 additions and 1081 deletions

View File

@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using StellaOps.Zastava.Core.Configuration;
namespace StellaOps.Zastava.Webhook.Configuration;
@@ -17,7 +18,10 @@ public sealed class ZastavaWebhookOptions
[Required]
public ZastavaWebhookBackendOptions Backend { get; init; } = new();
}
[Required]
public ZastavaSurfaceSecretsOptions Secrets { get; init; } = new();
}
public sealed class ZastavaWebhookAdmissionOptions
{

View File

@@ -12,7 +12,7 @@ internal interface IWebhookSurfaceFsClient
internal sealed class WebhookSurfaceFsClient : IWebhookSurfaceFsClient
{
private readonly ISurfaceManifestReader _manifestReader;
private readonly SurfaceManifestPathBuilder _pathBuilder;
private readonly SurfaceManifestStoreOptions _storeOptions;
private readonly IOptions<ZastavaRuntimeOptions> _runtimeOptions;
public WebhookSurfaceFsClient(
@@ -34,7 +34,7 @@ internal sealed class WebhookSurfaceFsClient : IWebhookSurfaceFsClient
throw new ArgumentNullException(nameof(storeOptions));
}
_pathBuilder = new SurfaceManifestPathBuilder(cacheOptions.Value, storeOptions.Value);
_storeOptions = storeOptions.Value ?? throw new ArgumentNullException(nameof(storeOptions.Value));
}
public async Task<(bool Found, string? ManifestUri)> TryGetManifestAsync(string manifestDigest, CancellationToken cancellationToken = default)
@@ -57,9 +57,36 @@ internal sealed class WebhookSurfaceFsClient : IWebhookSurfaceFsClient
? manifest.Tenant
: _runtimeOptions.Value.Tenant;
var digestHex = SurfaceManifestPathBuilder.EnsureSha256Digest(manifestDigest); // strips sha256:
var uri = _pathBuilder.BuildManifestUri(tenant, digestHex);
var digestHex = EnsureSha256Digest(manifestDigest); // strips sha256:
var uri = BuildManifestUri(_storeOptions, tenant, digestHex);
return (true, uri);
}
private static string BuildManifestUri(SurfaceManifestStoreOptions storeOptions, string tenant, string digestHex)
{
var tenantSegment = SanitizeTenant(tenant);
return $"{storeOptions.Scheme}://{storeOptions.Bucket}/{storeOptions.Prefix}/{tenantSegment}/{digestHex[..2]}/{digestHex[2..4]}/{digestHex}.json";
}
private static string SanitizeTenant(string value)
=> string.IsNullOrWhiteSpace(value)
? "default"
: value.Replace('/', '_').Replace('\\', '_');
private static string EnsureSha256Digest(string manifestDigest)
{
if (string.IsNullOrWhiteSpace(manifestDigest))
{
throw new ArgumentException("Digest cannot be null or empty.", nameof(manifestDigest));
}
const string prefix = "sha256:";
if (!manifestDigest.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Only sha256 digests are supported.", nameof(manifestDigest));
}
return manifestDigest[prefix.Length..].ToLowerInvariant();
}
}