# Export formats and evidence bundles

URL: /integrate/exports

Take evidence out of Foxborne in the format the next tool needs, from MCAP and Parquet to a BagIt bundle or a marked PDF case file. Every format works air-gapped, and every export is hashed, approved where the rules require it and recorded.



An export hands evidence to the people and tools that work outside Foxborne: a review board, a Foxglove session, a notebook or a MATLAB script. Every export starts from an incident. "Each is hashed, recorded in the delivery ledger and written to the audit log."

The **Exports** tab of **Integrations**, at `/app/integrations/exports`, lists every export with its status and manifest. Its tab label counts the exports waiting for approval. **New export**, at the top right, asks which incident to export and then opens that incident's export dialog.

## Formats [#formats]

The **Formats** panel lists seven formats. "Every format works air-gapped."

| Format                               | Class | What Foxborne writes, for INC-0142                                                              | Standard                                  |
| ------------------------------------ | ----- | ----------------------------------------------------------------------------------------------- | ----------------------------------------- |
| MCAP                                 | L2    | `inc-0142-r0931.mcap`                                                                           | MCAP specification                        |
| Apache Parquet                       | L2    | One file per signal family, such as `flight_controller.parquet` and `companion_journal.parquet` | Apache Parquet                            |
| CSV and JSONL                        | L2    | One `.csv` per signal family, plus `events.jsonl`                                               | RFC 4180 and JSON Lines                   |
| Original files with SHA-256 manifest | L2    | Each original under its own name, such as `14_13_19.ulg`                                        | FIPS 180-4 hashing; NIST IR 8387 practice |
| BagIt evidence bundle                | L2    | The originals under `data/originals/` and the case file under `data/case/`                      | RFC 8493                                  |
| PDF case file with CUI markings      | L1    | `inc-0142-case-file.pdf`, or `inc-0142-case-file-draft.pdf` without the reviewer's sign-off     | 32 CFR 2002.20 and DoDI 5200.48 marking   |
| MATLAB .mat v7.3                     | L2    | `inc-0142-r0931.mat`                                                                            | MathWorks format                          |

The signal families are `flight_controller`, `companion_journal`, `process_samples` and `ground_receive`, one for each source the run holds. With more than one format chosen, each format writes into its own folder: `mcap/`, `parquet/`, `csv/`, `originals/`, `bag/`, `pdf/` and `mat/`.

### PDF case file with CUI markings [#pdf-case-file-with-cui-markings]

The PDF is the report on marked pages. CUI goes in the banner and footer of every page and the designation indicator on the first, from the marking in **Settings**. Portion marks are optional, and Foxborne refuses to export an unmarked report from a CUI program.

<Figure caption="The top of a marked first page: the banner, then the designation indicator. The values are examples; yours come from your marking settings.">
  <MarkingBanner level="cui" />

  <DesignationIndicator by="Your organization" office="Your office" category="EXPT" control="FEDCON" poc="poc@example.mil" />
</Figure>

A report without the reviewer's sign-off exports stamped DRAFT on every page. The tag-manifest SHA-256 of a matching BagIt bundle is printed in the report, so the two bind together. See [CUI marking](/security/cui-marking).

### BagIt evidence bundle [#bagit-evidence-bundle]

"A standard bag: bagit.txt, the data/ payload, manifest-sha256.txt and manifest-sha512.txt, a tag manifest and bag-info.txt with the case metadata." Foxborne never writes `fetch.txt`, which would point outside the enclave.

Under RFC 8493, a bag is complete when every listed file is present and every payload file is listed. It is valid when it is complete and every checksum matches. Validate a bag before you rely on it, and never edit one: export a new one instead.

### Original files with SHA-256 manifest [#original-files-with-sha-256-manifest]

"Byte-identical originals and a sha256sum-style manifest for chain of custody. Hashes are taken at first receipt and checked again on every export." FIPS 180-4 defines SHA-256, and NIST IR 8387 recommends hashing evidence at first receipt.

### MCAP, Parquet, CSV and JSONL [#mcap-parquet-csv-and-jsonl]

MCAP replays the aligned timeline in Foxglove and ROS 2 tools, with schemas carried in the file. Foxborne writes the case ID and the SHA-256 of every source into MCAP Metadata records.

Parquet gives one table per signal family, with UTC timestamps in microseconds, for Athena, Spark or pandas. CSV serves spreadsheets and scripts, and JSON Lines serves SIEM and stream loaders. The CUI banner goes into CSV and JSONL as a header line only when the program asks for it, because many parsers stop on it.

### MATLAB .mat v7.3 [#matlab-mat-v73]

Version 7.3 is HDF5-based and handles variables of 2 GB or more, with partial loading. MATLAB's `save` defaults to version 7, which caps each variable at 2³¹ bytes, so Foxborne writes 7.3.

## Destinations [#destinations]

| **Destination**       | What the dialog says                                                                       | Boundary           |
| --------------------- | ------------------------------------------------------------------------------------------ | ------------------ |
| **Download**          | "Saved by your browser on this workstation."                                               | Inside the enclave |
| **Exports bucket**    | `s3://hfr-foxborne-exports`, "in this account. Kept for the retention period in Settings." | Inside the enclave |
| **On-premises share** | "Written to" `\\files.hfr.internal\reliability\cases` "on your network."                   | Inside the enclave |
| **Removable media**   | "An encrypted drive written at the media station, for hand carry out of the enclave."      | Leaves the enclave |

The bucket and the share shown are the example dataset's. Foxborne writes to the bucket with `PutObject` through `s3-fips.us-gov-west-1.amazonaws.com`, and to the share over SMB 3.1.1 with encryption.

## Approval [#approval]

**Approval policy**, at the top right of the **Exports** tab, opens a drawer subtitled "Checked before anything is written." Under **Rules** it lists:

* "L1 inside the enclave needs no approval. A PDF case file without the reviewer's sign-off is stamped DRAFT on every page."
* "L2 evidence inside the enclave needs one named approver, and the person who asks can never approve."
* "Anything leaving the enclave needs both named approvers: the two-person rule."
* "Approvers sign a specific manifest. If a file changes after they sign, the export stops."

An export takes the highest class among its formats. The PDF alone is L1, and any other format makes the export L2. The drawer's **Named approvers** lists the program's two approvers, and **Destinations** lists the four destinations, each marked where it leaves the enclave.

## Before you start [#before-you-start]

* You hold a role with **Export case files**: **Admin**, **Investigator**, **Reviewer** or **Auditor**. See [Roles and permissions](/security/roles).
* Enough named approvers other than you exist: one for L2 inside the enclave, two for removable media.
* For a signed-off PDF, the reviewer has approved the report.

## Export evidence [#export-evidence]

<Steps>
  <Step title="Open the export dialog">
    Open the incident and select **Export** in its header. The dialog **Export** *incident* opens with **PDF case file with CUI markings** ticked. From the **Exports** tab, **New export** does the same once you pick the incident.
  </Step>

  <Step title="Choose the formats">
    Under **Formats**, tick every format the next tool needs. Each shows its class and what it holds. The footer counts what will be written, such as "5 files and a SHA-256 manifest".
  </Step>

  <Step title="Choose the destination">
    Under **Destination**, select **Download**, **Exports bucket**, **On-premises share** or **Removable media**. **Exports bucket** is selected when the dialog opens.
  </Step>

  <Step title="Read the approval">
    **Approval** states the class and what it needs. For L2 inside the enclave, pick the **Approver**; the incident's reviewer is selected when eligible. For removable media, the dialog shows both named approvers.

    Either way, fill in **Reason**, "Who needs it, and why". The hint adds: "The approvers see this with the manifest they sign."
  </Step>

  <Step title="Set the options">
    **Remove coordinates** starts from your redaction policy: "From derived files and the case file. Originals stay byte-identical, so they keep theirs." **Portion marks** appears when the PDF or the BagIt bundle is ticked: "Mark each paragraph (CUI) or (U) in the case file."
  </Step>

  <Step title="Export or request approval">
    The button reads **Export** when no approval is needed, and **Request approval** otherwise. An export writes at once, and the toast gives its ID and manifest SHA-256.

    A request writes nothing yet. Its toast reads, for example, "EXP-0035 is waiting for" the approvers, then "Nothing is written until both approve."
  </Step>
</Steps>

## Follow an export [#follow-an-export]

The **Exports** table shows **Export**, **Case**, **Destination**, **Requested**, **Status** and **Manifest SHA-256**. **Status** reads **Completed** or **Waiting for approval**, with a line such as "1 of 2 approvals" or "No approval needed. Stamped DRAFT".

Open a row for its drawer. **Export** gives the status, class, destination, requester, reason, options and the time it was written. **Approvals** lists each approver with the time they approved, or "has not approved yet".

**Manifest** shows the exact lines the approvers sign: "Prepared at request. Approvers sign this manifest, and nothing is written until they have." Once written, **Ledger entry** opens the delivery in the ledger.

In the example dataset, EXP-0034 is a BagIt evidence bundle for INC-0143, bound for removable media. A2 prepared the pack, and the export waits with 1 of 2 approvals.

## Check what arrived [#check-what-arrived]

Copy the manifest from the drawer with **Copy**, save it beside the exported files and check every file against it.

```bash title="In the export's top folder" caption="manifest.txt holds the manifest copied from the drawer"
sha256sum -c manifest.txt
```

Each line prints the file name and `OK`. On macOS, run `shasum -a 256 -c manifest.txt` instead. Validate a BagIt bundle with a BagIt tool, and check the banner and designation indicator on the PDF.

## Retention with A4 [#retention-with-a4]

When a case moves to Approved, automation A4 builds a BagIt bag of the originals, derived MCAP and Parquet, the final PDF and both manifests. It writes the bag to WORM storage: S3 Object Lock in compliance mode in GovCloud, or on-prem WORM. A4 stays off until S3 with Object Lock is configured with egress on; see [Automations](/integrate/automations).

In compliance mode, no user can overwrite or delete a locked object version during its retention period, including the root user of the AWS account. Object Lock works only in buckets with S3 Versioning enabled.

## Troubleshoot [#troubleshoot]

**Request approval is disabled, with "Only 1 named approver can approve for you".** Fewer than two named approvers other than you exist, so the two-person rule cannot be met. "Ask an admin to name another approver."

**The export stays Waiting for approval.** Nothing is written until every named approver has signed the manifest. The drawer's **Approvals** list shows who has not approved yet.

**The PDF is stamped DRAFT.** The reviewer has not approved the report. The dialog says so: "The report has no sign-off from" the reviewer "yet, so the case file is stamped DRAFT on every page."

**A bag fails validation.** A payload file changed, went missing or was added after Foxborne built the bag. Export a new bag rather than repairing the old one.

**A variable will not save after someone edits the file in MATLAB.** MATLAB's `save` writes version 7 by default, which caps each variable at 2³¹ bytes. Save with `-v7.3`.

## Next [#next]

* [Export a case file](/investigate/export) walks through the dialog from the incident's **Report** tab.
* [Verify a report against the originals](/investigate/verify) checks excerpts against their SHA-256.
* [Egress, data classes and the delivery ledger](/integrate/egress-controls) explains L1, L2 and the ledger.
* [Retention, holds and redaction](/security/retention) sets how long originals and case files are kept.
