EntPEP agent host
=================

This package installs the EntPEP agent host: the Agent Fleet Manager and the sealed agent VMs it
launches. It holds four binaries and one systemd unit; no source code and no interpreters.

  bin/entpep-host       the Fleet Manager (:443), the relays to agents (:8001-8008) and the
                        agents' internal gateway (10.0.9.1, sharing :443)
  bin/entpep-agent      the agent (a unikernel that runs in its own VM)
  bin/entpep-reader     the document reader (a unikernel booted for one PDF / .doc / .xls / .ppt
                        file at a time, for one agent: no keys, no network beyond that agent)
  bin/uhyve             the hypervisor that boots each agent VM (uhyve 0.10.0)
  systemd/              the entpep-host unit template
  defaults/             Admin defaults for a proof of concept
  install.sh            the installer
  host.json.example     what install.sh writes to <prefix>/fleetcerts/host.json
  VERSION, SHA256SUMS

Requirements
------------
- x86_64 Linux with systemd and /dev/kvm (bare metal, or a cloud VM with nested virtualization).
  Tested on Ubuntu 26.04 LTS.
- 16 GB RAM minimum (32 GB recommended), 30 GB disk.
- A DNS name for the host and a TLS certificate for it: from a public CA, from --certbot (needs
  public DNS and inbound port 80), or from the organisation's internal CA (pass that CA with --ca).
- Outbound HTTPS to the model server (api.anthropic.com, Bedrock, or a private server),
  login.microsoftonline.com, graph.microsoft.com, the tenant's SharePoint host, and the ClickHouse
  server.

Install
-------
  tar xzf entpep-install-v1.tgz
  cd entpep-install-v1
  sudo ./install.sh --hostname poc.example.com --cert /path/fullchain.pem --key /path/privkey.pem

With a certificate from an internal CA, add --ca /path/internal-ca.pem (the root, and any
intermediates not already in fullchain.pem). The host and its agents then trust that CA as well as
the public ones; it also covers a TLS-inspecting proxy on the way out.

Open these inbound ports (firewall or cloud security group):

  TCP 443        the Fleet Manager                      from your users' addresses
  TCP 8000-8999  the agents (each opens on its own port, from your users' addresses
                 8001-8008 today)
  TCP 22         SSH                                    from your admin address
  TCP 80         only for --certbot (Let's Encrypt)     from anywhere

With only 443 open, a launched agent never gets past "Starting your sealed agent". Nothing else may
listen on port 443 on this machine (the installer stops if, say, nginx does).

Then open https://poc.example.com/ and sign in with any name and the password in
/opt/entpep/fleetcerts/fleet.pass. The installer prints the remaining steps:

- SharePoint: send the customer's Entra admin /opt/entpep/sharepoint-app.cer (the public half of
  the host's app certificate; the private key stays on the host), then add the IDs they send back:
    sudo ./install.sh --entra-tenant ID --entra-client ID --sharepoint-site ID
  (To share one already-registered app certificate between test hosts instead, add
  --sharepoint-key FILE --sharepoint-cert FILE.)
- Every option can go in one run. At the end the installer checks that the data lake and SharePoint
  answer, and prints this host's public IP (the data lake and model servers must allow it).
- Data lake:
    sudo ./install.sh --clickhouse-url https://datalake.example.com:8443/ \
      --clickhouse-password-file host.pass --clickhouse-desk-password-file desk.pass
- Model: an Anthropic key (--anthropic-key-file F, or typed when asked), or Bedrock or a private
  model server, set up in Admin.

Run ./install.sh --help for every option. Secrets are read from files, never from the command line.

Trial
-----
This is a trial build: the Fleet Manager and the agents stop working on the date in VERSION
("trial until ..."). From 30 days before, the Fleet Manager shows how many days are left. After it,
the Fleet Manager shows a notice, running agents are stopped and new ones can't start. A new
package with a later date (or a licensed build) replaces it with a normal upgrade.

Upgrade
-------
Stop all agents in the Fleet Manager, unpack the new package and run sudo ./install.sh from it.
Settings, secrets and archives are kept; the previous binaries are kept as bin/*.prev.

Layout
------
  /opt/entpep/bin/                       the four binaries
  /opt/entpep/fleetcerts/                config and secrets, mode 0600 (host.json, certificates, keys)
  /opt/entpep/vmstate/, fleetstate/      runtime state
  /opt/entpep/appliance-snapshots/       encrypted agent archives
  /etc/systemd/system/entpep-host.service
  users entpep-vm1 .. entpep-vm8         one unprivileged user per agent VM, created on first launch

Each agent VM runs as its slot's own user in a systemd sandbox: no capabilities, a system call
filter, no IP sockets, and a read-only view of only its own config, the agent and uhyve.

Agent VMs have no route to the internet. entpep-host keeps two iptables chains, ENTPEP-AGENTS
(FORWARD) and ENTPEP-AGENTS-IN (INPUT), rebuilt whenever an agent starts or stops: an agent VM may
reach only this host's gateway (10.0.9.1:443) and Web Search (10.0.9.5:443). Its model server and
SharePoint calls go through the gateway's credential relay, which attaches the real key or token, so
no model key and no SharePoint token ever enters a VM; the host itself makes those connections.

Known limits in this version
----------------------------
- One shared Fleet Manager password; no SSO.
- entpep-host runs as root (it creates the bridge, taps and the VM units).
- Secrets are files (mode 0600); no key store or HSM.

Uninstall
---------
  sudo systemctl disable --now entpep-host
  sudo rm /etc/systemd/system/entpep-host.service
  sudo rm -r /opt/entpep        (this deletes the archives and secrets)
  for n in 1 2 3 4 5 6 7 8; do sudo userdel entpep-vm$n 2>/dev/null; done
  sudo ip link del cbr0; for n in 1 2 3 4 5 6 7 8; do sudo ip link del ctap$n 2>/dev/null; done
