Attachment Management

Attachment Methods and Endpoints allow the management of attachments to OSCAL content, including management of the associated back matter resource content. The resource-uuid is the UUID value assigned to the resource within the OSCAL content.

The following methods are available for managing attachments associated with an OSCAL file.

Methods and Endpoints Description
GET /{model-name}/{content-uuid}/attachment Lists all the attachments of the identified OSCAL file stored within the repository.
POST /{model-name}/{content-uuid}/attachment Adds a new attachment to the repository, scoped to the identified OSCAL file and assigns an attachment ID to it.
GET /{model-name}/{content-uuid}/attachment/{resource-uuid} Gets a specific attachment.
PUT /{model-name}/{content-uuid}/attachment/{resource-uuid} Replaces a specific attachment with the file provided.
DELETE /{model-name}/{content-uuid}/attachment/{resource-uuid} Removes a specific attachment.
GET /{model-name}/{content-uuid}/attachment/{resource-uuid}/resource Retrieves the back-matter resource details about the attachment.
PUT /{model-name}/{content-uuid}/attachment/{resource-uuid}/resource Replaces the back-matter resource details about the attachment.

Prefer rlink Over base64

One goal of the OSACAL REST OpenAPI specification's approach to attachment handling is to allow the client to request OSCAL content without attachments, then govern which attachments it wants and when.

This flexibility is only possible with rlink attachments. Any base64 attachments are transmitted with the OSCAL content, often increasing the total payload by an order of magnitude or more.

The specification is designed to honor both rlink and base64 attachments, while giving preference to rlink. Specifically:

  • Any OSCAL content containing base64 attachments and sent to the implementation via POST /{model-name} or PUT /{model-name}/{content-uuid} is handled as-is.
  • GET /{model-name}/{content-uuid}/attachment/{resource-uuid} returns an attachment regardless of whether the OSCAL content handles it as an rlink or base64.
  • POST /{model-name}/{content-uuid}/attachment/{resource-uuid} is always added as an rlink attachment.
  • PUT /{model-name}/{content-uuid}/attachment/{resource-uuid} is always handled as an rlink attachment, even if the original attachment was base64. In other words, if this method is updating a base64 attachment, it will remove the base64 field and handle the attachment as an rlink from that point forward.

GET /{model-name}/{content-uuid}/attachment

GET /{model-name}/{content-uuid}/attachment returns a list of all back matter resources within the referenced OSCAL content. This list is always returned as JSON.

Each item in the list must include its resource UUID (resource-uuid) as well as the content identifier (content-uuid), which the client can later use for endpoints that require it.

The implementation should filter this list to only those attachments accessible by the asserted identity.

NOTES:

  • The implementation should omit the base64 field from each list item to protect performance.
  • With the exception of base64 (above), the implementation should return all other fields present for each item in the list, consistent with any fine-grain access control mechanisms the implementation may have in place.
  • The OSCAL specification only requires the resource's uuid field in the resource assembly. All other fields are optional.

all items in the the OSCAL content's back matter (//back-matter/resources).

Example

GET /catalog/0480f2a8-75e2-452f-985f-6578b001f07a/attachment returns:

{
   "attachment-list": [
      {
         "content-uuid": "0480f2a8-75e2-452f-985f-6578b001f07a",
         "resource-uuid": "0894bda3-f1c6-4b3e-92c9-ba5ba0c2fc2e",
         "title": "Policy Title",
         "description" : "A description of the policy document",
         "rlink" : [
            {
                "href" : "/0480f2a8-75e2-452f-985f-6578b001f07a/attachment/0894bda3-f1c6-4b3e-92c9-ba5ba0c2fc2e",
                "media-type": "application/pdf",
           }            
         ],
         "remarks": "string"
      }, 
      {
         "content-uuid": "0480f2a8-75e2-452f-985f-6578b001f07a",
         "resource-uuid": "1af7d6a3-2eb0-427a-8b81-69bb37c81076",
         "title": "Training Title",
         "rlink" : [
            {
                "href" : "/0480f2a8-75e2-452f-985f-6578b001f07a/attachment/1af7d6a3-2eb0-427a-8b81-69bb37c81076",
                "media-type": "application/ppt",
           }            
         ]
      }
   ]
}

POST /{model-name}/{content-uuid}/attachment

POST /{model-name}/{content-uuid}/attachment attaches a new file to the OSCAL content. Upon receipt the implementation must:

  1. store the file
  2. generate a new v4 or v5 UUID for the attachment
  3. create a new resource entry in the associated OSCAL content for the attachment
  4. assign the generated UUID as the resource entry's UUID
  5. insert an rlink entry into the resource entry with the href value set to /{content-uuid}/attachment/{resource-uuid}

NOTES:

  • If needed, the client can then use PUT /{content-uuid}/attachment/{resource-uuid}/resource to update additional fields in the resource entry.
  • The implementation is responsible for storing the attachment and maintaining the association with the OSCAL content and resource UUID. For example in a raw file system approach, the implementation could use `./attachments/{resource-uuid}/

GET /{model-name}/{content-uuid}/attachment/{resource-uuid}

GET /{model-name}/{content-uuid}/attachment/{resource-uuid} directs the implementation to deliver a specific attachment. Upon receipt of this request, the implementation must:

  1. check for the existence either:
  • a base64 field; or
  • an rlink field where the href points to an attachment within the implementation.
  1. Respond to the request with the attachment as the only payload

NOTES:

  • The implementation may check for base64 and rlink fields in either order.
  • Where both base64 and rlink fields exist, the implementation may define how it resolves the conflict.
  • When returning base64 the implementation should first decode the content back it its binary format.

PUT /{model-name}/{content-uuid}/attachment/{resource-uuid}

PUT /{model-name}/{content-uuid}/attachment/{resource-uuid} directs the implementation to replace an existing attachment with a revised version. When received, the implementation must:

  1. store the file
  2. insert or update the rlink entry into the resource entry with the href value set to /{content-uuid}/attachment/{resource-uuid}
  3. remove the base64 field if present.

NOTES:

  • While it is possible for OSCAL content to be received with pre-existing base64 attachments, any updated attachment should be handled by the implementation as an rlink to protect performance. \
  • The implementation should enforce access control and only update the attachment when the asserted identity has explicit permission to do so.

DELETE /{model-name}/{content-uuid}/attachment/{resource-uuid}

DELETE /{model-name}/{content-uuid}/attachment/{resource-uuid} directs the implementation to remove the referenced attachment from the local datastore. Upon receipt of this request, the implementation must:

  1. identify and delete the attachment itself; and
  2. delete the resource entry within the OSCAL content.

NOTES:

  • If the deleted content is subject to record retention policies, litigation holds, or other requirements, the implementation may either:
    • block the delete and return an error; or
    • render the content unavailable via the API, but otherwise retain it as required.
  • If the deleted content still exists within system backups, the implementation's owning organization may handle those backups in accordance with organizational requirements.
  • If deleted records are retained for any reason, the organization should take reasonable steps to notify the user of retention.
  • The implementation should enforce access control and only delete content when the asserted identity has explicit permission to do so.

GET /{model-name}/{content-uuid}/attachment/{resource-uuid}/resource

GET /{model-name}/{content-uuid}/attachment/{resource-uuid}/resource directs the implementation to deliver specific resource details from the OSCAL content's back-matter. Upon receipt of this request, the implementation must:

  1. find the referenced resource in the OSCAL content's back-matter.
  2. return the resource entry exactly as it appears in the JSON version of the OSCAL content.

NOTES:

  • This endpoint only returns JSON content.
  • Unlike GET /{model-name}/{content-uuid}/attachment, the implementation must include the base64 field in the returned content.
  • The implementation should enforce access control and only delete content when the asserted identity has explicit permission to do so.

PUT /{model-name}/{content-uuid}/attachment/{resource-uuid}/resource

PUT /{model-name}/{content-uuid}/attachment/{resource-uuid}/resource directs the implementation to replace an existing resource entry with a revised version. Upon receipt of this request, the implementation must:

  1. validate the syntax
  2. find the referenced resource
  3. replace the referenced resource with the content provided

NOTES:

  • if the uuid in the content does not match the resource-uuid in the endpoint, the implementation should raise an error, but may elect to apply other handling.
    • If the implementation allows a uuid with a different value, the implementation should then require future endpoint calls to use the revised uuid value and consider the prior uuid value to be invalid.
  • The implementation should enforce access control and only delete content when the asserted identity has explicit permission to do so.

Usage Examples

See Scenarios for usage examples.