up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-25 22:09:44 +02:00
parent 6bee1fdcf5
commit 9f6e6f7fb3
116 changed files with 4495 additions and 730 deletions

View File

@@ -0,0 +1,115 @@
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
namespace StellaOps.Excititor.Storage.Mongo.Migrations;
/// <summary>
/// Adds a $jsonSchema validator to the raw VEX collection to enforce aggregation-only
/// shape (immutable content hash + provenance fields).
/// ValidationAction=warn keeps rollout safe while surfacing violations.
/// </summary>
internal sealed class VexRawSchemaMigration : IVexMongoMigration
{
public string Id => "20251125-vex-raw-json-schema";
public async ValueTask ExecuteAsync(IMongoDatabase database, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(database);
var exists = await CollectionExistsAsync(database, VexMongoCollectionNames.Raw, cancellationToken)
.ConfigureAwait(false);
var validator = BuildValidator();
if (!exists)
{
await database.CreateCollectionAsync(
VexMongoCollectionNames.Raw,
new CreateCollectionOptions
{
Validator = validator,
ValidationAction = DocumentValidationAction.Warn,
ValidationLevel = DocumentValidationLevel.Moderate,
},
cancellationToken).ConfigureAwait(false);
return;
}
var command = new BsonDocument
{
{ "collMod", VexMongoCollectionNames.Raw },
{ "validator", validator },
{ "validationAction", "warn" },
{ "validationLevel", "moderate" },
};
await database.RunCommandAsync<BsonDocument>(command, cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
private static async Task<bool> CollectionExistsAsync(
IMongoDatabase database,
string name,
CancellationToken cancellationToken)
{
using var cursor = await database.ListCollectionNamesAsync(
new ListCollectionNamesOptions { Filter = new BsonDocument("name", name) },
cancellationToken).ConfigureAwait(false);
return await cursor.AnyAsync(cancellationToken).ConfigureAwait(false);
}
private static BsonDocument BuildValidator()
{
var properties = new BsonDocument
{
{ "_id", new BsonDocument { { "bsonType", "string" }, { "description", "digest" } } },
{ "providerId", new BsonDocument { { "bsonType", "string" }, { "minLength", 1 } } },
{ "format", new BsonDocument
{
{ "bsonType", "string" },
{ "enum", new BsonArray { "csaf", "cyclonedx", "openvex" } }
}
},
{ "sourceUri", new BsonDocument { { "bsonType", "string" }, { "minLength", 1 } } },
{ "retrievedAt", new BsonDocument { { "bsonType", "date" } } },
{ "digest", new BsonDocument { { "bsonType", "string" }, { "minLength", 32 } } },
{ "content", new BsonDocument
{
{ "bsonType", new BsonArray { "binData", "string" } }
}
},
{ "gridFsObjectId", new BsonDocument
{
{ "bsonType", new BsonArray { "objectId", "null", "string" } }
}
},
{ "metadata", new BsonDocument
{
{ "bsonType", "object" },
{ "additionalProperties", true },
{ "patternProperties", new BsonDocument
{
{ ".*", new BsonDocument { { "bsonType", "string" } } }
}
}
}
}
};
return new BsonDocument
{
{
"$jsonSchema",
new BsonDocument
{
{ "bsonType", "object" },
{ "required", new BsonArray { "_id", "providerId", "format", "sourceUri", "retrievedAt", "digest" } },
{ "properties", properties },
{ "additionalProperties", true }
}
}
};
}
}

View File

@@ -61,6 +61,7 @@ public static class VexMongoServiceCollectionExtensions
services.AddScoped<VexStatementBackfillService>();
services.AddScoped<IVexObservationLookup, MongoVexObservationLookup>();
services.AddSingleton<IVexMongoMigration, VexInitialIndexMigration>();
services.AddSingleton<IVexMongoMigration, VexRawSchemaMigration>();
services.AddSingleton<IVexMongoMigration, VexConsensusSignalsMigration>();
services.AddSingleton<IVexMongoMigration, VexConsensusHoldMigration>();
services.AddSingleton<IVexMongoMigration, VexObservationCollectionsMigration>();