
Svaki OSCAL validator tvrdi da „validira OSCAL“. Gotovo nijedan ne može vam reći što ta rečenica znači.
NIST-ovi OSCAL modeli napisani su u Metaschemi: osam korijenskih modula plus zajednički uvozi, tisuće redaka XML-a koji ne definiraju samo oblik dokumenta nego i semantiku: rječnike dopuštenih vrijednosti, pravila jedinstvenosti, indekse unakrsnih referenci, zahtjeve kardinalnosti. JSON Schema hvata oblik. Semantika je ono gdje dokumenti o usklađenosti zapravo griješe i gdje se „validiramo OSCAL“ tiho pretvara u „validiramo dio OSCAL-a, nismo sigurni koji“.
Mi smo htjeli biti sigurni koji. Zato smo svoj validator izgradili onako kako biste revidirali sustav: krenuti od izvora, popisati sve i obračunati svaku pojedinu stavku.
Prva odluka bila je ona važna: mjerodavni su izvori NIST-a, a ne referentna implementacija. Fiksirali smo usnistgov/OSCAL na commitu 21403b4a… (v1.2.2), pohranili svaki bajt Metascheme doslovno, sa SHA-256 sažecima, i tretirali cijenjeni Java OSCAL CLI kao ono što on zapravo jest: komparator koji treba unakrsno ispitati, a ne istinu koju treba kopirati. (Između ostaloga, on sadrži ugrađene veze za OSCAL 1.2.1; može obrađivati dokumente 1.2.2, ali ne govori 1.2.2.)
Zatim smo leksički popisali svako pojavljivanje ograničenja u fiksiranim izvorima. Ne vrste ograničenja, nego pojavljivanja, identificirana datotekom i retkom, tako da se dva ograničenja koja slučajno dijele ID nikada ne stope u jedno. Zbroj je iznosio 348.
Za svako pojavljivanje naša izgradnja mora imati točno jednu od tri presude, što provodi generator koji pri svakom pokretanju ponovno izračunava knjigu:
Neobračunato: nula.
Ta posljednja skupina, isključenja, bila je ono gdje je postalo zanimljivo.
Kada provjeravate 348 ograničenja jedno po jedno, nalazite stvari. Tri naša isključenja nedostaci su u samim izvorima NIST-a:
oscal_mapping-common_metaschema.xml u retku 657 ograničava zastavicu (flag) koja je definirana pet redaka ranije i na koju se zatim ništa ne poziva. Nijedan dokument koji može postojati ne nosi tu zastavicu. Ograničenje je nemoguće zadovoljiti.inventory-item primjenjuje se samo kada je @type jednak software, hardware ili service, ali inventory-item uopće ne deklarira zastavicu type. (Njegov susjed, asset-id, i sam je zakomentiran u izvoru.) Predikat se nikada ne može podudarati.with-child-controls. Čovjek koji čita izvor vidi ih; kompilirana shema ih nikada ne provodi. Sva tri nalaza prijavljena su uzvodno: usnistgov/OSCAL#2254, #2255, #2256.I revizija je sjekla u oba smjera: naš vlastiti evaluator imao je pogrešku zbog koje su se ograničenja usmjerena na zastavice (poput dopuštenih vrijednosti za action/@type) kompilirala u popis, ali se tiho nikada nisu aktivirala. Nismo je pronašli slučajno: kontrolna točka zatvaranja odbila je prihvatiti dokaze za ta dva pojavljivanja, što je upravo onaj način zakazivanja koji cijeli sustav treba razotkriti.
Tvrdnja da „referentna implementacija nešto propušta“ samo na temelju pregleda izvora upravo je vrsta nedokazane tvrdnje koju ovaj projekt želi iskorijeniti. Zato smo preuzeli Java OSCAL CLI 3.2.0 s Maven Centrala, provjerili mu sažetak i pokrenuli oba validatora nad obitelji testnih primjera čiji polazni dokumenti čisto prolaze na objema stranama, tako da se svako neslaganje može pripisati jednoj ubačenoj promjeni.
OSCAL 1.2.2 promijenio je, osim povećanja verzija, točno dva ograničenja (oba u modelu SSP). Java CLI, koji ima ugrađene veze za 1.2.1, na pogrešnoj je strani svake uočljive posljedice:
rel="validation" krši 1.2.2. Java: valjano, izlazni kôd 0.rel="validated-by" prema 1.2.2 je u redu (ograničenje je izbrisano). Java: nevaljano.responsible-role bez neobaveznog party-uuid prema 1.2.2 je u redu; NIST je predikat dodao upravo kako bi to ispravio. Java javlja pogrešku, doslovno, Key reference [null] not found.Zatim jedan slučaj koji uopće nije povezan s razlikom u verzijama: katalog čiji metapodatak action deklarira "type": "invented-type", što je zabranjeno u retku 877 Metascheme za metapodatke i u 1.2.2 i u izvorima 1.2.1 koje Java ima ugrađene. Java ga proglašava valjanim, i u JSON-u i u XML-u. Ograničenje cilja zastavicu; ograničenja usmjerena na zastavice koja se tiho ne aktiviraju upravo su klasa pogrešaka koju je naša kontrolna točka potpunosti uhvatila u našem vlastitom evaluatoru. Referentna implementacija ima istu klasu pogreške, a nema kontrolnu točku zatvaranja koja bi je uhvatila. Prijavili smo je uzvodno kao metaschema-framework/oscal-cli#279. (Klasu smo mapirali mehanički: točno 2 od 200 pojavljivanja dopuštenih vrijednosti ciljaju zastavice, a jedini član razine pogreške jest onaj koji smo stvarno testirali. Nema netestiranog ostatka.)
I trenutak iskrenosti, jer je pokretanje sjeklo u oba smjera: naš je validator odbio NIST-ov vlastiti katalog SP 800-53 rev5. Dvadeset pogrešaka, sve jedan nedostatak: naš evaluator indeksa tretirao je nedostajuće neobavezno polje ključa kao kršenje, dok specifikacija Metascheme kaže da je to null ključ. Java je prihvatila datoteku; mi smo pogriješili; ispravili smo to isti dan i 800-53 sada se čisto validira. Pokretanje je kasnije uhvatilo i drugi slučaj: nastavili smo provoditi OSCAL-ov rječnik vrsta radnji čak i kada je action/@system deklarirao prilagođeni URI, a to je upravo segmentacija po organizacijama koju traže NIST-ove vlastite napomene. I to je ispravljeno. Diferencijalni okvir koji uvijek pronalazi samo pogreške druge strane nije okvir za testiranje, nego marketing.
(Također pod „obje strane“: nijedan razrješivač nije semantički validirao vlastiti izlaz. Javin resolve-profile bez problema će zapisati katalog koji Javin vlastiti validate zatim odbija, a naš je radio isto: imao je kontrolu na razini sheme, ali ne i na razini semantike. Naš sada odbija zapisati semantički nevaljana razrješenja; Java to još uvijek ne može, jer zatvaranje te rupe zahtijeva semantički sloj kojem vjerujete.)
Druga stvar koja nedostaje postojećim alatima: OSCAL dokumenti ne žive sami. Rezultat procjene uvozi plan procjene, koji uvozi SSP, koji uvozi profil, koji se razrješava prema katalozima. Dokumentacija modela puna je odnosa koje nijedan validator jedne datoteke ne može provjeriti: „cilj ovog nalaza mora se razriješiti u izjavu u polaznoj osnovi“, „ovaj POA&M mora identificirati svoj sustav“.
Zato smo izgradili validaciju među dokumentima koja te veze stvarno razrješava. Zatražite od nje da provjeri SSP i ona će razriješiti uvezenu polaznu osnovu kroz cijeli cjevovod razrješavanja profila (prema nacrtu specifikacije) sve do kataloga, izračunati odabrani skup kontrola i reći vam:
{
"ruleId": "SSP-003.b",
"severity": "warning",
"path": "/…/implemented-requirements/1/control-id",
"message": "implemented control 'ac-99' is not supplied by the resolved import-profile 'file:///…/baseline.json'"
}
Uz jedno ključno pravilo dizajna: te provjere odnosa tumačenja su dokumentirane proze i tako ih i tretiramo: isključene su prema zadanim postavkama, upozorenja su, a ne pogreške, opseg razrješavanja svakog polja fiksiran je na njegov izvorni redak, a sve što se samo može zaključiti isključeno je poimence. Kada norma ostavlja prostor, validator ne bi smio blefirati. (Naš omiljeni primjer: specifikacija POA&M-a kaže da je potreban uvoz SSP-a ili system-id, „Both may be present.“ Zato upozoravamo samo kada ne postoji nijedno. Nema izmišljenog isključivog ILI.)
Zato što dokumenti žive u preglednicima, serverless funkcijama, CLI-jevima i bazama podataka, a mi smo htjeli jedan validator u svima njima, a ne JVM sidecar uz svaki. Validatori su unaprijed kompilirani samostalni Ajv moduli: običan generirani JavaScript, bez kompilacije shema tijekom izvođenja, s izlazom stabilnim na razini bajtova. Isti kôd koji pokreće naše površine za validaciju izvodi se nepromijenjen u kartici vašeg preglednika i u našem CLI-ju. A determinizam nije samo operativna pogodnost: on je ono što uopće omogućuje dokaze fiksirane sažecima.
import { createDiagnosticsOscalProcessor } from "@secani/oscal/diagnostics";
const result = createDiagnosticsOscalProcessor({ maxIssues: 50 }).validate(doc);
validate --resolve-imports --interpretive all)Cjelovito tehničko izvješće (model mjerodavnosti, zatvaranje potpunosti, tablica diferencijalnih potvrda i ono što namjerno ne tvrdimo) nalazi se u dokumentaciji validatora. Validator je u privatnoj pripremnoj fazi uoči izdavanja otvorenog koda; hostirani API za validaciju danas izlaže razinu sheme, a semantički sloj slijedi.
Secani povezuje opsege, dokaze, zadatke i AI agente u jednom zajedničkom radnom prostoru.
OLIR pruža sadržaj mapiranja i upravljanje njime. OSCAL pruža strojno čitljivu strukturu za upotrebu tih mapiranja u analizi nedostataka, ponovnoj upotrebi dokaza i tijekovima rada za procjenu utjecaja promjena.
OSCAL pretvara dokumente o usklađenosti u strukturirane podatke: osam modela dokumenata, tri formata i ekosustav koji postaje standard za regulativu.
S RFC-0024 i Consolidated Rules 2026 FedRAMP uvodi obvezu strukturiranih autorizacijskih podataka. Rokovi su postupni – smjer je nedvosmislen.