Restructure solution layout by module
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Docs CI / lint-and-preview (push) Has been cancelled
				
			This commit is contained in:
		| @@ -1,190 +1,190 @@ | ||||
| # 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://\<host\>:8443](https://<host>:8443) (self‑signed certificate) | ||||
|  | ||||
| > **Pinning best‑practice** – in production environments replace | ||||
| > `stella-ops:latest` with the immutable digest printed by | ||||
| > `docker images --digests`. | ||||
|  | ||||
| > **Repo bundles** – Development, staging, and air‑gapped Compose profiles live | ||||
| > under `deploy/compose/`, already tied to the release manifests in | ||||
| > `deploy/releases/`. Helm users can pull the same channel overlays from | ||||
| > `deploy/helm/stellaops/values-*.yaml` and validate everything with | ||||
| > `deploy/tools/validate-profiles.sh`. | ||||
|  | ||||
| ### 1.1 · Concelier authority configuration | ||||
|  | ||||
| The Concelier container reads configuration from `etc/concelier.yaml` plus | ||||
| `CONCELIER_` environment variables. To enable the new Authority integration: | ||||
|  | ||||
| 1. Add the following keys to `.env` (replace values for your environment): | ||||
|  | ||||
|    ```bash | ||||
|    CONCELIER_AUTHORITY__ENABLED=true | ||||
|    CONCELIER_AUTHORITY__ALLOWANONYMOUSFALLBACK=true   # temporary rollout only | ||||
|    CONCELIER_AUTHORITY__ISSUER="https://authority.internal" | ||||
|    CONCELIER_AUTHORITY__AUDIENCES__0="api://concelier" | ||||
|    CONCELIER_AUTHORITY__REQUIREDSCOPES__0="concelier.jobs.trigger" | ||||
|    CONCELIER_AUTHORITY__REQUIREDSCOPES__1="advisory:read" | ||||
|    CONCELIER_AUTHORITY__REQUIREDSCOPES__2="advisory:ingest" | ||||
|    CONCELIER_AUTHORITY__REQUIREDTENANTS__0="tenant-default" | ||||
|    CONCELIER_AUTHORITY__CLIENTID="concelier-jobs" | ||||
|    CONCELIER_AUTHORITY__CLIENTSCOPES__0="concelier.jobs.trigger" | ||||
|    CONCELIER_AUTHORITY__CLIENTSCOPES__1="advisory:read" | ||||
|    CONCELIER_AUTHORITY__CLIENTSCOPES__2="advisory:ingest" | ||||
|    CONCELIER_AUTHORITY__CLIENTSECRETFILE="/run/secrets/concelier_authority_client" | ||||
|    CONCELIER_AUTHORITY__BYPASSNETWORKS__0="127.0.0.1/32" | ||||
|    CONCELIER_AUTHORITY__BYPASSNETWORKS__1="::1/128" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__ENABLERETRIES=true | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__RETRYDELAYS__0="00:00:01" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__RETRYDELAYS__1="00:00:02" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__RETRYDELAYS__2="00:00:05" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK=true | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE="00:10:00" | ||||
|    ``` | ||||
|  | ||||
|    Store the client secret outside source control (Docker secrets, mounted file, | ||||
|    or Kubernetes Secret). Concelier 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 Concelier: | ||||
|  | ||||
|    ```bash | ||||
|    docker compose --env-file .env -f docker-compose.stella-ops.yml up -d concelier | ||||
|    ``` | ||||
|  | ||||
| 3. Tail the logs: `docker compose logs -f concelier`. Successful `/jobs*` calls now | ||||
|    emit `Concelier.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/concelier-authority-audit-runbook.md` for a full audit/alerting checklist. | ||||
|  | ||||
| > **Enforcement deadline** – keep `CONCELIER_AUTHORITY__ALLOWANONYMOUSFALLBACK=true` | ||||
| > only while validating the rollout. Set it to `false` (and restart Concelier) | ||||
| > 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.* | ||||
| # 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://\<host\>:8443](https://<host>:8443) (self‑signed certificate) | ||||
|  | ||||
| > **Pinning best‑practice** – in production environments replace | ||||
| > `stella-ops:latest` with the immutable digest printed by | ||||
| > `docker images --digests`. | ||||
|  | ||||
| > **Repo bundles** – Development, staging, and air‑gapped Compose profiles live | ||||
| > under `deploy/compose/`, already tied to the release manifests in | ||||
| > `deploy/releases/`. Helm users can pull the same channel overlays from | ||||
| > `deploy/helm/stellaops/values-*.yaml` and validate everything with | ||||
| > `deploy/tools/validate-profiles.sh`. | ||||
|  | ||||
| ### 1.1 · Concelier authority configuration | ||||
|  | ||||
| The Concelier container reads configuration from `etc/concelier.yaml` plus | ||||
| `CONCELIER_` environment variables. To enable the new Authority integration: | ||||
|  | ||||
| 1. Add the following keys to `.env` (replace values for your environment): | ||||
|  | ||||
|    ```bash | ||||
|    CONCELIER_AUTHORITY__ENABLED=true | ||||
|    CONCELIER_AUTHORITY__ALLOWANONYMOUSFALLBACK=true   # temporary rollout only | ||||
|    CONCELIER_AUTHORITY__ISSUER="https://authority.internal" | ||||
|    CONCELIER_AUTHORITY__AUDIENCES__0="api://concelier" | ||||
|    CONCELIER_AUTHORITY__REQUIREDSCOPES__0="concelier.jobs.trigger" | ||||
|    CONCELIER_AUTHORITY__REQUIREDSCOPES__1="advisory:read" | ||||
|    CONCELIER_AUTHORITY__REQUIREDSCOPES__2="advisory:ingest" | ||||
|    CONCELIER_AUTHORITY__REQUIREDTENANTS__0="tenant-default" | ||||
|    CONCELIER_AUTHORITY__CLIENTID="concelier-jobs" | ||||
|    CONCELIER_AUTHORITY__CLIENTSCOPES__0="concelier.jobs.trigger" | ||||
|    CONCELIER_AUTHORITY__CLIENTSCOPES__1="advisory:read" | ||||
|    CONCELIER_AUTHORITY__CLIENTSCOPES__2="advisory:ingest" | ||||
|    CONCELIER_AUTHORITY__CLIENTSECRETFILE="/run/secrets/concelier_authority_client" | ||||
|    CONCELIER_AUTHORITY__BYPASSNETWORKS__0="127.0.0.1/32" | ||||
|    CONCELIER_AUTHORITY__BYPASSNETWORKS__1="::1/128" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__ENABLERETRIES=true | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__RETRYDELAYS__0="00:00:01" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__RETRYDELAYS__1="00:00:02" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__RETRYDELAYS__2="00:00:05" | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK=true | ||||
|    CONCELIER_AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE="00:10:00" | ||||
|    ``` | ||||
|  | ||||
|    Store the client secret outside source control (Docker secrets, mounted file, | ||||
|    or Kubernetes Secret). Concelier 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 Concelier: | ||||
|  | ||||
|    ```bash | ||||
|    docker compose --env-file .env -f docker-compose.stella-ops.yml up -d concelier | ||||
|    ``` | ||||
|  | ||||
| 3. Tail the logs: `docker compose logs -f concelier`. Successful `/jobs*` calls now | ||||
|    emit `Concelier.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/concelier-authority-audit-runbook.md` for a full audit/alerting checklist. | ||||
|  | ||||
| > **Enforcement deadline** – keep `CONCELIER_AUTHORITY__ALLOWANONYMOUSFALLBACK=true` | ||||
| > only while validating the rollout. Set it to `false` (and restart Concelier) | ||||
| > 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.* | ||||
|   | ||||
		Reference in New Issue
	
	Block a user