Skip to content

Instantly share code, notes, and snippets.

@iamwillbar
Last active August 17, 2021 16:33
Show Gist options
  • Save iamwillbar/86a38b789a2e3e04b69094c4ae1d1f6a to your computer and use it in GitHub Desktop.
Save iamwillbar/86a38b789a2e3e04b69094c4ae1d1f6a to your computer and use it in GitHub Desktop.
spdx-3.0-primer

SPDX 3.0 Primer

Principles

Domain/use case specific profiles

SPDX documents must conform to the Core profile but can opt-in to additional profiles to support the use cases they are intending to address. This layering allows SPDX to be used for different use cases (licensing, security, bill of materials, …) while allowing adopters to focus on only the use cases they care about.

Separate logical and physical models

SPDX is a single logical model but can be represented by different physical models. These physical models may be to support different formats (JSON, YAML, …) or to allow more compact representation of the logical model. A logical model should be serializable to any of the defined physical models and any of the defined physical models should be deserializable to the logical model. This allows interop between formats and ensures the constraints defined in the logical model aren’t violated.

Extend beyond software

The Core profile will not constrain itself to the software domain allowing SPDX to be used for hardware, services, data, etc. by defining new profiles for those domains.

Maximize flexibility and minimize complexity

The logical model should remain flexible allowing new use cases to be added without breaking existing use cases. Mandatory information should be kept to the minimum needed to support a use case, interactions between profiles should be minimized, and classes decomposed to allow them to be combined in new ways. Maximizing flexibility and minimizing complexity will often be at odds and we will need to make intentional trade-offs.

Profiles

Core (mostly stable)

  • Element – most classes in SPDX derive from Element which provides basic building blocks such as identification, descriptive properties (such as name), as well as provenance (such as who created the element and when)
  • Artifact – represents a specific unit in the domain (such as a piece of software, hardware, defect)
  • ContextualCollection – grouping of logically related Artifacts
  • BOM – specific type of ContextualCollection that represents a bill of materials
  • Document – a grouping of Elements with no presumption of shared context
  • Relationship – describes the relationship between Elements, supports specifying the type of relationship (such as contains, depends on, built from, etc.), and can be extended for domain-specific relationships
  • Identity – an individual, organization, or tool
  • Annotation – assertion made in relation to one or more Elements
  • ExternalReference – reference to a resource outside of the scope of the content (such as an email address, web page, package manager)
  • IntegrityMethod – independently reproducible mechanism that permits unique verification of the integrity of a grouping of data (this can be subclassed to support different verification methods)
  • ExternalMap – map of Element identifiers that are used within a Document but defined external to that Document.

Software (mostly stable)

  • File (derives from Artifact) – an individual file (this could be a physical file on disk or a logical file)
  • Package (derives from Artifact) – a grouping of zero or more files into a logical container (this could be a package manager package, a directory of files, …)
  • Snippet (derives from Artifact) – a portion of a File

Vulnerabilities (in progress)

  • Vulnerability
  • DefectResponse

Usage (early)

Logical Model

Logical model diagram

Example Document

{
  "_1": "// Commit -> CI/CD (GitHub Actions) +-> Build Artifact",
  "_2": "//                                  |-> npm Package",
  "_3": "// Caveats: Physical representation, some data excluded, readability over brevity (mostly)",

  "id": "https://api.github.com/iamwillbar/license-list-XML/sboms#repository_f4ab225",
  "_type": "Document",
  "name": "SBOM for iamwillbar/license-listXML@f4ab225",
  "createdBy": "https://api.github.com/users/iamwillbar#v3",
  "externalMap": [
      {
          "externalID": "https://api.github.com/users/iamwillbar#v3",
          "elementURL": "",
          "verifiedUsing": [
              {
                  "": ""
              }
            ]
      }
  ],
  "created": "2021-05-17T12:00:00.000Z",
  "specVersion": "3.0-DRAFT",
  "profiles": ["core", "software"],
  "dataLicense": "CC0",
  "elements": [
    {
        "id": "#commit_f4ab225",
        "_type": "Package",
        "comment": "Fix merge",
        "artifactUrl": "pkg:github/iamwillbar/license-list-XML@..."
    },
    {
        "_type": "Relationship",
        "from": "#commit_f4",
        "to": ["#object_d4e5f6"],
        "relationshipType": "CONTAINS"
    },
    {
        "id": "#object_d4e5f6",
        "_type": "File",
        "name": "Makefile",
        "contentType": "text/plain",
        "comment": "Use local FSF Schema to fix travis-ci errors (spdx#1177)",
        "verifiedUsing": [
            {
                "_type": "Hash",
                "algorithm": "SHA512",
                "hashValue": "some_really_long_string"
            }
        ]
    },
    {
        "id": "#actions_runs_584753262",
        "_type": "ContextualCollection",
        "name": "Test4",
        "summary": ".github/workflows/validate.yaml #2: Pull request #2 opened by goneall",
        "createdBy": "https://api.github.com/users/goneall#v4",
        "created": "2021-02-20T12:00:00.000Z",
        "relationships": [
            {
                "relationshipType": "PRODUCED",
                "to": [
                    "#actions_artifacts_238748923748",
                    "https://registry.npmjs.com/sboms#[email protected]"
                ],
                "completeness": "INCOMPLETE"
            }
        ]
    },
    {
        "id": "#actions_artifacts_238748923748",
        "_type": "Package",
        "name": "license-list-XML 3.2",
        "createdBy": "https://api.github.com/users/goneall#v4",
        "created": "2021-02-20T12:00:00.000Z",
        "rootElement": "license#...",
        "elements": [
            ""
        ]
    },
    {
        "id": "https://registry.npmjs.com/sboms#[email protected]",
        "_type": "Package",
        "name": "[email protected]",
        "createdBy": "https://api.github.com/users/goneall#v4",
        "created": "2021-02-20T12:00:00.000Z",
        "specVersion": "3.0-DRAFT-2",
        "profiles": ["core", "defect"]
    },
    {
        "id": "https://api.github.com/users/iamwillbar#v3",
        "_type": "Person",
        "name": "William Bartholomew",
        "email": "[email protected]",
        "verifiedUsing": [
            {
                "_type": "SSH",
                "public": "SHA256:LouY6XvSZTCVQ9LBkEItEHZkxzqDZa38DbxdfQEduE8"
            },
            {
                "_type": "GPG",
                "keyId": "31BF1A3D538DB4FE"
            },
            {
                "_type": "X509",
                "publicKey": ""
            }
        ],
        "externalReferences": [
            {
                "externalReferenceType": "TWITTER",
                "locator": "@iamwillbar"
            }
        ]
    }
  ]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment