EasyDynamics / oscal-rest

An initial OpenAPI definition of an OSCAL REST API.
Creative Commons Attribution Share Alike 4.0 International
38 stars 13 forks source link

Usage of $ref to point to external OSCAL Catalogs causing errors #104

Open pjavan opened 2 months ago

pjavan commented 2 months ago

Describe the problem Current usage of $ref is attempting to point to external OSCAL schemas that are not OpenAPI formatted. $ref attempts to import the specific OpenAPI schema and results in an error in various tools and number of the sources are valid JSON schemas, but not OpenAPI.

Example Starting at Line 13623. In this example, the reference must be a valid OpenAPI formatted to be imported correctly.

  "components": {
    "schemas": {
      "OSCALCatalog": {
        "type": "object",
        "properties": {
          "catalog": {
            "$ref": "https://raw.githubusercontent.com/EasyDynamics/OSCAL/json-schema-ref-by-path/json/schema/oscal_catalog_schema.json#/definitions/assembly_oscal-catalog_catalog"
          }
        }

Additional context Tested in VSCode with OpenAPI (Swagger) Editor and Doc360 API Import resulted in reference error. These components are being referenced in other areas without warning but suspect any real schema resolution is not working properly.

        "requestBody": {
          "required" : true,
          "content" : 
            {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/OSCALCatalog"
                }
              },

Proposed solution Instead of Reference Object being used, External Documentation Object should be used to reference an external, non OpenAPI JSON file.

Proposed reference to external documentation:

  "components": {
    "schemas": {
      "OSCALCatalog": {
        "type": "object",
        "properties": {
            "externalDocs": {
                "type": "object",
                "properties": {
                    "description": {
                        "type": "string",
                        "default": "OSCAL JSON Catalog Schema"
                    },
                    "url": {
                        "type" :"string",
                        "format": "uri",
                        "default": "https://raw.githubusercontent.com/EasyDynamics/OSCAL/json-schema-ref-by-path/json/schema/oscal_catalog_schema.json#/definitions/assembly_oscal-catalog_catalog"
                    }
                },
                "required": ["url"]        
            }
          }
        },
fulldev0418 commented 2 months ago

The issue arises because the OpenAPI specification expects $ref to point to OpenAPI-formatted schemas, but the current usage is referencing external OSCAL JSON schemas that are not in OpenAPI format. This causes errors in various tools that expect OpenAPI-compliant references.

To resolve this issue, we need to modify the schema definitions in the components section. Instead of using $ref to directly reference external schemas, we should define the schema structure within the OpenAPI document and use externalDocs to provide a link to the full OSCAL schema for additional information.

Here's where you should update the code:

  1. Starting at line 13623, replace the OSCALCatalog schema definition with:
"OSCALCatalog": {
  "type": "object",
  "properties": {
    "catalog": {
      "type": "object",
      "description": "OSCAL Catalog",
      "externalDocs": {
        "description": "Full OSCAL Catalog Schema",
        "url": "https://raw.githubusercontent.com/EasyDynamics/OSCAL/json-schema-ref-by- path/json/schema/oscal_catalog_schema.json#/definitions/assembly_oscal-catalog_catalog"
      }
    }
  }
}
  1. Similarly, update the other schema definitions (OSCALProfile, OSCALComponentDefinition, etc.) following the same pattern.
  2. For the XML versions of schemas (like OSCALCatalogXML), we can use:
"OSCALCatalogXML": {
  "type": "object",
  "description": "OSCAL Catalog in XML format",
  "externalDocs": {
    "description": "Full OSCAL Catalog Schema",
    "url": "https://raw.githubusercontent.com/EasyDynamics/OSCAL/json-schema-ref-by-path/json/schema/oscal_catalog_schema.json#/definitions/assembly_oscal-catalog_catalog"
  },
  "xml": {
    "name": "catalog"
  }
}

By making these changes, we are defining the basic structure of the schemas within the OpenAPI document while providing links to the full OSCAL schemas for reference. This approach can resolve the issues with tools that expect OpenAPI-compliant references while still maintaining the connection to the detailed OSCAL schemas.

bluepinepcs810 commented 2 months ago

Instead of Reference Object being used, External Documentation Object should be used to reference an external. In order to do it, you have to add some domain approved hostnames in the OpenAPI file. In OpenAPI, specifying domain-approved hostnames can be done in the servers section of the specification. The servers section lists one or more server URLs that your API can be accessed through, which effectively represent the domain-approved hostnames.

You have to add your external object url (https://raw.githubusercontent.com/EasyDynamics/OSCAL) in the server list of OpenAPI file. You can see the server tag in the head part of file.