stabilize tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json.Serialization;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Contracts;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Contracts;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Notifier.Worker.Escalation;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Escalation;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Fallback;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notifier.Worker.Localization;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Localization;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notifier.WebService.Contracts;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Dispatch;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notifier.Worker.Templates;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notifier.Worker.Observability;
|
||||
using StellaOps.Notifier.Worker.Retention;
|
||||
using System.Linq;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Notifier.Worker.Correlation;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Correlation;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Notifier.Worker.Correlation;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Correlation;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notifier.WebService.Contracts;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Simulation;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Simulation;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notifier.Worker.StormBreaker;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.StormBreaker;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notifier.WebService.Contracts;
|
||||
using StellaOps.Notifier.Worker.Dispatch;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notifier.Worker.Templates;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using StellaOps.Notifier.Worker.Correlation;
|
||||
using StellaOps.Notifier.WebService.Extensions;
|
||||
using StellaOps.Notifier.Worker.Correlation;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Endpoints;
|
||||
|
||||
|
||||
@@ -123,10 +123,6 @@ app.UseWebSockets(new WebSocketOptions
|
||||
|
||||
app.MapHealthChecks("/healthz");
|
||||
|
||||
// Tenant context middleware (extracts and validates tenant from headers/query)
|
||||
app.UseTenantContext();
|
||||
app.TryUseStellaRouter(routerOptions);
|
||||
|
||||
// Deprecation headers for retiring v1 APIs (RFC 8594 / IETF Sunset)
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
@@ -141,6 +137,10 @@ app.Use(async (context, next) =>
|
||||
await next().ConfigureAwait(false);
|
||||
});
|
||||
|
||||
// Tenant context middleware (extracts and validates tenant from headers/query)
|
||||
app.UseTenantContext();
|
||||
app.TryUseStellaRouter(routerOptions);
|
||||
|
||||
app.MapPost("/api/v1/notify/pack-approvals", async (
|
||||
HttpContext context,
|
||||
PackApprovalRequest request,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Services;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Services;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Services;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Services;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Services;
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Setup;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
using StellaOps.Notify.Queue;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Notify.Queue;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Setup;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Setup;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Setup;
|
||||
|
||||
@@ -172,7 +173,10 @@ public sealed class PackApprovalTemplateSeeder : IHostedService
|
||||
var candidates = new[]
|
||||
{
|
||||
Path.Combine(contentRootPath, "StellaOps.Notifier.docs", "pack-approval-templates.json"),
|
||||
Path.Combine(contentRootPath, "..", "StellaOps.Notifier.docs", "pack-approval-templates.json")
|
||||
Path.Combine(contentRootPath, "..", "StellaOps.Notifier.docs", "pack-approval-templates.json"),
|
||||
Path.Combine(contentRootPath, "StellaOps.Notifier", "StellaOps.Notifier.docs", "pack-approval-templates.json"),
|
||||
Path.Combine(contentRootPath, "Notifier", "StellaOps.Notifier", "StellaOps.Notifier.docs", "pack-approval-templates.json"),
|
||||
Path.Combine(contentRootPath, "src", "Notifier", "StellaOps.Notifier", "StellaOps.Notifier.docs", "pack-approval-templates.json")
|
||||
};
|
||||
|
||||
foreach (var candidate in candidates)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Xml;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notifier.Worker.Storage;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Setup;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using StellaOps.Notify.Models;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace StellaOps.Notifier.WebService.Storage.Compat;
|
||||
|
||||
|
||||
@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
|
||||
| AUDIT-0395-M | DONE | Revalidated 2026-01-07; maintainability audit for StellaOps.Notifier.WebService. |
|
||||
| AUDIT-0395-T | DONE | Revalidated 2026-01-07; test coverage audit for StellaOps.Notifier.WebService. |
|
||||
| AUDIT-0395-A | TODO | Revalidated 2026-01-07 (open findings). |
|
||||
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"templateId": "identity-matched-email",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"channelType": "Email",
|
||||
"key": "identity-matched",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Markdown",
|
||||
"renderMode": "Html",
|
||||
"format": "Html",
|
||||
"description": "Identity watchlist match alert for Email",
|
||||
"description": "Email notification for identity watchlist matches",
|
||||
"metadata": {
|
||||
"category": "attestation",
|
||||
"eventKind": "attestor.identity.matched",
|
||||
"subject": "[{{ event.severity }}] Identity Watchlist Alert: {{ event.watchlistEntryName }}"
|
||||
"category": "attestation",
|
||||
"subject": "[{{ event.severity | upper }}] Identity Watchlist Alert: {{ event.watchlistEntryName }}"
|
||||
},
|
||||
"body": "# Identity Watchlist Alert\n\n**Watchlist Entry:** {{ event.watchlistEntryName }}\n\n**Severity:** {{ event.severity }}\n\n**Occurred:** {{ event.occurredAtUtc }}\n\n---\n\n## Matched Identity\n\n| Field | Value |\n|-------|-------|\n{% if event.matchedIdentity.issuer %}| Issuer | {{ event.matchedIdentity.issuer }} |{% endif %}\n{% if event.matchedIdentity.subjectAlternativeName %}| Subject Alternative Name | {{ event.matchedIdentity.subjectAlternativeName }} |{% endif %}\n{% if event.matchedIdentity.keyId %}| Key ID | {{ event.matchedIdentity.keyId }} |{% endif %}\n\n## Rekor Entry Details\n\n| Field | Value |\n|-------|-------|\n| UUID | {{ event.rekorEntry.uuid }} |\n| Log Index | {{ event.rekorEntry.logIndex }} |\n| Artifact SHA256 | {{ event.rekorEntry.artifactSha256 }} |\n| Integrated Time (UTC) | {{ event.rekorEntry.integratedTimeUtc }} |\n\n{% if event.suppressedCount > 0 %}\n---\n\n*Note: {{ event.suppressedCount }} similar alerts were suppressed within the deduplication window.*\n{% endif %}\n\n---\n\n*This alert was generated by Stella Ops identity watchlist monitoring.*"
|
||||
"body": "<!DOCTYPE html>\n<html>\n<head><style>body{font-family:sans-serif;line-height:1.5;}.severity-critical{color:#dc3545;}.severity-warning{color:#ffc107;}.severity-info{color:#0dcaf0;}.section{margin:1em 0;padding:1em;background:#f8f9fa;border-radius:4px;}.label{font-weight:bold;color:#666;}.mono{font-family:monospace;background:#e9ecef;padding:2px 6px;border-radius:3px;}</style></head>\n<body>\n<h2 class=\"severity-{{ event.severity }}\">Identity Watchlist Alert</h2>\n<div class=\"section\">\n<p><span class=\"label\">Severity:</span> <strong>{{ event.severity }}</strong></p>\n<p><span class=\"label\">Watchlist Entry:</span> {{ event.watchlistEntryName }}</p>\n</div>\n<div class=\"section\">\n<h3>Matched Identity</h3>\n{{ #if event.matchedIdentity.issuer }}<p><span class=\"label\">Issuer:</span> <span class=\"mono\">{{ event.matchedIdentity.issuer }}</span></p>{{ /if }}\n{{ #if event.matchedIdentity.subjectAlternativeName }}<p><span class=\"label\">Subject Alternative Name:</span> <span class=\"mono\">{{ event.matchedIdentity.subjectAlternativeName }}</span></p>{{ /if }}\n{{ #if event.matchedIdentity.keyId }}<p><span class=\"label\">Key ID:</span> <span class=\"mono\">{{ event.matchedIdentity.keyId }}</span></p>{{ /if }}\n</div>\n<div class=\"section\">\n<h3>Rekor Entry</h3>\n<p><span class=\"label\">UUID:</span> <span class=\"mono\">{{ event.rekorEntry.uuid }}</span></p>\n<p><span class=\"label\">Log Index:</span> {{ event.rekorEntry.logIndex }}</p>\n<p><span class=\"label\">Artifact SHA-256:</span> <span class=\"mono\">{{ event.rekorEntry.artifactSha256 }}</span></p>\n<p><span class=\"label\">Integrated Time (UTC):</span> {{ event.rekorEntry.integratedTimeUtc }}</p>\n</div>\n{{ #if (gt event.suppressedCount 0) }}<p><em>{{ event.suppressedCount }} duplicate alerts suppressed</em></p>{{ /if }}\n<hr>\n<p style=\"font-size:0.85em;color:#666;\">Event ID: {{ event.eventId }} | Occurred: {{ event.occurredAtUtc }}</p>\n</body>\n</html>"
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"templateId": "identity-matched-slack",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"channelType": "Slack",
|
||||
"key": "identity-matched",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Markdown",
|
||||
"format": "Json",
|
||||
"description": "Identity watchlist match alert for Slack",
|
||||
"description": "Slack notification for identity watchlist matches",
|
||||
"metadata": {
|
||||
"category": "attestation",
|
||||
"eventKind": "attestor.identity.matched"
|
||||
"eventKind": "attestor.identity.matched",
|
||||
"category": "attestation"
|
||||
},
|
||||
"body": ":warning: *Identity Watchlist Alert*\n\n*Entry:* {{ event.watchlistEntryName }}\n*Severity:* {{ event.severity }}\n\n*Matched Identity:*\n{% if event.matchedIdentity.issuer %}• Issuer: `{{ event.matchedIdentity.issuer }}`{% endif %}\n{% if event.matchedIdentity.subjectAlternativeName %}• SAN: `{{ event.matchedIdentity.subjectAlternativeName }}`{% endif %}\n{% if event.matchedIdentity.keyId %}• Key ID: `{{ event.matchedIdentity.keyId }}`{% endif %}\n\n*Rekor Entry:*\n• UUID: `{{ event.rekorEntry.uuid }}`\n• Log Index: `{{ event.rekorEntry.logIndex }}`\n• Artifact: `{{ event.rekorEntry.artifactSha256 }}`\n• Time: {{ event.rekorEntry.integratedTimeUtc }}\n\n{% if event.suppressedCount > 0 %}_({{ event.suppressedCount }} similar alerts suppressed)_{% endif %}"
|
||||
"body": "{{ #if (eq event.severity \"critical\") }}:rotating_light:{{ else if (eq event.severity \"warning\") }}:warning:{{ else }}:information_source:{{ /if }} *Identity Watchlist Alert*\n\n*Severity:* `{{ event.severity }}`\n*Watchlist Entry:* {{ event.watchlistEntryName }}\n\n*Matched Identity:*\n{{ #if event.matchedIdentity.issuer }}> Issuer: `{{ event.matchedIdentity.issuer }}`\n{{ /if }}{{ #if event.matchedIdentity.subjectAlternativeName }}> SAN: `{{ event.matchedIdentity.subjectAlternativeName }}`\n{{ /if }}{{ #if event.matchedIdentity.keyId }}> Key ID: `{{ event.matchedIdentity.keyId }}`\n{{ /if }}\n*Rekor Entry:*\n> UUID: `{{ event.rekorEntry.uuid }}`\n> Log Index: {{ event.rekorEntry.logIndex }}\n> Artifact: `{{ event.rekorEntry.artifactSha256 }}`\n> Integrated: {{ event.rekorEntry.integratedTimeUtc }}\n\n{{ #if (gt event.suppressedCount 0) }}:mute: {{ event.suppressedCount }} duplicate alerts suppressed\n{{ /if }}---\n_Event ID: {{ event.eventId }}_"
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
{
|
||||
"templateId": "identity-matched-teams",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "teams",
|
||||
"channelType": "Teams",
|
||||
"key": "identity-matched",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Markdown",
|
||||
"renderMode": "None",
|
||||
"format": "Json",
|
||||
"description": "Identity watchlist match alert for Microsoft Teams",
|
||||
"description": "Microsoft Teams adaptive card for identity watchlist matches",
|
||||
"metadata": {
|
||||
"eventKind": "attestor.identity.matched",
|
||||
"category": "attestation",
|
||||
"eventKind": "attestor.identity.matched"
|
||||
"contentType": "application/json"
|
||||
},
|
||||
"body": "{ \"@type\": \"MessageCard\", \"@context\": \"http://schema.org/extensions\", \"themeColor\": \"{% if event.severity == 'Critical' %}d13438{% elsif event.severity == 'Warning' %}ffb900{% else %}0078d4{% endif %}\", \"summary\": \"Identity Watchlist Alert: {{ event.watchlistEntryName }}\", \"sections\": [{ \"activityTitle\": \"⚠️ Identity Watchlist Alert\", \"activitySubtitle\": \"Entry: {{ event.watchlistEntryName }}\", \"facts\": [{ \"name\": \"Severity\", \"value\": \"{{ event.severity }}\" }, { \"name\": \"Occurred\", \"value\": \"{{ event.occurredAtUtc }}\" }{% if event.matchedIdentity.issuer %}, { \"name\": \"Issuer\", \"value\": \"{{ event.matchedIdentity.issuer }}\" }{% endif %}{% if event.matchedIdentity.subjectAlternativeName %}, { \"name\": \"SAN\", \"value\": \"{{ event.matchedIdentity.subjectAlternativeName }}\" }{% endif %}, { \"name\": \"Rekor UUID\", \"value\": \"{{ event.rekorEntry.uuid }}\" }, { \"name\": \"Log Index\", \"value\": \"{{ event.rekorEntry.logIndex }}\" }{% if event.suppressedCount > 0 %}, { \"name\": \"Suppressed Count\", \"value\": \"{{ event.suppressedCount }}\" }{% endif %}], \"markdown\": true }] }"
|
||||
"body": "{\"type\":\"message\",\"attachments\":[{\"contentType\":\"application/vnd.microsoft.card.adaptive\",\"content\":{\"$schema\":\"http://adaptivecards.io/schemas/adaptive-card.json\",\"type\":\"AdaptiveCard\",\"version\":\"1.4\",\"body\":[{\"type\":\"TextBlock\",\"text\":\"Identity Watchlist Alert\",\"weight\":\"bolder\",\"size\":\"large\",\"color\":\"{{ #if (eq event.severity 'critical') }}attention{{ else if (eq event.severity 'warning') }}warning{{ else }}default{{ /if }}\"},{\"type\":\"FactSet\",\"facts\":[{\"title\":\"Severity\",\"value\":\"{{ event.severity }}\"},{\"title\":\"Watchlist Entry\",\"value\":\"{{ event.watchlistEntryName }}\"}]},{\"type\":\"TextBlock\",\"text\":\"Matched Identity\",\"weight\":\"bolder\",\"spacing\":\"medium\"},{\"type\":\"FactSet\",\"facts\":[{{ #if event.matchedIdentity.issuer }}{\"title\":\"Issuer\",\"value\":\"{{ event.matchedIdentity.issuer }}\"},{{ /if }}{{ #if event.matchedIdentity.subjectAlternativeName }}{\"title\":\"SAN\",\"value\":\"{{ event.matchedIdentity.subjectAlternativeName }}\"},{{ /if }}{{ #if event.matchedIdentity.keyId }}{\"title\":\"Key ID\",\"value\":\"{{ event.matchedIdentity.keyId }}\"},{{ /if }}{\"title\":\"\",\"value\":\"\"}]},{\"type\":\"TextBlock\",\"text\":\"Rekor Entry\",\"weight\":\"bolder\",\"spacing\":\"medium\"},{\"type\":\"FactSet\",\"facts\":[{\"title\":\"UUID\",\"value\":\"{{ event.rekorEntry.uuid }}\"},{\"title\":\"Log Index\",\"value\":\"{{ event.rekorEntry.logIndex }}\"},{\"title\":\"Artifact\",\"value\":\"{{ event.rekorEntry.artifactSha256 }}\"},{\"title\":\"Integrated\",\"value\":\"{{ event.rekorEntry.integratedTimeUtc }}\"}]}{{ #if (gt event.suppressedCount 0) }},{\"type\":\"TextBlock\",\"text\":\"{{ event.suppressedCount }} duplicate alerts suppressed\",\"isSubtle\":true,\"spacing\":\"small\"}{{ /if }}],\"msteams\":{\"width\":\"Full\"}}}]}"
|
||||
}
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
{
|
||||
"templateId": "identity-matched-webhook",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "webhook",
|
||||
"channelType": "Webhook",
|
||||
"key": "identity-matched",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "None",
|
||||
"format": "Json",
|
||||
"description": "Identity watchlist match alert for Webhook (SIEM/SOC integration)",
|
||||
"description": "Webhook payload for identity watchlist matches",
|
||||
"metadata": {
|
||||
"eventKind": "attestor.identity.matched",
|
||||
"category": "attestation",
|
||||
"eventKind": "attestor.identity.matched"
|
||||
"contentType": "application/json"
|
||||
},
|
||||
"body": "{ \"eventType\": \"attestor.identity.matched\", \"eventId\": \"{{ event.eventId }}\", \"tenantId\": \"{{ event.tenantId }}\", \"severity\": \"{{ event.severity }}\", \"occurredAtUtc\": \"{{ event.occurredAtUtc }}\", \"watchlist\": { \"entryId\": \"{{ event.watchlistEntryId }}\", \"entryName\": \"{{ event.watchlistEntryName }}\" }, \"matchedIdentity\": { \"issuer\": \"{{ event.matchedIdentity.issuer }}\", \"subjectAlternativeName\": \"{{ event.matchedIdentity.subjectAlternativeName }}\", \"keyId\": \"{{ event.matchedIdentity.keyId }}\" }, \"rekorEntry\": { \"uuid\": \"{{ event.rekorEntry.uuid }}\", \"logIndex\": {{ event.rekorEntry.logIndex }}, \"artifactSha256\": \"{{ event.rekorEntry.artifactSha256 }}\", \"integratedTimeUtc\": \"{{ event.rekorEntry.integratedTimeUtc }}\" }, \"suppressedCount\": {{ event.suppressedCount }} }"
|
||||
"body": "{\"alertType\":\"identity-watchlist-match\",\"severity\":\"{{ event.severity }}\",\"watchlist\":{\"entryId\":\"{{ event.watchlistEntryId }}\",\"entryName\":\"{{ event.watchlistEntryName }}\"},\"matchedIdentity\":{\"issuer\":{{ #if event.matchedIdentity.issuer }}\"{{ event.matchedIdentity.issuer }}\"{{ else }}null{{ /if }},\"subjectAlternativeName\":{{ #if event.matchedIdentity.subjectAlternativeName }}\"{{ event.matchedIdentity.subjectAlternativeName }}\"{{ else }}null{{ /if }},\"keyId\":{{ #if event.matchedIdentity.keyId }}\"{{ event.matchedIdentity.keyId }}\"{{ else }}null{{ /if }}},\"rekorEntry\":{\"uuid\":\"{{ event.rekorEntry.uuid }}\",\"logIndex\":{{ event.rekorEntry.logIndex }},\"artifactSha256\":\"{{ event.rekorEntry.artifactSha256 }}\",\"integratedTimeUtc\":\"{{ event.rekorEntry.integratedTimeUtc }}\"},\"eventId\":\"{{ event.eventId }}\",\"occurredAtUtc\":\"{{ event.occurredAtUtc }}\",\"suppressedCount\":{{ event.suppressedCount }}}"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"templateId": "tmpl-risk-profile-state-email",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "Email",
|
||||
"key": "tmpl-risk-profile-state",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Html",
|
||||
"format": "Html",
|
||||
"description": "Email notification for risk profile state changes",
|
||||
"metadata": {
|
||||
"eventKind": "risk.profile.published",
|
||||
"category": "risk",
|
||||
"subject": "[Notify] Risk profile update: {{ event.profileName }}"
|
||||
},
|
||||
"body": "<!DOCTYPE html>\n<html>\n<head><style>body{font-family:sans-serif;line-height:1.5;}.section{margin:1em 0;padding:1em;background:#f8f9fa;border-radius:4px;}.label{font-weight:bold;color:#666;}.mono{font-family:monospace;background:#e9ecef;padding:2px 6px;border-radius:3px;}</style></head>\n<body>\n<h2>Risk Profile Update</h2>\n<div class=\"section\">\n<p><span class=\"label\">Profile:</span> <span class=\"mono\">{{ event.profileName }}</span></p>\n<p><span class=\"label\">State:</span> {{ event.state }}</p>\n<p><span class=\"label\">Owner:</span> {{ event.owner }}</p>\n<p><span class=\"label\">Summary:</span> {{ event.summary }}</p>\n{{ #if event.policyId }}<p><span class=\"label\">Policy:</span> {{ event.policyId }} (v{{ event.policyVersion }})</p>{{ /if }}\n</div>\n<hr>\n<p style=\"font-size:0.85em;color:#666;\">Event ID: {{ event.eventId }} | Occurred: {{ event.occurredAtUtc }}</p>\n</body>\n</html>"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"templateId": "tmpl-risk-profile-state-slack",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "Slack",
|
||||
"key": "tmpl-risk-profile-state",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Markdown",
|
||||
"format": "Json",
|
||||
"description": "Slack notification for risk profile state changes",
|
||||
"metadata": {
|
||||
"eventKind": "risk.profile.published",
|
||||
"category": "risk"
|
||||
},
|
||||
"body": ":information_source: *Risk profile update*\n\n*Profile:* {{ event.profileName }}\n*State:* {{ event.state }}\n*Owner:* {{ event.owner }}\n*Summary:* {{ event.summary }}\n\n{{ #if event.policyId }}*Policy:* {{ event.policyId }} (v{{ event.policyVersion }})\n{{ /if }}---\n_Event ID: {{ event.eventId }} | {{ event.occurredAtUtc }}_"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"templateId": "tmpl-risk-severity-change-email",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "Email",
|
||||
"key": "tmpl-risk-severity-change",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Html",
|
||||
"format": "Html",
|
||||
"description": "Email notification for risk severity changes",
|
||||
"metadata": {
|
||||
"eventKind": "risk.profile.severity.changed",
|
||||
"category": "risk",
|
||||
"subject": "[Notify] Risk severity changed: {{ event.profileName }}"
|
||||
},
|
||||
"body": "<!DOCTYPE html>\n<html>\n<head><style>body{font-family:sans-serif;line-height:1.5;}.section{margin:1em 0;padding:1em;background:#f8f9fa;border-radius:4px;}.label{font-weight:bold;color:#666;}.mono{font-family:monospace;background:#e9ecef;padding:2px 6px;border-radius:3px;}</style></head>\n<body>\n<h2>Risk Severity Changed</h2>\n<div class=\"section\">\n<p><span class=\"label\">Profile:</span> <span class=\"mono\">{{ event.profileName }}</span></p>\n<p><span class=\"label\">Previous:</span> {{ event.previousSeverity }}</p>\n<p><span class=\"label\">Current:</span> {{ event.newSeverity }}</p>\n<p><span class=\"label\">Reason:</span> {{ event.reason }}</p>\n{{ #if event.referenceUrl }}<p><span class=\"label\">Reference:</span> <a href=\"{{ event.referenceUrl }}\">{{ event.referenceUrl }}</a></p>{{ /if }}\n</div>\n<hr>\n<p style=\"font-size:0.85em;color:#666;\">Event ID: {{ event.eventId }} | Occurred: {{ event.occurredAtUtc }}</p>\n</body>\n</html>"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"templateId": "tmpl-risk-severity-change-slack",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "Slack",
|
||||
"key": "tmpl-risk-severity-change",
|
||||
"locale": "en-US",
|
||||
"schemaVersion": "1.0.0",
|
||||
"renderMode": "Markdown",
|
||||
"format": "Json",
|
||||
"description": "Slack notification for risk severity changes",
|
||||
"metadata": {
|
||||
"eventKind": "risk.profile.severity.changed",
|
||||
"category": "risk"
|
||||
},
|
||||
"body": ":rotating_light: *Risk severity changed*\n\n*Profile:* {{ event.profileName }}\n*Previous:* {{ event.previousSeverity }}\n*Current:* {{ event.newSeverity }}\n*Reason:* {{ event.reason }}\n\n{{ #if event.referenceUrl }}*Reference:* {{ event.referenceUrl }}\n{{ /if }}---\n_Event ID: {{ event.eventId }} | {{ event.occurredAtUtc }}_"
|
||||
}
|
||||
Reference in New Issue
Block a user