# Connect a storage source

URL: /collect/sources

Point Foxborne at the buckets, shares and directories where your logs already land, so new files arrive without an upload. Each source is read-only, and a connection test checks that before you add it.



A source is where Foxborne reads evidence without an upload: an object store, a file share or an endpoint your test rigs push to. Foxborne hashes each file it reads, matches it to a vehicle and a time, then assembles the runs.

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

* You need the **Admin** role. Only admins manage sources and collectors.
* Create a read-only credential on the storage side first: an IAM role, an access key, a managed identity, a service account or an SFTP account. Each type's page lists what it needs.
* The Foxborne worker must reach the location. The connection test starts from there.

## Add a source [#add-a-source]

<Steps>
  <Step title="Open Sources">
    Select **Sources** in the sidebar, under **Data**. The **Connections** tab lists each source with its **Location**, **Access**, **Last sync**, **Today** and **Status**. Select **Add source**.
  </Step>

  <Step title="Choose a type">
    The **Add a source** dialog reads &#x2A;*Foxborne reads from storage you already run. It never writes to it.** Pick a card, then select **Continue**.

    | Group          | Type                      | Description                                                                                          |
    | -------------- | ------------------------- | ---------------------------------------------------------------------------------------------------- |
    | Object storage | **Amazon S3**             | A bucket or prefix in your account, including GovCloud. Read through an IAM role you create.         |
    | Object storage | **S3-compatible storage** | MinIO, Ceph or any S3 API inside your network. Read-only access key.                                 |
    | Object storage | **Azure Blob Storage**    | A container in your subscription, including Azure Government. Managed identity.                      |
    | Object storage | **Google Cloud Storage**  | A bucket read through a service account with the viewer role.                                        |
    | File shares    | **SFTP**                  | A directory on a ground station or log server, polled on a schedule.                                 |
    | File shares    | **SMB or NFS share**      | A network share mounted read-only on the Foxborne worker.                                            |
    | Vehicles       | **Companion collector**   | A read-only service on each companion computer. Samples processes and journal units, spools offline. |
    | Vehicles       | **MAVLink receiver**      | Listens to telemetry on the ground and records every receipt with its own clock.                     |
    | Automation     | **Ingest API**            | Your test rigs and pipelines push signed bundles with a scoped service token.                        |

    **Companion collector** has no details step. It takes you to the **Vehicle collectors** tab, where you enroll each vehicle, as [Install and enroll the collector](/collect/collector/install) describes.
  </Step>

  <Step title="Fill in the details">
    Enter a **Name**, which is required, for example **Fleet log archive, west range**. Then fill in the three fields for the type:

    | Type                  | Fields                                                                    | Page                                                                      |
    | --------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
    | Amazon S3             | **Bucket and prefix**, **IAM role to assume**, **File pattern**           | [Amazon S3](/collect/sources/amazon-s3)                                   |
    | S3-compatible storage | **Endpoint**, **Bucket and prefix**, **Access key ID**                    | [S3-compatible storage](/collect/sources/amazon-s3#s3-compatible-storage) |
    | Azure Blob Storage    | **Storage account and container**, **Managed identity**, **File pattern** | [Azure Blob Storage](/collect/sources/azure-blob)                         |
    | Google Cloud Storage  | **Bucket and prefix**, **Service account**, **File pattern**              | [Google Cloud Storage](/collect/sources/google-cloud-storage)             |
    | SFTP                  | **Host and directory**, **Account**, **File pattern**                     | [SFTP, SMB and NFS](/collect/sources/file-shares)                         |
    | SMB or NFS share      | **Share**, **Service account**, **File pattern**                          | [SFTP, SMB and NFS](/collect/sources/file-shares#smb-and-nfs-shares)      |
    | MAVLink receiver      | **Listen on**, **System IDs**, **Record**                                 | [MAVLink ground receiver](/collect/receiver)                              |
    | Ingest API            | **Token name**, **Scope**, **Expires**                                    | [Push bundles with the Ingest API](/collect/sources/ingest-api)           |

    Under the fields, **Vehicle matching** explains how files find their vehicle. Foxborne matches files to vehicles by the MAVLink system ID in each flight log, or by the `{vehicle}` part of the file pattern.
  </Step>

  <Step title="Test the connection">
    Select **Test connection**. Four checks appear one after another, the same for every type:

    | Check                    | Result                                             |
    | ------------------------ | -------------------------------------------------- |
    | **Resolve and connect.** | **Reached the location from the Foxborne worker.** |
    | **List objects.**        | **Read access confirmed.**                         |
    | **Attempt a write.**     | **Refused, as it should be.**                      |
    | **Attempt a delete.**    | **Refused, as it should be.**                      |

    The last two checks are the read-only proof: Foxborne tries to write and to delete, and confirms that both are refused. After the fourth check, **Add source** becomes available. If you go **Back** and **Continue** again, run the test again.
  </Step>

  <Step title="Add the source">
    Select **Add source**. The toast names the source and says &#x2A;*The first sync is running.**
  </Step>
</Steps>

## Check the result [#check-the-result]

* The source appears in **Connections** with **Read-only, verified** under **Access** and **Healthy** under **Status**.
* **Today** counts the files read today, and **Last sync** shows when Foxborne last looked.
* The audit log records **Added source** with the name and a detail such as **Amazon S3, read-only test passed**.

The example dataset has five sources.

| Source                     | Location                                             | Access                           | Status              |
| -------------------------- | ---------------------------------------------------- | -------------------------------- | ------------------- |
| Fleet log archive          | `s3://hfr-flight-logs/px4/`                          | Read-only IAM role               | **Healthy**         |
| Companion collectors       | 15 of 16 vehicles enrolled                           | Outbound only, mutual TLS        | **Needs attention** |
| Range control receive logs | `sftp://rc1.range.hfr.internal/var/log/mav-receive/` | Key-based, read-only account     | **Healthy**         |
| Bench rig uploads          | `POST /api/fx/v1/ingest`                             | Service token, ingest scope only | **Healthy**         |
| Legacy journal share       | `\\fs01.hfr.internal\fieldops\journals`              | Read-only service account        | **Paused**          |

Under the table, the console notes that manual uploads are hashed and matched the same way as files from a source.

A second note reads &#x2A;*Endpoints that accept pushed evidence, such as the HTTPS ingest API, are listed under Integrations, Ingest.** Its link opens the **Ingest** tab of **Integrations**, which lists the endpoints Foxborne listens on and the files it imports. See [Integrations overview](/integrate).

## The source drawer [#the-source-drawer]

Select a row to open its drawer. The title is the source's name and the subtitle its type.

A note at the top explains any status that needs one, for example &#x2A;*UGV-05 is buffering behind the berm. UAS-07 reports an unsynchronised clock.**

| Section        | Rows                                                                                                                                                     |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Connection** | **Location**, **Access**, **Credential**, **Matches** (the file pattern) and **Schedule**                                                                |
| **Activity**   | **Status**, **Last sync**, **Files read** (for example **1,284, 61.2 GB**), **Today** (for example **12 new**) and **Added**, with who added it and when |
| **Guarantees** | What the source can and cannot do, below                                                                                                                 |

For a storage source, **Guarantees** lists three lines:

* **Read-only. The last connection test confirmed that writes and deletes are refused.**
* **Every file is hashed with SHA-256 before parsing and stored unmodified.**
* **Reads stay inside your network. Nothing is copied outside AWS GovCloud (US-West).** The environment is your deployment's.

For the collector source, it lists the collector's own three:

* **Outbound only, over mutual TLS. No port is opened on any vehicle.**
* **No command channel. The collector cannot send MAVLink to the flight controller.**
* **Offline samples are spooled, acknowledged before deletion, and any drop is written as a marker.**

## Sync, pause, resume and edit [#sync-pause-resume-and-edit]

The drawer's footer holds four actions. Each one is recorded in the audit log.

| Action       | What happens                                                                                                                                                                                                    | Audit entry                                |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| **Sync now** | Foxborne checks the source at once and updates **Last sync**. The toast reports the result, for example &#x2A;*Fleet log archive synced. No new files.** Not available while the source is paused.              | **Synced source**, **Manual sync**         |
| **Pause**    | Asks first, with &#x2A;*Foxborne stops reading new files from this source. Files already imported stay as they are.** Confirm with **Pause source**. The note then reads **Paused by**, your name and the date. | **Paused source**                          |
| **Resume**   | Starts reading again at once, with no confirmation, and clears the note.                                                                                                                                        | **Resumed source**                         |
| **Edit**     | Opens a dialog with **Name**, **Location**, **File pattern** and **Schedule**. &#x2A;*Changes apply from the next sync.** A field left blank keeps its value.                                                   | **Edited source**, **Connection settings** |

## Statuses [#statuses]

| Status              | What it means                                                             |
| ------------------- | ------------------------------------------------------------------------- |
| **Healthy**         | Foxborne reads the source normally.                                       |
| **Needs attention** | Something on the source needs a look, and the drawer's note says what.    |
| **Paused**          | An admin paused it. Nothing new is read until someone selects **Resume**. |
| **Error**           | Shown in red. Open the drawer and read its note.                          |

The **Sources** item in the sidebar counts sources that need attention or show an error.

## Troubleshoot [#troubleshoot]

* **Add source stays unavailable.** Run **Test connection** and wait for the fourth check. After **Back** and **Continue**, the test has to run again.
* **The Name field turns red.** A name is required.
* **Sync now is unavailable.** The source is paused. Select **Resume** first.
* **Files land on the wrong vehicle.** Check the `{vehicle}` part of the file pattern, and the MAVLink system ID in the flight logs.

## Next [#next]

<Cards>
  <Card title="Amazon S3 and S3-compatible storage" href="/collect/sources/amazon-s3" icon="database">
    A read-only IAM role, or a read-only key for MinIO and Ceph.
  </Card>

  <Card title="Azure Blob Storage" href="/collect/sources/azure-blob" icon="cloud">
    A container read through a managed identity.
  </Card>

  <Card title="Google Cloud Storage" href="/collect/sources/google-cloud-storage" icon="cloud">
    A bucket read through a service account with the viewer role.
  </Card>

  <Card title="SFTP, SMB and NFS" href="/collect/sources/file-shares" icon="folder">
    Ground station directories and network shares.
  </Card>

  <Card title="Push bundles with the Ingest API" href="/collect/sources/ingest-api" icon="code">
    Test rigs and pipelines push signed bundles.
  </Card>

  <Card title="MAVLink ground receiver" href="/collect/receiver" icon="antenna">
    What range control heard, on its own clock.
  </Card>
</Cards>
