# Deploy in your data center

URL: /deploy/on-premises

Run Foxborne on your own Kubernetes cluster or a pair of Linux hosts, next to the log servers you already have. Originals go to S3-compatible storage you run, under keys from your own key management.



Foxborne runs in your data center on your own Kubernetes or a pair of Linux hosts. Put it beside the log servers, ground stations and file shares that already hold your evidence. The deployment reads them read-only and sends nothing outside your network.

## What runs where [#what-runs-where]

| Part               | In your data center                                                                    |
| ------------------ | -------------------------------------------------------------------------------------- |
| Application        | Serves the console and manual uploads, on your network only                            |
| Workers            | Hash, parse, align and run rules. They read your sources and mount shares read-only.   |
| PostgreSQL 16      | Holds events, notes, reports and the audit log, in your network                        |
| Object storage     | Your S3-compatible storage, such as MinIO or Ceph, for originals, exports and basemaps |
| Key                | Your key management system. The key encrypts the object storage and the database.      |
| Identity and audit | Your SAML 2.0 identity provider and your SIEM                                          |

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

* You need the **Admin** role in Foxborne to open **Hosting** and manage sources.
* You run a Kubernetes cluster, or have a pair of Linux hosts for Foxborne.
* PostgreSQL 16 and S3-compatible object storage run inside your network.
* Your key management system can hold the key that encrypts them.
* Your identity provider signs users in over SAML 2.0, and your SIEM accepts syslog over TLS.
* You have the signed release bundle, a `.fxb` file, for the version you install.

## Prepare the data center [#prepare-the-data-center]

<Steps>
  <Step title="Choose the hosts">
    Run Foxborne on your own Kubernetes cluster or on a pair of Linux hosts. The application serves the console, and the workers parse, align and run rules.

    The console's example deployment runs two application nodes and two workers in AWS GovCloud. Treat that as one example, not as sizing guidance.
  </Step>

  <Step title="Keep the network closed">
    Deny outbound internet traffic from the Foxborne hosts at your firewall. Nothing in the deployment calls out: it sends no telemetry, checks its license offline and never calls a tile service.

    Engineers reach the console from your network or VPN. **Access**, **Sign-in**, **Sessions** lists the networks allowed to sign in, and the example allows `10.0.0.0/8` and the VPN range.
  </Step>

  <Step title="Prepare object storage">
    Create three buckets on your S3-compatible storage, as the example does: originals, exports and basemaps. Encrypt them with keys from your key management system.

    Originals must be write-once. If your store implements S3 Object Lock, as MinIO and the Ceph Object Gateway do, turn it on when you create the originals bucket. Then set a default retention in compliance mode.
  </Step>

  <Step title="Keep the key in your key management">
    The key that encrypts originals, exports, the database and the backups stays in your key management system. It rotates on your schedule.

    <Callout type="warning" title="The key controls the evidence">
      Disabling the key makes every stored original unreadable, to Foxborne as much as to anyone. Reports and case files encrypted with it become unreadable too.
    </Callout>
  </Step>

  <Step title="Run PostgreSQL 16">
    Run PostgreSQL 16 in your network, with its storage encrypted with your key. It holds events, notes, reports and the audit log, so back it up on your program's schedule.
  </Step>

  <Step title="Connect identity and audit">
    Foxborne signs users in through your identity provider over SAML 2.0 and provisions them over SCIM. Evidence marked export-controlled opens only for users whose identity provider asserts US person status, in the `usPerson` SAML attribute. The audit log streams to your SIEM over syslog with TLS.
  </Step>

  <Step title="Install the signed release">
    Each Foxborne release is one signed bundle, a `.fxb` file, with a software bill of materials. Foxborne checks the bundle's signature against the Foxborne release key before anything installs, and a bundle that does not match installs nothing.
  </Step>

  <Step title="Connect the log servers you already have">
    Add each existing store under **Sources** with **Add source**. The worker reads each one read-only:

    * **SFTP**: a directory on a ground station or log server, read with a key-based, read-only account and polled on a schedule. The example reads range control receive logs every 5 minutes with an ed25519 key.
    * **SMB or NFS share**: a share mounted read-only on the worker, reached with a read-only service account.
    * **S3-compatible storage**: a bucket and prefix, read with a read-only access key.

    **Test connection** reaches the location from the worker and confirms read access. It also shows that writes and deletes are refused.
  </Step>

  <Step title="Bring in range control and the vehicles">
    The MAVLink receiver listens for telemetry on the ground and records every receipt with its own clock, kept by NTP. The console's example listens on `udp://0.0.0.0:14560`.

    Collectors connect outbound from each vehicle to the deployment, over mutual TLS. Vehicles need a route to the deployment's address while they are on the ground.
  </Step>
</Steps>

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

Sign in through your identity provider and open **Hosting**. The panels read as in the example deployment, with your own hosts, stores and key in place of its values.

| Panel                         | What to confirm                                                                                                                                                                                                       |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Summary                       | **Mode** reads Self-hosted and **Environment** names where the deployment runs. **Version** carries **Signature verified**. **Network** reads No outbound internet, and **License** shows seats and the renewal date. |
| Data boundary                 | The dashed line encloses the application, the workers, PostgreSQL 16, original files, the customer-managed key and your IdP and SIEM. **Foxborne, Inc. receives nothing** sits outside it.                            |
| Where each kind of data lives | One row per store, from original files to backups, with your location, encryption and retention.                                                                                                                      |
| Encryption key                | The key's name and identifier, its **Custody** and its **Rotation** with the last rotation date.                                                                                                                      |
| Updates                       | **Installed** shows the version and date. **Signed by** names the Foxborne release key, and **Bill of materials** is stored with the release.                                                                         |
| Nodes                         | Application, workers and database, each **Healthy**. The footer shows **Last backup** and **Restore tested on**.                                                                                                      |
| Outbound connections          | Foxborne, Inc. **None**, map and tile services **None**, identity provider **Inbound**, your SIEM **Internal**.                                                                                                       |

Then open **Sources**. Each connection you added should read **Healthy**, with a recent **Last sync**.

## Troubleshoot [#troubleshoot]

**A share reads Paused.** Foxborne reads nothing new from a paused source, and files already imported stay as they are. Select **Resume** in the source's drawer when the share is ready.

**A vehicle's clock reads Not synchronised.** chrony on the companion computer has no reachable time source. Give it one inside your network, and [align the clock by hand](/investigate/align-a-clock) for runs already recorded.

**Collectors cannot connect.** Each vehicle opens an outbound HTTPS connection to the deployment's address while it is on the ground. Give that address a route from the network the vehicles use, as in [Install and enroll the collector](/collect/collector/install).

## Next [#next]

* [SFTP, SMB and NFS](/collect/sources/file-shares) covers file-share sources in detail.
* [MAVLink ground receiver](/collect/receiver) sets up receive logging at range control.
* [Install an update](/deploy/upgrades) when the next signed bundle arrives.
* [Air-gapped installation and updates](/deploy/air-gapped) applies when the data center has no path out.
