Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ The AI-SBOM schema is embedded from the immutable schema URL:
https://shiftleftcyber.io/ai-bom/schemas/ai-sbom-1.0.0.schema.json
```

AI-SBOM author signatures are validated against the schema's JSF `signaturecore`
shape when `metadata.sbomAuthorSignature` is present.

## Installation

Use `go get` to install the package:
Expand Down Expand Up @@ -169,6 +172,7 @@ AI-SBOM examples are included under `sample-sboms/`:
- `medical-triage-ai-sbom.json`
- `missing-required-metadata.json`
- `bad-types-and-enums-ai-sbom.json`
- `non-jsf-signature-ai-sbom.json`
- `unknown-extra-properties-ai-sbom.json`

## License
Expand Down
2 changes: 1 addition & 1 deletion sample-sboms/bad-types-and-enums-ai-sbom.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"sbomDataFormatName": "AI SBOM JSON",
"sbomDataFormatVersion": "1.0.0",
"sbomAuthorSignature": {
"algorithm": "ecdsa-p256-sha256",
"algorithm": "ES256",
"value": "signature"
},
"sbomToolName": "Example Tool",
Expand Down
11 changes: 9 additions & 2 deletions sample-sboms/customer-support-ai-sbom.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@
"sbomDataFormatName": "AI SBOM JSON",
"sbomDataFormatVersion": "1.0.0",
"sbomAuthorSignature": {
"algorithm": "ecdsa-p256-sha256",
"value": "MEUCIQDV8xF3h3Tn0Qj1exampleSignatureValue"
"algorithm": "ES256",
"keyId": "contoso-ai-sbom-signing-key-2026",
"publicKey": {
"kty": "EC",
"crv": "P-256",
"x": "6BKxpty8cI-exDzCkh-goU6dXq3MbcY0cd1LaAxiNrU",
"y": "mCbcvUzm44j3Lt2b5BPyQloQ91tf2D2V-gzeUxWaUdg"
},
"value": "ybT1qz5zHNi4Ndc6y7Zhamuf51IqXkPkZwjH1XcC-KSuBiaQplTw6Jasf2MbCLg3CF7PAdnMO__WSLwvI5r2jA"
},
"sbomToolName": "Contoso AI Inventory Builder",
"sbomToolVersion": "2.4.1",
Expand Down
44 changes: 44 additions & 0 deletions sample-sboms/non-jsf-signature-ai-sbom.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"schemaVersion": "1.0.0",
"metadata": {
"bomFormat": "AI-SBOM",
"sbomAuthor": "Example Author",
"sbomVersion": "1.0.0",
"sbomDataFormatName": "AI SBOM JSON",
"sbomDataFormatVersion": "1.0.0",
"sbomTimestamp": "2026-05-18T14:22:31Z",
"sbomAuthorSignature": {
"algorithm": "ecdsa-p256-sha256",
"certificateUrl": "https://example.com/certs/signing.pem",
"value": "signature"
}
},
"system": {
"systemName": [
"Example System"
],
"systemComponents": [
{
"name": "Example Model",
"type": "ai-model"
}
],
"systemProducer": "Example Producer"
},
"models": [
{
"modelName": [
"Example Model"
],
"modelIdentifiers": [
{
"type": "custom",
"value": "example-model"
}
],
"modelProducers": [
"Example Producer"
]
}
]
}
2 changes: 1 addition & 1 deletion sample-sboms/unknown-extra-properties-ai-sbom.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"sbomDataFormatName": "AI SBOM JSON",
"sbomDataFormatVersion": "1.0.0",
"sbomAuthorSignature": {
"algorithm": "ecdsa-p256-sha256",
"algorithm": "ES256",
"value": "signature"
},
"sbomToolName": "Example Tool",
Expand Down
170 changes: 153 additions & 17 deletions schemas/ai-bom/ai-sbom-1.0.0.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,158 @@
}
}
},
"jsfSignatureCore": {
"type": "object",
"title": "JSF signaturecore",
"description": "A simple JSON Signature Format (JSF) signature object. Only signaturecore is supported; multisignature signers and signature chains are intentionally not supported yet.",
"additionalProperties": false,
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"$ref": "#/$defs/jsfAlgorithm"
},
"keyId": {
"$ref": "#/$defs/nonEmptyString",
"description": "Optional application-specific identifier for the signature key."
},
"publicKey": {
"$ref": "#/$defs/jsfPublicKey"
},
"certificatePath": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/nonEmptyString"
},
"description": "Optional sorted array of base64url-encoded X.509 certificates where the first element contains the signing certificate."
},
"excludes": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/nonEmptyString"
},
"description": "Optional JSF excludes. Verifiers should reject unexpected excludes by policy."
},
"value": {
"$ref": "#/$defs/nonEmptyString",
"description": "The base64url-encoded signature value. This value is removed before JCS canonicalization during signature verification."
}
}
},
"jsfAlgorithm": {
"oneOf": [
{
"type": "string",
"enum": [
"RS256",
"RS384",
"RS512",
"PS256",
"PS384",
"PS512",
"ES256",
"ES384",
"ES512",
"Ed25519",
"Ed448",
"HS256",
"HS384",
"HS512"
]
},
{
"type": "string",
"pattern": "^(https?://|urn:).+",
"description": "Proprietary signature algorithms must be expressed as URIs."
}
]
},
"jsfPublicKey": {
"type": "object",
"title": "JSF publicKey",
"required": [
"kty"
],
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": [
"kty",
"crv",
"x",
"y"
],
"properties": {
"kty": {
"const": "EC"
},
"crv": {
"type": "string",
"enum": [
"P-256",
"P-384",
"P-521"
]
},
"x": {
"$ref": "#/$defs/nonEmptyString"
},
"y": {
"$ref": "#/$defs/nonEmptyString"
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": [
"kty",
"crv",
"x"
],
"properties": {
"kty": {
"const": "OKP"
},
"crv": {
"type": "string",
"enum": [
"Ed25519",
"Ed448"
]
},
"x": {
"$ref": "#/$defs/nonEmptyString"
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": [
"kty",
"n",
"e"
],
"properties": {
"kty": {
"const": "RSA"
},
"n": {
"$ref": "#/$defs/nonEmptyString"
},
"e": {
"$ref": "#/$defs/nonEmptyString"
}
}
}
]
},
"metadata": {
"type": "object",
"additionalProperties": false,
Expand Down Expand Up @@ -193,23 +345,7 @@
"$ref": "#/$defs/nonEmptyString"
},
"sbomAuthorSignature": {
"type": "object",
"additionalProperties": false,
"required": [
"algorithm",
"value"
],
"properties": {
"algorithm": {
"$ref": "#/$defs/nonEmptyString"
},
"value": {
"$ref": "#/$defs/nonEmptyString"
},
"certificateUrl": {
"$ref": "#/$defs/uri"
}
}
"$ref": "#/$defs/jsfSignatureCore"
},
"sbomToolName": {
"$ref": "#/$defs/nonEmptyString"
Expand Down
5 changes: 5 additions & 0 deletions validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,11 @@ func TestValidateSBOMDataOfflineAISBOM(t *testing.T) {
path: "sample-sboms/bad-types-and-enums-ai-sbom.json",
wantValid: false,
},
{
name: "Non-JSF Signature",
path: "sample-sboms/non-jsf-signature-ai-sbom.json",
wantValid: false,
},
{
name: "Unknown Extra Properties",
path: "sample-sboms/unknown-extra-properties-ai-sbom.json",
Expand Down
Loading