Refactor code structure and optimize performance across multiple modules
This commit is contained in:
12
devops/offline/feeds/manifest.json
Normal file
12
devops/offline/feeds/manifest.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"generated_utc": "2025-11-18T21:41:23.244597Z",
|
||||
"summary": "Offline feed bundles registered here. Add entries when baking air-gap bundles.",
|
||||
"feeds": [
|
||||
{
|
||||
"name": "telemetry-offline-bundle",
|
||||
"path": "offline/feeds/telemetry-offline-bundle.tar.gz",
|
||||
"sha256": "49d3ac3502bad1caaed4c1f7bceaa4ce40fdfce6210d4ae20c90386aeb84ca4e",
|
||||
"description": "Telemetry offline bundle (migrated from out/telemetry)"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
devops/offline/feeds/telemetry-offline-bundle.tar.gz
Normal file
BIN
devops/offline/feeds/telemetry-offline-bundle.tar.gz
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
49d3ac3502bad1caaed4c1f7bceaa4ce40fdfce6210d4ae20c90386aeb84ca4e telemetry-offline-bundle.tar.gz
|
||||
@@ -0,0 +1,4 @@
|
||||
bb1da224c09031996224154611f2e1c2143c23b96ab583191766f7d281b20800 hashes.sha256
|
||||
421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18 sample-sbom-context.json
|
||||
e5aecfba5cee8d412408fb449f12fa4d5bf0a7cb7e5b316b99da3b9019897186 sample-vuln-output.ndjson
|
||||
736efd36508de7b72c9cbddf851335d9534c326af1670be7d101cbb91634357d sbom-context-response.json
|
||||
@@ -0,0 +1,2 @@
|
||||
421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18 out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json
|
||||
e5aecfba5cee8d412408fb449f12fa4d5bf0a7cb7e5b316b99da3b9019897186 out/console/guardrails/cli-vuln-29-001/sample-vuln-output.ndjson
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schema": "stellaops.sbom.context/1.0",
|
||||
"input": "sbom.json",
|
||||
"generated": "2025-11-19T00:00:00Z",
|
||||
"packages": [
|
||||
{"name": "openssl", "version": "1.1.1w", "purl": "pkg:deb/openssl@1.1.1w"},
|
||||
{"name": "zlib", "version": "1.2.11", "purl": "pkg:deb/zlib@1.2.11"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"command":"stella vuln scan","version":"0.1.0","tenant":"demo","input":"sbom.json","generated":"2025-11-19T00:00:00Z","summary":{"packages":3,"vulnerabilities":2},"vulnerabilities":[{"id":"CVE-2024-1234","package":"openssl","version":"1.1.1w","severity":"HIGH","source":"nvd","path":"/usr/lib/libssl.so"},{"id":"CVE-2024-2345","package":"zlib","version":"1.2.11","severity":"MEDIUM","source":"nvd","path":"/usr/lib/libz.so"}],"provenance":{"sbom_digest":"sha256:dummy-sbom","profile":"offline","evidence_bundle":"mirror-thin-m0-sample"}}
|
||||
@@ -0,0 +1 @@
|
||||
{"schema":"stellaops.sbom.context/1.0","generated":"2025-11-19T00:00:00Z","packages":[{"name":"openssl","version":"1.1.1w","purl":"pkg:deb/openssl@1.1.1w"},{"name":"zlib","version":"1.2.11","purl":"pkg:deb/zlib@1.2.11"}],"timeline":8,"dependencyPaths":5,"hash":"sha256:421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18"}
|
||||
@@ -0,0 +1,4 @@
|
||||
bb1da224c09031996224154611f2e1c2143c23b96ab583191766f7d281b20800 hashes.sha256
|
||||
421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18 sample-sbom-context.json
|
||||
e5aecfba5cee8d412408fb449f12fa4d5bf0a7cb7e5b316b99da3b9019897186 sample-vuln-output.ndjson
|
||||
1f8df765be98c193ac6fa52af778e2e0ec24a7c5acbdfe7a4a461d45bf98f573 sbom-context-response.json
|
||||
@@ -0,0 +1,2 @@
|
||||
421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18 out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json
|
||||
e5aecfba5cee8d412408fb449f12fa4d5bf0a7cb7e5b316b99da3b9019897186 out/console/guardrails/cli-vuln-29-001/sample-vuln-output.ndjson
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"schema": "stellaops.sbom.context/1.0",
|
||||
"input": "sbom.json",
|
||||
"generated": "2025-11-19T00:00:00Z",
|
||||
"packages": [
|
||||
{"name": "openssl", "version": "1.1.1w", "purl": "pkg:deb/openssl@1.1.1w"},
|
||||
{"name": "zlib", "version": "1.2.11", "purl": "pkg:deb/zlib@1.2.11"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"command":"stella vuln scan","version":"0.1.0","tenant":"demo","input":"sbom.json","generated":"2025-11-19T00:00:00Z","summary":{"packages":3,"vulnerabilities":2},"vulnerabilities":[{"id":"CVE-2024-1234","package":"openssl","version":"1.1.1w","severity":"HIGH","source":"nvd","path":"/usr/lib/libssl.so"},{"id":"CVE-2024-2345","package":"zlib","version":"1.2.11","severity":"MEDIUM","source":"nvd","path":"/usr/lib/libz.so"}],"provenance":{"sbom_digest":"sha256:dummy-sbom","profile":"offline","evidence_bundle":"mirror-thin-m0-sample"}}
|
||||
@@ -0,0 +1 @@
|
||||
{"schema":"stellaops.sbom.context/1.0","generated":"2025-12-08T15:34:22.6874898+00:00","artifactId":"ghcr.io/stellaops/sample-api","purl":"pkg:npm/lodash@4.17.21","versions":[{"version":"2025.11.16.1","firstObserved":"2025-11-16T12:00:00+00:00","lastObserved":"2025-11-16T12:00:00+00:00","status":"observed","source":"scanner:surface_bundle_mock_v1.tgz","isFixAvailable":false,"metadata":{"provenance":"scanner:surface_bundle_mock_v1.tgz","digest":"sha256:112","source_bundle_hash":"sha256:bundle112"}},{"version":"2025.11.15.1","firstObserved":"2025-11-15T12:00:00+00:00","lastObserved":"2025-11-15T12:00:00+00:00","status":"observed","source":"scanner:surface_bundle_mock_v1.tgz","isFixAvailable":false,"metadata":{"provenance":"scanner:surface_bundle_mock_v1.tgz","digest":"sha256:111","source_bundle_hash":"sha256:bundle111"}}],"dependencyPaths":[{"nodes":[{"identifier":"sample-api","version":null},{"identifier":"rollup","version":null},{"identifier":"lodash","version":null}],"isRuntime":false,"source":"sbom.paths","metadata":{"environment":"prod","path_length":"3","artifact":"ghcr.io/stellaops/sample-api@sha256:111","nearest_safe_version":"pkg:npm/lodash@4.17.22","blast_radius":"low","scope":"build"}},{"nodes":[{"identifier":"sample-api","version":null},{"identifier":"express","version":null},{"identifier":"lodash","version":null}],"isRuntime":true,"source":"sbom.paths","metadata":{"environment":"prod","path_length":"3","artifact":"ghcr.io/stellaops/sample-api@sha256:111","nearest_safe_version":"pkg:npm/lodash@4.17.22","blast_radius":"medium","scope":"runtime"}}],"environmentFlags":{"prod":"2"},"blastRadius":{"impactedAssets":2,"impactedWorkloads":1,"impactedNamespaces":1,"impactedPercentage":0.5,"metadata":{"path_sample_count":"2","blast_radius_tags":"low,medium"}},"metadata":{"generated_at":"2025-12-08T15:34:22.6874898+00:00","artifact":"ghcr.io/stellaops/sample-api","version_count":"2","dependency_count":"2","source":"sbom-service","environment_flag_count":"1","blast_radius_present":"True"},"hash":"sha256:0c705259fdf984bf300baba0abf484fc3bbae977cf8a0a2d1877481f552d600d"}
|
||||
14
devops/offline/fixtures/notifier/artifact-hashes.json
Normal file
14
devops/offline/fixtures/notifier/artifact-hashes.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"hash_algorithm": "blake3-256",
|
||||
"entries": [
|
||||
{ "path": "docs/notifications/schemas/notify-schemas-catalog.json", "digest": "34e8655b0c7ca70c844d4b9aee56bdd7bd30b6a8666d2af75a70856b16f5605d" },
|
||||
{ "path": "docs/notifications/schemas/notify-schemas-catalog.dsse.json", "digest": "7c537ff728312cefb0769568bd376adc2bd79f6926173bf21f50c873902133dc" },
|
||||
{ "path": "docs/notifications/gaps-nr1-nr10.md", "digest": "b889dfd19a9d0a0f7bafb958135fde151e63c1e5259453d592d6519ae1667819" },
|
||||
{ "path": "docs/notifications/fixtures/rendering/index.ndjson", "digest": "3a41e62687b6e04f50e86ea74706eeae28eef666d7c4dbb5dc2281e6829bf41a" },
|
||||
{ "path": "docs/notifications/fixtures/redaction/sample.json", "digest": "dd4eefc8dded5d6f46c832e959ba0eef95ee8b77f10ac0aae90f7c89ad42906c" },
|
||||
{ "path": "docs/notifications/operations/dashboards/notify-slo.json", "digest": "8b380cb5491727a3ec69d50789f5522ac66c97804bebbf7de326568e52b38fa9" },
|
||||
{ "path": "docs/notifications/operations/alerts/notify-slo-alerts.yaml", "digest": "2c3b702c42d3e860c7f4e51d577f77961e982e1d233ef5ec392cba5414a0056d" },
|
||||
{ "path": "offline/notifier/notify-kit.manifest.json", "digest": "15e0b2f670e6b8089c6c960e354f16ba8201d993a077a28794a30b8d1cb23e9a" },
|
||||
{ "path": "offline/notifier/notify-kit.manifest.dsse.json", "digest": "68742f4e5bd202afe2cc90964d51fea7971395f3e57a875ae7111dcbb760321e" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"payloadType": "application/vnd.notify.manifest+json",
|
||||
"payload": "ewogICJzY2hlbWFfdmVyc2lvbiI6ICJ2MS4wIiwKICAiZ2VuZXJhdGVkX2F0IjogIjIwMjUtMTItMDRUMDA6MDA6MDBaIiwKICAidGVuYW50X3Njb3BlIjogIioiLAogICJlbnZpcm9ubWVudCI6ICJvZmZsaW5lIiwKICAiYXJ0aWZhY3RzIjogWwogICAgeyAibmFtZSI6ICJzY2hlbWEtY2F0YWxvZyIsICJwYXRoIjogImRvY3Mvbm90aWZpY2F0aW9ucy9zY2hlbWFzL25vdGlmeS1zY2hlbWFzLWNhdGFsb2cuanNvbiIsICJkaWdlc3QiOiAiMzRlODY1NWIwYzdjYTcwYzg0NGQ0YjlhZWU1NmJkZDdiZDMwYjZhODY2NmQyYWY3NWE3MDg1NmIxNmY1NjA1ZCIgfSwKICAgIHsgIm5hbWUiOiAic2NoZW1hLWNhdGFsb2ctZHNzZSIsICJwYXRoIjogImRvY3Mvbm90aWZpY2F0aW9ucy9zY2hlbWFzL25vdGlmeS1zY2hlbWFzLWNhdGFsb2cuZHNzZS5qc29uIiwgImRpZ2VzdCI6ICI3YzUzN2ZmNzI4MzEyY2VmYjA3Njk1NjhiZDM3NmFkYzJiZDc5ZjY5MjYxNzNiZjIxZjUwYzg3MzkwMjEzM2RjIiB9LAogICAgeyAibmFtZSI6ICJydWxlcyIsICJwYXRoIjogImRvY3Mvbm90aWZpY2F0aW9ucy9nYXBzLW5yMS1ucjEwLm1kIiwgImRpZ2VzdCI6ICJiODg5ZGZkMTlhOWQwYTBmN2JhZmI5NTgxMzVmZGUxNTFlNjNjMWU1MjU5NDUzZDU5MmQ2NTE5YWUxNjY3ODE5IiB9LAogICAgeyAibmFtZSI6ICJmaXh0dXJlcy1yZW5kZXJpbmciLCAicGF0aCI6ICJkb2NzL25vdGlmaWNhdGlvbnMvZml4dHVyZXMvcmVuZGVyaW5nL2luZGV4Lm5kanNvbiIsICJkaWdlc3QiOiAiM2E0MWU2MjY4N2I2ZTA0ZjUwZTg2ZWE3NDcwNmVlYWUyOGVlZjY2NmQ3YzRkYmI1ZGMyMjgxZTY4MjliZjQxYSIgfSwKICAgIHsgIm5hbWUiOiAiZml4dHVyZXMtcmVkYWN0aW9uIiwgInBhdGgiOiAiZG9jcy9ub3RpZmljYXRpb25zL2ZpeHR1cmVzL3JlZGFjdGlvbi9zYW1wbGUuanNvbiIsICJkaWdlc3QiOiAiZGQ0ZWVmYzhkZGVkNWQ2ZjQ2YzgzMmU5NTliYTBlZWY5NWVlOGI3N2YxMGFjMGFhZTkwZjdjODlhZDQyOTA2YyIgfSwKICAgIHsgIm5hbWUiOiAiZGFzaGJvYXJkcyIsICJwYXRoIjogImRvY3Mvbm90aWZpY2F0aW9ucy9vcGVyYXRpb25zL2Rhc2hib2FyZHMvbm90aWZ5LXNsby5qc29uIiwgImRpZ2VzdCI6ICI4YjM4MGNiNTQ5MTcyN2EzZWM2OWQ1MDc4OWY1NTIyYWM2NmM5NzgwNGJlYmJmN2RlMzI2NTY4ZTUyYjM4ZmE5IiB9LAogICAgeyAibmFtZSI6ICJhbGVydHMiLCAicGF0aCI6ICJkb2NzL25vdGlmaWNhdGlvbnMvb3BlcmF0aW9ucy9hbGVydHMvbm90aWZ5LXNsby1hbGVydHMueWFtbCIsICJkaWdlc3QiOiAiMmMzYjcwMmM0MmQzZTg2MGM3ZjRlNTFkNTc3Zjc3OTYxZTk4MmUxZDIzM2VmNWVjMzkyY2JhNTQxNGEwMDU2ZCIgfQogIF0sCiAgImhhc2hfYWxnb3JpdGhtIjogImJsYWtlMy0yNTYiLAogICJjYW5vbmljYWxpemF0aW9uIjogImpzb24tbm9ybWFsaXplZC11dGY4Igp9Cg==",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "DZwohxh6AOAP7Qf9geoZjw2jTXVU3rR8sYw4mgKpMu0=",
|
||||
"keyid": "notify-dev-hmac-001",
|
||||
"signedAt": "2025-12-04T21:13:10+00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
17
devops/offline/fixtures/notifier/notify-kit.manifest.json
Normal file
17
devops/offline/fixtures/notifier/notify-kit.manifest.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"schema_version": "v1.0",
|
||||
"generated_at": "2025-12-04T00:00:00Z",
|
||||
"tenant_scope": "*",
|
||||
"environment": "offline",
|
||||
"artifacts": [
|
||||
{ "name": "schema-catalog", "path": "docs/notifications/schemas/notify-schemas-catalog.json", "digest": "34e8655b0c7ca70c844d4b9aee56bdd7bd30b6a8666d2af75a70856b16f5605d" },
|
||||
{ "name": "schema-catalog-dsse", "path": "docs/notifications/schemas/notify-schemas-catalog.dsse.json", "digest": "7c537ff728312cefb0769568bd376adc2bd79f6926173bf21f50c873902133dc" },
|
||||
{ "name": "rules", "path": "docs/notifications/gaps-nr1-nr10.md", "digest": "b889dfd19a9d0a0f7bafb958135fde151e63c1e5259453d592d6519ae1667819" },
|
||||
{ "name": "fixtures-rendering", "path": "docs/notifications/fixtures/rendering/index.ndjson", "digest": "3a41e62687b6e04f50e86ea74706eeae28eef666d7c4dbb5dc2281e6829bf41a" },
|
||||
{ "name": "fixtures-redaction", "path": "docs/notifications/fixtures/redaction/sample.json", "digest": "dd4eefc8dded5d6f46c832e959ba0eef95ee8b77f10ac0aae90f7c89ad42906c" },
|
||||
{ "name": "dashboards", "path": "docs/notifications/operations/dashboards/notify-slo.json", "digest": "8b380cb5491727a3ec69d50789f5522ac66c97804bebbf7de326568e52b38fa9" },
|
||||
{ "name": "alerts", "path": "docs/notifications/operations/alerts/notify-slo-alerts.yaml", "digest": "2c3b702c42d3e860c7f4e51d577f77961e982e1d233ef5ec392cba5414a0056d" }
|
||||
],
|
||||
"hash_algorithm": "blake3-256",
|
||||
"canonicalization": "json-normalized-utf8"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-expiry-warning-email-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"key": "tmpl-attest-expiry-warning",
|
||||
"locale": "en-us",
|
||||
"renderMode": "html",
|
||||
"format": "email",
|
||||
"description": "Expiry warning for attestations approaching their expiration window.",
|
||||
"body": "<h2>Attestation expiry notice</h2>\n<p>The attestation for <code>{{payload.subject.repository}}</code> (digest {{payload.subject.digest}}) expires on <strong>{{payload.attestation.expiresAt}}</strong>.</p>\n<ul>\n <li>Issued: {{payload.attestation.issuedAt}}</li>\n <li>Signer: <code>{{payload.signer.kid}}</code> ({{payload.signer.algorithm}})</li>\n <li>Time remaining: {{expires_in payload.attestation.expiresAt event.ts}}</li>\n</ul>\n<p>Please rotate the attestation before expiry using <a href=\"{{payload.links.docs}}\">these instructions</a>.</p>\n<p>Console: <a href=\"{{payload.links.console}}\">{{payload.links.console}}</a></p>\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-expiry-warning-slack-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"key": "tmpl-attest-expiry-warning",
|
||||
"locale": "en-us",
|
||||
"renderMode": "markdown",
|
||||
"format": "slack",
|
||||
"description": "Slack reminder for attestations approaching their expiration window.",
|
||||
"body": ":warning: Attestation for `{{payload.subject.digest}}` expires {{expires_in payload.attestation.expiresAt event.ts}}\nRepo: `{{payload.subject.repository}}`{{#if payload.subject.tag}} ({{payload.subject.tag}}){{/if}}\nSigner: `{{fingerprint payload.signer.kid}}` ({{payload.signer.algorithm}})\nIssued: {{payload.attestation.issuedAt}} · Expires: {{payload.attestation.expiresAt}}\nRenewal steps: {{link \"Docs\" payload.links.docs}} · Console: {{link \"Open\" payload.links.console}}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-16"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-key-rotation-email-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"key": "tmpl-attest-key-rotation",
|
||||
"locale": "en-us",
|
||||
"renderMode": "html",
|
||||
"format": "email",
|
||||
"description": "Email bulletin for attestation key rotation or revocation events.",
|
||||
"body": "<h2>Attestation key rotation notice</h2>\n<p>Authority rotated or revoked signing keys at {{payload.rotation.executedAt}}.</p>\n<ul>\n <li>Rotation batch: {{payload.rotation.batchId}}</li>\n <li>Impacted services: {{payload.rotation.impactedServices}}</li>\n <li>Reason: {{payload.rotation.reason}}</li>\n</ul>\n<p>Recommended action: {{payload.recommendation}}</p>\n<p>Docs: <a href=\"{{payload.links.docs}}\">Rotation playbook</a></p>\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-key-rotation-webhook-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "webhook",
|
||||
"key": "tmpl-attest-key-rotation",
|
||||
"locale": "en-us",
|
||||
"renderMode": "json",
|
||||
"format": "webhook",
|
||||
"description": "Webhook payload for attestation key rotation/revocation events.",
|
||||
"body": "{\n \"event\": \"authority.keys.rotated\",\n \"tenantId\": \"{{event.tenant}}\",\n \"batchId\": \"{{payload.rotation.batchId}}\",\n \"executedAt\": \"{{payload.rotation.executedAt}}\",\n \"impactedServices\": \"{{payload.rotation.impactedServices}}\",\n \"reason\": \"{{payload.rotation.reason}}\",\n \"links\": {\n \"docs\": \"{{payload.links.docs}}\",\n \"console\": \"{{payload.links.console}}\"\n }\n}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-transparency-anomaly-slack-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"key": "tmpl-attest-transparency-anomaly",
|
||||
"locale": "en-us",
|
||||
"renderMode": "markdown",
|
||||
"format": "slack",
|
||||
"description": "Slack alert for transparency witness anomalies.",
|
||||
"body": ":warning: Transparency anomaly detected for `{{payload.subject.digest}}`\nWitness: `{{payload.transparency.witnessId}}` ({{payload.transparency.classification}})\nRekor index: {{payload.transparency.rekorIndex}}\nAnomaly window: {{payload.transparency.windowStart}} → {{payload.transparency.windowEnd}}\nRecommended action: {{payload.recommendation}}\nConsole details: {{link \"Open in Console\" payload.links.console}}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-transparency-anomaly-webhook-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "webhook",
|
||||
"key": "tmpl-attest-transparency-anomaly",
|
||||
"locale": "en-us",
|
||||
"renderMode": "json",
|
||||
"format": "webhook",
|
||||
"description": "Webhook payload for Rekor transparency anomalies.",
|
||||
"body": "{\n \"event\": \"attestor.transparency.anomaly\",\n \"tenantId\": \"{{event.tenant}}\",\n \"subjectDigest\": \"{{payload.subject.digest}}\",\n \"witnessId\": \"{{payload.transparency.witnessId}}\",\n \"classification\": \"{{payload.transparency.classification}}\",\n \"rekorIndex\": {{payload.transparency.rekorIndex}},\n \"window\": {\n \"start\": \"{{payload.transparency.windowStart}}\",\n \"end\": \"{{payload.transparency.windowEnd}}\"\n },\n \"links\": {\n \"console\": \"{{payload.links.console}}\",\n \"rekor\": \"{{payload.links.rekor}}\"\n },\n \"recommendation\": \"{{payload.recommendation}}\"\n}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-verify-fail-email-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"key": "tmpl-attest-verify-fail",
|
||||
"locale": "en-us",
|
||||
"renderMode": "html",
|
||||
"format": "email",
|
||||
"description": "Email notice for attestation verification failures.",
|
||||
"body": "<h2>Attestation verification failure</h2>\n<p>The attestation for <code>{{payload.subject.repository}}</code> (digest {{payload.subject.digest}}) failed verification at {{event.ts}}.</p>\n<ul>\n <li>Reason: <code>{{payload.failure.reasonCode}}</code> — {{payload.failure.reason}}</li>\n <li>Signer: <code>{{payload.signer.kid}}</code> ({{payload.signer.algorithm}})</li>\n <li>Rekor entry: <a href=\"{{payload.links.rekor}}\">{{payload.links.rekor}}</a></li>\n <li>Last valid attestation: <a href=\"{{payload.links.console}}\">Console report</a></li>\n</ul>\n<p>{{payload.recommendation}}</p>\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-verify-fail-slack-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"key": "tmpl-attest-verify-fail",
|
||||
"locale": "en-us",
|
||||
"renderMode": "markdown",
|
||||
"format": "slack",
|
||||
"description": "Slack alert for attestation verification failures with Rekor traceability.",
|
||||
"body": ":rotating_light: {{attestation_status_badge payload.failure.status}} verification failed for `{{payload.subject.digest}}`\nSigner: `{{fingerprint payload.signer.kid}}` ({{payload.signer.algorithm}})\nReason: `{{payload.failure.reasonCode}}` — {{payload.failure.reason}}\nLast valid attestation: {{link \"Console\" payload.links.console}}\nRekor entry: {{link \"Transparency log\" payload.links.rekor}}\nRecommended action: {{payload.recommendation}}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-attest-verify-fail-webhook-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "webhook",
|
||||
"key": "tmpl-attest-verify-fail",
|
||||
"locale": "en-us",
|
||||
"renderMode": "json",
|
||||
"format": "webhook",
|
||||
"description": "JSON payload for Pager/SOC integrations on attestation verification failures.",
|
||||
"body": "{\n \"event\": \"attestor.verification.failed\",\n \"tenantId\": \"{{event.tenant}}\",\n \"subjectDigest\": \"{{payload.subject.digest}}\",\n \"repository\": \"{{payload.subject.repository}}\",\n \"reasonCode\": \"{{payload.failure.reasonCode}}\",\n \"reason\": \"{{payload.failure.reason}}\",\n \"signer\": {\n \"kid\": \"{{payload.signer.kid}}\",\n \"algorithm\": \"{{payload.signer.algorithm}}\"\n },\n \"rekor\": {\n \"url\": \"{{payload.links.rekor}}\",\n \"uuid\": \"{{payload.rekor.uuid}}\",\n \"index\": {{payload.rekor.index}}\n },\n \"recommendation\": \"{{payload.recommendation}}\"\n}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-api-deprecation-email-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"key": "tmpl-api-deprecation",
|
||||
"locale": "en-us",
|
||||
"renderMode": "html",
|
||||
"format": "email",
|
||||
"description": "Email notification for retiring Notifier API versions.",
|
||||
"body": "<h2>Notifier API deprecation notice</h2>\n<p>The Notifier API v1 endpoints are scheduled for sunset on <strong>{{metadata.sunset}}</strong>.</p>\n<ul>\n <li>Paths affected: {{metadata.paths}}</li>\n <li>Scope: notify.*</li>\n <li>Replacement: {{metadata.replacement}}</li>\n</ul>\n<p>Action: {{metadata.action}}</p>\n<p>Details: <a href=\"{{metadata.docs}}\">Deprecation bulletin</a></p>\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-17"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-api-deprecation-slack-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"key": "tmpl-api-deprecation",
|
||||
"locale": "en-us",
|
||||
"renderMode": "markdown",
|
||||
"format": "slack",
|
||||
"description": "Slack notice for retiring Notifier API versions.",
|
||||
"body": ":warning: Notifier API v1 is being deprecated.\nSunset: {{metadata.sunset}}\nPaths affected: {{metadata.paths}}\nDocs: {{link \"Deprecation details\" metadata.docs}}\nAction: {{metadata.action}}\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-17"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-risk-profile-state-email-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"key": "tmpl-risk-profile-state",
|
||||
"locale": "en-us",
|
||||
"renderMode": "html",
|
||||
"format": "email",
|
||||
"description": "Email notice when risk profiles are published, deprecated, or thresholds change.",
|
||||
"body": "<h2>Risk profile update</h2>\n<p>Profile <strong>{{payload.profile.id}}</strong> is now <strong>{{payload.state}}</strong> (version {{payload.profile.version}}).</p>\n<ul>\n <li>Thresholds: {{payload.thresholds}}</li>\n <li>Owner: {{payload.owner}}</li>\n <li>Effective at: {{payload.effectiveAt}}</li>\n</ul>\n<p>Notes: {{payload.notes}}</p>\n<p>Console: <a href=\"{{payload.links.console}}\">View profile</a></p>\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-24"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-risk-profile-state-slack-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"key": "tmpl-risk-profile-state",
|
||||
"locale": "en-us",
|
||||
"renderMode": "markdown",
|
||||
"format": "json",
|
||||
"description": "Slack notice when risk profiles publish, deprecate, or thresholds change.",
|
||||
"body": "*Risk profile {{payload.profile.id}}* is now *{{payload.state}}* (v{{payload.profile.version}})\n• thresholds: {{payload.thresholds}}\n• owner: {{payload.owner}}\n• effective: {{payload.effectiveAt}}\n<{{payload.links.console}}|View profile>",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-24"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-risk-severity-change-email-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "email",
|
||||
"key": "tmpl-risk-severity-change",
|
||||
"locale": "en-us",
|
||||
"renderMode": "html",
|
||||
"format": "email",
|
||||
"description": "Email notice for risk severity escalation or downgrade.",
|
||||
"body": "<h2>Risk severity updated</h2>\n<p>Risk profile <strong>{{payload.profile.id}}</strong> changed severity from {{payload.previous.severity}} to {{payload.current.severity}} at {{event.ts}}.</p>\n<ul>\n <li>Asset: {{payload.asset.purl}}</li>\n <li>Profile version: {{payload.profile.version}}</li>\n <li>Reason: {{payload.reason}}</li>\n</ul>\n<p>View details: <a href=\"{{payload.links.console}}\">Console</a></p>\n",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-24"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"schemaVersion": "notify.template@1",
|
||||
"templateId": "tmpl-risk-severity-change-slack-en-us",
|
||||
"tenantId": "bootstrap",
|
||||
"channelType": "slack",
|
||||
"key": "tmpl-risk-severity-change",
|
||||
"locale": "en-us",
|
||||
"renderMode": "markdown",
|
||||
"format": "json",
|
||||
"description": "Slack notice for risk severity escalation or downgrade.",
|
||||
"body": "*Risk severity changed* for {{payload.profile.id}}\n• from: {{payload.previous.severity}} → to: {{payload.current.severity}}\n• asset: {{payload.asset.purl}}\n• version: {{payload.profile.version}}\n• reason: {{payload.reason}}\n<{{payload.links.console}}|Open in console>",
|
||||
"metadata": {
|
||||
"author": "notifications-bootstrap",
|
||||
"version": "2025-11-24"
|
||||
}
|
||||
}
|
||||
56
devops/offline/fixtures/notifier/verify_notify_kit.sh
Normal file
56
devops/offline/fixtures/notifier/verify_notify_kit.sh
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT=$(cd "$(dirname "$0")" && pwd)
|
||||
|
||||
missing=0
|
||||
for f in notify-kit.manifest.json notify-kit.manifest.dsse.json artifact-hashes.json; do
|
||||
if [ ! -f "$ROOT/$f" ]; then
|
||||
echo "[FAIL] missing $f" >&2
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python - <<'PY'
|
||||
import json, sys, pathlib, base64
|
||||
try:
|
||||
import blake3
|
||||
except ImportError:
|
||||
sys.stderr.write("blake3 module missing; install with `python -m pip install blake3`\n")
|
||||
sys.exit(1)
|
||||
|
||||
if '__file__' in globals() and __file__ not in (None, '<stdin>'):
|
||||
root = pathlib.Path(__file__).resolve().parent
|
||||
else:
|
||||
root = pathlib.Path.cwd()
|
||||
hashes = json.loads((root / "artifact-hashes.json").read_text())
|
||||
|
||||
def h(path: pathlib.Path):
|
||||
if path.suffix == ".json":
|
||||
data = json.dumps(json.loads(path.read_text()), sort_keys=True, separators=(',', ':')).encode()
|
||||
else:
|
||||
data = path.read_bytes()
|
||||
return blake3.blake3(data).hexdigest()
|
||||
|
||||
ok = True
|
||||
for entry in hashes["entries"]:
|
||||
path = root.parent.parent / entry["path"]
|
||||
digest = entry["digest"]
|
||||
if not path.exists():
|
||||
sys.stderr.write(f"[FAIL] missing file {path}\n")
|
||||
ok = False
|
||||
continue
|
||||
actual = h(path)
|
||||
if actual != digest:
|
||||
sys.stderr.write(f"[FAIL] digest mismatch {path}: expected {digest}, got {actual}\n")
|
||||
ok = False
|
||||
|
||||
if not ok:
|
||||
sys.exit(1)
|
||||
|
||||
print("[OK] All artifact hashes verified with blake3.")
|
||||
PY
|
||||
@@ -0,0 +1,39 @@
|
||||
groups:
|
||||
- name: ledger-observability
|
||||
interval: 30s
|
||||
rules:
|
||||
- alert: LedgerWriteLatencyHighP95
|
||||
expr: histogram_quantile(0.95, sum(rate(ledger_write_latency_seconds_bucket[5m])) by (le, tenant)) > 0.12
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Ledger write latency p95 high (tenant {{ $labels.tenant }})"
|
||||
description: "ledger_write_latency_seconds p95 > 120ms for >10m. Check DB/queue."
|
||||
|
||||
- alert: ProjectionLagHigh
|
||||
expr: max_over_time(ledger_projection_lag_seconds[10m]) > 30
|
||||
for: 10m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Ledger projection lag high"
|
||||
description: "projection lag over 30s; projections falling behind ingest."
|
||||
|
||||
- alert: MerkleAnchorFailures
|
||||
expr: sum(rate(ledger_merkle_anchor_failures_total[15m])) by (tenant, reason) > 0
|
||||
for: 15m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Merkle anchor failures (tenant {{ $labels.tenant }})"
|
||||
description: "Anchoring failures detected (reason={{ $labels.reason }}). Investigate signing/storage."
|
||||
|
||||
- alert: AttachmentFailures
|
||||
expr: sum(rate(ledger_attachments_encryption_failures_total[10m])) by (tenant, stage) > 0
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Attachment pipeline failures (tenant {{ $labels.tenant }}, stage {{ $labels.stage }})"
|
||||
description: "Attachment encryption/sign/upload reported failures in the last 10m."
|
||||
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"id": null,
|
||||
"title": "StellaOps Findings Ledger",
|
||||
"timezone": "utc",
|
||||
"schemaVersion": 39,
|
||||
"version": 1,
|
||||
"refresh": "30s",
|
||||
"tags": ["ledger", "findings", "stellaops"],
|
||||
"panels": [
|
||||
{
|
||||
"type": "timeseries",
|
||||
"title": "Ledger Write Latency (P50/P95)",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
|
||||
"targets": [
|
||||
{ "expr": "histogram_quantile(0.5, sum(rate(ledger_write_latency_seconds_bucket{tenant=\"$tenant\"}[5m])) by (le))", "legendFormat": "p50" },
|
||||
{ "expr": "histogram_quantile(0.95, sum(rate(ledger_write_latency_seconds_bucket{tenant=\"$tenant\"}[5m])) by (le))", "legendFormat": "p95" }
|
||||
],
|
||||
"fieldConfig": { "defaults": { "unit": "s" } }
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"title": "Write Throughput",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 },
|
||||
"targets": [
|
||||
{ "expr": "sum(rate(ledger_events_total{tenant=\"$tenant\"}[5m])) by (event_type)", "legendFormat": "{{event_type}}" }
|
||||
],
|
||||
"fieldConfig": { "defaults": { "unit": "ops" } }
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"title": "Projection Lag",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
|
||||
"targets": [
|
||||
{ "expr": "max(ledger_projection_lag_seconds{tenant=\"$tenant\"})", "legendFormat": "lag" }
|
||||
],
|
||||
"fieldConfig": { "defaults": { "unit": "s" } }
|
||||
},
|
||||
{
|
||||
"type": "timeseries",
|
||||
"title": "Merkle Anchor Duration",
|
||||
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
|
||||
"targets": [
|
||||
{ "expr": "histogram_quantile(0.95, sum(rate(ledger_merkle_anchor_duration_seconds_bucket{tenant=\"$tenant\"}[5m])) by (le))", "legendFormat": "p95" }
|
||||
],
|
||||
"fieldConfig": { "defaults": { "unit": "s" } }
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"title": "Merkle Anchor Failures (5m)",
|
||||
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 16 },
|
||||
"targets": [
|
||||
{ "expr": "sum(rate(ledger_merkle_anchor_failures_total{tenant=\"$tenant\"}[5m]))", "legendFormat": "fail/s" }
|
||||
],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] } }
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"title": "Attachment Failures (5m)",
|
||||
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 16 },
|
||||
"targets": [
|
||||
{ "expr": "sum(rate(ledger_attachments_encryption_failures_total{tenant=\"$tenant\"}[5m])) by (stage)", "legendFormat": "{{stage}}" }
|
||||
],
|
||||
"options": { "reduceOptions": { "calcs": ["lastNotNull"] } }
|
||||
},
|
||||
{
|
||||
"type": "stat",
|
||||
"title": "Ledger Backlog",
|
||||
"gridPos": { "h": 4, "w": 6, "x": 12, "y": 16 },
|
||||
"targets": [
|
||||
{ "expr": "sum(ledger_ingest_backlog_events{tenant=\"$tenant\"})", "legendFormat": "events" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"name": "tenant",
|
||||
"type": "query",
|
||||
"label": "Tenant",
|
||||
"datasource": null,
|
||||
"query": "label_values(ledger_events_total, tenant)",
|
||||
"refresh": 1,
|
||||
"multi": false,
|
||||
"includeAll": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"annotations": { "list": [] },
|
||||
"time": { "from": "now-6h", "to": "now" },
|
||||
"timepicker": { "refresh_intervals": ["30s", "1m", "5m", "15m", "1h"] }
|
||||
}
|
||||
6
devops/offline/templates/mirror-thin-v1.manifest.json
Normal file
6
devops/offline/templates/mirror-thin-v1.manifest.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"created": "$CREATED",
|
||||
"indexes": [],
|
||||
"layers": [],
|
||||
"version": "1.0.0"
|
||||
}
|
||||
Reference in New Issue
Block a user