# Stella Ops — Installation Guide (Docker & Air‑Gap)

<!--
  This file is processed by the Eleventy build.  
  Do **not** hard‑code versions or quota numbers; inherit from
  docs/_includes/CONSTANTS.md instead.
    {{ dotnet }}     → ".NET 10 LTS"
    {{ angular }}    → "20"
-->

> **Status — public α not yet published.**  
> The commands below will work as soon as the first image is tagged  
> `registry.stella-ops.org/stella-ops/stella-ops:0.1.0-alpha`  
> (target date: **late 2025**). Track progress on the  
> [road‑map](/roadmap/).

---

## 0 · Prerequisites

| Item | Minimum | Notes |
|------|---------|-------|
| Linux | Ubuntu 22.04 LTS / Alma 9 | x86‑64 or arm64 |
| CPU / RAM | 2 vCPU / 2 GiB | Laptop baseline |
| Disk | 10 GiB SSD | SBOM + vuln DB cache |
| Docker | **Engine 25 + Compose v2** | `docker -v` |
| TLS | OpenSSL 1.1 +  | Self‑signed cert generated at first run |

---

## 1 · Connected‑host install (Docker Compose)

```bash
# 1. Make a working directory
mkdir stella && cd stella

# 2. Download the signed Compose bundle + example .env
curl -LO https://get.stella-ops.org/releases/latest/.env.example
curl -LO https://get.stella-ops.org/releases/latest/.env.example.sig
curl -LO https://get.stella-ops.org/releases/latest/docker-compose.infrastructure.yml
curl -LO https://get.stella-ops.org/releases/latest/docker-compose.infrastructure.yml.sig
curl -LO https://get.stella-ops.org/releases/latest/docker-compose.stella-ops.yml
curl -LO https://get.stella-ops.org/releases/latest/docker-compose.stella-ops.yml.sig

# 3. Verify provenance (Cosign public key is stable)
cosign verify-blob \
  --key https://stella-ops.org/keys/cosign.pub \
  --signature .env.example.sig \
  .env.example

cosign verify-blob \
  --key https://stella-ops.org/keys/cosign.pub \
  --signature docker-compose.infrastructure.yml.sig \
  docker-compose.infrastructure.yml

cosign verify-blob \
  --key https://stella-ops.org/keys/cosign.pub \
  --signature docker-compose.stella-ops.yml.sig \
  docker-compose.stella-ops.yml

# 4. Copy .env.example → .env and edit secrets
cp .env.example .env
$EDITOR .env

# 5. Launch databases (MongoDB + Redis)
docker compose --env-file .env -f docker-compose.infrastructure.yml up -d

# 6. Launch Stella Ops (first run pulls ~50 MB merged vuln DB)
docker compose --env-file .env -f docker-compose.stella-ops.yml up -d
````

*Default login:* `admin / changeme`
UI: [https://\&lt;host\&gt;:8443](https://&lt;host&gt;:8443) (self‑signed certificate)

> **Pinning best‑practice** – in production environments replace
> `stella-ops:latest` with the immutable digest printed by
> `docker images --digests`.

### 1.1 · Feedser authority configuration

The Feedser container reads configuration from `etc/feedser.yaml` plus
`FEEDSER_` environment variables. To enable the new Authority integration:

1. Add the following keys to `.env` (replace values for your environment):

   ```bash
   FEEDSER_AUTHORITY__ENABLED=true
   FEEDSER_AUTHORITY__ALLOWANONYMOUSFALLBACK=true   # temporary rollout only
   FEEDSER_AUTHORITY__ISSUER="https://authority.internal"
   FEEDSER_AUTHORITY__AUDIENCES__0="api://feedser"
   FEEDSER_AUTHORITY__REQUIREDSCOPES__0="feedser.jobs.trigger"
   FEEDSER_AUTHORITY__CLIENTID="feedser-jobs"
   FEEDSER_AUTHORITY__CLIENTSECRETFILE="/run/secrets/feedser_authority_client"
   FEEDSER_AUTHORITY__BYPASSNETWORKS__0="127.0.0.1/32"
   FEEDSER_AUTHORITY__BYPASSNETWORKS__1="::1/128"
   FEEDSER_AUTHORITY__RESILIENCE__ENABLERETRIES=true
   FEEDSER_AUTHORITY__RESILIENCE__RETRYDELAYS__0="00:00:01"
   FEEDSER_AUTHORITY__RESILIENCE__RETRYDELAYS__1="00:00:02"
   FEEDSER_AUTHORITY__RESILIENCE__RETRYDELAYS__2="00:00:05"
   FEEDSER_AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK=true
   FEEDSER_AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE="00:10:00"
   ```

   Store the client secret outside source control (Docker secrets, mounted file,
   or Kubernetes Secret). Feedser loads the secret during post-configuration, so
   the value never needs to appear in the YAML template.

   Connected sites can keep the retry ladder short (1 s, 2 s, 5 s) so job triggers fail fast when Authority is down. For air‑gapped or intermittently connected deployments, extend `RESILIENCE__OFFLINECACHETOLERANCE` (e.g. `00:30:00`) so cached discovery/JWKS data remains valid while the Offline Kit synchronises upstream changes.

2. Redeploy Feedser:

   ```bash
   docker compose --env-file .env -f docker-compose.stella-ops.yml up -d feedser
   ```

3. Tail the logs: `docker compose logs -f feedser`. Successful `/jobs*` calls now
   emit `Feedser.Authorization.Audit` entries with `route`, `status`, `subject`,
   `clientId`, `scopes`, `bypass`, and `remote` fields. 401 denials keep the same
   shape—watch for `bypass=True`, which indicates a bypass CIDR accepted an anonymous
   call. See `docs/ops/feedser-authority-audit-runbook.md` for a full audit/alerting checklist.

> **Enforcement deadline** – keep `FEEDSER_AUTHORITY__ALLOWANONYMOUSFALLBACK=true`
> only while validating the rollout. Set it to `false` (and restart Feedser)
> before **2025-12-31 UTC** to require tokens in production.

---

## 2 · Optional: request a free quota token

Anonymous installs allow **{{ quota\_anon }} scans per UTC day**.
Email `token@stella-ops.org` to receive a signed JWT that raises the limit to
**{{ quota\_token }} scans/day**. Insert it into `.env`:

```bash
STELLA_JWT="paste‑token‑here"
docker compose --env-file .env -f docker-compose.stella-ops.yml \
  exec stella-ops stella set-jwt "$STELLA_JWT"
```

>  The UI shows a reminder at 200 scans and throttles above the limit but will
>  **never block** your pipeline.

---

## 3 · Air‑gapped install (Offline Update Kit)

When running on an isolated network use the **Offline Update Kit (OUK)**:

```bash
# Download & verify on a connected host
curl -LO https://get.stella-ops.org/ouk/stella-ops-offline-kit-v0.1a.tgz
curl -LO https://get.stella-ops.org/ouk/stella-ops-offline-kit-v0.1a.tgz.sig

cosign verify-blob \
  --key https://stella-ops.org/keys/cosign.pub \
  --signature stella-ops-offline-kit-v0.1a.tgz.sig \
  stella-ops-offline-kit-v0.1a.tgz

# Transfer → air‑gap → import
docker compose --env-file .env -f docker-compose.stella-ops.yml \
  exec stella admin import-offline-usage-kit stella-ops-offline-kit-v0.1a.tgz
```

*Import is atomic; no service downtime.*

For details see the dedicated [Offline Kit guide](/offline/).

---

## 4 · Next steps

* **5‑min Quick‑Start:** `/quickstart/`
* **CI recipes:** `docs/ci/20_CI_RECIPES.md`
* **Plug‑in SDK:** `/plugins/`

---

*Generated {{ "now" | date: "%Y‑%m‑%d" }} — build tags inserted at render time.*
