Files
git.stella-ops.org/docs/integrations/LOCAL_SERVICES.md
master 398d0659eb docs: UI-driven local setup sprints + module dossier sync
Add SPRINT_20260413_004 (platform UI-only setup bootstrap closure)
with BOOTSTRAP-001..006 delivery tracker, and update sprint 003 and
sprint 20260410-001 execution logs to reflect the completed
persistence / orchestrator / secret-authority work.

Sync module dossiers and operator guides with the new reality: setup
wizard UX, platform-service architecture, CLI setup guide, integrations
architecture + local services, release-orchestrator architecture,
install guide, and compose README.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 07:56:45 +03:00

18 KiB

Local Integration Services

This guide covers the third-party services available for local integration testing with Stella Ops.

Architecture Overview

                          stellaops network
  +------------------------------------------------------------------+
  |                                                                    |
  |  STELLA OPS CORE                  INTEGRATION SERVICES             |
  |  (docker-compose.stella-ops.yml)  (docker-compose.integrations.yml)|
  |                                                                    |
  |  router-gateway ─────────> gitea        (SCM)       127.1.2.1:3000 |
  |  concelier      ─────────> jenkins      (CI/CD)     127.1.2.2:8080 |
  |  integrations   ─────────> nexus        (Registry)  127.1.2.3:8081 |
  |  scanner        ─────────> vault        (Secrets)   127.1.2.4:8200 |
  |  evidence-locker ────────> docker-reg   (Registry)  127.1.2.5:5000 |
  |  airgap-controller ──────> minio        (S3)        127.1.2.6:9000 |
  |                            gitlab [heavy](All-in-1) 127.1.2.7:8929 |
  |                                                                    |
  |  MOCK FIXTURES (docker-compose.integration-fixtures.yml)           |
  |  harbor-fixture   (Registry mock)   127.1.1.6:80                   |
  |  github-app-fixture (SCM mock)      127.1.1.7:80                   |
  |  advisory-fixture (Advisory mock)   127.1.1.8:80                   |
  +------------------------------------------------------------------+

Quick Start

Prerequisites

  • Docker Desktop with 8 GB+ RAM allocated
  • The main Stella Ops stack running (docker-compose.stella-ops.yml)
  • Hosts file entries (see below)

1. Add hosts file entries

Add to C:\Windows\System32\drivers\etc\hosts:

127.1.2.1  gitea.stella-ops.local
127.1.2.2  jenkins.stella-ops.local
127.1.2.3  nexus.stella-ops.local
127.1.2.4  vault.stella-ops.local
127.1.2.5  registry.stella-ops.local
127.1.2.6  minio.stella-ops.local
127.1.2.7  gitlab.stella-ops.local
127.1.2.8  consul.stella-ops.local

2. Start services

cd devops/compose

# Start the default low-idle services (recommended)
docker compose -f docker-compose.integrations.yml up -d

# Or start specific services only
docker compose -f docker-compose.integrations.yml up -d gitea vault jenkins

# Start WITH mock fixtures (for full integration testing)
docker compose \
  -f docker-compose.integrations.yml \
  -f docker-compose.integration-fixtures.yml \
  up -d

# Start Consul only when validating the Consul connector
docker compose -f docker-compose.integrations.yml --profile consul up -d consul

# Start GitLab CE (heavy, 4 GB+ RAM, ~3 min startup)
docker compose -f docker-compose.integrations.yml --profile heavy up -d gitlab

# Re-enable GitLab registry/package surfaces for registry-specific tests
GITLAB_ENABLE_REGISTRY=true GITLAB_ENABLE_PACKAGES=true \
  docker compose -f docker-compose.integrations.yml --profile heavy up -d gitlab

3. Verify services

# Quick health check for all services
docker compose -f docker-compose.integrations.yml ps

# Gitea is only complete once the container is healthy
docker compose -f docker-compose.integrations.yml ps gitea

4. Register the local integration catalog

After the core stack plus the local provider lanes are running, there are two supported local operator paths.

Browser-driven Integrations Hub path:

node src/Web/StellaOps.Web/scripts/live-integrations-ui-bootstrap.mjs
  • Drives the live browser through /setup/integrations/onboarding/*.
  • Persists evidence to src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.json.
  • The harness now supports inline GitLab secret staging through the browser when STELLAOPS_UI_BOOTSTRAP_GITLAB_ACCESS_TOKEN and STELLAOPS_UI_BOOTSTRAP_GITLAB_REGISTRY_BASIC are supplied.
  • The separate first-run setup wizard (/setup-wizard/wizard) now reaches the Platform setup API through the frontdoor and uses persisted, installation-scoped setup sessions for the five truthful control-plane steps.

Scripted convergence path:

powershell -ExecutionPolicy Bypass -File scripts/register-local-integrations.ps1 `
  -Tenant demo-prod

This converges the default local-ready lane to 13 healthy entries:

  • Harbor fixture
  • Docker Registry
  • Nexus
  • GitHub App fixture
  • Gitea
  • Jenkins
  • Vault
  • Consul
  • eBPF runtime-host fixture
  • MinIO (S3Compatible)
  • StellaOps mirror
  • NVD mirror
  • OSV mirror

Optional GitLab providers require Vault-backed credentials. The recommended local flow is:

# Reuse or rotate the local GitLab bootstrap PAT and write it to Vault.
powershell -ExecutionPolicy Bypass -File scripts/bootstrap-local-gitlab-secrets.ps1 `
  -VerifyRegistry

# Register SCM + CI using the bootstrapped authref://vault/gitlab#access-token
powershell -ExecutionPolicy Bypass -File scripts/register-local-integrations.ps1 `
  -Tenant demo-prod `
  -IncludeGitLab

# Also requires GitLab registry enabled; uses authref://vault/gitlab#registry-basic
powershell -ExecutionPolicy Bypass -File scripts/register-local-integrations.ps1 `
  -Tenant demo-prod `
  -IncludeGitLab `
  -IncludeGitLabRegistry

# Or do the GitLab-backed registration in one step
powershell -ExecutionPolicy Bypass -File scripts/register-local-integrations.ps1 `
  -Tenant demo-prod `
  -IncludeGitLab `
  -IncludeGitLabRegistry `
  -BootstrapGitLabSecrets

For a repeatable browser-driven proof of the same Integrations Hub path, run:

node src/Web/StellaOps.Web/scripts/live-integrations-ui-bootstrap.mjs

It authenticates against https://stella-ops.local, creates integrations through the onboarding UI routes, and records the final catalog plus health results in src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.json.

docker-compose.testing.yml is the separate infrastructure-test lane. It starts postgres-test, valkey-test, mocks, and an isolated Gitea profile on different ports; it does not start Consul or GitLab.


Service Reference

Gitea (SCM)

Property Value
URL http://gitea.stella-ops.local:3000
API http://gitea.stella-ops.local:3000/api/v1
SSH gitea.stella-ops.local:2222
Admin stellaops / Stella2026! on fresh volumes
Bootstrap Container entrypoint seeds the repo root and first admin before health goes green
Swagger http://gitea.stella-ops.local:3000/api/swagger
Integration type SCM (Gitea provider)
Docker DNS gitea.stella-ops.local

Stella Ops integration config:

  • Endpoint: http://gitea.stella-ops.local:3000
  • AuthRef: authref://vault/gitea#api-token
  • Organization: (your Gitea org name)

Create an API token:

  1. Log in to Gitea as stellaops / Stella2026! on a fresh volume, or use the existing admin user if this environment was already initialized.
  2. Settings > Applications > Generate Token
  3. Store in Vault at secret/gitea with key api-token

The previous local-service flow was contradictory: the compose profile marked Gitea as install-locked while the docs still described a manual first-login admin creation path. The compose bootstrap now makes the service deterministic and leaves only PAT creation as a manual step.


Jenkins (CI/CD)

Property Value
URL http://jenkins.stella-ops.local:8080
API http://jenkins.stella-ops.local:8080/api/json
Admin Setup wizard disabled; create user via script console
Agent port 127.1.2.2:50000
Integration type CI/CD (Jenkins provider)
Docker DNS jenkins.stella-ops.local

Stella Ops integration config:

  • Endpoint: http://jenkins.stella-ops.local:8080
  • AuthRef: authref://vault/jenkins#api-token

Create an API token:

  1. Open Jenkins > Manage Jenkins > Users > admin > Configure
  2. Add API Token
  3. Store in Vault at secret/jenkins with key api-token

Nexus (Repository Manager)

Property Value
URL http://nexus.stella-ops.local:8081
API http://nexus.stella-ops.local:8081/service/rest/v1/status
Docker hosted nexus.stella-ops.local:8082
Docker proxy nexus.stella-ops.local:8083
Admin admin / (see /nexus-data/admin.password on first run)
Integration type Registry (Nexus provider)
Docker DNS nexus.stella-ops.local

Get initial admin password:

docker exec stellaops-nexus cat /nexus-data/admin.password

Stella Ops integration config:

  • Endpoint: http://nexus.stella-ops.local:8081
  • AuthRef: authref://vault/nexus#admin-password

Setup Docker hosted repository:

  1. Login to Nexus UI
  2. Server Administration > Repositories > Create > docker (hosted)
  3. HTTP port: 8082, Allow redeploy: true
  4. Create a docker (proxy) repository pointing to Docker Hub, HTTP port: 8083

HashiCorp Vault (Secrets)

Property Value
URL http://vault.stella-ops.local:8200
API http://vault.stella-ops.local:8200/v1/sys/health
Root token stellaops-dev-root-token-2026
Mode Dev server (in-memory, unsealed)
Integration type Secrets (Vault provider)
Docker DNS vault.stella-ops.local

Stella Ops integration config:

  • Endpoint: http://vault.stella-ops.local:8200
  • AuthRef: (Vault is the auth provider itself)

Store integration credentials in Vault:

# Enable KV v2 engine (already enabled in dev mode at secret/)
export VAULT_ADDR=http://vault.stella-ops.local:8200
export VAULT_TOKEN=stellaops-dev-root-token-2026

# Store Harbor credentials
vault kv put secret/harbor robot-account="harbor-robot-token"

# Store GitHub App credentials
vault kv put secret/github app-private-key="-----BEGIN RSA PRIVATE KEY-----..."

# Store Gitea API token
vault kv put secret/gitea api-token="your-gitea-token"

# Store Jenkins API token
vault kv put secret/jenkins api-token="your-jenkins-token"

# Store Nexus admin password
vault kv put secret/nexus admin-password="your-nexus-password"

# Store GitLab PATs for API and registry access (manual override path)
vault kv put secret/gitlab access-token="glpat-your-token" registry-basic="root:glpat-your-token"

Inline secret staging no longer requires a manual Vault write for GitLab-class providers:

stella config integrations secrets targets
stella config integrations secrets upsert-bundle --bundle gitlab-server --target <vault-integration-id> --path gitlab/server --entry access-token=glpat-...

Consul (Optional KV / Settings Store)

Property Value
URL http://consul.stella-ops.local:8500
API http://consul.stella-ops.local:8500/v1/status/leader
Auth None (single-node local server)
Start mode --profile consul only
Integration type Settings / KV (Consul provider)
Docker DNS consul.stella-ops.local

Start Consul only when needed:

docker compose -f docker-compose.integrations.yml --profile consul up -d consul

Why opt-in: even in its lower-idle local mode, Consul is still an extra control-plane service that most local connector checks do not need. The default integration lane keeps it off unless you are explicitly validating the Consul connector.

Runtime mode: the local compose profile now runs Consul as a persistent single-node server with the UI enabled instead of agent -dev. That preserves the HTTP KV surface while materially lowering idle CPU.

Stella Ops integration config:

  • Endpoint: http://consul.stella-ops.local:8500
  • AuthRef: (none required in local mode)

Docker Registry (OCI v2)

Property Value
URL http://registry.stella-ops.local:5000
API http://registry.stella-ops.local:5000/v2/
Auth None (open dev registry)
Integration type Registry (generic OCI)
Docker DNS registry.stella-ops.local

Push a test image:

docker tag alpine:latest registry.stella-ops.local:5000/test/alpine:latest
docker push registry.stella-ops.local:5000/test/alpine:latest

# List repositories
curl http://registry.stella-ops.local:5000/v2/_catalog

Stella Ops integration config:

  • Endpoint: http://registry.stella-ops.local:5000
  • AuthRef: (none required for dev)

MinIO (S3 Storage)

Property Value
Console http://minio.stella-ops.local:9001
S3 API http://minio.stella-ops.local:9000
Access key stellaops
Secret key Stella2026!
Integration type Object Storage (S3Compatible provider)
Docker DNS minio.stella-ops.local

Create buckets for Stella Ops:

# Install mc CLI
docker exec stellaops-minio mc alias set local http://localhost:9000 stellaops Stella2026!

# Create buckets
docker exec stellaops-minio mc mb local/evidence-locker
docker exec stellaops-minio mc mb local/airgap-bundles
docker exec stellaops-minio mc mb local/scan-results
docker exec stellaops-minio mc mb local/sbom-archive

Stella Ops integration config:

  • Endpoint: http://minio.stella-ops.local:9000
  • Type: ObjectStorage
  • Provider: S3Compatible
  • AuthRef: optional for the default local health probe

GitLab CE (Heavy, Optional)

Property Value
URL http://gitlab.stella-ops.local:8929
Admin root / Stella2026!
SSH gitlab.stella-ops.local:2224
Container Registry gitlab.stella-ops.local:5050 (GITLAB_ENABLE_REGISTRY=true only)
RAM required 4 GB+
Startup time ~3-5 minutes
Integration type SCM + CI/CD + Registry
Docker DNS gitlab.stella-ops.local

Start GitLab (uses heavy profile):

docker compose -f docker-compose.integrations.yml --profile heavy up -d gitlab

Default local tuning:

  • SCM/API coverage stays available.
  • Registry and package surfaces are disabled by default to reduce idle CPU.
  • Puma and Sidekiq run in reduced-concurrency mode for local connector checks.

Enable registry/package coverage explicitly when needed:

GITLAB_ENABLE_REGISTRY=true GITLAB_ENABLE_PACKAGES=true \
  docker compose -f docker-compose.integrations.yml --profile heavy up -d gitlab

Stella Ops integration config (SCM / CI):

  • Endpoint: http://gitlab.stella-ops.local:8929
  • AuthRef: authref://vault/gitlab#access-token
  • Bootstrap helper: powershell -ExecutionPolicy Bypass -File scripts/bootstrap-local-gitlab-secrets.ps1

Stella Ops integration config (Registry):

  • Endpoint: http://gitlab.stella-ops.local:5050
  • AuthRef: authref://vault/gitlab#registry-basic
  • Secret format: username:personal-access-token (local default: root:<token>)
  • The Docker registry connector follows GitLab's WWW-Authenticate: Bearer challenge and exchanges this basic secret against /jwt/auth before retrying catalog and tag probes.
  • scripts/bootstrap-local-gitlab-secrets.ps1 -VerifyRegistry reuses a valid local Vault secret when possible and otherwise rotates the local stella-local-integration PAT before writing both authrefs.

Mock Fixtures

In addition to real services, lightweight nginx-based fixtures provide deterministic mock APIs for UI testing.

Fixture Mocks Address Compose file
harbor-fixture Harbor v2 API 127.1.1.6:80 docker-compose.integration-fixtures.yml
github-app-fixture GitHub App API 127.1.1.7:80 docker-compose.integration-fixtures.yml
advisory-fixture CERT-In, FSTEC, VEX Hub, StellaOps Mirror, etc. 127.1.1.8:80 docker-compose.integration-fixtures.yml
# Start fixtures only
docker compose -f docker-compose.integration-fixtures.yml up -d

IP Address Map

IP Service Port(s)
127.1.0.1 stella-ops.local (gateway) 443
127.1.0.4 authority (OIDC) 80
127.1.1.1 postgres 5432
127.1.1.2 valkey 6379
127.1.1.6 harbor-fixture 80
127.1.1.7 github-app-fixture 80
127.1.1.8 advisory-fixture 80
127.1.2.1 gitea 3000, 2222
127.1.2.2 jenkins 8080, 50000
127.1.2.3 nexus 8081, 8082, 8083
127.1.2.4 vault 8200
127.1.2.5 docker-registry 5000
127.1.2.6 minio 9000, 9001
127.1.2.7 gitlab (heavy) 8929, 2224, 5050

Volumes

All service data persists in named Docker volumes. To reset a service:

# Stop and remove a specific service + its volume
docker compose -f docker-compose.integrations.yml down -v nexus
docker volume rm stellaops-nexus-data

# Reset ALL integration services
docker compose -f docker-compose.integrations.yml down -v

Integration Matrix

Stella Ops Category Provider Local Service Status
Registry Harbor harbor-fixture (mock) Ready
Registry Docker Hub / OCI docker-registry Ready
Registry Nexus nexus Ready
Registry GitLab Registry gitlab (heavy) Ready when GITLAB_ENABLE_REGISTRY=true and authref://vault/gitlab#registry-basic is populated
SCM GitHub App github-app-fixture (mock) Ready
SCM Gitea gitea Ready
SCM GitLab Server gitlab (heavy) Ready with Vault-backed PAT
CI/CD Jenkins jenkins Ready
CI/CD GitLab CI gitlab (heavy) Ready with reduced local concurrency
Secrets Vault vault Ready
Secrets Consul consul Opt-in (--profile consul)
Runtime Host eBPF Agent runtime-host-fixture (mock) Ready
Feed Mirror StellaOps / NVD / OSV mirror concelier Ready
Storage S3-compatible (MinIO) minio Ready
Advisory & VEX 74 sources advisory-fixture + live 74/74 healthy

Current provider list: the local Integrations service currently reports connector plugins for Harbor, Docker Registry, GitLab Container Registry, Nexus, GitHub App, Gitea, GitLab Server, GitLab CI, Jenkins, Vault, Consul, eBPF Agent, the S3Compatible object-storage provider, the feed mirror providers (StellaOpsMirror, NvdMirror, OsvMirror), and the test-only InMemory provider.

Storage note: the S3Compatible connector defaults to probing /minio/health/live when the configured endpoint is the service root, which matches the local MinIO fixture.

Auth caveat: several connector plugins validate public health/version endpoints only. A green connection test proves reachability and the plugin wiring, but it does not guarantee that privileged API operations are fully configured unless you also provision the corresponding secret material in Vault.