Strongly-typed C# models for OSCAL (Open Security Controls Assessment Language), generated from NIST Metaschema definitions.
| Package | Description | NuGet | Downloads |
|---|---|---|---|
| DamianH.Oscal | Strongly-typed C# models for OSCAL generated from NIST Metaschema definitions | NuGet | Downloads |
- All 8 OSCAL model types — Catalog, Profile, Component Definition, SSP, SAP, SAR, POA&M, and Mapping
- Versioned namespaces —
Oscal.V1_2_0, allowing multiple OSCAL versions to coexist - Zero runtime dependencies — pure models with
System.Text.Jsonsource generation - Modern C# —
sealed recordtypes,requiredproperties,init-only setters,IReadOnlyList<T>collections - High-performance serialization — JSON source generation via
V1_2_0JsonContext
dotnet add package DamianH.Oscal
Requires .NET 10.0 or later.
using System.Text.Json; using Oscal.V1_2_0; // Deserialize using source-generated context (fastest) var json = File.ReadAllText("nist-800-53-catalog.json"); var catalog = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.Catalog); Console.WriteLine($"Catalog: {catalog.Metadata.Title}"); // Serialize back to JSON var output = JsonSerializer.Serialize(catalog, V1_2_0JsonContext.Default.Catalog);
using System.Text.Json; using Oscal.V1_2_0; var catalog = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.Catalog); var profile = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.Profile); var ssp = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.SystemSecurityPlan); var compDef = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.ComponentDefinition); var sap = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.AssessmentPlan); var sar = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.AssessmentResults); var poam = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.PlanOfActionAndMilestones); var mapping = JsonSerializer.Deserialize(json, V1_2_0JsonContext.Default.MappingCollection);
using OscalV1_2_0 = Oscal.V1_2_0; using OscalV1_3_0 = Oscal.V1_3_0; // future var oldCatalog = JsonSerializer.Deserialize<OscalV1_2_0.Catalog>(oldJson); var newCatalog = JsonSerializer.Deserialize<OscalV1_3_0.Catalog>(newJson);
| OSCAL Version | Namespace | Status |
|---|---|---|
| 1.2.0 | Oscal.V1_2_0 |
Generated |
Reference metaschema definitions are stored for all OSCAL releases from v1.0.0 through v1.2.0.
Models are generated from NIST OSCAL Metaschema XML definitions. Each type is a sealed record:
public sealed record Catalog { [JsonPropertyName("uuid")] public required Guid Uuid { get; init; } [JsonPropertyName("metadata")] public required Metadata Metadata { get; init; } [JsonPropertyName("controls")] public IReadOnlyList<Control> Controls { get; init; } = []; [JsonPropertyName("groups")] public IReadOnlyList<Group> Groups { get; init; } = []; [JsonPropertyName("back-matter")] public BackMatter? BackMatter { get; init; } }
JSON serialization uses System.Text.Json source generation with kebab-case naming:
[JsonSourceGenerationOptions( WriteIndented = true, PropertyNamingPolicy = JsonKnownNamingPolicy.KebabCaseLower, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] [JsonSerializable(typeof(Catalog))] [JsonSerializable(typeof(Profile))] // ... all 134 types public partial class V1_2_0JsonContext : JsonSerializerContext { }
dotnet run build.cs # clean + build + test dotnet run build.cs -- pack # create NuGet packages dotnet run build.cs -- test # run tests only
dotnet run build.cs -- update-oscal 1.2.0 # fetch specific version dotnet run build.cs -- update-oscal all # fetch all versions
MIT