up
Some checks failed
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
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Some checks failed
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
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
| Task ID | Status | Sprint | Owners | Key dependency / next step | Notes |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| SAMPLES-GRAPH-24-003 | BLOCKED (2025-11-18) | SPRINT_0509_0001_0001_samples | Samples Guild · SBOM Service Guild | Await Graph Guild overlay field/manifest decision (checkpoint 2025-11-22) and approval of mock SBOM source list. | Large-scale SBOM graph fixture (~40k nodes) + policy overlay snapshot for perf/regression suites. |
|
||||
| SAMPLES-GRAPH-24-004 | TODO | SPRINT_0509_0001_0001_samples | Samples Guild · UI Guild | Depends on SAMPLES-GRAPH-24-003 fixture availability. | Vulnerability explorer JSON/CSV fixtures with conflicting evidence/policy outputs for UI/CLI tests. |
|
||||
| SAMPLES-LNM-22-001 | BLOCKED | SPRINT_0509_0001_0001_samples | Samples Guild · Concelier Guild | Waiting on finalized Concelier advisory linkset schema. | Advisory observation/linkset fixtures (NVD, GHSA, OSV disagreements). |
|
||||
| SAMPLES-LNM-22-002 | BLOCKED | SPRINT_0509_0001_0001_samples | Samples Guild · Excititor Guild | Depends on 22-001 outputs + Excititor linkset implementation. | VEX observation/linkset fixtures with status conflicts/path relevance; include raw blobs. |
|
||||
| SAMPLES-GRAPH-24-003 | DONE (2025-12-02) | SPRINT_0509_0001_0001_samples | Samples Guild · SBOM Service Guild | Delivered `samples/graph/graph-40k` fixture with overlay and manifest; see README + hashes. | Large-scale SBOM graph fixture (~40k nodes) + policy overlay snapshot for perf/regression suites. |
|
||||
| SAMPLES-GRAPH-24-004 | DONE (2025-12-02) | SPRINT_0509_0001_0001_samples | Samples Guild · UI Guild | Built from graph-40k overlays; artefacts in `samples/graph/graph-40k/explorer`. | Vulnerability explorer JSON/CSV fixtures with conflicting evidence/policy outputs for UI/CLI tests. |
|
||||
| SAMPLES-LNM-22-001 | DONE (2025-11-24) | SPRINT_0509_0001_0001_samples | Samples Guild · Concelier Guild | Fixtures published under `samples/linkset/lnm-22-001/`. | Advisory observation/linkset fixtures (NVD, GHSA, OSV disagreements). |
|
||||
| SAMPLES-LNM-22-002 | DONE (2025-11-24) | SPRINT_0509_0001_0001_samples | Samples Guild · Excititor Guild | Fixtures published under `samples/linkset/lnm-22-002/`. | VEX observation/linkset fixtures with status conflicts/path relevance; include raw blobs. |
|
||||
|
||||
Status updates must stay in sync with the corresponding sprint tracker.
|
||||
|
||||
@@ -6,37 +6,34 @@
|
||||
- Ensure offline parity: fixtures packaged for Offline Kit consumption (NDJSON + manifest hashes).
|
||||
|
||||
## Assumptions / Pending confirmations
|
||||
- Overlay format: waiting on Graph Guild decision (checkpoint 2025-11-22) regarding overlay fields and snapshot manifest layout.
|
||||
- SBOM bundle source: use scanner surface mock bundle v1 unless real caches land; confirm with Graph Guild.
|
||||
- Tenant: default to `demo-tenant` unless advised otherwise; all IDs and timestamps must be deterministic.
|
||||
- Overlay format resolved: `policy.overlay.v1` with `overlay_id = sha256(tenant|nodeId|overlayKind)`, verdict + severity, optional edge to policy rule node for bench compatibility.
|
||||
- SBOM bundle source: scanner surface mock bundle v1; swap in real cache when approved without schema changes.
|
||||
- Tenant: `demo-tenant`; timestamps frozen to `2025-11-22T00:00:00Z`.
|
||||
|
||||
## Proposed fixture contents
|
||||
- `nodes.ndjson`: ~40k nodes; sorted by id; includes artifact, package, relationship nodes.
|
||||
- `edges.ndjson`: matching edges; sorted by id.
|
||||
- `overlays/policy.ndjson`: policy overlay snapshot aligned with chosen overlay schema.
|
||||
- `manifest.json`: hashes (SHA-256) of all files plus counts; UTC timestamps rounded to seconds.
|
||||
- `README.md`: execution + verification steps, expected counts/hashes.
|
||||
## Canonical fixture (delivered 2025-12-02)
|
||||
- Location: `samples/graph/graph-40k/`
|
||||
- `nodes.ndjson`: 40,000 component nodes (`pkg:pypi/demo-*`)
|
||||
- `edges.ndjson`: 100,071 `DEPENDS_ON` edges (fan-out ≤4, DAG order)
|
||||
- `overlay.ndjson`: 100 `policy.overlay.v1` records (verdict/severity + optional policy-rule edge)
|
||||
- `manifest.json`: hashes (SHA-256) and counts (nodes `d14e8c64…`, edges `143a2944…`, overlay `627a0d8c…`)
|
||||
- `README.md` and `verify.py`: usage, hashes, offline verification
|
||||
|
||||
## Generation sketch
|
||||
1) Start from existing mock SBOM bundle (scanner surface v1); sample driver script will:
|
||||
- deterministically seed random generators;
|
||||
- produce nodes/edges via Graph Indexer schema helpers;
|
||||
- emit overlays using placeholder policy verdicts (allow/deny/defer) until final schema confirmed.
|
||||
2) Write NDJSON with stable ordering; compute SHA-256 for each file; write manifest.
|
||||
3) Run validation script to assert counts, schema shape, and hash reproducibility.
|
||||
## Generation sketch (implemented)
|
||||
1) Deterministic generator `samples/graph/scripts/generate_canonical.py` (seed `424242`, snapshot `graph-40k-policy-overlay-20251122`).
|
||||
2) Writes nodes/edges/overlay with sorted keys, then manifest with hashes/counts.
|
||||
3) `verify.py` recomputes hashes/counts to confirm reproducibility.
|
||||
|
||||
## Interim fixtures (delivered 2025-12-01)
|
||||
- Synthetic deterministic graphs generated under `samples/graph/interim/`:
|
||||
## Interim fixtures (still available, delivered 2025-12-01)
|
||||
- Synthetic deterministic graphs under `samples/graph/interim/`:
|
||||
- `graph-50k` (50k nodes, ~200k edges)
|
||||
- `graph-100k` (100k nodes, ~400k edges)
|
||||
- Minimal schema (`id, kind, name, version, tenant`), seeded RNG, stable ordering, manifests with hashes.
|
||||
- Purpose: unblock BENCH-GRAPH-21-001/002 while overlay format is finalized. Overlays not included yet.
|
||||
- Purpose: throughput/latency benches; overlay-free.
|
||||
|
||||
## Open items (to resolve before canonical data generation)
|
||||
- Confirm overlay field set and file naming (Graph Guild, due 2025-11-22).
|
||||
- Confirm allowed mock SBOM source list and artifact naming (Graph Guild / SBOM Service Guild).
|
||||
- Provide expected node/edge cardinality breakdown (packages vs files vs relationships) to guide generation.
|
||||
## Open items
|
||||
- Regenerate if Graph overlay schema changes; update manifest/hashes and downstream references.
|
||||
- Consider adding advisory/VEX nodes once Graph/Concelier schema freeze lands; currently component-focused.
|
||||
|
||||
## Next steps
|
||||
- Keep SAMPLES-GRAPH-24-003 blocked until overlay/schema confirmation, but interim fixtures are available for benches.
|
||||
- Once overlay schema final, extend generator to emit overlays + CAS manifests and promote to official fixture.
|
||||
- Wire `graph-40k` into BENCH-GRAPH-21-001/002 results and UI fixtures (SAMPLES-GRAPH-24-004).
|
||||
- Add CAS/DSSE manifest once Offline Kit package format is finalized.
|
||||
|
||||
33
samples/graph/graph-40k/README.md
Normal file
33
samples/graph/graph-40k/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Graph-40k fixture (SAMPLES-GRAPH-24-003)
|
||||
|
||||
Canonical large SBOM graph fixture with policy overlay for performance/regression suites.
|
||||
|
||||
## Contents
|
||||
- `nodes.ndjson` — 40,000 component nodes (`pkg:pypi/demo-*`) for tenant `demo-tenant`.
|
||||
- `edges.ndjson` — 100,071 `DEPENDS_ON` edges (fan-out ≤4, DAG order).
|
||||
- `overlay.ndjson` — 100 `policy.overlay.v1` records with verdict/severity + optional edge to policy rule node.
|
||||
- `manifest.json` — counts and SHA-256 hashes.
|
||||
- `verify.py` — offline verifier for hashes/counts.
|
||||
|
||||
## Determinism
|
||||
- Fixed seed `424242`, snapshot `graph-40k-policy-overlay-20251122`, timestamp `2025-11-22T00:00:00Z`.
|
||||
- Sorted NDJSON rows, stable overlay ID scheme `sha256(tenant|nodeId|overlayKind)`.
|
||||
- Generated via `samples/graph/scripts/generate_canonical.py` (no network access).
|
||||
|
||||
## Hashes (from manifest)
|
||||
- nodes: `d14e8c642d1b4450d8779971da79cecc190af22fe237dee56ec0dd583f0442f5`
|
||||
- edges: `143a294446f46ffa273846e821f83fd5e5023aea2cf74947ba7ccaeeab7ceba4`
|
||||
- overlay: `627a0d8c273f55b2426c8c005037ef01d88324a75084ad44bd620b1330a539cc`
|
||||
|
||||
## Verify
|
||||
```bash
|
||||
cd samples/graph/graph-40k
|
||||
python verify.py
|
||||
```
|
||||
|
||||
## Regenerate (optional)
|
||||
```bash
|
||||
python ../scripts/generate_canonical.py --out-dir samples/graph/graph-40k
|
||||
```
|
||||
|
||||
Ensure manifest hashes match after regeneration before promoting to offline kits.
|
||||
100071
samples/graph/graph-40k/edges.ndjson
Normal file
100071
samples/graph/graph-40k/edges.ndjson
Normal file
File diff suppressed because it is too large
Load Diff
34
samples/graph/graph-40k/explorer/README.md
Normal file
34
samples/graph/graph-40k/explorer/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Vulnerability Explorer fixtures (SAMPLES-GRAPH-24-004)
|
||||
|
||||
Derives a small, deterministic explorer dataset from the canonical graph-40k fixture.
|
||||
|
||||
## Files
|
||||
- `vuln-explorer.json` — 5 records covering mixed policy verdicts and reachability (reachable/unreachable alternation).
|
||||
- `vuln-explorer.csv` — same data for CSV-driven UI/CLI tests; `evidence` is `;`-separated.
|
||||
- `manifest.json` — SHA-256 hashes for both files.
|
||||
|
||||
## Source
|
||||
- Built from `samples/graph/graph-40k/overlay.ndjson` (policy overlays) using `samples/graph/scripts/build_explorer_fixture.py`.
|
||||
- Tenant: `demo-tenant`; snapshot: `graph-40k-policy-overlay-20251122`.
|
||||
|
||||
## Determinism
|
||||
- Fixed advisory list and order.
|
||||
- Overlay rows sorted by `overlay_id`; first 5 overlays selected.
|
||||
- No randomness; rerunning `build_explorer_fixture.py` produces identical hashes.
|
||||
|
||||
## Verify
|
||||
```bash
|
||||
python samples/graph/scripts/build_explorer_fixture.py
|
||||
python - <<'PY'
|
||||
import json,hashlib,Pathlib
|
||||
from pathlib import Path
|
||||
base=Path("samples/graph/graph-40k/explorer")
|
||||
for name in ["vuln-explorer.json","vuln-explorer.csv"]:
|
||||
h=hashlib.sha256((base/name).read_bytes()).hexdigest()
|
||||
print(name, h)
|
||||
PY
|
||||
```
|
||||
|
||||
## Consumption hints
|
||||
- UI: seed list/detail views and policy conflict badges (fields: `reachability`, `policy_verdict`, `conflict`).
|
||||
- CLI: pipe JSON into explorer tests or convert from CSV as needed.
|
||||
15
samples/graph/graph-40k/explorer/manifest.json
Normal file
15
samples/graph/graph-40k/explorer/manifest.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"advisories": [
|
||||
"CVE-2024-0001",
|
||||
"CVE-2024-0002",
|
||||
"CVE-2023-9999",
|
||||
"CVE-2025-1234",
|
||||
"CVE-2022-4242"
|
||||
],
|
||||
"count": 5,
|
||||
"fixture": "graph-40k",
|
||||
"hashes": {
|
||||
"vuln-explorer.csv": "d116f2451fe82c7895325b1ceda10f024dd5df822131bf5882f5a1b97ea60ea0",
|
||||
"vuln-explorer.json": "d34938dbb6d7de14751c6e49392de27766703425f18ab949861bc1d1147abb01"
|
||||
}
|
||||
}
|
||||
6
samples/graph/graph-40k/explorer/vuln-explorer.csv
Normal file
6
samples/graph/graph-40k/explorer/vuln-explorer.csv
Normal file
@@ -0,0 +1,6 @@
|
||||
component,advisory,advisory_severity,reachability,status,policy_overlay_id,policy_verdict,policy_severity,policy_rule_id,evidence,conflict,snapshot,tenant
|
||||
pkg:pypi/demo-15400@1.0.0,CVE-2024-0001,critical,reachable,affected,00f6635f7e16f4249116313369beadeee8836ae6da36dedaec23b38130b92f24,deny,low,RULE-06000,sbom:mock-sbom-v1;overlay:00f6635f7e16f4249116313369beadeee8836ae6da36dedaec23b38130b92f24,policy_deny_vs_scanner_affected,graph-40k-policy-overlay-20251122,demo-tenant
|
||||
pkg:pypi/demo-6040@1.0.0,CVE-2024-0002,high,unreachable,not_affected,065090e3b6aa2f247cfd6844c5d00dda582516b606f068adbe497ac84fb71f99,defer,critical,RULE-35600,sbom:mock-sbom-v1;overlay:065090e3b6aa2f247cfd6844c5d00dda582516b606f068adbe497ac84fb71f99,,graph-40k-policy-overlay-20251122,demo-tenant
|
||||
pkg:pypi/demo-14320@1.0.0,CVE-2023-9999,medium,reachable,affected,06a3cb2fef361ef22f596d1cb2a9dba7da6cf4316b43892f3aa1041b55fdf457,deny,none,RULE-04800,sbom:mock-sbom-v1;overlay:06a3cb2fef361ef22f596d1cb2a9dba7da6cf4316b43892f3aa1041b55fdf457,policy_deny_vs_scanner_affected,graph-40k-policy-overlay-20251122,demo-tenant
|
||||
pkg:pypi/demo-4961@1.0.1,CVE-2025-1234,low,unreachable,not_affected,076cf3660de3a883d6a148a1850347300bd368e8177491b3c8a880e1f000bda6,defer,high,RULE-34400,sbom:mock-sbom-v1;overlay:076cf3660de3a883d6a148a1850347300bd368e8177491b3c8a880e1f000bda6,,graph-40k-policy-overlay-20251122,demo-tenant
|
||||
pkg:pypi/demo-6761@1.0.1,CVE-2022-4242,none,reachable,affected,08471f5759128be339110c0a72cf3cc6de36da9f5315a148f9e41602af808546,deny,none,RULE-36400,sbom:mock-sbom-v1;overlay:08471f5759128be339110c0a72cf3cc6de36da9f5315a148f9e41602af808546,policy_deny_vs_scanner_affected,graph-40k-policy-overlay-20251122,demo-tenant
|
||||
|
92
samples/graph/graph-40k/explorer/vuln-explorer.json
Normal file
92
samples/graph/graph-40k/explorer/vuln-explorer.json
Normal file
@@ -0,0 +1,92 @@
|
||||
[
|
||||
{
|
||||
"advisory": "CVE-2024-0001",
|
||||
"advisory_severity": "critical",
|
||||
"component": "pkg:pypi/demo-15400@1.0.0",
|
||||
"conflict": "policy_deny_vs_scanner_affected",
|
||||
"evidence": [
|
||||
"sbom:mock-sbom-v1",
|
||||
"overlay:00f6635f7e16f4249116313369beadeee8836ae6da36dedaec23b38130b92f24"
|
||||
],
|
||||
"policy_overlay_id": "00f6635f7e16f4249116313369beadeee8836ae6da36dedaec23b38130b92f24",
|
||||
"policy_rule_id": "RULE-06000",
|
||||
"policy_severity": "low",
|
||||
"policy_verdict": "deny",
|
||||
"reachability": "reachable",
|
||||
"snapshot": "graph-40k-policy-overlay-20251122",
|
||||
"status": "affected",
|
||||
"tenant": "demo-tenant"
|
||||
},
|
||||
{
|
||||
"advisory": "CVE-2024-0002",
|
||||
"advisory_severity": "high",
|
||||
"component": "pkg:pypi/demo-6040@1.0.0",
|
||||
"conflict": "",
|
||||
"evidence": [
|
||||
"sbom:mock-sbom-v1",
|
||||
"overlay:065090e3b6aa2f247cfd6844c5d00dda582516b606f068adbe497ac84fb71f99"
|
||||
],
|
||||
"policy_overlay_id": "065090e3b6aa2f247cfd6844c5d00dda582516b606f068adbe497ac84fb71f99",
|
||||
"policy_rule_id": "RULE-35600",
|
||||
"policy_severity": "critical",
|
||||
"policy_verdict": "defer",
|
||||
"reachability": "unreachable",
|
||||
"snapshot": "graph-40k-policy-overlay-20251122",
|
||||
"status": "not_affected",
|
||||
"tenant": "demo-tenant"
|
||||
},
|
||||
{
|
||||
"advisory": "CVE-2023-9999",
|
||||
"advisory_severity": "medium",
|
||||
"component": "pkg:pypi/demo-14320@1.0.0",
|
||||
"conflict": "policy_deny_vs_scanner_affected",
|
||||
"evidence": [
|
||||
"sbom:mock-sbom-v1",
|
||||
"overlay:06a3cb2fef361ef22f596d1cb2a9dba7da6cf4316b43892f3aa1041b55fdf457"
|
||||
],
|
||||
"policy_overlay_id": "06a3cb2fef361ef22f596d1cb2a9dba7da6cf4316b43892f3aa1041b55fdf457",
|
||||
"policy_rule_id": "RULE-04800",
|
||||
"policy_severity": "none",
|
||||
"policy_verdict": "deny",
|
||||
"reachability": "reachable",
|
||||
"snapshot": "graph-40k-policy-overlay-20251122",
|
||||
"status": "affected",
|
||||
"tenant": "demo-tenant"
|
||||
},
|
||||
{
|
||||
"advisory": "CVE-2025-1234",
|
||||
"advisory_severity": "low",
|
||||
"component": "pkg:pypi/demo-4961@1.0.1",
|
||||
"conflict": "",
|
||||
"evidence": [
|
||||
"sbom:mock-sbom-v1",
|
||||
"overlay:076cf3660de3a883d6a148a1850347300bd368e8177491b3c8a880e1f000bda6"
|
||||
],
|
||||
"policy_overlay_id": "076cf3660de3a883d6a148a1850347300bd368e8177491b3c8a880e1f000bda6",
|
||||
"policy_rule_id": "RULE-34400",
|
||||
"policy_severity": "high",
|
||||
"policy_verdict": "defer",
|
||||
"reachability": "unreachable",
|
||||
"snapshot": "graph-40k-policy-overlay-20251122",
|
||||
"status": "not_affected",
|
||||
"tenant": "demo-tenant"
|
||||
},
|
||||
{
|
||||
"advisory": "CVE-2022-4242",
|
||||
"advisory_severity": "none",
|
||||
"component": "pkg:pypi/demo-6761@1.0.1",
|
||||
"conflict": "policy_deny_vs_scanner_affected",
|
||||
"evidence": [
|
||||
"sbom:mock-sbom-v1",
|
||||
"overlay:08471f5759128be339110c0a72cf3cc6de36da9f5315a148f9e41602af808546"
|
||||
],
|
||||
"policy_overlay_id": "08471f5759128be339110c0a72cf3cc6de36da9f5315a148f9e41602af808546",
|
||||
"policy_rule_id": "RULE-36400",
|
||||
"policy_severity": "none",
|
||||
"policy_verdict": "deny",
|
||||
"reachability": "reachable",
|
||||
"snapshot": "graph-40k-policy-overlay-20251122",
|
||||
"status": "affected",
|
||||
"tenant": "demo-tenant"
|
||||
}
|
||||
]
|
||||
26
samples/graph/graph-40k/manifest.json
Normal file
26
samples/graph/graph-40k/manifest.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"counts": {
|
||||
"edges": 100071,
|
||||
"nodes": 40000,
|
||||
"overlays": {
|
||||
"policy.overlay.v1": 100
|
||||
}
|
||||
},
|
||||
"generated_at": "2025-11-22T00:00:00Z",
|
||||
"hashes": {
|
||||
"edges_ndjson_sha256": "143a294446f46ffa273846e821f83fd5e5023aea2cf74947ba7ccaeeab7ceba4",
|
||||
"nodes_ndjson_sha256": "d14e8c642d1b4450d8779971da79cecc190af22fe237dee56ec0dd583f0442f5",
|
||||
"overlay_ndjson_sha256": "627a0d8c273f55b2426c8c005037ef01d88324a75084ad44bd620b1330a539cc"
|
||||
},
|
||||
"inputs": {
|
||||
"sbom_source": "mock-sbom-v1"
|
||||
},
|
||||
"overlay": {
|
||||
"id_scheme": "sha256(tenant|nodeId|overlayKind)",
|
||||
"kind": "policy.overlay.v1",
|
||||
"path": "overlay.ndjson"
|
||||
},
|
||||
"seed": 424242,
|
||||
"snapshot_id": "graph-40k-policy-overlay-20251122",
|
||||
"tenant": "demo-tenant"
|
||||
}
|
||||
40000
samples/graph/graph-40k/nodes.ndjson
Normal file
40000
samples/graph/graph-40k/nodes.ndjson
Normal file
File diff suppressed because it is too large
Load Diff
100
samples/graph/graph-40k/overlay.ndjson
Normal file
100
samples/graph/graph-40k/overlay.ndjson
Normal file
@@ -0,0 +1,100 @@
|
||||
{"explain":"demo policy decision for demo-15400","node_id":"pkg:pypi/demo-15400@1.0.0","overlay_id":"00f6635f7e16f4249116313369beadeee8836ae6da36dedaec23b38130b92f24","overlay_kind":"policy.overlay.v1","rule_id":"RULE-06000","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-15400@1.0.0","target":"policy:rule:RULE-06000","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-6040","node_id":"pkg:pypi/demo-6040@1.0.0","overlay_id":"065090e3b6aa2f247cfd6844c5d00dda582516b606f068adbe497ac84fb71f99","overlay_kind":"policy.overlay.v1","rule_id":"RULE-35600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-6040@1.0.0","target":"policy:rule:RULE-35600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-14320","node_id":"pkg:pypi/demo-14320@1.0.0","overlay_id":"06a3cb2fef361ef22f596d1cb2a9dba7da6cf4316b43892f3aa1041b55fdf457","overlay_kind":"policy.overlay.v1","rule_id":"RULE-04800","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-14320@1.0.0","target":"policy:rule:RULE-04800","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-4961","node_id":"pkg:pypi/demo-4961@1.0.1","overlay_id":"076cf3660de3a883d6a148a1850347300bd368e8177491b3c8a880e1f000bda6","overlay_kind":"policy.overlay.v1","rule_id":"RULE-34400","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-4961@1.0.1","target":"policy:rule:RULE-34400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-6761","node_id":"pkg:pypi/demo-6761@1.0.1","overlay_id":"08471f5759128be339110c0a72cf3cc6de36da9f5315a148f9e41602af808546","overlay_kind":"policy.overlay.v1","rule_id":"RULE-36400","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-6761@1.0.1","target":"policy:rule:RULE-36400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-4600","node_id":"pkg:pypi/demo-4600@1.0.0","overlay_id":"08ca8c4ddf56fc9bea303282a6055aa6c206b353f765f022a8b496a68d555f4e","overlay_kind":"policy.overlay.v1","rule_id":"RULE-34000","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-4600@1.0.0","target":"policy:rule:RULE-34000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-22600","node_id":"pkg:pypi/demo-22600@1.0.0","overlay_id":"0f188a4d940341451b6dbfd4c521d1a048fc2b6a83984f441b436dae46a22622","overlay_kind":"policy.overlay.v1","rule_id":"RULE-14000","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-22600@1.0.0","target":"policy:rule:RULE-14000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-7120","node_id":"pkg:pypi/demo-7120@1.0.0","overlay_id":"11aeb49bf42ab18724a9b9f4b52179d76a77b9239ba08f1cf10a60f2d30e07bd","overlay_kind":"policy.overlay.v1","rule_id":"RULE-36800","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-7120@1.0.0","target":"policy:rule:RULE-36800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-26200","node_id":"pkg:pypi/demo-26200@1.0.0","overlay_id":"12a82e8a3e21aebc98fbe91de3bb3b7288b02754274b977be52e2741bc57520a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-18000","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-26200@1.0.0","target":"policy:rule:RULE-18000","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-31961","node_id":"pkg:pypi/demo-31961@1.0.1","overlay_id":"16fe80c9d4496b8bb446d8b260696b7882fe379ec29dd5284d737f4f39559183","overlay_kind":"policy.overlay.v1","rule_id":"RULE-24400","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-31961@1.0.1","target":"policy:rule:RULE-24400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-34841","node_id":"pkg:pypi/demo-34841@1.0.1","overlay_id":"1ed19ed6c761fcb27bfd9d67bad34da3572b2d1a228a8b0a0377bfc25e8cc38b","overlay_kind":"policy.overlay.v1","rule_id":"RULE-27600","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-34841@1.0.1","target":"policy:rule:RULE-27600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-20800","node_id":"pkg:pypi/demo-20800@1.0.0","overlay_id":"1f075142eea7b0d274a30b55f102e0ebaaa0d385a94dc60217270b632a516b31","overlay_kind":"policy.overlay.v1","rule_id":"RULE-12000","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-20800@1.0.0","target":"policy:rule:RULE-12000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-24400","node_id":"pkg:pypi/demo-24400@1.0.0","overlay_id":"1f8ad1be2a2298ef6ffc345171c22c2f0d8f8c64419f8c1797e1d0724bdc2970","overlay_kind":"policy.overlay.v1","rule_id":"RULE-16000","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-24400@1.0.0","target":"policy:rule:RULE-16000","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-29801","node_id":"pkg:pypi/demo-29801@1.0.1","overlay_id":"20141ff2685b718a9ecf5c609ebd207f28c105f6906976c57304c6eac8bc2e68","overlay_kind":"policy.overlay.v1","rule_id":"RULE-22000","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-29801@1.0.1","target":"policy:rule:RULE-22000","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-27641","node_id":"pkg:pypi/demo-27641@1.0.1","overlay_id":"20b6a284c90061f2fb4569e87ffe3afb341d6b5b8ce74622bf2516d1448862eb","overlay_kind":"policy.overlay.v1","rule_id":"RULE-19600","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-27641@1.0.1","target":"policy:rule:RULE-19600","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-29081","node_id":"pkg:pypi/demo-29081@1.0.1","overlay_id":"21c1c06a5e4ba9b26ed55ace0f98438a2064ff3adb91faf6a4753dfefcbaa797","overlay_kind":"policy.overlay.v1","rule_id":"RULE-21200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-29081@1.0.1","target":"policy:rule:RULE-21200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-19721","node_id":"pkg:pypi/demo-19721@1.0.1","overlay_id":"26bec47969f1bace1fb739006919f4c9435c379831fd7cc8c7983f3133098f20","overlay_kind":"policy.overlay.v1","rule_id":"RULE-10800","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-19721@1.0.1","target":"policy:rule:RULE-10800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-38441","node_id":"pkg:pypi/demo-38441@1.0.1","overlay_id":"27372ff2b40f0f0fefd4a9e463f97b45b67047152886e2ada438fb1c1a1952f2","overlay_kind":"policy.overlay.v1","rule_id":"RULE-31600","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-38441@1.0.1","target":"policy:rule:RULE-31600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-17921","node_id":"pkg:pypi/demo-17921@1.0.1","overlay_id":"2a7fcdb6269249a627ff44ee3a201f3ebd6f4a33edb87e1a4b1696d7b1025701","overlay_kind":"policy.overlay.v1","rule_id":"RULE-08800","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-17921@1.0.1","target":"policy:rule:RULE-08800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-17200","node_id":"pkg:pypi/demo-17200@1.0.0","overlay_id":"2da59c89375950b114eb110344c700df1af9e7a4ddcb241c1c0da5dc3d1d80a1","overlay_kind":"policy.overlay.v1","rule_id":"RULE-08000","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-17200@1.0.0","target":"policy:rule:RULE-08000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-35921","node_id":"pkg:pypi/demo-35921@1.0.1","overlay_id":"2e3df2943656dfbc96d5cc9d9fa4ed6a8f87df84789bf47855cf59d0b803ece1","overlay_kind":"policy.overlay.v1","rule_id":"RULE-28800","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-35921@1.0.1","target":"policy:rule:RULE-28800","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-23681","node_id":"pkg:pypi/demo-23681@1.0.1","overlay_id":"2e5d6cf6bca4774b171cd81a201d82d60c67d5c82be92e524e26edd216b74fd0","overlay_kind":"policy.overlay.v1","rule_id":"RULE-15200","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-23681@1.0.1","target":"policy:rule:RULE-15200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-4240","node_id":"pkg:pypi/demo-4240@1.0.0","overlay_id":"3522560d95b46feec42d0be807cf9a8cf9bcb8c71b35a4708af5e00c0ebd0d42","overlay_kind":"policy.overlay.v1","rule_id":"RULE-33600","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-4240@1.0.0","target":"policy:rule:RULE-33600","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-28361","node_id":"pkg:pypi/demo-28361@1.0.1","overlay_id":"3cd52522d3bcdf2e061be34e227f3314fe40848449c2552518b984da9b396eab","overlay_kind":"policy.overlay.v1","rule_id":"RULE-20400","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-28361@1.0.1","target":"policy:rule:RULE-20400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-20080","node_id":"pkg:pypi/demo-20080@1.0.0","overlay_id":"3f3c04bce6724af0f15641c75f4e8487226149c1c05913304f9f0ea0f8136c3c","overlay_kind":"policy.overlay.v1","rule_id":"RULE-11200","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-20080@1.0.0","target":"policy:rule:RULE-11200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-15040","node_id":"pkg:pypi/demo-15040@1.0.0","overlay_id":"46f8052bed54eed8f59a3ce612d24edf6f19b4361795f661d1682fe1d4c84df3","overlay_kind":"policy.overlay.v1","rule_id":"RULE-05600","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-15040@1.0.0","target":"policy:rule:RULE-05600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-28000","node_id":"pkg:pypi/demo-28000@1.0.0","overlay_id":"473d00587b256d93ecb8d3beabb6b6ed9d17ec65560ec29f3314a2334a47d88d","overlay_kind":"policy.overlay.v1","rule_id":"RULE-20000","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-28000@1.0.0","target":"policy:rule:RULE-20000","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-32320","node_id":"pkg:pypi/demo-32320@1.0.0","overlay_id":"4a5f730c78be6f6ab37b6585283834901c8d1149dce4c1c6a0d060095d04a74d","overlay_kind":"policy.overlay.v1","rule_id":"RULE-24800","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-32320@1.0.0","target":"policy:rule:RULE-24800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-21881","node_id":"pkg:pypi/demo-21881@1.0.1","overlay_id":"50e4cb1286bfddfee0fdbfa14e0171c55d8213cfeee3db952700070760d8b0cb","overlay_kind":"policy.overlay.v1","rule_id":"RULE-13200","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-21881@1.0.1","target":"policy:rule:RULE-13200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-8561","node_id":"pkg:pypi/demo-8561@1.0.1","overlay_id":"53887178f6f3c16748cf963697941c4394b328fa50585029151b7f8ce7b9c879","overlay_kind":"policy.overlay.v1","rule_id":"RULE-38400","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-8561@1.0.1","target":"policy:rule:RULE-38400","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-39161","node_id":"pkg:pypi/demo-39161@1.0.1","overlay_id":"5436b7bda222583e8a2424febc18f5cea9786c36ef5117b899bb12d7ca898d14","overlay_kind":"policy.overlay.v1","rule_id":"RULE-32400","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-39161@1.0.1","target":"policy:rule:RULE-32400","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-9641","node_id":"pkg:pypi/demo-9641@1.0.1","overlay_id":"569537ee49b377bafb1e0bc377b611bd1fc9deda7ee5fef159775b003f02afb0","overlay_kind":"policy.overlay.v1","rule_id":"RULE-39600","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-9641@1.0.1","target":"policy:rule:RULE-39600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-20440","node_id":"pkg:pypi/demo-20440@1.0.0","overlay_id":"57cb73d1d4d01babb0288fc3fa9920bfef967df09d8dfa1ddcadfaf5d19dda28","overlay_kind":"policy.overlay.v1","rule_id":"RULE-11600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-20440@1.0.0","target":"policy:rule:RULE-11600","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-17561","node_id":"pkg:pypi/demo-17561@1.0.1","overlay_id":"583342875a32559c2d5a8a7f4624a374cfc93bcaf1248c677eb9f8a4af2a5410","overlay_kind":"policy.overlay.v1","rule_id":"RULE-08400","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-17561@1.0.1","target":"policy:rule:RULE-08400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-37361","node_id":"pkg:pypi/demo-37361@1.0.1","overlay_id":"59692ee61859b213e4e35a8a38109c61214e49f4593731fc0448df45176df42f","overlay_kind":"policy.overlay.v1","rule_id":"RULE-30400","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-37361@1.0.1","target":"policy:rule:RULE-30400","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-0","node_id":"pkg:pypi/demo-0@1.0.0","overlay_id":"5ad64d33fe51038314ae68f71bd7c9fbbb9d3c6f1310a93faa43705f7158be24","overlay_kind":"policy.overlay.v1","rule_id":"RULE-00000","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-0@1.0.0","target":"policy:rule:RULE-00000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-30520","node_id":"pkg:pypi/demo-30520@1.0.0","overlay_id":"5aef610e89bd3533396db32a26396868c3dfc44be0fa062c717e8436c6faf68f","overlay_kind":"policy.overlay.v1","rule_id":"RULE-22800","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-30520@1.0.0","target":"policy:rule:RULE-22800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-36641","node_id":"pkg:pypi/demo-36641@1.0.1","overlay_id":"5b210791fdeabe175c63d4c02ea51ea28b3a230f9dfb28d5706d6f2ad156d23a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-29600","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-36641@1.0.1","target":"policy:rule:RULE-29600","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-30881","node_id":"pkg:pypi/demo-30881@1.0.1","overlay_id":"5bc784e95ed042b4234b55e15e164e8b3ed4259232fdeedeeefc407f21779aff","overlay_kind":"policy.overlay.v1","rule_id":"RULE-23200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-30881@1.0.1","target":"policy:rule:RULE-23200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-12881","node_id":"pkg:pypi/demo-12881@1.0.1","overlay_id":"5eb75e3b7cec31993f42304ef1bf4222c428d58afdde56b7749b277c0a7c12d8","overlay_kind":"policy.overlay.v1","rule_id":"RULE-03200","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-12881@1.0.1","target":"policy:rule:RULE-03200","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-37000","node_id":"pkg:pypi/demo-37000@1.0.0","overlay_id":"60ec249e7d9aaeb9152051ea30f8d5950e1863cca3a573e95e98fa9a147973d0","overlay_kind":"policy.overlay.v1","rule_id":"RULE-30000","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-37000@1.0.0","target":"policy:rule:RULE-30000","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-39521","node_id":"pkg:pypi/demo-39521@1.0.1","overlay_id":"647091b2c6a7a639ebc3f6c662c62402e16a60adb0d45f654f5e82e86bd13891","overlay_kind":"policy.overlay.v1","rule_id":"RULE-32800","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-39521@1.0.1","target":"policy:rule:RULE-32800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-33400","node_id":"pkg:pypi/demo-33400@1.0.0","overlay_id":"6600cb30c992e0969a7a1b5b6af50be2d5f2bd081d0593c1ddb7271aea9c994e","overlay_kind":"policy.overlay.v1","rule_id":"RULE-26000","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-33400@1.0.0","target":"policy:rule:RULE-26000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-11080","node_id":"pkg:pypi/demo-11080@1.0.0","overlay_id":"67f7f34940ab048a9cb4f13003a8d8f6331495217c2c13e8e1b19f50eb9035de","overlay_kind":"policy.overlay.v1","rule_id":"RULE-01200","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-11080@1.0.0","target":"policy:rule:RULE-01200","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-38801","node_id":"pkg:pypi/demo-38801@1.0.1","overlay_id":"6ae30cc9c4ffc69ca8b310922b102d8b1d7c45766cf4d874da08211c70eb56e9","overlay_kind":"policy.overlay.v1","rule_id":"RULE-32000","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-38801@1.0.1","target":"policy:rule:RULE-32000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-39882","node_id":"pkg:pypi/demo-39882@1.0.2","overlay_id":"6cf07249525dbbcc9a47f05c5819c3af869556c028aa6d6e3380eea61dbf9141","overlay_kind":"policy.overlay.v1","rule_id":"RULE-33200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-39882@1.0.2","target":"policy:rule:RULE-33200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-31240","node_id":"pkg:pypi/demo-31240@1.0.0","overlay_id":"6f8f777acdfa66e0be08b1626dc647def53cff7cb1ceb6ebdf9b18caf394d13b","overlay_kind":"policy.overlay.v1","rule_id":"RULE-23600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-31240@1.0.0","target":"policy:rule:RULE-23600","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-29441","node_id":"pkg:pypi/demo-29441@1.0.1","overlay_id":"738f32825ad6beeedac2bc5dfb4df56c93b39950296c516f8497e69f6394e11c","overlay_kind":"policy.overlay.v1","rule_id":"RULE-21600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-29441@1.0.1","target":"policy:rule:RULE-21600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-19000","node_id":"pkg:pypi/demo-19000@1.0.0","overlay_id":"73bb0f8c0d3229fa269ecd196204423a9261e9f3f98996cc729ce2231a20cdb1","overlay_kind":"policy.overlay.v1","rule_id":"RULE-10000","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-19000@1.0.0","target":"policy:rule:RULE-10000","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-7481","node_id":"pkg:pypi/demo-7481@1.0.1","overlay_id":"747fc10ceb149b0d8140a1d4c0485fdf3643204c06b4fb218670c9e97b38e4f3","overlay_kind":"policy.overlay.v1","rule_id":"RULE-37200","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-7481@1.0.1","target":"policy:rule:RULE-37200","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-35561","node_id":"pkg:pypi/demo-35561@1.0.1","overlay_id":"76900fee410f614d7b11c55a395ee5260408989421740dfd78b6ac55850d2542","overlay_kind":"policy.overlay.v1","rule_id":"RULE-28400","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-35561@1.0.1","target":"policy:rule:RULE-28400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-23320","node_id":"pkg:pypi/demo-23320@1.0.0","overlay_id":"76b56b10c70cc1dcdd872bbd065cd44dbd7c3aa7032e82ce3ef0820978d69e27","overlay_kind":"policy.overlay.v1","rule_id":"RULE-14800","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-23320@1.0.0","target":"policy:rule:RULE-14800","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-18641","node_id":"pkg:pypi/demo-18641@1.0.1","overlay_id":"773e4bd52baff94e36068ce517d63ebf78f89210b3e5163dc8b4c61966c8a47a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-09600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-18641@1.0.1","target":"policy:rule:RULE-09600","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-25481","node_id":"pkg:pypi/demo-25481@1.0.1","overlay_id":"7a536bc0ad6b4095768935986291ea7d6ee88c8c0d5b170ae8bba2c0a61179b7","overlay_kind":"policy.overlay.v1","rule_id":"RULE-17200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-25481@1.0.1","target":"policy:rule:RULE-17200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-21160","node_id":"pkg:pypi/demo-21160@1.0.0","overlay_id":"7f47db20c7fab82d4aef26cdffc6cb83e4acf32e976d2c8fef225f3573a69101","overlay_kind":"policy.overlay.v1","rule_id":"RULE-12400","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-21160@1.0.0","target":"policy:rule:RULE-12400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-30160","node_id":"pkg:pypi/demo-30160@1.0.0","overlay_id":"8137c50cbfdb865b279e2789d69381a27bc293147be20795364451f43900d6a6","overlay_kind":"policy.overlay.v1","rule_id":"RULE-22400","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-30160@1.0.0","target":"policy:rule:RULE-22400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-27281","node_id":"pkg:pypi/demo-27281@1.0.1","overlay_id":"82bbe85a44c2ff19be60a38ee8aa087c28364dcef6918305fbede27bf6a5f5d0","overlay_kind":"policy.overlay.v1","rule_id":"RULE-19200","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-27281@1.0.1","target":"policy:rule:RULE-19200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-28721","node_id":"pkg:pypi/demo-28721@1.0.1","overlay_id":"870bc162cf683f85b025396c6a30b468d4a32943c75c6ea8c60d2fb825fa570d","overlay_kind":"policy.overlay.v1","rule_id":"RULE-20800","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-28721@1.0.1","target":"policy:rule:RULE-20800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-8921","node_id":"pkg:pypi/demo-8921@1.0.1","overlay_id":"898d6aef138e31652e6b36f174fc94e47b12ba42a14d60919898c1c4e7d2b3cc","overlay_kind":"policy.overlay.v1","rule_id":"RULE-38800","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-8921@1.0.1","target":"policy:rule:RULE-38800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-35200","node_id":"pkg:pypi/demo-35200@1.0.0","overlay_id":"9065259780ee9c21319907a5c6b1bde32878a5eb00396052c3e9fdb5f35ca245","overlay_kind":"policy.overlay.v1","rule_id":"RULE-28000","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-35200@1.0.0","target":"policy:rule:RULE-28000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-11440","node_id":"pkg:pypi/demo-11440@1.0.0","overlay_id":"92e12041d5145e58289ae813615f19bc48779db5535c5b1807fcf643cc20f9ac","overlay_kind":"policy.overlay.v1","rule_id":"RULE-01600","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-11440@1.0.0","target":"policy:rule:RULE-01600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-33761","node_id":"pkg:pypi/demo-33761@1.0.1","overlay_id":"9873f2329abea8f4222d21321a59c92e232edf27a561d63942beb880bf3d31b0","overlay_kind":"policy.overlay.v1","rule_id":"RULE-26400","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-33761@1.0.1","target":"policy:rule:RULE-26400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-26921","node_id":"pkg:pypi/demo-26921@1.0.1","overlay_id":"9cb926442a11156980b13ce305a20f390e4ad7af84bbdd94a8511b0436d660b7","overlay_kind":"policy.overlay.v1","rule_id":"RULE-18800","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-26921@1.0.1","target":"policy:rule:RULE-18800","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-25841","node_id":"pkg:pypi/demo-25841@1.0.1","overlay_id":"9d1408c934dff88449d4ada0afc48806fcefa452aae778e4a16f5d2b2d8c589e","overlay_kind":"policy.overlay.v1","rule_id":"RULE-17600","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-25841@1.0.1","target":"policy:rule:RULE-17600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-16481","node_id":"pkg:pypi/demo-16481@1.0.1","overlay_id":"9d4592d52a314b009a849d5dea86912c28f8373f235563ac2549d14f2942147e","overlay_kind":"policy.overlay.v1","rule_id":"RULE-07200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-16481@1.0.1","target":"policy:rule:RULE-07200","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-34481","node_id":"pkg:pypi/demo-34481@1.0.1","overlay_id":"9e8c59b06c30d2127ba50fc0307efdb531a63e80d229595a90327b94675d99d9","overlay_kind":"policy.overlay.v1","rule_id":"RULE-27200","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-34481@1.0.1","target":"policy:rule:RULE-27200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-8200","node_id":"pkg:pypi/demo-8200@1.0.0","overlay_id":"9f9e64f467caf1cbd0d367b79a0e473871eeda5873c17c572e34a1857f45bd39","overlay_kind":"policy.overlay.v1","rule_id":"RULE-38000","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-8200@1.0.0","target":"policy:rule:RULE-38000","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-13961","node_id":"pkg:pypi/demo-13961@1.0.1","overlay_id":"a6be168a9f820a1f1713835ed6a814556ce117cfd6896d738f12153d51660aa6","overlay_kind":"policy.overlay.v1","rule_id":"RULE-04400","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-13961@1.0.1","target":"policy:rule:RULE-04400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-36281","node_id":"pkg:pypi/demo-36281@1.0.1","overlay_id":"a705207f1f1265799bc5f4e4387cd6f3ed82635921d00093da234c2ca7e7be17","overlay_kind":"policy.overlay.v1","rule_id":"RULE-29200","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-36281@1.0.1","target":"policy:rule:RULE-29200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-19361","node_id":"pkg:pypi/demo-19361@1.0.1","overlay_id":"a740234b5fa022f52bce480e1d70250cdc5936eb6d42fb8736543ef46c7fac31","overlay_kind":"policy.overlay.v1","rule_id":"RULE-10400","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-19361@1.0.1","target":"policy:rule:RULE-10400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-37721","node_id":"pkg:pypi/demo-37721@1.0.1","overlay_id":"a7f55958a80bde9440ab5e8a4d6ca1210f0b8dfe165b0d8cf363abdda1b5b60b","overlay_kind":"policy.overlay.v1","rule_id":"RULE-30800","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-37721@1.0.1","target":"policy:rule:RULE-30800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-13240","node_id":"pkg:pypi/demo-13240@1.0.0","overlay_id":"ab483d159acde6ade084c4b9bc238479962b0aab11ca539c53df916dafe69f05","overlay_kind":"policy.overlay.v1","rule_id":"RULE-03600","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-13240@1.0.0","target":"policy:rule:RULE-03600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-14681","node_id":"pkg:pypi/demo-14681@1.0.1","overlay_id":"b17887773245f01828ebb6aa286b094a3403e382fb353117e2893d744028148a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-05200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-14681@1.0.1","target":"policy:rule:RULE-05200","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-15761","node_id":"pkg:pypi/demo-15761@1.0.1","overlay_id":"b30375cf0b5d69e4aacc88d81fbf76e5e2410a16fe5d7f59f9f3a4d98ca4a866","overlay_kind":"policy.overlay.v1","rule_id":"RULE-06400","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-15761@1.0.1","target":"policy:rule:RULE-06400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-12160","node_id":"pkg:pypi/demo-12160@1.0.0","overlay_id":"b566f79616c3560fdbad0e8418c2ce9b78776ef59e0c2070663be7cf6a7f4c0a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-02400","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-12160@1.0.0","target":"policy:rule:RULE-02400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-22240","node_id":"pkg:pypi/demo-22240@1.0.0","overlay_id":"b95cdc7fb15fd216c22616040ca4b4c676a64edab04c06c16ffafd1738713fbc","overlay_kind":"policy.overlay.v1","rule_id":"RULE-13600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-22240@1.0.0","target":"policy:rule:RULE-13600","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-10720","node_id":"pkg:pypi/demo-10720@1.0.0","overlay_id":"c06cd9cf8b8074d90b31eac5ad85e92421b4e362480e092ce7c5e7b62565d928","overlay_kind":"policy.overlay.v1","rule_id":"RULE-00800","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-10720@1.0.0","target":"policy:rule:RULE-00800","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-9281","node_id":"pkg:pypi/demo-9281@1.0.1","overlay_id":"c27f4d22caaa383d0a6875e5dbdf17412961c51c220b98b324009526fade3a76","overlay_kind":"policy.overlay.v1","rule_id":"RULE-39200","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-9281@1.0.1","target":"policy:rule:RULE-39200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-13600","node_id":"pkg:pypi/demo-13600@1.0.0","overlay_id":"c739d23b17155d1516d7d984ba747bf050f2d8d08541da3a4a1d7df26e26712a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-04000","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-13600@1.0.0","target":"policy:rule:RULE-04000","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-32681","node_id":"pkg:pypi/demo-32681@1.0.1","overlay_id":"c768334e27b299ae15f65ab67b3f55be479fb5b9c4b74e430f2a4aaadea30162","overlay_kind":"policy.overlay.v1","rule_id":"RULE-25200","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-32681@1.0.1","target":"policy:rule:RULE-25200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-5320","node_id":"pkg:pypi/demo-5320@1.0.0","overlay_id":"c9f5ed394a4df94e31421a6ec0026b3a5ed5109716505caf65ba61a80af0115a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-34800","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-5320@1.0.0","target":"policy:rule:RULE-34800","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-12520","node_id":"pkg:pypi/demo-12520@1.0.0","overlay_id":"d0fc77494141b806cfce5988733178603a4dfaa0aa0efd426721027a1a85fdcc","overlay_kind":"policy.overlay.v1","rule_id":"RULE-02800","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-12520@1.0.0","target":"policy:rule:RULE-02800","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-6400","node_id":"pkg:pypi/demo-6400@1.0.0","overlay_id":"d3b8197c027e178dbe45b91c61e361f8835fbb1cea208a78698e576631386969","overlay_kind":"policy.overlay.v1","rule_id":"RULE-36000","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-6400@1.0.0","target":"policy:rule:RULE-36000","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-10360","node_id":"pkg:pypi/demo-10360@1.0.0","overlay_id":"d59fdeb104183f21f5a99297dcc8e5eb86ae1aa5e4779d57ee731995ad8d7368","overlay_kind":"policy.overlay.v1","rule_id":"RULE-00400","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-10360@1.0.0","target":"policy:rule:RULE-00400","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-16120","node_id":"pkg:pypi/demo-16120@1.0.0","overlay_id":"da8e4aaa7d7647c75c4e193e5a75fab30324c53a4b9afee451db071faff90d8e","overlay_kind":"policy.overlay.v1","rule_id":"RULE-06800","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-16120@1.0.0","target":"policy:rule:RULE-06800","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-21520","node_id":"pkg:pypi/demo-21520@1.0.0","overlay_id":"ded0fc8ab38cac14c6b658aca50704e487e5ad833426da232b9955b6e14ed327","overlay_kind":"policy.overlay.v1","rule_id":"RULE-12800","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-21520@1.0.0","target":"policy:rule:RULE-12800","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-26561","node_id":"pkg:pypi/demo-26561@1.0.1","overlay_id":"e00ff0db63667e6c55f9b20579a51276c1f49811f9f7604210f0eb7ce038e855","overlay_kind":"policy.overlay.v1","rule_id":"RULE-18400","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-26561@1.0.1","target":"policy:rule:RULE-18400","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-11800","node_id":"pkg:pypi/demo-11800@1.0.0","overlay_id":"e22a9972cc9be86bb5cec77f2947fa6762901e9dba57e0373bf3a6dee2bb8c84","overlay_kind":"policy.overlay.v1","rule_id":"RULE-02000","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-11800@1.0.0","target":"policy:rule:RULE-02000","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-24040","node_id":"pkg:pypi/demo-24040@1.0.0","overlay_id":"e31ee0323e6950c3d3e5f3422bc5dbdc387abbfe48d89e232cef45f1439bd99d","overlay_kind":"policy.overlay.v1","rule_id":"RULE-15600","severity":"none","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-24040@1.0.0","target":"policy:rule:RULE-15600","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-22961","node_id":"pkg:pypi/demo-22961@1.0.1","overlay_id":"e453eb7d805d37065b70bef0a38a2b5e9dc1fc8b5bd6ca7018609217f16642fa","overlay_kind":"policy.overlay.v1","rule_id":"RULE-14400","severity":"high","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-22961@1.0.1","target":"policy:rule:RULE-14400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-24761","node_id":"pkg:pypi/demo-24761@1.0.1","overlay_id":"e63454641abcc1e5982c58ca88490801b5a2e30f881f04a1566342d710bff7e9","overlay_kind":"policy.overlay.v1","rule_id":"RULE-16400","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-24761@1.0.1","target":"policy:rule:RULE-16400","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-38081","node_id":"pkg:pypi/demo-38081@1.0.1","overlay_id":"e6e57c9f3f4bea1c960388da97328eb7615e30b5ea67ccc7800501fabf0e3912","overlay_kind":"policy.overlay.v1","rule_id":"RULE-31200","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-38081@1.0.1","target":"policy:rule:RULE-31200","tenant":"demo-tenant","verdict":"allow"}
|
||||
{"explain":"demo policy decision for demo-25120","node_id":"pkg:pypi/demo-25120@1.0.0","overlay_id":"ea8985e9a94c5649b08ca043155ea85aff78b86648d173052ff0d4f4ee34d15a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-16800","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-25120@1.0.0","target":"policy:rule:RULE-16800","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-5681","node_id":"pkg:pypi/demo-5681@1.0.1","overlay_id":"eaca42bea0d33828f5c3445fa2a2b518d9925b3c42cff93675fbbcd4de04d339","overlay_kind":"policy.overlay.v1","rule_id":"RULE-35200","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-5681@1.0.1","target":"policy:rule:RULE-35200","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-7841","node_id":"pkg:pypi/demo-7841@1.0.1","overlay_id":"edae72b82895f4feea26750764fdb4ae16b938cbd15bf5d48cdffc3ab23b79d3","overlay_kind":"policy.overlay.v1","rule_id":"RULE-37600","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-7841@1.0.1","target":"policy:rule:RULE-37600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-33040","node_id":"pkg:pypi/demo-33040@1.0.0","overlay_id":"ef05ab5b8b24f89cf3b4cceeb93e585e29f5e780c99aeda79b60f51be5b0d302","overlay_kind":"policy.overlay.v1","rule_id":"RULE-25600","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-33040@1.0.0","target":"policy:rule:RULE-25600","tenant":"demo-tenant","verdict":"defer"}
|
||||
{"explain":"demo policy decision for demo-16841","node_id":"pkg:pypi/demo-16841@1.0.1","overlay_id":"f74c9409e13ffb8fdbbe81eb017fd4fa8f6fda9bd1ba665f9ab0635972a28f4a","overlay_kind":"policy.overlay.v1","rule_id":"RULE-07600","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-16841@1.0.1","target":"policy:rule:RULE-07600","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-34120","node_id":"pkg:pypi/demo-34120@1.0.0","overlay_id":"f80abfd650a8a18de358b126c0bbe743e379870dcf7ce67bb265989bc45285e8","overlay_kind":"policy.overlay.v1","rule_id":"RULE-26800","severity":"medium","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-34120@1.0.0","target":"policy:rule:RULE-26800","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-31600","node_id":"pkg:pypi/demo-31600@1.0.0","overlay_id":"f81295294c128612ccf8b6338fa4a0f908b440078cb91707ee0d9e4c4a71d745","overlay_kind":"policy.overlay.v1","rule_id":"RULE-24000","severity":"low","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-31600@1.0.0","target":"policy:rule:RULE-24000","tenant":"demo-tenant","verdict":"deny"}
|
||||
{"explain":"demo policy decision for demo-18281","node_id":"pkg:pypi/demo-18281@1.0.1","overlay_id":"f8511677dc634ea2bd5fe93d2c739ee177340773dd57be164563e4217fe8938f","overlay_kind":"policy.overlay.v1","rule_id":"RULE-09200","severity":"critical","snapshot":"graph-40k-policy-overlay-20251122","source":"pkg:pypi/demo-18281@1.0.1","target":"policy:rule:RULE-09200","tenant":"demo-tenant","verdict":"allow"}
|
||||
58
samples/graph/graph-40k/verify.py
Normal file
58
samples/graph/graph-40k/verify.py
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Verify graph-40k fixture hashes and counts against manifest.json.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
h = hashlib.sha256()
|
||||
with path.open("rb") as f:
|
||||
for chunk in iter(lambda: f.read(8192), b""):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def count_lines(path: Path) -> int:
|
||||
with path.open("r", encoding="utf-8") as f:
|
||||
return sum(1 for _ in f if _.strip())
|
||||
|
||||
|
||||
def verify(manifest_path: Path) -> Tuple[bool, str]:
|
||||
manifest = json.loads(manifest_path.read_text())
|
||||
base = manifest_path.parent
|
||||
|
||||
nodes_path = base / "nodes.ndjson"
|
||||
edges_path = base / "edges.ndjson"
|
||||
overlay_path = base / manifest["overlay"]["path"]
|
||||
|
||||
checks = [
|
||||
("nodes hash", sha256(nodes_path) == manifest["hashes"]["nodes_ndjson_sha256"]),
|
||||
("edges hash", sha256(edges_path) == manifest["hashes"]["edges_ndjson_sha256"]),
|
||||
("overlay hash", sha256(overlay_path) == manifest["hashes"]["overlay_ndjson_sha256"]),
|
||||
("nodes count", count_lines(nodes_path) == manifest["counts"]["nodes"]),
|
||||
("edges count", count_lines(edges_path) == manifest["counts"]["edges"]),
|
||||
("overlay count", count_lines(overlay_path) == manifest["counts"]["overlays"]["policy.overlay.v1"]),
|
||||
]
|
||||
|
||||
failed = [name for name, ok in checks if not ok]
|
||||
if failed:
|
||||
return False, f"Failed checks: {', '.join(failed)}"
|
||||
return True, "All hashes and counts match manifest."
|
||||
|
||||
|
||||
def main() -> int:
|
||||
manifest_path = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path(__file__).resolve().parent / "manifest.json"
|
||||
ok, message = verify(manifest_path)
|
||||
print(message)
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
139
samples/graph/scripts/build_explorer_fixture.py
Normal file
139
samples/graph/scripts/build_explorer_fixture.py
Normal file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build vulnerability explorer fixtures (JSON + CSV) from the canonical graph-40k fixture.
|
||||
|
||||
Generates deterministic outputs in `samples/graph/graph-40k/explorer/`:
|
||||
- vuln-explorer.json
|
||||
- vuln-explorer.csv
|
||||
- manifest.json (hashes + counts)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
GRAPH_ROOT = ROOT / "graph-40k"
|
||||
OVERLAY_PATH = GRAPH_ROOT / "overlay.ndjson"
|
||||
OUT_DIR = GRAPH_ROOT / "explorer"
|
||||
|
||||
# Fixed advisory set to keep fixtures stable and small.
|
||||
ADVISORIES = [
|
||||
("CVE-2024-0001", "critical"),
|
||||
("CVE-2024-0002", "high"),
|
||||
("CVE-2023-9999", "medium"),
|
||||
("CVE-2025-1234", "low"),
|
||||
("CVE-2022-4242", "none"),
|
||||
]
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
h = hashlib.sha256()
|
||||
with path.open("rb") as f:
|
||||
for chunk in iter(lambda: f.read(8192), b""):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def load_overlays() -> List[dict]:
|
||||
overlays: List[dict] = []
|
||||
with OVERLAY_PATH.open("r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
if line.strip():
|
||||
overlays.append(json.loads(line))
|
||||
overlays.sort(key=lambda o: o["overlay_id"])
|
||||
return overlays
|
||||
|
||||
|
||||
def build_records() -> List[dict]:
|
||||
overlays = load_overlays()[: len(ADVISORIES)]
|
||||
records: List[dict] = []
|
||||
for idx, overlay in enumerate(overlays):
|
||||
advisory_id, advisory_sev = ADVISORIES[idx]
|
||||
reachable = idx % 2 == 0 # alternate reachable/unreachable for UI coverage
|
||||
status = "affected" if reachable else "not_affected"
|
||||
conflict = "policy_deny_vs_scanner_affected" if overlay["verdict"] == "deny" and reachable else None
|
||||
|
||||
record = {
|
||||
"component": overlay["node_id"],
|
||||
"advisory": advisory_id,
|
||||
"advisory_severity": advisory_sev,
|
||||
"reachability": "reachable" if reachable else "unreachable",
|
||||
"status": status,
|
||||
"policy_overlay_id": overlay["overlay_id"],
|
||||
"policy_verdict": overlay["verdict"],
|
||||
"policy_severity": overlay["severity"],
|
||||
"policy_rule_id": overlay["rule_id"],
|
||||
"evidence": [
|
||||
"sbom:mock-sbom-v1",
|
||||
f"overlay:{overlay['overlay_id']}",
|
||||
],
|
||||
"conflict": conflict or "",
|
||||
"snapshot": overlay["snapshot"],
|
||||
"tenant": overlay["tenant"],
|
||||
}
|
||||
records.append(record)
|
||||
return records
|
||||
|
||||
|
||||
def write_json(records: List[dict], path: Path) -> None:
|
||||
path.write_text(json.dumps(records, indent=2, sort_keys=True))
|
||||
|
||||
|
||||
def write_csv(records: List[dict], path: Path) -> None:
|
||||
fieldnames = [
|
||||
"component",
|
||||
"advisory",
|
||||
"advisory_severity",
|
||||
"reachability",
|
||||
"status",
|
||||
"policy_overlay_id",
|
||||
"policy_verdict",
|
||||
"policy_severity",
|
||||
"policy_rule_id",
|
||||
"evidence",
|
||||
"conflict",
|
||||
"snapshot",
|
||||
"tenant",
|
||||
]
|
||||
with path.open("w", encoding="utf-8", newline="") as f:
|
||||
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
for r in records:
|
||||
row = r.copy()
|
||||
row["evidence"] = ";".join(r["evidence"])
|
||||
writer.writerow(row)
|
||||
|
||||
|
||||
def write_manifest(json_path: Path, csv_path: Path, count: int, manifest_path: Path) -> None:
|
||||
manifest = {
|
||||
"fixture": "graph-40k",
|
||||
"advisories": [a for a, _ in ADVISORIES],
|
||||
"count": count,
|
||||
"hashes": {
|
||||
"vuln-explorer.json": sha256(json_path),
|
||||
"vuln-explorer.csv": sha256(csv_path),
|
||||
},
|
||||
}
|
||||
manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True))
|
||||
|
||||
|
||||
def main() -> int:
|
||||
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
records = build_records()
|
||||
json_path = OUT_DIR / "vuln-explorer.json"
|
||||
csv_path = OUT_DIR / "vuln-explorer.csv"
|
||||
manifest_path = OUT_DIR / "manifest.json"
|
||||
|
||||
write_json(records, json_path)
|
||||
write_csv(records, csv_path)
|
||||
write_manifest(json_path, csv_path, len(records), manifest_path)
|
||||
print(f"Wrote {len(records)} records to {OUT_DIR}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
179
samples/graph/scripts/generate_canonical.py
Normal file
179
samples/graph/scripts/generate_canonical.py
Normal file
@@ -0,0 +1,179 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate canonical SAMPLES-GRAPH-24-003 fixture.
|
||||
|
||||
Outputs:
|
||||
- nodes.ndjson, edges.ndjson, overlay.ndjson
|
||||
- manifest.json with counts and SHA-256 hashes
|
||||
|
||||
Deterministic and offline-only: fixed seed, fixed timestamps, sorted output.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import random
|
||||
from pathlib import Path
|
||||
from typing import Iterable, List, Tuple
|
||||
|
||||
TENANT = "demo-tenant"
|
||||
SNAPSHOT_ID = "graph-40k-policy-overlay-20251122"
|
||||
GENERATED_AT = "2025-11-22T00:00:00Z"
|
||||
DEFAULT_NODE_COUNT = 40_000
|
||||
SEED = 424_242
|
||||
MAX_FANOUT = 4
|
||||
OVERLAY_INTERVAL = 400 # one overlay per 400 nodes -> ~100 overlays for 40k nodes
|
||||
OVERLAY_VERDICTS = ("allow", "deny", "defer")
|
||||
OVERLAY_SEVERITIES = ("none", "low", "medium", "high", "critical")
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
h = hashlib.sha256()
|
||||
with path.open("rb") as f:
|
||||
for chunk in iter(lambda: f.read(8192), b""):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def write_ndjson(path: Path, rows: Iterable[dict]) -> None:
|
||||
with path.open("w", encoding="utf-8", newline="\n") as f:
|
||||
for row in rows:
|
||||
f.write(json.dumps(row, sort_keys=True, separators=(",", ":")))
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def build_nodes(count: int, rng: random.Random) -> List[dict]:
|
||||
nodes: List[dict] = []
|
||||
for i in range(count):
|
||||
version_patch = i % 5
|
||||
purl = f"pkg:pypi/demo-{i}@1.0.{version_patch}"
|
||||
node = {
|
||||
"id": purl,
|
||||
"kind": "component",
|
||||
"name": f"demo-{i}",
|
||||
"purl": purl,
|
||||
"tenant": TENANT,
|
||||
"version": f"1.0.{version_patch}",
|
||||
"snapshot": SNAPSHOT_ID,
|
||||
}
|
||||
nodes.append(node)
|
||||
nodes.sort(key=lambda n: n["id"])
|
||||
return nodes
|
||||
|
||||
|
||||
def build_edges(nodes: List[dict], rng: random.Random) -> List[dict]:
|
||||
edges: List[dict] = []
|
||||
for idx, node in enumerate(nodes):
|
||||
if idx == 0:
|
||||
continue
|
||||
fanout = rng.randint(1, min(MAX_FANOUT, idx))
|
||||
targets_idx = rng.sample(range(idx), fanout)
|
||||
for tgt_idx in targets_idx:
|
||||
edges.append(
|
||||
{
|
||||
"source": node["id"],
|
||||
"target": nodes[tgt_idx]["id"],
|
||||
"kind": "DEPENDS_ON",
|
||||
"provenance": "mock-sbom-v1",
|
||||
"snapshot": SNAPSHOT_ID,
|
||||
"tenant": TENANT,
|
||||
}
|
||||
)
|
||||
edges.sort(key=lambda e: (e["source"], e["target"]))
|
||||
return edges
|
||||
|
||||
|
||||
def build_overlays(nodes: List[dict], rng: random.Random) -> List[dict]:
|
||||
overlays: List[dict] = []
|
||||
for idx, node in enumerate(nodes):
|
||||
if idx % OVERLAY_INTERVAL != 0:
|
||||
continue
|
||||
verdict = rng.choice(OVERLAY_VERDICTS)
|
||||
severity = rng.choice(OVERLAY_SEVERITIES)
|
||||
rule_id = f"RULE-{idx:05d}"
|
||||
overlay_id = hashlib.sha256(f"{TENANT}|{node['id']}|policy.overlay.v1".encode()).hexdigest()
|
||||
overlays.append(
|
||||
{
|
||||
"overlay_id": overlay_id,
|
||||
"overlay_kind": "policy.overlay.v1",
|
||||
"tenant": TENANT,
|
||||
"snapshot": SNAPSHOT_ID,
|
||||
"node_id": node["id"],
|
||||
"verdict": verdict,
|
||||
"rule_id": rule_id,
|
||||
"severity": severity,
|
||||
"explain": f"demo policy decision for {node['name']}",
|
||||
# bridge to bench overlay support (optional edge application)
|
||||
"source": node["id"],
|
||||
"target": f"policy:rule:{rule_id}",
|
||||
}
|
||||
)
|
||||
overlays.sort(key=lambda o: o["overlay_id"])
|
||||
return overlays
|
||||
|
||||
|
||||
def generate(out_dir: Path, node_count: int, seed: int) -> Tuple[Path, Path, Path, Path]:
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
rng = random.Random(seed)
|
||||
|
||||
nodes = build_nodes(node_count, rng)
|
||||
edges = build_edges(nodes, rng)
|
||||
overlays = build_overlays(nodes, rng)
|
||||
|
||||
nodes_path = out_dir / "nodes.ndjson"
|
||||
edges_path = out_dir / "edges.ndjson"
|
||||
overlay_path = out_dir / "overlay.ndjson"
|
||||
|
||||
write_ndjson(nodes_path, nodes)
|
||||
write_ndjson(edges_path, edges)
|
||||
write_ndjson(overlay_path, overlays)
|
||||
|
||||
manifest = {
|
||||
"snapshot_id": SNAPSHOT_ID,
|
||||
"tenant": TENANT,
|
||||
"generated_at": GENERATED_AT,
|
||||
"seed": seed,
|
||||
"counts": {
|
||||
"nodes": len(nodes),
|
||||
"edges": len(edges),
|
||||
"overlays": {"policy.overlay.v1": len(overlays)},
|
||||
},
|
||||
"hashes": {
|
||||
"nodes_ndjson_sha256": sha256(nodes_path),
|
||||
"edges_ndjson_sha256": sha256(edges_path),
|
||||
"overlay_ndjson_sha256": sha256(overlay_path),
|
||||
},
|
||||
"overlay": {
|
||||
"path": "overlay.ndjson",
|
||||
"kind": "policy.overlay.v1",
|
||||
"id_scheme": "sha256(tenant|nodeId|overlayKind)",
|
||||
},
|
||||
"inputs": {"sbom_source": "mock-sbom-v1"},
|
||||
}
|
||||
|
||||
manifest_path = out_dir / "manifest.json"
|
||||
manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True))
|
||||
return nodes_path, edges_path, overlay_path, manifest_path
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Generate canonical graph fixture (SAMPLES-GRAPH-24-003).")
|
||||
parser.add_argument("--out-dir", default="samples/graph/graph-40k", help="Output directory for fixture files")
|
||||
parser.add_argument("--nodes", type=int, default=DEFAULT_NODE_COUNT, help="Number of nodes to generate")
|
||||
parser.add_argument("--seed", type=int, default=SEED, help="Seed for deterministic generation")
|
||||
args = parser.parse_args()
|
||||
|
||||
out_dir = Path(args.out_dir).resolve()
|
||||
nodes_path, edges_path, overlay_path, manifest_path = generate(out_dir, args.nodes, args.seed)
|
||||
|
||||
print("Generated fixture:")
|
||||
print(f" nodes: {nodes_path}")
|
||||
print(f" edges: {edges_path}")
|
||||
print(f" overlay: {overlay_path}")
|
||||
print(f" manifest:{manifest_path}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user