Add 12 new sprint files (Integrations, Graph, JobEngine, FE, Router, AdvisoryAI), archive completed scheduler UI sprint, update module architecture docs (router, graph, jobengine, web, integrations), and add Gitea entrypoint script for local dev. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15 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
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:
- Log in to Gitea as
stellaops/Stella2026!on a fresh volume, or use the existing admin user if this environment was already initialized. - Settings > Applications > Generate Token
- Store in Vault at
secret/giteawith keyapi-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:
- Open Jenkins > Manage Jenkins > Users > admin > Configure
- Add API Token
- Store in Vault at
secret/jenkinswith keyapi-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:
- Login to Nexus UI
- Server Administration > Repositories > Create > docker (hosted)
- HTTP port: 8082, Allow redeploy: true
- 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"
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):
- Endpoint:
http://gitlab.stella-ops.local:8929 - AuthRef:
authref://vault/gitlab#access-token
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 |
| 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
S3Compatibleobject-storage provider, the feed mirror providers (StellaOpsMirror,NvdMirror,OsvMirror), and the test-only InMemory provider.Storage note: the
S3Compatibleconnector defaults to probing/minio/health/livewhen 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.