--- title: "Attachment Management" slug: "attachment-management" updated: 2024-09-12T18:29:42Z published: 2024-09-12T18:29:42Z canonical: "docs.oscal.io/attachment-management" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.oscal.io/llms.txt > Use this file to discover all available pages before exploring further. # 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](/v1/docs/scenarios) for usage examples.