
Formato NDJSON di grafo di attacco neutrale rispetto al fornitore con tassonomia di nodi/archi, mappature AWS/GCP/Azure, regole di derivazione e un database di esposizione per strumenti di sicurezza offensiva.
Un attack graph che puoi davvero passare a qualcun altro.
Ogni prodotto di sicurezza basato su grafi tiene il tuo attack graph bloccato dentro un archivio proprietario. Non puoi esportarlo, confrontare due scansioni, metterlo sotto controllo di versione o interrogarlo con qualcosa di diverso dall'interfaccia del fornitore. Quando l'engagement finisce, il grafo se ne va con esso.
RAGE è un formato di file vendor-neutral per grafi di sicurezza offensiva, più il corpus aperto che gli dà significato: la tassonomia di nodi e archi, le mappature e le ricette di raccolta AWS/GCP/Azure, e le regole di derivazione degli archi. Un file. Qualsiasi linguaggio. Pronto all'uso.
Stato: bozza iniziale (spec_version: 0.1). Non ancora stabile; feedback e pull request
sono benvenuti.
Un grafo RAGE è un singolo file NDJSON (un oggetto JSON per riga). La riga 1 è il manifest;
ogni altra riga è un record etichettato con kind.
{"kind":"manifest","spec_version":"0.1"}
{"kind":"node","node_id":"gcp|proj-a|gcp:iam:service-account|sa-deploy","node_type":"ServiceAccount"}
{"kind":"node","node_id":"gcp|proj-a|gcp:iam:service-account|sa-admin","node_type":"ServiceAccount"}
{"kind":"node","node_id":"gcp|proj-a|gcp:storage:bucket|bucket-crown","node_type":"ObjectStorage"}
{"kind":"edge","type":"CanImpersonate","source":"gcp|proj-a|…|sa-deploy","target":"gcp|proj-a|…|sa-admin"}
{"kind":"edge","type":"CanReadData","source":"gcp|proj-a|…|sa-admin","target":"gcp|proj-a|…|bucket-crown"}
{"kind":"finding","resource_id":"gcp|proj-a|…|bucket-crown","severity":"critical"}
Una catena a due salti che rispetta la tassonomia: sa-deploy può impersonare sa-admin
(un arco da identità a identità), che può leggere il bucket crown-jewels (da identità a
storage).
Leggilo in tre righe di qualsiasi linguaggio:
for line in open("graph.rage.ndjson"): rec = json.loads(line) # switch on rec["kind"]
jq 'select(.kind=="edge" and .type=="CanImpersonate")' graph.rage.ndjson
| kind | campi richiesti | scopo |
|---|---|---|
manifest | spec_version | riga 1: versione + counts/scope/producer opzionali |
node | node_id, node_type | una risorsa o identità |
edge | source, target, type | una capacità o relazione |
fact | fact_id | un'osservazione normalizzata da cui è stato costruito il grafo |
evidence | evidence_id, content_hash | ricevuta a prova di manomissione (un'operazione API/raccolta) |
finding | resource_id, severity | un'esposizione |
surface / path | - | tipi di estensione opzionali |
La catena di provenienza è evidence (API) poi fact poi edge/finding, collegati da id.
node_type e il type degli archi provengono dai registri aperti in vocab/. Tutto
il resto è arricchimento opzionale. Vedi spec/format.md.
Il formato è solo metà di RAGE. L'altra metà è il corpus condiviso che dà significato ai tipi,
così due strumenti indipendenti concordano su cosa sia CanImpersonate e dove una credenziale
possa trapelare:
vocab/): 105 tipi di nodo in 10 classi, 80 tipi di arco in 9 categorie.providers/): 219 tipi di risorsa nativi su AWS, GCP e Azure, ciascuno mappato a un tipo di nodo generico con le chiamate che lo enumerano.rules/): il contratto in rules/derivation.json più oltre 2.400 regole eseguibili match/where/emit su come vengono derivati gli archi.exposure-db/): 1.049 siti di leak di credenziali mappati, ciascuno legato all'arco RAGE che emette e alla ricetta che lo legge.L'intero corpus, leggibile dall'uomo, è in TAXONOMY.md.
RAGE è progettato perché chiunque possa produrlo o consumarlo. Il formato è il contratto; gli strumenti sono intercambiabili, e la lista è aperta.
RAGE è il formato, Thunderstorm lo produce, Blaze lo esplora.
| implementazione | ruolo | dove |
|---|---|---|
| Thunderstorm | produttore: collector cloud read-only + motore di derivazione | github.com/ustayready/thunderstorm |
| il tuo strumento qui | produttore o consumatore | emetti o leggi .rage.ndjson e interopera |
Qualsiasi cosa legga o scriva il formato parla RAGE. Produttori e motori conformi si
conformano ai registri in questo repository; RAGE non dipende da nessuno di essi. Vedi
COMPATIBILITY.md per come le implementazioni si ancorano a una spec_version.
spec/format.md - il formato di trasmissione (record, grammatica di node_id, .rage.zip, scope).spec/edges.md - semantica degli archi: direzione/traversal, state, weight/walkable, canonicalizzazione.spec/rules.md - semantica di valutazione delle regole: fixpoint, state-merge, il catalogo delle funzioni.schemas/ - JSON Schema per tutti gli 8 tipi di record.vocab/ - node-types.json + edge-types.json + conditions.json.rules/derivation.json - il contratto di derivazione degli archi (per arco: condizioni + permessi/trigger per cloud).rules/{derived,explicit}/** - il corpus eseguibile di oltre 2.400 regole match/where/emit.providers/{aws,gcp,azure}.json - mappature da nativo a generico + ricette di nodi + ricette di fact.exposure-db/{aws,gcp,azure}.json + vocabulary.json - l'Exposure DB (1.049 siti di leak).TAXONOMY.md - l'intero corpus, leggibile dall'uomo (generato dai registri sopra).tools/rage_engine.py - il motore di regole di riferimento: esegue il corpus di regole derivate su un grafo fino a un fixpoint.validate/ - validatori di record (JSON Schema completo), registri, stringhe di permessi e corpus di regole.examples/ - un grafo valido minimale che esercita tutti gli 8 tipi di record.python3 -m venv .venv && ./.venv/bin/pip install -r requirements.txt
./.venv/bin/python validate/rage_validate.py examples/minimal.rage.ndjson # full JSON Schema + refs
./.venv/bin/python validate/check_registries.py # registry integrity
./.venv/bin/python validate/check_rules.py # rule corpus vs vocab
La CI esegue tutto quanto sopra più un gate no-drift di gen_taxonomy.
Apache-2.0 (vedi LICENSE).