feat: Enhance traceability and logging in Risk and Vulnerability clients
- Implemented shared trace ID generation utility for Risk and Vulnerability clients, ensuring consistent trace headers across API calls. - Updated RiskHttpClient and VulnerabilityHttpClient to utilize the new trace ID generation method. - Added validation for artifact metadata in PackRun endpoints, ensuring all artifacts include a digest and positive size. - Enhanced logging payloads in PackRun to include artifact digests and sizes. - Created a utility for generating trace IDs, preferring crypto.randomUUID when available, with a fallback to a ULID-style string. - Added unit tests to verify the presence of trace IDs in HTTP requests for VulnerabilityHttpClient. - Documented query-hash metrics for Vuln Explorer, detailing hashing rules and logging filters to ensure compliance with privacy standards. - Consolidated findings from late-November reviews into a comprehensive advisory for Scanner and SBOM/VEX areas, outlining remediation tracks and gaps.
This commit is contained in:
@@ -2,9 +2,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.Scanner.Surface.FS;
|
||||
using Xunit;
|
||||
|
||||
@@ -34,7 +37,8 @@ public sealed class FileSurfaceManifestStoreTests : IAsyncDisposable
|
||||
_store = new FileSurfaceManifestStore(
|
||||
cacheOptions,
|
||||
manifestOptions,
|
||||
NullLogger<FileSurfaceManifestStore>.Instance);
|
||||
NullLogger<FileSurfaceManifestStore>.Instance,
|
||||
new TestCryptoHash());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -201,6 +205,31 @@ public sealed class FileSurfaceManifestStoreTests : IAsyncDisposable
|
||||
$"{hex}.json");
|
||||
}
|
||||
|
||||
private sealed class TestCryptoHash : ICryptoHash
|
||||
{
|
||||
public byte[] ComputeHash(ReadOnlySpan<byte> data, string? algorithmId = null)
|
||||
=> SHA256.HashData(data);
|
||||
|
||||
public string ComputeHashHex(ReadOnlySpan<byte> data, string? algorithmId = null)
|
||||
=> Convert.ToHexString(ComputeHash(data, algorithmId)).ToLowerInvariant();
|
||||
|
||||
public string ComputeHashBase64(ReadOnlySpan<byte> data, string? algorithmId = null)
|
||||
=> Convert.ToBase64String(ComputeHash(data, algorithmId));
|
||||
|
||||
public async ValueTask<byte[]> ComputeHashAsync(Stream stream, string? algorithmId = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await using var buffer = new MemoryStream();
|
||||
await stream.CopyToAsync(buffer, cancellationToken).ConfigureAwait(false);
|
||||
return SHA256.HashData(buffer.ToArray());
|
||||
}
|
||||
|
||||
public async ValueTask<string> ComputeHashHexAsync(Stream stream, string? algorithmId = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var hash = await ComputeHashAsync(stream, algorithmId, cancellationToken).ConfigureAwait(false);
|
||||
return Convert.ToHexString(hash).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
|
||||
Reference in New Issue
Block a user