namespace StellaOps.Zastava.Core.Contracts;
///
/// Envelope published by the observer towards Scanner runtime ingestion.
///
public sealed record class RuntimeEventEnvelope
{
///
/// Contract identifier consumed by negotiation logic (zastava.runtime.event@v1).
///
public required string SchemaVersion { get; init; }
///
/// Runtime event payload.
///
public required RuntimeEvent Event { get; init; }
///
/// Creates an envelope using the provided runtime contract version.
///
public static RuntimeEventEnvelope Create(RuntimeEvent runtimeEvent, ZastavaContractVersions.ContractVersion contract)
{
ArgumentNullException.ThrowIfNull(runtimeEvent);
return new RuntimeEventEnvelope
{
SchemaVersion = contract.ToString(),
Event = runtimeEvent
};
}
///
/// Checks whether the envelope schema is supported by the current runtime.
///
public bool IsSupported()
=> ZastavaContractVersions.IsRuntimeEventSupported(SchemaVersion);
}
///
/// Canonical runtime event emitted by the observer.
///
public sealed record class RuntimeEvent
{
public required string EventId { get; init; }
public required DateTimeOffset When { get; init; }
public required RuntimeEventKind Kind { get; init; }
public required string Tenant { get; init; }
public required string Node { get; init; }
public required RuntimeEngine Runtime { get; init; }
public required RuntimeWorkload Workload { get; init; }
public RuntimeProcess? Process { get; init; }
[JsonPropertyName("loadedLibs")]
public IReadOnlyList LoadedLibraries { get; init; } = Array.Empty();
public RuntimePosture? Posture { get; init; }
public RuntimeDelta? Delta { get; init; }
public IReadOnlyList Evidence { get; init; } = Array.Empty();
public IReadOnlyDictionary? Annotations { get; init; }
}
public enum RuntimeEventKind
{
ContainerStart,
ContainerStop,
Drift,
PolicyViolation,
AttestationStatus
}
public sealed record class RuntimeEngine
{
public required string Engine { get; init; }
public string? Version { get; init; }
}
public sealed record class RuntimeWorkload
{
public required string Platform { get; init; }
[JsonPropertyName("namespace")]
public string? Namespace { get; init; }
public string? Pod { get; init; }
public string? Container { get; init; }
public string? ContainerId { get; init; }
public string? ImageRef { get; init; }
public RuntimeWorkloadOwner? Owner { get; init; }
}
public sealed record class RuntimeWorkloadOwner
{
public string? Kind { get; init; }
public string? Name { get; init; }
}
public sealed record class RuntimeProcess
{
public int Pid { get; init; }
public IReadOnlyList Entrypoint { get; init; } = Array.Empty();
[JsonPropertyName("entryTrace")]
public IReadOnlyList EntryTrace { get; init; } = Array.Empty();
}
public sealed record class RuntimeEntryTrace
{
public string? File { get; init; }
public int? Line { get; init; }
public string? Op { get; init; }
public string? Target { get; init; }
}
public sealed record class RuntimeLoadedLibrary
{
public required string Path { get; init; }
public long? Inode { get; init; }
public string? Sha256 { get; init; }
}
public sealed record class RuntimePosture
{
public bool? ImageSigned { get; init; }
public string? SbomReferrer { get; init; }
public RuntimeAttestation? Attestation { get; init; }
}
public sealed record class RuntimeAttestation
{
public string? Uuid { get; init; }
public bool? Verified { get; init; }
}
public sealed record class RuntimeDelta
{
public string? BaselineImageDigest { get; init; }
public IReadOnlyList ChangedFiles { get; init; } = Array.Empty();
public IReadOnlyList NewBinaries { get; init; } = Array.Empty();
}
public sealed record class RuntimeNewBinary
{
public required string Path { get; init; }
public string? Sha256 { get; init; }
}
public sealed record class RuntimeEvidence
{
public required string Signal { get; init; }
public string? Value { get; init; }
}