devops folders consolidate

This commit is contained in:
master
2026-01-25 23:27:41 +02:00
parent 6e687b523a
commit a743bb9a1d
613 changed files with 8611 additions and 41846 deletions

View File

@@ -1,35 +0,0 @@
# AGENTS - DevOps
## Roles
- DevOps engineer: maintain devops services, tools, and release assets.
- QA engineer: add and maintain tests for devops services and tools.
- Docs/PM: keep sprint status and devops docs aligned.
## Working directory
- Primary: `devops/**`
- Avoid edits outside devops unless a sprint explicitly allows it.
## Required reading (treat as read before DOING)
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/ARCHITECTURE_OVERVIEW.md`
- `docs/operations/devops/architecture.md`
- `docs/modules/platform/architecture-overview.md`
- Sprint file under `docs/implplan/`.
## Coding standards
- Target .NET 10; enable preview features when configured.
- TreatWarningsAsErrors must be true in new projects.
- Deterministic outputs only; avoid environment-dependent behavior.
- Use invariant culture for parsing/formatting in production and tests.
## Testing
- Use xUnit; tests must be offline-safe and deterministic.
- For web services, prefer in-memory TestServer or WebApplicationFactory.
## Sprint/status discipline
- Update sprint task status: TODO -> DOING -> DONE/BLOCKED.
- Log execution updates and decisions in the sprint file.
## Contacts/ownership
- Module owner: DevOps Guild

View File

@@ -1,12 +0,0 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="FluentAssertions" Version="8.8.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>
</Project>

57
devops/README.md Normal file
View File

@@ -0,0 +1,57 @@
# DevOps
Deployment infrastructure for StellaOps.
## Stack
| Component | Technology |
|-----------|------------|
| Database | PostgreSQL 18.1 |
| Cache/Queue | Valkey 9.0.1 |
| Storage | RustFS |
| Transparency | Rekor v2 |
## Structure
```
devops/
├── compose/ # Docker Compose files
├── helm/ # Kubernetes Helm chart
├── docker/ # Dockerfiles
├── database/ # PostgreSQL migrations
├── scripts/ # Operational scripts
├── offline/ # Air-gap support
├── telemetry/ # Alerts & dashboards
├── logging/ # Log config templates
├── release/ # Release tools
├── releases/ # Release manifests
├── secrets/ # Secret templates
└── tools/ # Validation scripts
```
## Quick Start
```bash
# Local stack
docker compose -f devops/compose/docker-compose.stella-ops.yml up -d
# With telemetry
docker compose -f devops/compose/docker-compose.stella-ops.yml \
-f devops/compose/docker-compose.telemetry.yml up -d
# Kubernetes
helm install stellaops devops/helm/stellaops \
-f devops/helm/stellaops/values-prod.yaml \
-n stellaops --create-namespace
```
## Compose Files
| File | Purpose |
|------|---------|
| `stella-ops.yml` | Main stack |
| `telemetry.yml` | Observability |
| `testing.yml` | CI infrastructure |
| `compliance-china.yml` | SM2/SM3/SM4 |
| `compliance-russia.yml` | GOST |
| `compliance-eu.yml` | eIDAS |

View File

@@ -1,181 +0,0 @@
# Zastava Agent Ansible Deployment
Ansible playbook for deploying StellaOps Zastava Agent on VM/bare-metal hosts.
## Prerequisites
- Ansible 2.10 or later
- Target hosts must have:
- Docker installed and running
- SSH access with sudo privileges
- systemd as init system
- Internet access (for downloading agent binaries) OR local artifact repository
## Quick Start
1. **Create inventory file:**
```bash
cp inventory.yml.sample inventory.yml
```
2. **Edit inventory with your hosts and configuration:**
```yaml
zastava_agents:
hosts:
your-host:
ansible_host: 192.168.1.100
ansible_user: ubuntu
vars:
zastava_tenant: your-tenant
scanner_backend_url: https://scanner.internal
```
3. **Run the playbook:**
```bash
ansible-playbook -i inventory.yml zastava-agent.yml
```
## Configuration Variables
### Required Variables
| Variable | Description |
|----------|-------------|
| `zastava_tenant` | Tenant identifier for multi-tenancy isolation |
| `scanner_backend_url` | URL of the Scanner backend service |
### Optional Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `zastava_version` | `latest` | Agent version to deploy |
| `zastava_node_name` | hostname | Override node name in events |
| `zastava_health_port` | `8080` | Health check HTTP port |
| `docker_socket` | `/var/run/docker.sock` | Docker socket path |
| `zastava_log_level` | `Information` | Serilog log level |
| `scanner_backend_insecure` | `false` | Allow HTTP backend (NOT for production) |
| `download_base_url` | `https://releases.stellaops.org` | Base URL for agent downloads |
### Advanced Variables
| Variable | Description |
|----------|-------------|
| `zastava_extra_env` | Dictionary of additional environment variables |
## Directory Structure
After deployment, the agent is installed with the following structure:
```
/opt/stellaops/zastava-agent/ # Agent binaries
/etc/stellaops/zastava-agent.env # Environment configuration
/var/lib/zastava-agent/ # Data directory
/var/lib/zastava-agent/runtime-events/ # Event buffer (disk-backed)
/etc/systemd/system/zastava-agent.service # systemd unit
```
## Post-Deployment Verification
### Check Service Status
```bash
systemctl status zastava-agent
```
### View Logs
```bash
journalctl -u zastava-agent -f
```
### Health Endpoints
| Endpoint | Description |
|----------|-------------|
| `/healthz` | Liveness probe - agent is running |
| `/readyz` | Readiness probe - agent can process events |
| `/livez` | Alias for liveness probe |
```bash
curl http://localhost:8080/healthz
curl http://localhost:8080/readyz
```
## Air-Gapped Deployment
For air-gapped environments:
1. Download agent tarball to a local artifact server
2. Set `download_base_url` to your local server:
```yaml
download_base_url: https://artifacts.internal/stellaops
```
3. Ensure the URL structure matches:
`{download_base_url}/zastava-agent/{version}/zastava-agent-linux-{arch}.tar.gz`
## Security Notes
### Docker Socket Access
The agent requires read access to the Docker socket to monitor container events.
The service runs as the `zastava-agent` user in the `docker` group.
See `docs/modules/zastava/operations/docker-socket-permissions.md` for security
considerations and alternative configurations.
### systemd Hardening
The service unit includes security hardening:
- `NoNewPrivileges=true` - Prevent privilege escalation
- `ProtectSystem=strict` - Read-only system directories
- `PrivateTmp=true` - Isolated /tmp
- `ProtectKernelTunables=true` - No kernel parameter modification
- Resource limits on file descriptors and memory
## Troubleshooting
### Agent Won't Start
1. Check Docker service: `systemctl status docker`
2. Verify Docker socket permissions: `ls -la /var/run/docker.sock`
3. Check agent logs: `journalctl -u zastava-agent -e`
### Cannot Connect to Backend
1. Verify network connectivity: `curl -I ${scanner_backend_url}/healthz`
2. Check TLS certificates if using HTTPS
3. Ensure firewall allows outbound connections
### Events Not Being Sent
1. Check event buffer directory permissions
2. Verify health endpoint returns healthy: `curl localhost:8080/readyz`
3. Check agent logs for connection errors
## Uninstallation
To remove the agent:
```bash
# Stop and disable service
sudo systemctl stop zastava-agent
sudo systemctl disable zastava-agent
# Remove files
sudo rm -rf /opt/stellaops/zastava-agent
sudo rm -f /etc/stellaops/zastava-agent.env
sudo rm -f /etc/systemd/system/zastava-agent.service
sudo rm -rf /var/lib/zastava-agent
# Remove user
sudo userdel zastava-agent
# Reload systemd
sudo systemctl daemon-reload
```

View File

@@ -1,58 +0,0 @@
[Unit]
Description=StellaOps Zastava Agent - Container Runtime Monitor
Documentation=https://docs.stellaops.org/zastava/agent/
After=network-online.target docker.service containerd.service
Wants=network-online.target
Requires=docker.service
[Service]
Type=notify
ExecStart=/opt/stellaops/zastava-agent/StellaOps.Zastava.Agent
WorkingDirectory=/opt/stellaops/zastava-agent
Restart=always
RestartSec=5
# Environment configuration
EnvironmentFile=-/etc/stellaops/zastava-agent.env
Environment=DOTNET_ENVIRONMENT=Production
Environment=ASPNETCORE_ENVIRONMENT=Production
# User and permissions
User=zastava-agent
Group=docker
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictSUIDSGID=true
# Allow read access to Docker socket
ReadWritePaths=/var/run/docker.sock
ReadWritePaths=/var/lib/zastava-agent
# Capabilities
CapabilityBoundingSet=
AmbientCapabilities=
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096
MemoryMax=512M
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=zastava-agent
# Watchdog (5 minute timeout)
WatchdogSec=300
[Install]
WantedBy=multi-user.target

View File

@@ -1,46 +0,0 @@
---
# Sample Ansible Inventory for Zastava Agent Deployment
#
# Copy this file to inventory.yml and customize for your environment.
# Then run: ansible-playbook -i inventory.yml zastava-agent.yml
all:
children:
zastava_agents:
hosts:
# Add your VM/bare-metal hosts here
vm-node-1:
ansible_host: 192.168.1.101
ansible_user: ubuntu
vm-node-2:
ansible_host: 192.168.1.102
ansible_user: ubuntu
# Example with SSH key
vm-node-3:
ansible_host: 192.168.1.103
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/stellaops_key
vars:
# Required: Set these for your environment
zastava_tenant: my-tenant
scanner_backend_url: https://scanner.example.com
# Optional: Override node name per host
# zastava_node_name: custom-node-name
# Optional: Change health check port
# zastava_health_port: 8080
# Optional: Custom Docker socket path
# docker_socket: /var/run/docker.sock
# Optional: Set log level (Verbose, Debug, Information, Warning, Error)
# zastava_log_level: Information
# Optional: Allow insecure HTTP (NOT for production)
# scanner_backend_insecure: false
# Optional: Additional environment variables
# zastava_extra_env:
# CUSTOM_VAR: custom_value

View File

@@ -1,40 +0,0 @@
# StellaOps Zastava Agent Configuration
# Managed by Ansible - Do not edit manually
# Generated: {{ ansible_date_time.iso8601 }}
# Tenant identifier for multi-tenancy
ZASTAVA_TENANT={{ zastava_tenant }}
# Scanner backend URL
ZASTAVA_AGENT__Backend__BaseAddress={{ scanner_backend_url }}
{% if zastava_node_name is defined %}
# Node name override
ZASTAVA_NODE_NAME={{ zastava_node_name }}
{% endif %}
# Docker socket endpoint
ZASTAVA_AGENT__DockerEndpoint=unix://{{ docker_socket }}
# Event buffer path
ZASTAVA_AGENT__EventBufferPath={{ zastava_data_dir }}/runtime-events
# Health check port
ZASTAVA_AGENT__HealthCheck__Port={{ zastava_health_port }}
{% if scanner_backend_insecure | default(false) | bool %}
# WARNING: Insecure HTTP backend enabled
ZASTAVA_AGENT__Backend__AllowInsecureHttp=true
{% endif %}
{% if zastava_log_level is defined %}
# Logging level
Serilog__MinimumLevel__Default={{ zastava_log_level }}
{% endif %}
{% if zastava_extra_env is defined %}
# Additional environment variables
{% for key, value in zastava_extra_env.items() %}
{{ key }}={{ value }}
{% endfor %}
{% endif %}

View File

@@ -1,232 +0,0 @@
---
# Ansible Playbook for Zastava Agent VM/Bare-Metal Deployment
#
# Requirements:
# - Target hosts must have Docker installed and running
# - Ansible 2.10+ with community.docker collection
#
# Usage:
# ansible-playbook -i inventory.yml zastava-agent.yml \
# -e zastava_tenant=my-tenant \
# -e scanner_backend_url=https://scanner.internal
#
# Variables (can be set in inventory or via -e):
# zastava_tenant: Tenant identifier (required)
# scanner_backend_url: Scanner backend URL (required)
# zastava_version: Version to deploy (default: latest)
# zastava_node_name: Override node name (default: hostname)
# zastava_health_port: Health check port (default: 8080)
# docker_socket: Docker socket path (default: /var/run/docker.sock)
- name: Deploy StellaOps Zastava Agent
hosts: zastava_agents
become: true
vars:
zastava_version: "{{ zastava_version | default('latest') }}"
zastava_install_dir: /opt/stellaops/zastava-agent
zastava_config_dir: /etc/stellaops
zastava_data_dir: /var/lib/zastava-agent
zastava_user: zastava-agent
zastava_group: docker
zastava_health_port: "{{ zastava_health_port | default(8080) }}"
docker_socket: "{{ docker_socket | default('/var/run/docker.sock') }}"
download_base_url: "{{ download_base_url | default('https://releases.stellaops.org') }}"
pre_tasks:
- name: Validate required variables
ansible.builtin.assert:
that:
- zastava_tenant is defined and zastava_tenant | length > 0
- scanner_backend_url is defined and scanner_backend_url | length > 0
fail_msg: |
Required variables not set.
Please provide:
- zastava_tenant: Your tenant identifier
- scanner_backend_url: Scanner backend URL
- name: Check Docker service is running
ansible.builtin.systemd:
name: docker
state: started
check_mode: true
register: docker_status
- name: Fail if Docker is not available
ansible.builtin.fail:
msg: "Docker service is not running on {{ inventory_hostname }}"
when: docker_status.status.ActiveState != 'active'
tasks:
# =========================================================================
# User and Directory Setup
# =========================================================================
- name: Create zastava-agent system user
ansible.builtin.user:
name: "{{ zastava_user }}"
comment: StellaOps Zastava Agent
system: true
shell: /usr/sbin/nologin
groups: "{{ zastava_group }}"
create_home: false
state: present
- name: Create installation directory
ansible.builtin.file:
path: "{{ zastava_install_dir }}"
state: directory
owner: "{{ zastava_user }}"
group: "{{ zastava_group }}"
mode: '0755'
- name: Create configuration directory
ansible.builtin.file:
path: "{{ zastava_config_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Create data directory
ansible.builtin.file:
path: "{{ zastava_data_dir }}"
state: directory
owner: "{{ zastava_user }}"
group: "{{ zastava_group }}"
mode: '0750'
- name: Create event buffer directory
ansible.builtin.file:
path: "{{ zastava_data_dir }}/runtime-events"
state: directory
owner: "{{ zastava_user }}"
group: "{{ zastava_group }}"
mode: '0750'
# =========================================================================
# Download and Install Agent
# =========================================================================
- name: Determine architecture
ansible.builtin.set_fact:
arch_suffix: "{{ 'x64' if ansible_architecture == 'x86_64' else 'arm64' if ansible_architecture == 'aarch64' else ansible_architecture }}"
- name: Download Zastava Agent binary
ansible.builtin.get_url:
url: "{{ download_base_url }}/zastava-agent/{{ zastava_version }}/zastava-agent-linux-{{ arch_suffix }}.tar.gz"
dest: /tmp/zastava-agent.tar.gz
mode: '0644'
register: download_result
retries: 3
delay: 5
- name: Extract Zastava Agent
ansible.builtin.unarchive:
src: /tmp/zastava-agent.tar.gz
dest: "{{ zastava_install_dir }}"
remote_src: true
owner: "{{ zastava_user }}"
group: "{{ zastava_group }}"
extra_opts:
- --strip-components=1
notify: Restart zastava-agent
- name: Make agent binary executable
ansible.builtin.file:
path: "{{ zastava_install_dir }}/StellaOps.Zastava.Agent"
mode: '0755'
- name: Clean up downloaded archive
ansible.builtin.file:
path: /tmp/zastava-agent.tar.gz
state: absent
# =========================================================================
# Configuration
# =========================================================================
- name: Deploy environment configuration
ansible.builtin.template:
src: zastava-agent.env.j2
dest: "{{ zastava_config_dir }}/zastava-agent.env"
owner: root
group: "{{ zastava_group }}"
mode: '0640'
notify: Restart zastava-agent
# =========================================================================
# systemd Service
# =========================================================================
- name: Install systemd service unit
ansible.builtin.copy:
src: zastava-agent.service
dest: /etc/systemd/system/zastava-agent.service
owner: root
group: root
mode: '0644'
notify:
- Reload systemd
- Restart zastava-agent
- name: Enable and start zastava-agent service
ansible.builtin.systemd:
name: zastava-agent
state: started
enabled: true
daemon_reload: true
# =========================================================================
# Health Verification
# =========================================================================
- name: Wait for agent health endpoint
ansible.builtin.uri:
url: "http://localhost:{{ zastava_health_port }}/healthz"
method: GET
status_code: 200
register: health_result
retries: 30
delay: 2
until: health_result.status == 200
- name: Display agent status
ansible.builtin.debug:
msg: "Zastava Agent deployed successfully on {{ inventory_hostname }}"
handlers:
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Restart zastava-agent
ansible.builtin.systemd:
name: zastava-agent
state: restarted
# =============================================================================
# Post-deployment verification play
# =============================================================================
- name: Verify Zastava Agent Deployment
hosts: zastava_agents
become: false
gather_facts: false
tasks:
- name: Check agent readiness
ansible.builtin.uri:
url: "http://localhost:{{ zastava_health_port | default(8080) }}/readyz"
method: GET
return_content: true
register: ready_check
- name: Display deployment summary
ansible.builtin.debug:
msg: |
Zastava Agent Deployment Summary:
- Host: {{ inventory_hostname }}
- Status: {{ 'Ready' if ready_check.status == 200 else 'Not Ready' }}
- Health Endpoint: http://localhost:{{ zastava_health_port | default(8080) }}/healthz
- Tenant: {{ zastava_tenant }}
- Backend: {{ scanner_backend_url }}

View File

@@ -1,474 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="f3a0021b-dfb3-4082-af95-f1eafac6d6e5" name="@DESKTOP-7GHGC2M 2025-11-25 03:06:57" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2025-11-25T03:06:57.6881410+00:00" queuing="2025-11-25T03:06:57.6881411+00:00" start="2025-11-25T03:06:19.0356492+00:00" finish="2025-11-25T03:06:57.6979352+00:00" />
<TestSettings name="default" id="67ad58d5-5c7e-42c3-a9e6-344f5eac3e53">
<Deployment runDeploymentRoot="_DESKTOP-7GHGC2M_2025-11-25_03_06_57" />
</TestSettings>
<Results>
<UnitTestResult executionId="d3dec3a6-6647-4d62-a7d5-f372009ed25b" testId="fbedf19a-bc7b-9a2d-979a-ba574f7a6f23" testName="StellaOps.Concelier.WebService.Tests.WebServiceEndpointsTests.HealthAndReadyEndpointsRespond" computerName="DESKTOP-7GHGC2M" duration="00:00:00.4031915" startTime="2025-11-25T03:06:57.5011498+00:00" endTime="2025-11-25T03:06:57.5011813+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="d3dec3a6-6647-4d62-a7d5-f372009ed25b" />
</Results>
<TestDefinitions>
<UnitTest name="StellaOps.Concelier.WebService.Tests.WebServiceEndpointsTests.HealthAndReadyEndpointsRespond" storage="/mnt/e/dev/git.stella-ops.org/src/concelier/__tests/stellaops.concelier.webservice.tests/bin/debug/net10.0/stellaops.concelier.webservice.tests.dll" id="fbedf19a-bc7b-9a2d-979a-ba574f7a6f23">
<Execution id="d3dec3a6-6647-4d62-a7d5-f372009ed25b" />
<TestMethod codeBase="/mnt/e/dev/git.stella-ops.org/src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/bin/Debug/net10.0/StellaOps.Concelier.WebService.Tests.dll" adapterTypeName="executor://xunit/VsTestRunner2/netcoreapp" className="StellaOps.Concelier.WebService.Tests.WebServiceEndpointsTests" name="HealthAndReadyEndpointsRespond" />
</UnitTest>
</TestDefinitions>
<TestEntries>
<TestEntry testId="fbedf19a-bc7b-9a2d-979a-ba574f7a6f23" executionId="d3dec3a6-6647-4d62-a7d5-f372009ed25b" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
</TestEntries>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Completed">
<Counters total="1" executed="1" passed="1" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0-rc.2.25502.107)
[xUnit.net 00:00:00.26] Discovering: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.33] Discovered: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.34] Starting: StellaOps.Concelier.WebService.Tests
{"t":{"$date":"2025-11-25T03:06:53.170+00:00"},"s":"I", "c":"CONTROL", "id":23285, "ctx":"main","msg":"Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'"}
{"t":{"$date":"2025-11-25T03:06:53.171+00:00"},"s":"W", "c":"ASIO", "id":22601, "ctx":"main","msg":"No TransportLayer configured during NetworkInterface startup"}
{"t":{"$date":"2025-11-25T03:06:53.171+00:00"},"s":"I", "c":"NETWORK", "id":4648601, "ctx":"main","msg":"Implicit TCP FastOpen unavailable. If TCP FastOpen is required, set tcpFastOpenServer, tcpFastOpenClient, and tcpFastOpenQueueSize."}
{"t":{"$date":"2025-11-25T03:06:53.171+00:00"},"s":"W", "c":"ASIO", "id":22601, "ctx":"main","msg":"No TransportLayer configured during NetworkInterface startup"}
{"t":{"$date":"2025-11-25T03:06:53.172+00:00"},"s":"I", "c":"STORAGE", "id":4615611, "ctx":"initandlisten","msg":"MongoDB starting","attr":{"pid":138154,"port":33929,"dbPath":"/tmp/yifc3x13.bsnecd0ff0e2d3d45ff96e2_33929","architecture":"64-bit","host":"DESKTOP-7GHGC2M"}}
{"t":{"$date":"2025-11-25T03:06:53.172+00:00"},"s":"I", "c":"CONTROL", "id":23403, "ctx":"initandlisten","msg":"Build Info","attr":{"buildInfo":{"version":"4.4.4","gitVersion":"8db30a63db1a9d84bdcad0c83369623f708e0397","openSSLVersion":"OpenSSL 1.1.1f 31 Mar 2020","modules":[],"allocator":"tcmalloc","environment":{"distmod":"ubuntu2004","distarch":"x86_64","target_arch":"x86_64"}}}}
{"t":{"$date":"2025-11-25T03:06:53.172+00:00"},"s":"I", "c":"CONTROL", "id":51765, "ctx":"initandlisten","msg":"Operating System","attr":{"os":{"name":"Ubuntu","version":"24.04"}}}
{"t":{"$date":"2025-11-25T03:06:53.172+00:00"},"s":"I", "c":"CONTROL", "id":21951, "ctx":"initandlisten","msg":"Options set by command line","attr":{"options":{"net":{"bindIp":"127.0.0.1","port":33929},"replication":{"replSet":"singleNodeReplSet"},"storage":{"dbPath":"/tmp/yifc3x13.bsnecd0ff0e2d3d45ff96e2_33929"}}}}
{"t":{"$date":"2025-11-25T03:06:53.173+00:00"},"s":"I", "c":"STORAGE", "id":22297, "ctx":"initandlisten","msg":"Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem","tags":["startupWarnings"]}
{"t":{"$date":"2025-11-25T03:06:53.174+00:00"},"s":"I", "c":"STORAGE", "id":22315, "ctx":"initandlisten","msg":"Opening WiredTiger","attr":{"config":"create,cache_size=7485M,session_max=33000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000,close_scan_interval=10,close_handle_minimum=250),statistics_log=(wait=0),verbose=[recovery_progress,checkpoint_progress,compact_progress],"}}
{"t":{"$date":"2025-11-25T03:06:53.622+00:00"},"s":"I", "c":"STORAGE", "id":22430, "ctx":"initandlisten","msg":"WiredTiger message","attr":{"message":"[1764040013:622123][138154:0x72dd8d1c4cc0], txn-recover: [WT_VERB_RECOVERY | WT_VERB_RECOVERY_PROGRESS] Set global recovery timestamp: (0, 0)"}}
{"t":{"$date":"2025-11-25T03:06:53.622+00:00"},"s":"I", "c":"STORAGE", "id":22430, "ctx":"initandlisten","msg":"WiredTiger message","attr":{"message":"[1764040013:622190][138154:0x72dd8d1c4cc0], txn-recover: [WT_VERB_RECOVERY | WT_VERB_RECOVERY_PROGRESS] Set global oldest timestamp: (0, 0)"}}
{"t":{"$date":"2025-11-25T03:06:53.635+00:00"},"s":"I", "c":"STORAGE", "id":4795906, "ctx":"initandlisten","msg":"WiredTiger opened","attr":{"durationMillis":461}}
{"t":{"$date":"2025-11-25T03:06:53.635+00:00"},"s":"I", "c":"RECOVERY", "id":23987, "ctx":"initandlisten","msg":"WiredTiger recoveryTimestamp","attr":{"recoveryTimestamp":{"$timestamp":{"t":0,"i":0}}}}
{"t":{"$date":"2025-11-25T03:06:53.667+00:00"},"s":"I", "c":"STORAGE", "id":4366408, "ctx":"initandlisten","msg":"No table logging settings modifications are required for existing WiredTiger tables","attr":{"loggingEnabled":false}}
{"t":{"$date":"2025-11-25T03:06:53.668+00:00"},"s":"I", "c":"STORAGE", "id":22262, "ctx":"initandlisten","msg":"Timestamp monitor starting"}
{"t":{"$date":"2025-11-25T03:06:53.676+00:00"},"s":"W", "c":"CONTROL", "id":22120, "ctx":"initandlisten","msg":"Access control is not enabled for the database. Read and write access to data and configuration is unrestricted","tags":["startupWarnings"]}
{"t":{"$date":"2025-11-25T03:06:53.677+00:00"},"s":"I", "c":"STORAGE", "id":20536, "ctx":"initandlisten","msg":"Flow Control is enabled on this deployment"}
{"t":{"$date":"2025-11-25T03:06:53.679+00:00"},"s":"I", "c":"SHARDING", "id":20997, "ctx":"initandlisten","msg":"Refreshed RWC defaults","attr":{"newDefaults":{}}}
{"t":{"$date":"2025-11-25T03:06:53.679+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"local.startup_log","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"5f608eed-817b-4ac1-94e3-ae0e0a954ec5"}},"options":{"capped":true,"size":10485760}}}
{"t":{"$date":"2025-11-25T03:06:53.697+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.startup_log","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}
{"t":{"$date":"2025-11-25T03:06:53.697+00:00"},"s":"I", "c":"FTDC", "id":20625, "ctx":"initandlisten","msg":"Initializing full-time diagnostic data capture","attr":{"dataDirectory":"/tmp/yifc3x13.bsnecd0ff0e2d3d45ff96e2_33929/diagnostic.data"}}
{"t":{"$date":"2025-11-25T03:06:53.699+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"local.replset.oplogTruncateAfterPoint","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"763ae47e-5634-4a14-9ef6-4ffd6dc93918"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:53.720+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.replset.oplogTruncateAfterPoint","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}
{"t":{"$date":"2025-11-25T03:06:53.720+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"local.replset.minvalid","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"54bed8e9-a7bd-4897-8c05-ad4fa62f77c5"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:53.740+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.replset.minvalid","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}
{"t":{"$date":"2025-11-25T03:06:53.740+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"local.replset.election","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"97e32968-ba25-4803-bcca-c4008661ee27"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:53.759+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.replset.election","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}
{"t":{"$date":"2025-11-25T03:06:53.760+00:00"},"s":"I", "c":"REPL", "id":21311, "ctx":"initandlisten","msg":"Did not find local initialized voted for document at startup"}
{"t":{"$date":"2025-11-25T03:06:53.760+00:00"},"s":"I", "c":"REPL", "id":21312, "ctx":"initandlisten","msg":"Did not find local Rollback ID document at startup. Creating one"}
{"t":{"$date":"2025-11-25T03:06:53.760+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"initandlisten","msg":"createCollection","attr":{"namespace":"local.system.rollback.id","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"c9e78c6d-5f57-428c-b6d4-05340e2fef65"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:53.781+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"initandlisten","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.system.rollback.id","index":"_id_","commitTimestamp":{"$timestamp":{"t":0,"i":0}}}}
{"t":{"$date":"2025-11-25T03:06:53.781+00:00"},"s":"I", "c":"REPL", "id":21531, "ctx":"initandlisten","msg":"Initialized the rollback ID","attr":{"rbid":1}}
{"t":{"$date":"2025-11-25T03:06:53.781+00:00"},"s":"I", "c":"REPL", "id":21313, "ctx":"initandlisten","msg":"Did not find local replica set configuration document at startup","attr":{"error":{"code":47,"codeName":"NoMatchingDocument","errmsg":"Did not find replica set configuration document in local.system.replset"}}}
{"t":{"$date":"2025-11-25T03:06:53.782+00:00"},"s":"I", "c":"CONTROL", "id":20714, "ctx":"LogicalSessionCacheRefresh","msg":"Failed to refresh session cache, will try again at the next refresh interval","attr":{"error":"NotYetInitialized: Replication has not yet been configured"}}
{"t":{"$date":"2025-11-25T03:06:53.783+00:00"},"s":"I", "c":"CONTROL", "id":20712, "ctx":"LogicalSessionCacheReap","msg":"Sessions collection is not set up; waiting until next sessions reap interval","attr":{"error":"NamespaceNotFound: config.system.sessions does not exist"}}
{"t":{"$date":"2025-11-25T03:06:53.783+00:00"},"s":"I", "c":"REPL", "id":40440, "ctx":"initandlisten","msg":"Starting the TopologyVersionObserver"}
{"t":{"$date":"2025-11-25T03:06:53.783+00:00"},"s":"I", "c":"REPL", "id":40445, "ctx":"TopologyVersionObserver","msg":"Started TopologyVersionObserver"}
{"t":{"$date":"2025-11-25T03:06:53.784+00:00"},"s":"I", "c":"NETWORK", "id":23015, "ctx":"listener","msg":"Listening on","attr":{"address":"/tmp/mongodb-33929.sock"}}
{"t":{"$date":"2025-11-25T03:06:53.784+00:00"},"s":"I", "c":"NETWORK", "id":23015, "ctx":"listener","msg":"Listening on","attr":{"address":"127.0.0.1"}}
{"t":{"$date":"2025-11-25T03:06:53.784+00:00"},"s":"I", "c":"NETWORK", "id":23016, "ctx":"listener","msg":"Waiting for connections","attr":{"port":33929,"ssl":"off"}}
{"t":{"$date":"2025-11-25T03:06:53.796+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47046","connectionId":1,"connectionCount":1}}
{"t":{"$date":"2025-11-25T03:06:53.820+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn1","msg":"client metadata","attr":{"remote":"127.0.0.1:47046","client":"conn1","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:53.852+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47050","connectionId":2,"connectionCount":2}}
{"t":{"$date":"2025-11-25T03:06:53.854+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn2","msg":"client metadata","attr":{"remote":"127.0.0.1:47050","client":"conn2","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:53.859+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47052","connectionId":3,"connectionCount":3}}
{"t":{"$date":"2025-11-25T03:06:53.860+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn3","msg":"client metadata","attr":{"remote":"127.0.0.1:47052","client":"conn3","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:53.872+00:00"},"s":"I", "c":"REPL", "id":21356, "ctx":"conn3","msg":"replSetInitiate admin command received from client"}
{"t":{"$date":"2025-11-25T03:06:53.872+00:00"},"s":"I", "c":"REPL", "id":21357, "ctx":"conn3","msg":"replSetInitiate config object parses ok","attr":{"numMembers":1}}
{"t":{"$date":"2025-11-25T03:06:53.872+00:00"},"s":"I", "c":"REPL", "id":21251, "ctx":"conn3","msg":"Creating replication oplog","attr":{"oplogSizeMB":48118}}
{"t":{"$date":"2025-11-25T03:06:53.872+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"local.oplog.rs","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"26641ba6-7282-4c09-a7b5-c06683c09d25"}},"options":{"capped":true,"size":50456355840.0,"autoIndexId":false}}}
{"t":{"$date":"2025-11-25T03:06:53.881+00:00"},"s":"I", "c":"STORAGE", "id":22383, "ctx":"conn3","msg":"The size storer reports that the oplog contains","attr":{"numRecords":0,"dataSize":0}}
{"t":{"$date":"2025-11-25T03:06:53.881+00:00"},"s":"I", "c":"STORAGE", "id":22382, "ctx":"conn3","msg":"WiredTiger record store oplog processing finished","attr":{"durationMillis":0}}
{"t":{"$date":"2025-11-25T03:06:53.921+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"local.system.replset","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"e329ace1-6110-413a-a7f9-c929c43b7823"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:53.941+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.system.replset","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040013,"i":1}}}}
{"t":{"$date":"2025-11-25T03:06:53.942+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"admin.system.version","uuidDisposition":"provided","uuid":{"uuid":{"$uuid":"1515c214-38af-4280-bd1e-e79281395c7e"}},"options":{"uuid":{"$uuid":"1515c214-38af-4280-bd1e-e79281395c7e"}}}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"admin.system.version","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040013,"i":1}}}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"COMMAND", "id":20459, "ctx":"conn3","msg":"Setting featureCompatibilityVersion","attr":{"newVersion":"4.4"}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"NETWORK", "id":22991, "ctx":"conn3","msg":"Skip closing connection for connection","attr":{"connectionId":3}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"NETWORK", "id":22991, "ctx":"conn3","msg":"Skip closing connection for connection","attr":{"connectionId":2}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"NETWORK", "id":22991, "ctx":"conn3","msg":"Skip closing connection for connection","attr":{"connectionId":1}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"REPL", "id":21392, "ctx":"conn3","msg":"New replica set config in use","attr":{"config":{"_id":"singleNodeReplSet","version":1,"term":0,"protocolVersion":1,"writeConcernMajorityJournalDefault":true,"members":[{"_id":0,"host":"127.0.0.1:33929","arbiterOnly":false,"buildIndexes":true,"hidden":false,"priority":1.0,"tags":{},"slaveDelay":0,"votes":1}],"settings":{"chainingAllowed":true,"heartbeatIntervalMillis":2000,"heartbeatTimeoutSecs":10,"electionTimeoutMillis":10000,"catchUpTimeoutMillis":-1,"catchUpTakeoverDelayMillis":30000,"getLastErrorModes":{},"getLastErrorDefaults":{"w":1,"wtimeout":0},"replicaSetId":{"$oid":"69251d4d4fa9b5bd940f91b6"}}}}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"REPL", "id":21393, "ctx":"conn3","msg":"Found self in config","attr":{"hostAndPort":"127.0.0.1:33929"}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"REPL", "id":21358, "ctx":"conn3","msg":"Replica set state transition","attr":{"newState":"STARTUP2","oldState":"STARTUP"}}
{"t":{"$date":"2025-11-25T03:06:53.959+00:00"},"s":"I", "c":"REPL", "id":21306, "ctx":"conn3","msg":"Starting replication storage threads"}
{"t":{"$date":"2025-11-25T03:06:53.963+00:00"},"s":"I", "c":"REPL", "id":21358, "ctx":"conn3","msg":"Replica set state transition","attr":{"newState":"RECOVERING","oldState":"STARTUP2"}}
{"t":{"$date":"2025-11-25T03:06:53.963+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"local.replset.initialSyncId","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"2f0157f6-a696-485a-90cd-25ebdc98434e"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:53.981+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"local.replset.initialSyncId","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040013,"i":1}}}}
{"t":{"$date":"2025-11-25T03:06:53.981+00:00"},"s":"I", "c":"REPL", "id":21299, "ctx":"conn3","msg":"Starting replication fetcher thread"}
{"t":{"$date":"2025-11-25T03:06:53.981+00:00"},"s":"I", "c":"REPL", "id":21300, "ctx":"conn3","msg":"Starting replication applier thread"}
{"t":{"$date":"2025-11-25T03:06:53.981+00:00"},"s":"I", "c":"REPL", "id":21301, "ctx":"conn3","msg":"Starting replication reporter thread"}
{"t":{"$date":"2025-11-25T03:06:53.981+00:00"},"s":"I", "c":"REPL", "id":21224, "ctx":"OplogApplier-0","msg":"Starting oplog application"}
{"t":{"$date":"2025-11-25T03:06:53.981+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn3","msg":"Slow query","attr":{"type":"command","ns":"local.system.replset","command":{"replSetInitiate":{"_id":"singleNodeReplSet","members":[{"_id":0,"host":"127.0.0.1:33929"}]},"$db":"admin","lsid":{"id":{"$uuid":"e2f41f2f-e77f-4af9-81e0-32d8592d6a54"}}},"numYields":0,"reslen":163,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":18}},"ReplicationStateTransition":{"acquireCount":{"w":19}},"Global":{"acquireCount":{"r":11,"w":6,"W":2}},"Database":{"acquireCount":{"r":10,"w":4,"W":2}},"Collection":{"acquireCount":{"r":3,"w":5}},"Mutex":{"acquireCount":{"r":17}},"oplog":{"acquireCount":{"w":1}}},"flowControl":{"acquireCount":5,"timeAcquiringMicros":5},"storage":{},"protocol":"op_msg","durationMillis":109}}
{"t":{"$date":"2025-11-25T03:06:53.982+00:00"},"s":"I", "c":"REPL", "id":21358, "ctx":"OplogApplier-0","msg":"Replica set state transition","attr":{"newState":"SECONDARY","oldState":"RECOVERING"}}
{"t":{"$date":"2025-11-25T03:06:53.982+00:00"},"s":"I", "c":"ELECTION", "id":4615652, "ctx":"OplogApplier-0","msg":"Starting an election, since we've seen no PRIMARY in election timeout period","attr":{"electionTimeoutPeriodMillis":10000}}
{"t":{"$date":"2025-11-25T03:06:53.982+00:00"},"s":"I", "c":"ELECTION", "id":21438, "ctx":"OplogApplier-0","msg":"Conducting a dry run election to see if we could be elected","attr":{"currentTerm":0}}
{"t":{"$date":"2025-11-25T03:06:53.982+00:00"},"s":"I", "c":"ELECTION", "id":21444, "ctx":"ReplCoord-0","msg":"Dry election run succeeded, running for election","attr":{"newTerm":1}}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"ELECTION", "id":21450, "ctx":"ReplCoord-1","msg":"Election succeeded, assuming primary role","attr":{"term":1}}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21358, "ctx":"ReplCoord-1","msg":"Replica set state transition","attr":{"newState":"PRIMARY","oldState":"SECONDARY"}}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21106, "ctx":"ReplCoord-1","msg":"Resetting sync source to empty","attr":{"previousSyncSource":":27017"}}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21359, "ctx":"ReplCoord-1","msg":"Entering primary catch-up mode"}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21363, "ctx":"ReplCoord-1","msg":"Exited primary catch-up mode"}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21107, "ctx":"ReplCoord-1","msg":"Stopping replication producer"}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21239, "ctx":"ReplBatcher","msg":"Oplog buffer has been drained","attr":{"term":1}}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21343, "ctx":"RstlKillOpThread","msg":"Starting to kill user operations"}
{"t":{"$date":"2025-11-25T03:06:53.984+00:00"},"s":"I", "c":"REPL", "id":21344, "ctx":"RstlKillOpThread","msg":"Stopped killing user operations"}
{"t":{"$date":"2025-11-25T03:06:53.985+00:00"},"s":"I", "c":"REPL", "id":21340, "ctx":"RstlKillOpThread","msg":"State transition ops metrics","attr":{"metrics":{"lastStateTransition":"stepUp","userOpsKilled":0,"userOpsRunning":1}}}
{"t":{"$date":"2025-11-25T03:06:53.985+00:00"},"s":"I", "c":"REPL", "id":4508103, "ctx":"OplogApplier-0","msg":"Increment the config term via reconfig"}
{"t":{"$date":"2025-11-25T03:06:53.985+00:00"},"s":"I", "c":"REPL", "id":21353, "ctx":"OplogApplier-0","msg":"replSetReconfig config object parses ok","attr":{"numMembers":1}}
{"t":{"$date":"2025-11-25T03:06:53.985+00:00"},"s":"I", "c":"REPL", "id":51814, "ctx":"OplogApplier-0","msg":"Persisting new config to disk"}
{"t":{"$date":"2025-11-25T03:06:53.986+00:00"},"s":"I", "c":"REPL", "id":21392, "ctx":"OplogApplier-0","msg":"New replica set config in use","attr":{"config":{"_id":"singleNodeReplSet","version":1,"term":1,"protocolVersion":1,"writeConcernMajorityJournalDefault":true,"members":[{"_id":0,"host":"127.0.0.1:33929","arbiterOnly":false,"buildIndexes":true,"hidden":false,"priority":1.0,"tags":{},"slaveDelay":0,"votes":1}],"settings":{"chainingAllowed":true,"heartbeatIntervalMillis":2000,"heartbeatTimeoutSecs":10,"electionTimeoutMillis":10000,"catchUpTimeoutMillis":-1,"catchUpTakeoverDelayMillis":30000,"getLastErrorModes":{},"getLastErrorDefaults":{"w":1,"wtimeout":0},"replicaSetId":{"$oid":"69251d4d4fa9b5bd940f91b6"}}}}}
{"t":{"$date":"2025-11-25T03:06:53.986+00:00"},"s":"I", "c":"REPL", "id":21393, "ctx":"OplogApplier-0","msg":"Found self in config","attr":{"hostAndPort":"127.0.0.1:33929"}}
{"t":{"$date":"2025-11-25T03:06:53.986+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"OplogApplier-0","msg":"createCollection","attr":{"namespace":"config.transactions","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"7b6e3a69-23e4-40fc-8365-b5c595eea4b1"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:54.003+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"OplogApplier-0","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"config.transactions","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040013,"i":3}}}}
{"t":{"$date":"2025-11-25T03:06:54.003+00:00"},"s":"I", "c":"STORAGE", "id":20657, "ctx":"OplogApplier-0","msg":"IndexBuildsCoordinator::onStepUp - this node is stepping up to primary"}
{"t":{"$date":"2025-11-25T03:06:54.004+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"OplogApplier-0","msg":"createCollection","attr":{"namespace":"config.system.indexBuilds","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"a78b2f2c-d49d-40ec-b777-5c4f678f8ea2"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:54.019+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"OplogApplier-0","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"config.system.indexBuilds","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040014,"i":2}}}}
{"t":{"$date":"2025-11-25T03:06:54.019+00:00"},"s":"I", "c":"REPL", "id":21331, "ctx":"OplogApplier-0","msg":"Transition to primary complete; database writes are now permitted"}
{"t":{"$date":"2025-11-25T03:06:54.020+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"monitoring-keys-for-HMAC","msg":"createCollection","attr":{"namespace":"admin.system.keys","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"5ac7de93-626f-4635-aad0-423907ebaaae"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:54.036+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"monitoring-keys-for-HMAC","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"admin.system.keys","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040014,"i":3}}}}
{"t":{"$date":"2025-11-25T03:06:54.038+00:00"},"s":"I", "c":"STORAGE", "id":22310, "ctx":"WTJournalFlusher","msg":"Triggering the first stable checkpoint","attr":{"initialData":{"$timestamp":{"t":1764040013,"i":1}},"prevStable":{"$timestamp":{"t":0,"i":0}},"currStable":{"$timestamp":{"t":1764040014,"i":4}}}}
warn: StellaOps.Concelier.WebService[0]
Authority enabled: False, test signing secret configured: True
warn: StellaOps.Concelier.WebService[0]
Legacy merge module disabled via concelier:features:noMergeEnabled; Link-Not-Merge mode active.
{"t":{"$date":"2025-11-25T03:06:55.284+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.source","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"b5dcc880-19fc-4c9b-a878-ac99d5f77246"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.308+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":1}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection source
{"t":{"$date":"2025-11-25T03:06:55.316+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.source_state","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"9475ed88-bc52-4c6d-abcb-5dfaf2d5cf5b"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.336+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source_state","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":2}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection source_state
{"t":{"$date":"2025-11-25T03:06:55.339+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.document","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"ad2a5b15-8e65-4ed1-9efa-d0fd1e643131"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.358+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.document","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":3}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection document
{"t":{"$date":"2025-11-25T03:06:55.361+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.dto","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"81a72f1b-58d0-4a25-a0bc-0dd9362247f8"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.377+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.dto","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":4}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection dto
{"t":{"$date":"2025-11-25T03:06:55.380+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.advisory","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"c2e4124c-bf80-4e3c-9272-cea8f40106f5"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.397+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":5}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection advisory
{"t":{"$date":"2025-11-25T03:06:55.400+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.advisory_raw","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"70542ec2-832b-4f93-8c96-4ca814f1fbbc"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.416+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_raw","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":6}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection advisory_raw
{"t":{"$date":"2025-11-25T03:06:55.419+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.alias","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"6a6a3cc5-2ba2-4756-bf3f-197fd1a306a0"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.435+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.alias","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":7}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection alias
{"t":{"$date":"2025-11-25T03:06:55.438+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.affected","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"ef930a9b-1097-41f9-9d77-2659520d64dc"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.456+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.affected","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":8}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection affected
{"t":{"$date":"2025-11-25T03:06:55.460+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.reference","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"24d0213b-0677-42fa-b7ae-b0a19b36317d"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.495+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.reference","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":9}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection reference
{"t":{"$date":"2025-11-25T03:06:55.499+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.kev_flag","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"3155caef-fd8b-4512-8480-f18fea9f8ae9"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.520+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.kev_flag","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":10}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection kev_flag
{"t":{"$date":"2025-11-25T03:06:55.524+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.ru_flags","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"4c64a0cb-1b22-4055-8cf9-2ddaf8b2eecc"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.541+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.ru_flags","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":11}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection ru_flags
{"t":{"$date":"2025-11-25T03:06:55.544+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.jp_flags","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"39e4df97-ce8e-4ae2-9996-eae3fb682e43"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.562+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.jp_flags","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":12}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection jp_flags
{"t":{"$date":"2025-11-25T03:06:55.565+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.psirt_flags","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"d61fab06-e185-4905-a581-78d6188f9cbf"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.597+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.psirt_flags","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":13}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection psirt_flags
{"t":{"$date":"2025-11-25T03:06:55.600+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.merge_event","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"21f05a29-c17f-4fae-af85-30ede0275435"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.621+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.merge_event","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":14}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection merge_event
{"t":{"$date":"2025-11-25T03:06:55.624+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.export_state","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"1d816e12-6eb0-40fa-87ae-8bac12a31e53"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.642+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.export_state","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":15}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection export_state
{"t":{"$date":"2025-11-25T03:06:55.645+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.source_change_history","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"0c0938b6-7eb1-4e92-a8a8-5ed971581ddc"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.662+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source_change_history","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":16}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection source_change_history
{"t":{"$date":"2025-11-25T03:06:55.665+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.advisory_statements","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"46b5cd3a-fd22-47d2-81cc-2c756d9cfe62"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.682+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_statements","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":17}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection advisory_statements
{"t":{"$date":"2025-11-25T03:06:55.685+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.advisory_conflicts","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"e830a702-eb38-4e79-bd71-139b63066228"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.702+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_conflicts","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":18}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection advisory_conflicts
{"t":{"$date":"2025-11-25T03:06:55.705+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.advisory_observations","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"2d30c6a9-a970-4507-9548-c93174011df9"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.730+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observations","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":19}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection advisory_observations
{"t":{"$date":"2025-11-25T03:06:55.733+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.locks","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"c8dc3f6d-0481-4693-ad61-36b23257b47f"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.752+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.locks","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":20}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection locks
{"t":{"$date":"2025-11-25T03:06:55.755+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.jobs","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"b46075e8-3e6f-4a66-913f-60021219351a"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.773+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.jobs","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":21}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection jobs
{"t":{"$date":"2025-11-25T03:06:55.776+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn3","msg":"createCollection","attr":{"namespace":"concelier.schema_migrations","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"41eb8ab9-7155-4f1f-929d-bf08fe8d877e"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.798+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.schema_migrations","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":22}}}}
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Created Mongo collection schema_migrations
{"t":{"$date":"2025-11-25T03:06:55.823+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn3","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"5c6b2846-9d1d-46de-ac5f-b2f85a6d097c"}},"namespace":"concelier.locks","collectionUUID":{"uuid":{"$uuid":"c8dc3f6d-0481-4693-ad61-36b23257b47f"}},"indexes":1,"firstIndex":{"name":"ttl_at_ttl"}}}
{"t":{"$date":"2025-11-25T03:06:55.831+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.locks","index":"ttl_at_ttl","commitTimestamp":{"$timestamp":{"t":1764040015,"i":23}}}}
{"t":{"$date":"2025-11-25T03:06:55.831+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn3","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"5c6b2846-9d1d-46de-ac5f-b2f85a6d097c"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:55.831+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn3","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"5c6b2846-9d1d-46de-ac5f-b2f85a6d097c"}}}}
{"t":{"$date":"2025-11-25T03:06:55.835+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47428","connectionId":4,"connectionCount":4}}
{"t":{"$date":"2025-11-25T03:06:55.841+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn4","msg":"client metadata","attr":{"remote":"127.0.0.1:47428","client":"conn4","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.849+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn4","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"1146b67d-4236-4bc9-bae4-3fa891517889"}},"namespace":"concelier.jobs","collectionUUID":{"uuid":{"$uuid":"b46075e8-3e6f-4a66-913f-60021219351a"}},"indexes":3,"firstIndex":{"name":"jobs_createdAt_desc"}}}
{"t":{"$date":"2025-11-25T03:06:55.858+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47432","connectionId":5,"connectionCount":5}}
{"t":{"$date":"2025-11-25T03:06:55.858+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn3","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"b267ade3-39a8-4744-8ffe-e091e3a60a76"}},"namespace":"concelier.advisory","collectionUUID":{"uuid":{"$uuid":"c2e4124c-bf80-4e3c-9272-cea8f40106f5"}},"indexes":5,"firstIndex":{"name":"advisory_key_unique"}}}
{"t":{"$date":"2025-11-25T03:06:55.859+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn5","msg":"client metadata","attr":{"remote":"127.0.0.1:47432","client":"conn5","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.859+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47448","connectionId":6,"connectionCount":6}}
{"t":{"$date":"2025-11-25T03:06:55.859+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn6","msg":"client metadata","attr":{"remote":"127.0.0.1:47448","client":"conn6","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.860+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn5","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"8634f626-1a30-4a22-93a9-65dc7b3e7493"}},"namespace":"concelier.document","collectionUUID":{"uuid":{"$uuid":"ad2a5b15-8e65-4ed1-9efa-d0fd1e643131"}},"indexes":3,"firstIndex":{"name":"document_source_uri_unique"}}}
{"t":{"$date":"2025-11-25T03:06:55.860+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn6","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"9ebafb07-90b6-47d0-9e2c-257bf2f104f7"}},"namespace":"concelier.dto","collectionUUID":{"uuid":{"$uuid":"81a72f1b-58d0-4a25-a0bc-0dd9362247f8"}},"indexes":2,"firstIndex":{"name":"dto_documentId"}}}
{"t":{"$date":"2025-11-25T03:06:55.860+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47460","connectionId":7,"connectionCount":7}}
{"t":{"$date":"2025-11-25T03:06:55.861+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47464","connectionId":8,"connectionCount":8}}
{"t":{"$date":"2025-11-25T03:06:55.861+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn7","msg":"client metadata","attr":{"remote":"127.0.0.1:47460","client":"conn7","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.861+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn8","msg":"client metadata","attr":{"remote":"127.0.0.1:47464","client":"conn8","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.862+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn7","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"a56fab5b-f9c9-47ab-a907-c260047bad5e"}},"namespace":"concelier.alias","collectionUUID":{"uuid":{"$uuid":"6a6a3cc5-2ba2-4756-bf3f-197fd1a306a0"}},"indexes":1,"firstIndex":{"name":"alias_scheme_value"}}}
{"t":{"$date":"2025-11-25T03:06:55.862+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn8","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"7df22170-a963-4a06-b173-cde909e8764c"}},"namespace":"concelier.affected","collectionUUID":{"uuid":{"$uuid":"ef930a9b-1097-41f9-9d77-2659520d64dc"}},"indexes":2,"firstIndex":{"name":"affected_platform_name"}}}
{"t":{"$date":"2025-11-25T03:06:55.871+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47476","connectionId":9,"connectionCount":9}}
{"t":{"$date":"2025-11-25T03:06:55.871+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47488","connectionId":10,"connectionCount":10}}
{"t":{"$date":"2025-11-25T03:06:55.871+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn9","msg":"client metadata","attr":{"remote":"127.0.0.1:47476","client":"conn9","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.872+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn10","msg":"client metadata","attr":{"remote":"127.0.0.1:47488","client":"conn10","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.872+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn9","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"e75019bf-293c-4d90-bfa3-90e20b305975"}},"namespace":"concelier.source_state","collectionUUID":{"uuid":{"$uuid":"9475ed88-bc52-4c6d-abcb-5dfaf2d5cf5b"}},"indexes":1,"firstIndex":{"name":"source_state_unique"}}}
{"t":{"$date":"2025-11-25T03:06:55.873+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn10","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"25b0858f-8e1d-43bc-afab-07712ea8e760"}},"namespace":"concelier.reference","collectionUUID":{"uuid":{"$uuid":"24d0213b-0677-42fa-b7ae-b0a19b36317d"}},"indexes":2,"firstIndex":{"name":"reference_url"}}}
{"t":{"$date":"2025-11-25T03:06:55.876+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47504","connectionId":11,"connectionCount":11}}
{"t":{"$date":"2025-11-25T03:06:55.876+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn11","msg":"client metadata","attr":{"remote":"127.0.0.1:47504","client":"conn11","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.878+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47506","connectionId":12,"connectionCount":12}}
{"t":{"$date":"2025-11-25T03:06:55.878+00:00"},"s":"I", "c":"COMMAND", "id":51806, "ctx":"conn11","msg":"CMD: dropIndexes","attr":{"namespace":"concelier.psirt_flags","uuid":{"uuid":{"$uuid":"d61fab06-e185-4905-a581-78d6188f9cbf"}},"indexes":"\"psirt_advisoryKey_unique\""}}
{"t":{"$date":"2025-11-25T03:06:55.878+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn12","msg":"client metadata","attr":{"remote":"127.0.0.1:47506","client":"conn12","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn4","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.jobs","index":"jobs_createdAt_desc","commitTimestamp":{"$timestamp":{"t":1764040015,"i":26}}}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn4","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.jobs","index":"jobs_kind_createdAt","commitTimestamp":{"$timestamp":{"t":1764040015,"i":26}}}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn4","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.jobs","index":"jobs_status_createdAt","commitTimestamp":{"$timestamp":{"t":1764040015,"i":26}}}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn4","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"1146b67d-4236-4bc9-bae4-3fa891517889"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47514","connectionId":13,"connectionCount":13}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn12","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"e231aaa5-d5f8-4c88-9860-fe69d60d65f5"}},"namespace":"concelier.advisory_statements","collectionUUID":{"uuid":{"$uuid":"46b5cd3a-fd22-47d2-81cc-2c756d9cfe62"}},"indexes":2,"firstIndex":{"name":"advisory_statements_vulnerability_asof_desc"}}}
{"t":{"$date":"2025-11-25T03:06:55.879+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn4","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"1146b67d-4236-4bc9-bae4-3fa891517889"}}}}
{"t":{"$date":"2025-11-25T03:06:55.880+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn13","msg":"client metadata","attr":{"remote":"127.0.0.1:47514","client":"conn13","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.881+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47524","connectionId":14,"connectionCount":14}}
{"t":{"$date":"2025-11-25T03:06:55.881+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn13","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"eba85195-e631-4fb2-a8ba-d155fcbe0411"}},"namespace":"concelier.advisory_conflicts","collectionUUID":{"uuid":{"$uuid":"e830a702-eb38-4e79-bd71-139b63066228"}},"indexes":2,"firstIndex":{"name":"advisory_conflicts_vulnerability_asof_desc"}}}
{"t":{"$date":"2025-11-25T03:06:55.881+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn14","msg":"client metadata","attr":{"remote":"127.0.0.1:47524","client":"conn14","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.882+00:00"},"s":"I", "c":"NETWORK", "id":22943, "ctx":"listener","msg":"Connection accepted","attr":{"remote":"127.0.0.1:47538","connectionId":15,"connectionCount":15}}
{"t":{"$date":"2025-11-25T03:06:55.882+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn14","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"054c0484-e72e-411f-bced-3f555ef0d361"}},"namespace":"concelier.advisory_observations","collectionUUID":{"uuid":{"$uuid":"2d30c6a9-a970-4507-9548-c93174011df9"}},"indexes":4,"firstIndex":{"name":"advisory_obs_tenant_upstream"}}}
{"t":{"$date":"2025-11-25T03:06:55.882+00:00"},"s":"I", "c":"NETWORK", "id":51800, "ctx":"conn15","msg":"client metadata","attr":{"remote":"127.0.0.1:47538","client":"conn15","doc":{"driver":{"name":"mongo-csharp-driver","version":"3.5.0"},"os":{"type":"Linux","name":"Ubuntu 24.04.3 LTS","architecture":"x86_64","version":"24.04.3"},"platform":".NET 10.0.0-rc.2.25502.107"}}}
{"t":{"$date":"2025-11-25T03:06:55.883+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn15","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"9756e330-8423-4878-bd4f-a3e1a8400472"}},"namespace":"concelier.source_change_history","collectionUUID":{"uuid":{"$uuid":"0c0938b6-7eb1-4e92-a8a8-5ed971581ddc"}},"indexes":3,"firstIndex":{"name":"history_source_advisory_capturedAt"}}}
{"t":{"$date":"2025-11-25T03:06:55.883+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn4","msg":"createCollection","attr":{"namespace":"concelier.documents.files","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"c6f88ce0-e49c-4b58-aa67-0a5021c6c7b1"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:55.928+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn4","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.documents.files","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040015,"i":31}}}}
{"t":{"$date":"2025-11-25T03:06:55.928+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn4","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.documents.files","index":"gridfs_files_expiresAt_ttl","commitTimestamp":{"$timestamp":{"t":1764040015,"i":31}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory","index":"advisory_key_unique","commitTimestamp":{"$timestamp":{"t":1764040015,"i":33}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory","index":"advisory_modified_desc","commitTimestamp":{"$timestamp":{"t":1764040015,"i":33}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory","index":"advisory_published_desc","commitTimestamp":{"$timestamp":{"t":1764040015,"i":33}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory","index":"advisory_normalizedVersions_pkg_scheme_type","commitTimestamp":{"$timestamp":{"t":1764040015,"i":33}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn3","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory","index":"advisory_normalizedVersions_value","commitTimestamp":{"$timestamp":{"t":1764040015,"i":33}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn3","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"b267ade3-39a8-4744-8ffe-e091e3a60a76"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:55.945+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn3","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"b267ade3-39a8-4744-8ffe-e091e3a60a76"}}}}
{"t":{"$date":"2025-11-25T03:06:55.968+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn6","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.dto","index":"dto_documentId","commitTimestamp":{"$timestamp":{"t":1764040015,"i":35}}}}
{"t":{"$date":"2025-11-25T03:06:55.968+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn6","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.dto","index":"dto_source_validated","commitTimestamp":{"$timestamp":{"t":1764040015,"i":35}}}}
{"t":{"$date":"2025-11-25T03:06:55.968+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn6","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"9ebafb07-90b6-47d0-9e2c-257bf2f104f7"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:55.968+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn6","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"9ebafb07-90b6-47d0-9e2c-257bf2f104f7"}}}}
{"t":{"$date":"2025-11-25T03:06:55.974+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn6","msg":"Slow query","attr":{"type":"command","ns":"concelier.dto","command":{"createIndexes":"dto","indexes":[{"key":{"documentId":1},"name":"dto_documentId"},{"key":{"sourceName":1,"validatedAt":-1},"name":"dto_source_validated"}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"0dce06ab-6c9e-44d5-a568-2c08aeae4f70"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":2},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":113}}
{"t":{"$date":"2025-11-25T03:06:55.983+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn9","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source_state","index":"source_state_unique","commitTimestamp":{"$timestamp":{"t":1764040015,"i":36}}}}
{"t":{"$date":"2025-11-25T03:06:55.983+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn9","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"e75019bf-293c-4d90-bfa3-90e20b305975"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:55.983+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn9","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"e75019bf-293c-4d90-bfa3-90e20b305975"}}}}
{"t":{"$date":"2025-11-25T03:06:55.988+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn9","msg":"Slow query","attr":{"type":"command","ns":"concelier.source_state","command":{"createIndexes":"source_state","indexes":[{"key":{"sourceName":1},"name":"source_state_unique","unique":true}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"8671be39-6be8-4a57-932e-fcddeacacfc5"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":1},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":116}}
{"t":{"$date":"2025-11-25T03:06:56.016+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn5","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.document","index":"document_source_uri_unique","commitTimestamp":{"$timestamp":{"t":1764040016,"i":1}}}}
{"t":{"$date":"2025-11-25T03:06:56.016+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn5","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.document","index":"document_fetchedAt_desc","commitTimestamp":{"$timestamp":{"t":1764040016,"i":1}}}}
{"t":{"$date":"2025-11-25T03:06:56.016+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn5","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.document","index":"document_expiresAt_ttl","commitTimestamp":{"$timestamp":{"t":1764040016,"i":1}}}}
{"t":{"$date":"2025-11-25T03:06:56.016+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn5","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"8634f626-1a30-4a22-93a9-65dc7b3e7493"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.016+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn5","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"8634f626-1a30-4a22-93a9-65dc7b3e7493"}}}}
{"t":{"$date":"2025-11-25T03:06:56.016+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn14","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"tenant":1,"upstream.upstream_id":1,"upstream.document_version":1},"name":"advisory_obs_tenant_upstream","unique":false,"v":2},{"key":{"tenant":1,"linkset.aliases":1},"name":"advisory_obs_tenant_aliases","v":2},{"key":{"tenant":1,"linkset.purls":1},"name":"advisory_obs_tenant_purls","v":2},{"key":{"tenant":1,"createdAt":-1},"name":"advisory_obs_tenant_createdAt","v":2}],"buildUUID":{"uuid":{"$uuid":"054c0484-e72e-411f-bced-3f555ef0d361"}},"collectionUUID":{"uuid":{"$uuid":"2d30c6a9-a970-4507-9548-c93174011df9"}}}}
{"t":{"$date":"2025-11-25T03:06:56.017+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn15","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"source":1,"advisoryKey":1,"capturedAt":-1},"name":"history_source_advisory_capturedAt","v":2},{"key":{"capturedAt":-1},"name":"history_capturedAt","v":2},{"key":{"documentId":1},"name":"history_documentId","v":2}],"buildUUID":{"uuid":{"$uuid":"9756e330-8423-4878-bd4f-a3e1a8400472"}},"collectionUUID":{"uuid":{"$uuid":"0c0938b6-7eb1-4e92-a8a8-5ed971581ddc"}}}}
{"t":{"$date":"2025-11-25T03:06:56.017+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn15","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"source":1,"advisoryKey":1,"capturedAt":-1},"name":"history_source_advisory_capturedAt","v":2},{"key":{"capturedAt":-1},"name":"history_capturedAt","v":2},{"key":{"documentId":1},"name":"history_documentId","v":2}],"buildUUID":{"uuid":{"$uuid":"9756e330-8423-4878-bd4f-a3e1a8400472"}},"collectionUUID":{"uuid":{"$uuid":"0c0938b6-7eb1-4e92-a8a8-5ed971581ddc"}}}}
{"t":{"$date":"2025-11-25T03:06:56.017+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn8","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"platform":1,"name":1},"name":"affected_platform_name","v":2},{"key":{"advisoryId":1},"name":"affected_advisoryId","v":2}],"buildUUID":{"uuid":{"$uuid":"7df22170-a963-4a06-b173-cde909e8764c"}},"collectionUUID":{"uuid":{"$uuid":"ef930a9b-1097-41f9-9d77-2659520d64dc"}}}}
{"t":{"$date":"2025-11-25T03:06:56.017+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn8","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"platform":1,"name":1},"name":"affected_platform_name","v":2},{"key":{"advisoryId":1},"name":"affected_advisoryId","v":2}],"buildUUID":{"uuid":{"$uuid":"7df22170-a963-4a06-b173-cde909e8764c"}},"collectionUUID":{"uuid":{"$uuid":"ef930a9b-1097-41f9-9d77-2659520d64dc"}}}}
{"t":{"$date":"2025-11-25T03:06:56.018+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn5","msg":"Slow query","attr":{"type":"command","ns":"concelier.document","command":{"createIndexes":"document","indexes":[{"key":{"sourceName":1,"uri":1},"name":"document_source_uri_unique","unique":true},{"key":{"fetchedAt":-1},"name":"document_fetchedAt_desc"},{"key":{"expiresAt":1},"name":"document_expiresAt_ttl","expireAfterSeconds":0.0,"partialFilterExpression":{"expiresAt":{"$exists":true}}}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"d31918ca-399a-4f47-8207-80777cac4b29"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":3},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":158}}
{"t":{"$date":"2025-11-25T03:06:56.020+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn11","msg":"Slow query","attr":{"type":"command","ns":"concelier.psirt_flags","command":{"dropIndexes":"psirt_flags","index":"psirt_advisoryKey_unique","writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"12d8a496-37e2-46f8-8e2f-a41a2f99ac09"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"ok":0,"errMsg":"index not found with name [psirt_advisoryKey_unique]","errName":"IndexNotFound","errCode":27,"reslen":266,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":2}},"ReplicationStateTransition":{"acquireCount":{"w":4}},"Global":{"acquireCount":{"r":2,"w":2}},"Database":{"acquireCount":{"w":2}},"Collection":{"acquireCount":{"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":2,"timeAcquiringMicros":1},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":141}}
{"t":{"$date":"2025-11-25T03:06:56.031+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn11","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"59b6cebf-aee3-46b7-814a-856404eb982d"}},"namespace":"concelier.psirt_flags","collectionUUID":{"uuid":{"$uuid":"d61fab06-e185-4905-a581-78d6188f9cbf"}},"indexes":1,"firstIndex":{"name":"psirt_vendor"}}}
{"t":{"$date":"2025-11-25T03:06:56.035+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn10","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.reference","index":"reference_url","commitTimestamp":{"$timestamp":{"t":1764040016,"i":3}}}}
{"t":{"$date":"2025-11-25T03:06:56.035+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn10","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.reference","index":"reference_advisoryId","commitTimestamp":{"$timestamp":{"t":1764040016,"i":3}}}}
{"t":{"$date":"2025-11-25T03:06:56.035+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn10","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"25b0858f-8e1d-43bc-afab-07712ea8e760"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.035+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn10","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"25b0858f-8e1d-43bc-afab-07712ea8e760"}}}}
{"t":{"$date":"2025-11-25T03:06:56.037+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn10","msg":"Slow query","attr":{"type":"command","ns":"concelier.reference","command":{"createIndexes":"reference","indexes":[{"key":{"url":1},"name":"reference_url"},{"key":{"advisoryId":1},"name":"reference_advisoryId"}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"e8db91b1-ad7d-4cb3-a86b-47d5b309fc80"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":2},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":164}}
{"t":{"$date":"2025-11-25T03:06:56.051+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn13","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_conflicts","index":"advisory_conflicts_vulnerability_asof_desc","commitTimestamp":{"$timestamp":{"t":1764040016,"i":5}}}}
{"t":{"$date":"2025-11-25T03:06:56.051+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn13","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_conflicts","index":"advisory_conflicts_conflictHash_unique","commitTimestamp":{"$timestamp":{"t":1764040016,"i":5}}}}
{"t":{"$date":"2025-11-25T03:06:56.051+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn13","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"eba85195-e631-4fb2-a8ba-d155fcbe0411"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.051+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn13","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"eba85195-e631-4fb2-a8ba-d155fcbe0411"}}}}
{"t":{"$date":"2025-11-25T03:06:56.053+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn13","msg":"Slow query","attr":{"type":"command","ns":"concelier.advisory_conflicts","command":{"createIndexes":"advisory_conflicts","indexes":[{"key":{"vulnerabilityKey":1,"asOf":-1},"name":"advisory_conflicts_vulnerability_asof_desc"},{"key":{"conflictHash":1},"name":"advisory_conflicts_conflictHash_unique","unique":true}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"92e1dc41-2888-47f4-a1dc-abd349a494a4"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":2},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":172}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn7","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.alias","index":"alias_scheme_value","commitTimestamp":{"$timestamp":{"t":1764040016,"i":6}}}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn7","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"a56fab5b-f9c9-47ab-a907-c260047bad5e"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn7","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"a56fab5b-f9c9-47ab-a907-c260047bad5e"}}}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn14","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"tenant":1,"upstream.upstream_id":1,"upstream.document_version":1},"name":"advisory_obs_tenant_upstream","unique":false,"v":2},{"key":{"tenant":1,"linkset.aliases":1},"name":"advisory_obs_tenant_aliases","v":2},{"key":{"tenant":1,"linkset.purls":1},"name":"advisory_obs_tenant_purls","v":2},{"key":{"tenant":1,"createdAt":-1},"name":"advisory_obs_tenant_createdAt","v":2}],"buildUUID":{"uuid":{"$uuid":"054c0484-e72e-411f-bced-3f555ef0d361"}},"collectionUUID":{"uuid":{"$uuid":"2d30c6a9-a970-4507-9548-c93174011df9"}}}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn14","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"tenant":1,"upstream.upstream_id":1,"upstream.document_version":1},"name":"advisory_obs_tenant_upstream","unique":false,"v":2},{"key":{"tenant":1,"linkset.aliases":1},"name":"advisory_obs_tenant_aliases","v":2},{"key":{"tenant":1,"linkset.purls":1},"name":"advisory_obs_tenant_purls","v":2},{"key":{"tenant":1,"createdAt":-1},"name":"advisory_obs_tenant_createdAt","v":2}],"buildUUID":{"uuid":{"$uuid":"054c0484-e72e-411f-bced-3f555ef0d361"}},"collectionUUID":{"uuid":{"$uuid":"2d30c6a9-a970-4507-9548-c93174011df9"}}}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn11","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"vendor":1},"name":"psirt_vendor","v":2}],"buildUUID":{"uuid":{"$uuid":"59b6cebf-aee3-46b7-814a-856404eb982d"}},"collectionUUID":{"uuid":{"$uuid":"d61fab06-e185-4905-a581-78d6188f9cbf"}}}}
{"t":{"$date":"2025-11-25T03:06:56.059+00:00"},"s":"I", "c":"STORAGE", "id":4715500, "ctx":"conn11","msg":"Too many index builds running simultaneously, waiting until the number of active index builds is below the threshold","attr":{"numActiveIndexBuilds":3,"maxNumActiveUserIndexBuilds":3,"indexSpecs":[{"key":{"vendor":1},"name":"psirt_vendor","v":2}],"buildUUID":{"uuid":{"$uuid":"59b6cebf-aee3-46b7-814a-856404eb982d"}},"collectionUUID":{"uuid":{"$uuid":"d61fab06-e185-4905-a581-78d6188f9cbf"}}}}
{"t":{"$date":"2025-11-25T03:06:56.062+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn7","msg":"Slow query","attr":{"type":"command","ns":"concelier.alias","command":{"createIndexes":"alias","indexes":[{"key":{"scheme":1,"value":1},"name":"alias_scheme_value","unique":false}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"9451e45a-666e-4afb-b7dc-24139346c68a"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":1},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":199}}
{"t":{"$date":"2025-11-25T03:06:56.076+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn8","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.affected","index":"affected_platform_name","commitTimestamp":{"$timestamp":{"t":1764040016,"i":8}}}}
{"t":{"$date":"2025-11-25T03:06:56.076+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn8","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.affected","index":"affected_advisoryId","commitTimestamp":{"$timestamp":{"t":1764040016,"i":8}}}}
{"t":{"$date":"2025-11-25T03:06:56.100+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn15","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source_change_history","index":"history_source_advisory_capturedAt","commitTimestamp":{"$timestamp":{"t":1764040016,"i":11}}}}
{"t":{"$date":"2025-11-25T03:06:56.100+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn15","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source_change_history","index":"history_capturedAt","commitTimestamp":{"$timestamp":{"t":1764040016,"i":11}}}}
{"t":{"$date":"2025-11-25T03:06:56.100+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn15","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.source_change_history","index":"history_documentId","commitTimestamp":{"$timestamp":{"t":1764040016,"i":11}}}}
{"t":{"$date":"2025-11-25T03:06:56.101+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn15","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"9756e330-8423-4878-bd4f-a3e1a8400472"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.101+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn15","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"9756e330-8423-4878-bd4f-a3e1a8400472"}}}}
{"t":{"$date":"2025-11-25T03:06:56.103+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn15","msg":"Slow query","attr":{"type":"command","ns":"concelier.source_change_history","command":{"createIndexes":"source_change_history","indexes":[{"key":{"source":1,"advisoryKey":1,"capturedAt":-1},"name":"history_source_advisory_capturedAt"},{"key":{"capturedAt":-1},"name":"history_capturedAt"},{"key":{"documentId":1},"name":"history_documentId"}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"8b32a551-8036-4a89-ab2e-c86d08aa9663"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":27}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":3},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":220}}
{"t":{"$date":"2025-11-25T03:06:56.132+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn14","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observations","index":"advisory_obs_tenant_upstream","commitTimestamp":{"$timestamp":{"t":1764040016,"i":15}}}}
{"t":{"$date":"2025-11-25T03:06:56.132+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn14","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observations","index":"advisory_obs_tenant_aliases","commitTimestamp":{"$timestamp":{"t":1764040016,"i":15}}}}
{"t":{"$date":"2025-11-25T03:06:56.132+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn14","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observations","index":"advisory_obs_tenant_purls","commitTimestamp":{"$timestamp":{"t":1764040016,"i":15}}}}
{"t":{"$date":"2025-11-25T03:06:56.132+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn14","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observations","index":"advisory_obs_tenant_createdAt","commitTimestamp":{"$timestamp":{"t":1764040016,"i":15}}}}
{"t":{"$date":"2025-11-25T03:06:56.132+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn14","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"054c0484-e72e-411f-bced-3f555ef0d361"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.132+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn14","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"054c0484-e72e-411f-bced-3f555ef0d361"}}}}
{"t":{"$date":"2025-11-25T03:06:56.137+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn14","msg":"Slow query","attr":{"type":"command","ns":"concelier.advisory_observations","command":{"createIndexes":"advisory_observations","indexes":[{"key":{"tenant":1,"upstream.upstream_id":1,"upstream.document_version":1},"name":"advisory_obs_tenant_upstream","unique":false},{"key":{"tenant":1,"linkset.aliases":1},"name":"advisory_obs_tenant_aliases"},{"key":{"tenant":1,"linkset.purls":1},"name":"advisory_obs_tenant_purls"},{"key":{"tenant":1,"createdAt":-1},"name":"advisory_obs_tenant_createdAt"}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"959fef49-dc3d-44bf-824f-522cb94dcab9"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":1},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":255}}
{"t":{"$date":"2025-11-25T03:06:56.142+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn11","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.psirt_flags","index":"psirt_vendor","commitTimestamp":{"$timestamp":{"t":1764040016,"i":16}}}}
{"t":{"$date":"2025-11-25T03:06:56.142+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn11","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"59b6cebf-aee3-46b7-814a-856404eb982d"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.142+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn11","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"59b6cebf-aee3-46b7-814a-856404eb982d"}}}}
{"t":{"$date":"2025-11-25T03:06:56.145+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn11","msg":"Slow query","attr":{"type":"command","ns":"concelier.psirt_flags","command":{"createIndexes":"psirt_flags","indexes":[{"key":{"vendor":1},"name":"psirt_vendor"}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"12d8a496-37e2-46f8-8e2f-a41a2f99ac09"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040016,"i":2}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":1},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":113}}
{"t":{"$date":"2025-11-25T03:06:56.158+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_statements","index":"advisory_statements_vulnerability_asof_desc","commitTimestamp":{"$timestamp":{"t":1764040016,"i":18}}}}
{"t":{"$date":"2025-11-25T03:06:56.158+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_statements","index":"advisory_statements_statementHash_unique","commitTimestamp":{"$timestamp":{"t":1764040016,"i":18}}}}
{"t":{"$date":"2025-11-25T03:06:56.158+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn12","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"e231aaa5-d5f8-4c88-9860-fe69d60d65f5"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.158+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn8","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"7df22170-a963-4a06-b173-cde909e8764c"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.158+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn12","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"e231aaa5-d5f8-4c88-9860-fe69d60d65f5"}}}}
{"t":{"$date":"2025-11-25T03:06:56.158+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn8","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"7df22170-a963-4a06-b173-cde909e8764c"}}}}
{"t":{"$date":"2025-11-25T03:06:56.160+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn8","msg":"Slow query","attr":{"type":"command","ns":"concelier.affected","command":{"createIndexes":"affected","indexes":[{"key":{"platform":1,"name":1},"name":"affected_platform_name"},{"key":{"advisoryId":1},"name":"affected_advisoryId"}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"db62eb74-b9d0-420f-b476-36bfe600a00e"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":3},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":297}}
{"t":{"$date":"2025-11-25T03:06:56.160+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn12","msg":"Slow query","attr":{"type":"command","ns":"concelier.advisory_statements","command":{"createIndexes":"advisory_statements","indexes":[{"key":{"vulnerabilityKey":1,"asOf":-1},"name":"advisory_statements_vulnerability_asof_desc"},{"key":{"statementHash":1},"name":"advisory_statements_statementHash_unique","unique":true}],"writeConcern":{"w":"majority","wtimeout":30000.0},"$db":"concelier","lsid":{"id":{"$uuid":"e30476f3-96d5-4a1b-b952-b9c3c8c48f05"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1764040015,"i":24}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}}},"numYields":0,"reslen":271,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":3}},"ReplicationStateTransition":{"acquireCount":{"w":6}},"Global":{"acquireCount":{"r":2,"w":4}},"Database":{"acquireCount":{"w":3}},"Collection":{"acquireCount":{"r":1,"w":1,"W":1}},"Mutex":{"acquireCount":{"r":3}}},"flowControl":{"acquireCount":3,"timeAcquiringMicros":2},"writeConcern":{"w":"majority","wtimeout":30000,"provenance":"clientSupplied"},"storage":{},"protocol":"op_msg","durationMillis":281}}
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20241005_document_expiry_indexes: Ensure document.expiresAt index matches configured retention
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20241005_document_expiry_indexes applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20241005_gridfs_expiry_indexes: Ensure GridFS metadata.expiresAt TTL index reflects retention settings
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20241005_gridfs_expiry_indexes applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 2025-11-07-advisory-canonical-key: Populate advisory_key and links for advisory_raw documents.
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 2025-11-07-advisory-canonical-key applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251011-semver-style-backfill: Populate advisory.normalizedVersions for existing documents when SemVer style storage is enabled.
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251011-semver-style-backfill applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251019_advisory_event_collections: Ensure advisory_statements and advisory_conflicts indexes exist for event log storage.
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251019_advisory_event_collections applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251028_advisory_raw_idempotency_index: Ensure advisory_raw collection enforces idempotency via unique compound index.
{"t":{"$date":"2025-11-25T03:06:56.373+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn12","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"d0d7de72-350c-4703-88fe-4604a6c0d70c"}},"namespace":"concelier.advisory_raw","collectionUUID":{"uuid":{"$uuid":"70542ec2-832b-4f93-8c96-4ca814f1fbbc"}},"indexes":1,"firstIndex":{"name":"advisory_raw_idempotency"}}}
{"t":{"$date":"2025-11-25T03:06:56.381+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_raw","index":"advisory_raw_idempotency","commitTimestamp":{"$timestamp":{"t":1764040016,"i":24}}}}
{"t":{"$date":"2025-11-25T03:06:56.381+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn12","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"d0d7de72-350c-4703-88fe-4604a6c0d70c"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.381+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn12","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"d0d7de72-350c-4703-88fe-4604a6c0d70c"}}}}
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251028_advisory_raw_idempotency_index applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251028_advisory_raw_validator: Ensure advisory_raw collection enforces Aggregation-Only Contract schema
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251028_advisory_raw_validator applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251028_advisory_supersedes_backfill: Backfill advisory_raw supersedes chains and replace legacy advisory collection with read-only view.
{"t":{"$date":"2025-11-25T03:06:56.422+00:00"},"s":"I", "c":"COMMAND", "id":20400, "ctx":"conn12","msg":"renameCollectionForCommand","attr":{"sourceNamespace":"concelier.advisory","targetNamespace":"concelier.advisory_backup_20251028","dropTarget":"no"}}
{"t":{"$date":"2025-11-25T03:06:56.422+00:00"},"s":"I", "c":"STORAGE", "id":20319, "ctx":"conn12","msg":"renameCollection","attr":{"uuid":{"uuid":{"$uuid":"c2e4124c-bf80-4e3c-9272-cea8f40106f5"}},"fromName":"concelier.advisory","toName":"concelier.advisory_backup_20251028"}}
{"t":{"$date":"2025-11-25T03:06:56.427+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn12","msg":"createCollection","attr":{"namespace":"concelier.system.views","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"11aeedd7-8f4c-4bf6-a15f-508c507370da"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:56.445+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.system.views","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040016,"i":29}}}}
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251028_advisory_supersedes_backfill applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251104_advisory_observations_raw_linkset: Populate rawLinkset field for advisory observations using stored advisory_raw documents.
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251104_advisory_observations_raw_linkset applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251117_advisory_linksets_tenant_lower: Lowercase tenant ids in advisory_linksets to match query filters.
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251117_advisory_linksets_tenant_lower applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251120_advisory_observation_events: Ensure advisory_observation_events collection and indexes exist for observation event fan-out.
{"t":{"$date":"2025-11-25T03:06:56.489+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn12","msg":"createCollection","attr":{"namespace":"concelier.advisory_observation_events","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"2ee210ff-d50f-4a43-9d2b-8160e01daa2f"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:56.524+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observation_events","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040016,"i":36}}}}
{"t":{"$date":"2025-11-25T03:06:56.525+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observation_events","index":"advisory_observation_events_tenant_ingested_desc","commitTimestamp":{"$timestamp":{"t":1764040016,"i":36}}}}
{"t":{"$date":"2025-11-25T03:06:56.525+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.advisory_observation_events","index":"advisory_observation_events_hash_unique","commitTimestamp":{"$timestamp":{"t":1764040016,"i":36}}}}
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251120_advisory_observation_events applied
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Applying Mongo migration 20251122_orchestrator_registry_commands: Ensure orchestrator registry, commands, and heartbeats collections exist with indexes
{"t":{"$date":"2025-11-25T03:06:56.535+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn12","msg":"createCollection","attr":{"namespace":"concelier.orchestrator_registry","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"6649d503-b817-4ea5-88ce-a93b0536995d"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:56.551+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_registry","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040016,"i":38}}}}
{"t":{"$date":"2025-11-25T03:06:56.554+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn12","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"0f95b012-1a7d-415e-9a84-9839c759b37e"}},"namespace":"concelier.orchestrator_registry","collectionUUID":{"uuid":{"$uuid":"6649d503-b817-4ea5-88ce-a93b0536995d"}},"indexes":2,"firstIndex":{"name":"orch_registry_tenant_connector"}}}
{"t":{"$date":"2025-11-25T03:06:56.577+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_registry","index":"orch_registry_tenant_connector","commitTimestamp":{"$timestamp":{"t":1764040016,"i":40}}}}
{"t":{"$date":"2025-11-25T03:06:56.577+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_registry","index":"orch_registry_source","commitTimestamp":{"$timestamp":{"t":1764040016,"i":40}}}}
{"t":{"$date":"2025-11-25T03:06:56.577+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn12","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"0f95b012-1a7d-415e-9a84-9839c759b37e"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.577+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn12","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"0f95b012-1a7d-415e-9a84-9839c759b37e"}}}}
{"t":{"$date":"2025-11-25T03:06:56.581+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn12","msg":"createCollection","attr":{"namespace":"concelier.orchestrator_commands","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"f1a79279-2004-4cfd-8ae9-cb752e102dff"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:56.601+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_commands","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040016,"i":41}}}}
{"t":{"$date":"2025-11-25T03:06:56.604+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn12","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"edb14da3-273d-4518-a0ff-db0a490facc4"}},"namespace":"concelier.orchestrator_commands","collectionUUID":{"uuid":{"$uuid":"f1a79279-2004-4cfd-8ae9-cb752e102dff"}},"indexes":2,"firstIndex":{"name":"orch_cmd_tenant_connector_run_seq"}}}
{"t":{"$date":"2025-11-25T03:06:56.623+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_commands","index":"orch_cmd_tenant_connector_run_seq","commitTimestamp":{"$timestamp":{"t":1764040016,"i":43}}}}
{"t":{"$date":"2025-11-25T03:06:56.623+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_commands","index":"orch_cmd_expiresAt_ttl","commitTimestamp":{"$timestamp":{"t":1764040016,"i":43}}}}
{"t":{"$date":"2025-11-25T03:06:56.623+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn12","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"edb14da3-273d-4518-a0ff-db0a490facc4"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.623+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn12","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"edb14da3-273d-4518-a0ff-db0a490facc4"}}}}
{"t":{"$date":"2025-11-25T03:06:56.627+00:00"},"s":"I", "c":"STORAGE", "id":20320, "ctx":"conn12","msg":"createCollection","attr":{"namespace":"concelier.orchestrator_heartbeats","uuidDisposition":"generated","uuid":{"uuid":{"$uuid":"52b32b90-719b-4668-8aab-021f90ae99f1"}},"options":{}}}
{"t":{"$date":"2025-11-25T03:06:56.644+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_heartbeats","index":"_id_","commitTimestamp":{"$timestamp":{"t":1764040016,"i":44}}}}
{"t":{"$date":"2025-11-25T03:06:56.648+00:00"},"s":"I", "c":"INDEX", "id":20438, "ctx":"conn12","msg":"Index build: registering","attr":{"buildUUID":{"uuid":{"$uuid":"f262f49e-88f3-4b71-ade5-24ba982d5f71"}},"namespace":"concelier.orchestrator_heartbeats","collectionUUID":{"uuid":{"$uuid":"52b32b90-719b-4668-8aab-021f90ae99f1"}},"indexes":2,"firstIndex":{"name":"orch_hb_tenant_connector_run_seq"}}}
{"t":{"$date":"2025-11-25T03:06:56.664+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_heartbeats","index":"orch_hb_tenant_connector_run_seq","commitTimestamp":{"$timestamp":{"t":1764040016,"i":46}}}}
{"t":{"$date":"2025-11-25T03:06:56.664+00:00"},"s":"I", "c":"INDEX", "id":20345, "ctx":"conn12","msg":"Index build: done building","attr":{"buildUUID":null,"namespace":"concelier.orchestrator_heartbeats","index":"orch_hb_timestamp_desc","commitTimestamp":{"$timestamp":{"t":1764040016,"i":46}}}}
{"t":{"$date":"2025-11-25T03:06:56.664+00:00"},"s":"I", "c":"INDEX", "id":20440, "ctx":"conn12","msg":"Index build: waiting for index build to complete","attr":{"buildUUID":{"uuid":{"$uuid":"f262f49e-88f3-4b71-ade5-24ba982d5f71"}},"deadline":{"$date":{"$numberLong":"9223372036854775807"}}}}
{"t":{"$date":"2025-11-25T03:06:56.664+00:00"},"s":"I", "c":"INDEX", "id":20447, "ctx":"conn12","msg":"Index build: completed","attr":{"buildUUID":{"uuid":{"$uuid":"f262f49e-88f3-4b71-ade5-24ba982d5f71"}}}}
info: StellaOps.Concelier.Storage.Mongo.Migrations.MongoMigrationRunner[0]
Mongo migration 20251122_orchestrator_registry_commands applied
info: StellaOps.Concelier.Storage.Mongo.MongoBootstrapper[0]
Mongo bootstrapper completed
info: MongoBootstrapper[0]
Mongo bootstrap completed in 1453.7631 ms
info: StellaOps.Concelier.Core.Jobs.JobSchedulerHostedService[0]
No cron-based jobs registered; scheduler idle.
info: StellaOps.Concelier.Storage.Mongo.Observations.AdvisoryObservationTransportWorker[0]
Observation transport worker disabled.
info: StellaOps.Concelier.Storage.Mongo.Observations.AdvisoryObservationTransportWorker[0]
Observation transport worker disabled.
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: /mnt/e/dev/git.stella-ops.org/src/Concelier/StellaOps.Concelier.WebService
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost/health - - -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'HTTP: GET /health'
info: Microsoft.AspNetCore.Http.Result.ContentResult[2]
Write content with HTTP Response ContentType of application/json; charset=utf-8
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'HTTP: GET /health'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET http://localhost/health - 200 291 application/json;+charset=utf-8 151.1386ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost/ready - - -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'HTTP: GET /ready'
info: Microsoft.AspNetCore.Http.Result.ContentResult[2]
Write content with HTTP Response ContentType of application/json; charset=utf-8
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'HTTP: GET /ready'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET http://localhost/ready - 200 198 application/json;+charset=utf-8 12.4201ms
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
[xUnit.net 00:00:36.48] Finished: StellaOps.Concelier.WebService.Tests
</StdOut>
</Output>
<RunInfos>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T03:06:57.6059023+00:00">
<Text>Data collector 'Blame' message: All tests finished running, Sequence file will not be generated.</Text>
</RunInfo>
</RunInfos>
</ResultSummary>
</TestRun>

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="2a53c3de-54ca-4f07-8702-1a9c0210c1e2" name="@DESKTOP-7GHGC2M 2025-11-25 03:08:54" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2025-11-25T03:08:54.4332618+00:00" queuing="2025-11-25T03:08:54.4332619+00:00" start="2025-11-25T03:08:52.3185390+00:00" finish="2025-11-25T03:08:54.4418259+00:00" />
<TestSettings name="default" id="3ce5bdb0-5cad-4ee1-a2b9-696735144c3d">
<Deployment runDeploymentRoot="_DESKTOP-7GHGC2M_2025-11-25_03_08_54" />
</TestSettings>
<Results>
<UnitTestResult executionId="c67ce2d6-5c72-4327-ac7f-be88c6c0ecc3" testId="11684acb-bbea-2e6b-ce0d-1cc21a7bc201" testName="StellaOps.Excititor.WebService.Tests.AirgapImportEndpointTests.Import_accepts_valid_payload" computerName="DESKTOP-7GHGC2M" duration="00:00:00.0019351" startTime="2025-11-25T03:08:54.2414474+00:00" endTime="2025-11-25T03:08:54.2414476+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="c67ce2d6-5c72-4327-ac7f-be88c6c0ecc3" />
<UnitTestResult executionId="21c16366-1bea-4eec-af4e-a15f4fdeb918" testId="da5d5507-70fd-de85-95fe-e405d157cf98" testName="StellaOps.Excititor.WebService.Tests.AirgapImportEndpointTests.Import_returns_bad_request_when_signature_missing" computerName="DESKTOP-7GHGC2M" duration="00:00:00.2374169" startTime="2025-11-25T03:08:54.2172539+00:00" endTime="2025-11-25T03:08:54.2173027+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="21c16366-1bea-4eec-af4e-a15f4fdeb918" />
</Results>
<TestDefinitions>
<UnitTest name="StellaOps.Excititor.WebService.Tests.AirgapImportEndpointTests.Import_returns_bad_request_when_signature_missing" storage="/mnt/e/dev/git.stella-ops.org/src/excititor/__tests/stellaops.excititor.webservice.tests/bin/debug/net10.0/stellaops.excititor.webservice.tests.dll" id="da5d5507-70fd-de85-95fe-e405d157cf98">
<Execution id="21c16366-1bea-4eec-af4e-a15f4fdeb918" />
<TestMethod codeBase="/mnt/e/dev/git.stella-ops.org/src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/bin/Debug/net10.0/StellaOps.Excititor.WebService.Tests.dll" adapterTypeName="executor://xunit/VsTestRunner2/netcoreapp" className="StellaOps.Excititor.WebService.Tests.AirgapImportEndpointTests" name="Import_returns_bad_request_when_signature_missing" />
</UnitTest>
<UnitTest name="StellaOps.Excititor.WebService.Tests.AirgapImportEndpointTests.Import_accepts_valid_payload" storage="/mnt/e/dev/git.stella-ops.org/src/excititor/__tests/stellaops.excititor.webservice.tests/bin/debug/net10.0/stellaops.excititor.webservice.tests.dll" id="11684acb-bbea-2e6b-ce0d-1cc21a7bc201">
<Execution id="c67ce2d6-5c72-4327-ac7f-be88c6c0ecc3" />
<TestMethod codeBase="/mnt/e/dev/git.stella-ops.org/src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/bin/Debug/net10.0/StellaOps.Excititor.WebService.Tests.dll" adapterTypeName="executor://xunit/VsTestRunner2/netcoreapp" className="StellaOps.Excititor.WebService.Tests.AirgapImportEndpointTests" name="Import_accepts_valid_payload" />
</UnitTest>
</TestDefinitions>
<TestEntries>
<TestEntry testId="11684acb-bbea-2e6b-ce0d-1cc21a7bc201" executionId="c67ce2d6-5c72-4327-ac7f-be88c6c0ecc3" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestEntry testId="da5d5507-70fd-de85-95fe-e405d157cf98" executionId="21c16366-1bea-4eec-af4e-a15f4fdeb918" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
</TestEntries>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Completed">
<Counters total="2" executed="2" passed="2" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0-rc.2.25502.107)
[xUnit.net 00:00:00.23] Discovering: StellaOps.Excititor.WebService.Tests
[xUnit.net 00:00:00.29] Discovered: StellaOps.Excititor.WebService.Tests
[xUnit.net 00:00:00.30] Starting: StellaOps.Excititor.WebService.Tests
[xUnit.net 00:00:00.64] Finished: StellaOps.Excititor.WebService.Tests
</StdOut>
</Output>
<RunInfos>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T03:08:54.3453289+00:00">
<Text>Data collector 'Blame' message: All tests finished running, Sequence file will not be generated.</Text>
</RunInfo>
</RunInfos>
</ResultSummary>
</TestRun>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="6532f9f9-e718-4fe1-b82a-33fa91310011" name="@DESKTOP-7GHGC2M 2025-11-25 03:46:20" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2025-11-25T03:46:20.2426491+00:00" queuing="2025-11-25T03:46:20.2426492+00:00" start="2025-11-25T03:46:16.0469600+00:00" finish="2025-11-25T03:46:20.2433850+00:00" />
<TestSettings name="default" id="9a249eb2-1aba-42f8-b18c-72c4811061af">
<Deployment runDeploymentRoot="_DESKTOP-7GHGC2M_2025-11-25_03_46_20" />
</TestSettings>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Completed">
<Counters total="0" executed="0" passed="0" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0-rc.2.25502.107)
[xUnit.net 00:00:01.08] Discovering: StellaOps.Concelier.Storage.Mongo.Tests
[xUnit.net 00:00:01.15] Discovered: StellaOps.Concelier.Storage.Mongo.Tests
[xUnit.net 00:00:01.16] Starting: StellaOps.Concelier.Storage.Mongo.Tests
[xUnit.net 00:00:01.18] Finished: StellaOps.Concelier.Storage.Mongo.Tests
</StdOut>
</Output>
<RunInfos>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T03:46:20.0884769+00:00">
<Text>No test matches the given testcase filter `FullyQualifiedName~Orchestrator` in /mnt/e/dev/git.stella-ops.org/src/Concelier/__Tests/StellaOps.Concelier.Storage.Mongo.Tests/bin/Debug/net10.0/StellaOps.Concelier.Storage.Mongo.Tests.dll</Text>
</RunInfo>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T03:46:20.1812017+00:00">
<Text>Data collector 'Blame' message: All tests finished running, Sequence file will not be generated.</Text>
</RunInfo>
</RunInfos>
</ResultSummary>
</TestRun>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="46df7432-fefa-4761-bcc7-948b0285de35" name="@DESKTOP-7GHGC2M 2025-11-25 06:21:32" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2025-11-25T06:21:32.4196369+00:00" queuing="2025-11-25T06:21:32.4196369+00:00" start="2025-11-25T06:21:30.6110195+00:00" finish="2025-11-25T06:21:32.4202858+00:00" />
<TestSettings name="default" id="3f4bcc73-49aa-4ce4-bb02-f965f41971dd">
<Deployment runDeploymentRoot="_DESKTOP-7GHGC2M_2025-11-25_06_21_32" />
</TestSettings>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Completed">
<Counters total="0" executed="0" passed="0" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0-rc.2.25502.107)
[xUnit.net 00:00:00.26] Discovering: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.33] Discovered: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.34] Starting: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.36] Finished: StellaOps.Concelier.WebService.Tests
</StdOut>
</Output>
<RunInfos>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T06:21:32.2626160+00:00">
<Text>No test matches the given testcase filter `ClassName~OrchestratorEndpointsTests` in /mnt/e/dev/git.stella-ops.org/src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/bin/Debug/net10.0/StellaOps.Concelier.WebService.Tests.dll</Text>
</RunInfo>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T06:21:32.3486581+00:00">
<Text>Data collector 'Blame' message: All tests finished running, Sequence file will not be generated.</Text>
</RunInfo>
</RunInfos>
</ResultSummary>
</TestRun>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="e44b0a6b-d4da-4536-94a0-c7abc31b8451" name="@DESKTOP-7GHGC2M 2025-11-25 07:00:37" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2025-11-25T07:00:37.8701208+00:00" queuing="2025-11-25T07:00:37.8701209+00:00" start="2025-11-25T07:00:35.6229608+00:00" finish="2025-11-25T07:00:37.8707653+00:00" />
<TestSettings name="default" id="61b86be5-caaf-4b76-a125-1141acf7e2ef">
<Deployment runDeploymentRoot="_DESKTOP-7GHGC2M_2025-11-25_07_00_37" />
</TestSettings>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Completed">
<Counters total="0" executed="0" passed="0" failed="0" error="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="0" inProgress="0" pending="0" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0-rc.2.25502.107)
[xUnit.net 00:00:00.35] Discovering: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.43] Discovered: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.44] Starting: StellaOps.Concelier.WebService.Tests
[xUnit.net 00:00:00.46] Finished: StellaOps.Concelier.WebService.Tests
</StdOut>
</Output>
<RunInfos>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T07:00:37.6968672+00:00">
<Text>No test matches the given testcase filter `OrchestratorEndpointsTests` in /mnt/e/dev/git.stella-ops.org/src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/bin/Debug/net10.0/StellaOps.Concelier.WebService.Tests.dll</Text>
</RunInfo>
<RunInfo computerName="DESKTOP-7GHGC2M" outcome="Warning" timestamp="2025-11-25T07:00:37.8060888+00:00">
<Text>Data collector 'Blame' message: All tests finished running, Sequence file will not be generated.</Text>
</RunInfo>
</RunInfos>
</ResultSummary>
</TestRun>

View File

@@ -1,7 +0,0 @@
{
"run_id": "20251207T131911Z",
"image_tag": "stellaops/console-runner:offline-20251207T131911Z",
"image_id": "sha256:39049b927c85ca8ae7cae79939fb36d2fa3a7ca04fb82220ef6b339b704cc0e3",
"repo_digest": "stellaops/console-runner@sha256:39049b927c85ca8ae7cae79939fb36d2fa3a7ca04fb82220ef6b339b704cc0e3",
"output_tar": "ops/devops/artifacts/console-runner/console-runner-20251207T131911Z.tar"
}

View File

@@ -1,24 +0,0 @@
# Attestation Alerts & Dashboards (DEVOPS-ATTEST-75-001)
## Prometheus alert rules
File: `ops/devops/attestation/attestation-alerts.yaml`
- `AttestorSignLatencyP95High`: p95 signing latency > 2s for 5m.
- `AttestorVerifyLatencyP95High`: p95 verification latency > 2s for 5m.
- `AttestorVerifyFailureRate`: verification failures / requests > 2% over 5m.
- `AttestorKeyRotationStale`: key not rotated in 30d.
Metrics expected:
- `attestor_sign_duration_seconds_bucket`
- `attestor_verify_duration_seconds_bucket`
- `attestor_verify_failures_total`
- `attestor_verify_requests_total`
- `attestor_key_last_rotated_seconds` (gauge of Unix epoch seconds of last rotation)
## Grafana
File: `ops/devops/attestation/grafana/attestation-latency.json`
- Panels: signing p50/p95, verification p50/p95, failure rate, key-age gauge, last 24h error counts.
## Runbook
- Verify exporters scrape `attestor-*` metrics from Attestor service.
- Ensure alertmanager routes `team=devops` to on-call.
- Key rotation alert: rotate via standard KMS workflow; acknowledge alert after new metric value observed.

View File

@@ -1,10 +0,0 @@
# Attestor CI/Secrets (DEVOPS-ATTEST-73-001/002)
Artifacts added for the DevOps attestation track:
- `ci.yml` — GitHub Actions workflow (parity stub) that restores/builds/tests Attestor solution and uploads test artefacts. Offline/airgap friendly when mirrored into local runner; set DOTNET_* envs for determinism.
- Secrets storage plan:
- Use KMS-backed cosign key refs (e.g., `azurekms://...` or `awskms://...`).
- Store ref in CI secret `ATTESTOR_COSIGN_KEY`; pipeline passes via env and never writes key material to disk.
- Audit logs: enable KMS audit + CI job logs; avoid plaintext key dumps.
- Next steps: wire `.gitea/workflows/attestor-ci.yml` to mirror this job, add `cosign sign-blob` stage for DSSE envelopes, and publish artefacts to `ops/devops/artifacts/attestor/<ts>/` with checksums.

View File

@@ -1,38 +0,0 @@
name: Attestor CI
on:
workflow_dispatch:
push:
paths:
- 'src/Attestor/**'
- '.gitea/workflows/attestor-ci.yml'
- 'ops/devops/attestation/**'
jobs:
build-test:
runs-on: ubuntu-latest
env:
DOTNET_NOLOGO: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
steps:
- uses: actions/checkout@v4
- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Restore
run: dotnet restore src/Attestor/StellaOps.Attestor.sln
- name: Build
run: dotnet build --no-restore -c Release src/Attestor/StellaOps.Attestor.sln
- name: Test
run: dotnet test --no-build -c Release src/Attestor/StellaOps.Attestor.sln
- name: Publish artefacts
if: always()
run: |
mkdir -p out/ci/attestor
find src/Attestor -name '*.trx' -o -name '*.xml' | tar -czf out/ci/attestor/test-artifacts.tgz -T-
- name: Upload artefacts
uses: actions/upload-artifact@v4
with:
name: attestor-ci-artifacts
path: out/ci/attestor/test-artifacts.tgz

View File

@@ -1,38 +0,0 @@
{
"title": "Attestor Latency & Errors",
"time": { "from": "now-24h", "to": "now" },
"panels": [
{
"type": "timeseries",
"title": "Signing latency p50/p95",
"targets": [
{ "expr": "histogram_quantile(0.5, sum(rate(attestor_sign_duration_seconds_bucket[5m])) by (le))", "legendFormat": "p50" },
{ "expr": "histogram_quantile(0.95, sum(rate(attestor_sign_duration_seconds_bucket[5m])) by (le))", "legendFormat": "p95" }
]
},
{
"type": "timeseries",
"title": "Verification latency p50/p95",
"targets": [
{ "expr": "histogram_quantile(0.5, sum(rate(attestor_verify_duration_seconds_bucket[5m])) by (le))", "legendFormat": "p50" },
{ "expr": "histogram_quantile(0.95, sum(rate(attestor_verify_duration_seconds_bucket[5m])) by (le))", "legendFormat": "p95" }
]
},
{
"type": "timeseries",
"title": "Verification failure rate",
"targets": [
{ "expr": "rate(attestor_verify_failures_total[5m]) / rate(attestor_verify_requests_total[5m])", "legendFormat": "failure rate" }
]
},
{
"type": "stat",
"title": "Key age (days)",
"targets": [
{ "expr": "(time() - attestor_key_last_rotated_seconds) / 86400" }
]
}
],
"schemaVersion": 39,
"version": 1
}

View File

@@ -1,57 +0,0 @@
# Transparency Log Witness Deployment Plan (DEVOPS-ATTEST-74-001)
## Goals
- Deploy and monitor a Sigstore-compatible witness for Rekor v2 logs (and air-gap mirrors).
- Provide offline-ready configs and evidence (hashes, DSSE attestations) for bootstrap packs.
## Scope
- Environments: staging → prod (online), sealed/offline mirror (optional, read-only).
- Witness duties: verify inclusion proofs, publish checkpoints/signed STHs, expose metrics and health.
## Architecture
- Witness binary (sigstore/witness or equivalent) in a hardened container:
- Non-root user, read-only rootfs, seccomp/AppArmor defaults.
- TLS with mTLS between witness and collector; optional OIDC for admin endpoints.
- Inputs:
- Rekor base URL(s) + public keys.
- Mirror CAR path + signature (for air-gap).
- Outputs:
- Signed checkpoints (STH) rotated hourly; stored in object storage + DSSE manifest.
- Metrics: Prometheus `/metrics` endpoint (request latency, verify failures, checkpoint age).
- Logs: JSON, structured, no PII.
## Deployment steps
1) Build/pull witness image (pin digest); generate SBOM + cosign attestations.
2) Create config:
- `rekor_urls`: prod/staging
- `rekor_keys`: PEMs
- `checkpoint_interval`: 1h
- `mirror_path` (optional): `/data/rekor-mirror.car`
- `signer`: KMS ref or file key (sealed-mode uses file key from bootstrap pack)
3) Helm/Compose template:
- read-only rootfs, drop NET_RAW, memory/cpu limits
- PVC for checkpoints (`/var/lib/witness/checkpoints`)
- Service exposing HTTPS + `/metrics`
4) CI:
- Lint chart
- Run e2e: start Rekor test instance, run witness, verify checkpoint written, verify metrics non-zero.
- Publish image SBOM/attestations and chart checksums.
5) Monitoring/alerts:
- `witness_verify_failures_total` > 0 over 5m
- `witness_checkpoint_age_seconds` > 5400
- `witness_backfill_queue_depth` (if supported) above threshold
## Offline/air-gap mode
- Consume signed Rekor mirror (CAR + manifest) from bootstrap pack.
- Run witness in verify-only mode against mirror; disable outbound network.
- Emit checkpoints signed with offline key; store in mirror bundle for audit.
## Evidence to capture
- Image digest, SBOM hash, chart checksum.
- Signed checkpoint sample and DSSE manifest.
- CI e2e logs and metrics sample (scrape output).
## Owners
- Build/deploy: DevOps Guild
- Keys/config: Platform Security
- Observability: Observability Guild

View File

@@ -1,147 +0,0 @@
# =============================================================================
# LOCAL CI TESTING ENVIRONMENT VARIABLES
# =============================================================================
# Copy this file to .env.local and customize for your local environment.
# The .env.local file is gitignored and should NOT be committed.
#
# Usage:
# cp devops/ci-local/.env.local.sample devops/ci-local/.env.local
# # Edit .env.local with your values
#
# =============================================================================
# =============================================================================
# DATABASE CONFIGURATION
# =============================================================================
# These values match docker-compose.ci.yaml defaults
# Port 5433 is used to avoid conflicts with development PostgreSQL
STELLAOPS_TEST_POSTGRES_CONNECTION="Host=localhost;Port=5433;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
# Alternative connection string format
POSTGRES_HOST=localhost
POSTGRES_PORT=5433
POSTGRES_USER=stellaops_ci
POSTGRES_PASSWORD=ci_test_password
POSTGRES_DB=stellaops_test
# =============================================================================
# CACHE & MESSAGING
# =============================================================================
# Valkey (Redis-compatible) - Port 6380 to avoid conflicts
VALKEY_CONNECTION_STRING="localhost:6380"
VALKEY_HOST=localhost
VALKEY_PORT=6380
# NATS JetStream - Port 4223 to avoid conflicts
#NATS_URL="nats://localhost:4223"
#NATS_HOST=localhost
#NATS_PORT=4223
# =============================================================================
# MOCK CONTAINER REGISTRY
# =============================================================================
# Local registry for release dry-run testing
REGISTRY_HOST=localhost:5001
REGISTRY_USERNAME=local
REGISTRY_PASSWORD=local
# =============================================================================
# MOCK S3 STORAGE (RustFS)
# =============================================================================
S3_ENDPOINT=http://localhost:9100
S3_ACCESS_KEY=rustfsadmin
S3_SECRET_KEY=rustfsadmin
S3_BUCKET=stellaops-ci
# =============================================================================
# SIGNING CONFIGURATION
# =============================================================================
# Mock signing keys for local testing - DO NOT USE IN PRODUCTION!
# Generate real keys with: cosign generate-key-pair
# Base64-encoded private key (leave empty to skip signing tests)
COSIGN_PRIVATE_KEY_B64=
# Password for the signing key
COSIGN_PASSWORD=local-test-password
# For keyless signing (requires internet)
# COSIGN_EXPERIMENTAL=1
# =============================================================================
# OPTIONAL: REAL SECRETS FOR FULL TESTING
# =============================================================================
# Uncomment and fill in for full integration testing
# These are NOT required for basic local CI runs
# Gitea API token for registry operations
# GITEA_TOKEN=
# GitHub Container Registry token
# GHCR_TOKEN=
# AI API key for AdvisoryAI tests
# AI_API_KEY=
# Slack webhook for notification tests
# SLACK_WEBHOOK=
# =============================================================================
# LOCAL CI CONFIGURATION
# =============================================================================
# Execution mode: docker, native, or act
LOCAL_CI_MODE=docker
# Number of parallel test runners (default: auto-detect CPU count)
LOCAL_CI_PARALLEL=4
# Enable verbose output
LOCAL_CI_VERBOSE=false
# Results output directory (relative to repo root)
LOCAL_CI_RESULTS_DIR=out/local-ci
# =============================================================================
# DEPLOYMENT FLAGS
# =============================================================================
# Always dry-run for local testing
DEPLOYMENT_DRY_RUN=true
# Mock deployment targets
DEPLOYMENT_HOST=localhost
DEPLOYMENT_USERNAME=testuser
DEPLOYMENT_PATH=/tmp/stellaops-deploy
# =============================================================================
# FEATURE FLAGS
# =============================================================================
# Skip tests requiring external network access
STELLAOPS_SKIP_NETWORK_TESTS=false
# Enable offline mode (uses cached/mock data)
STELLAOPS_OFFLINE_MODE=false
# Skip slow benchmark tests
SKIP_BENCHMARK_TESTS=true
# Skip chaos/resilience tests
SKIP_CHAOS_TESTS=true
# =============================================================================
# .NET BUILD CONFIGURATION
# =============================================================================
# These match CI environment exactly
DOTNET_NOLOGO=1
DOTNET_CLI_TELEMETRY_OPTOUT=1
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
TZ=UTC
# Build configuration
BUILD_CONFIGURATION=Release
# Warnings as errors (match CI)
DOTNET_WARNASERROR=true

View File

@@ -1,48 +0,0 @@
{
"action": "opened",
"number": 999,
"pull_request": {
"number": 999,
"title": "[Local CI] Test Pull Request",
"body": "This is a simulated pull request for local CI testing.",
"state": "open",
"draft": false,
"head": {
"ref": "feature/local-ci-test",
"sha": "0000000000000000000000000000000000000000",
"repo": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org"
}
},
"base": {
"ref": "main",
"sha": "0000000000000000000000000000000000000001",
"repo": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org"
}
},
"labels": [],
"user": {
"login": "local-ci-user",
"type": "User"
},
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
},
"repository": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org",
"default_branch": "main",
"private": true,
"owner": {
"login": "stellaops",
"type": "Organization"
}
},
"sender": {
"login": "local-ci-user",
"type": "User"
}
}

View File

@@ -1,54 +0,0 @@
{
"ref": "refs/heads/main",
"before": "0000000000000000000000000000000000000001",
"after": "0000000000000000000000000000000000000002",
"created": false,
"deleted": false,
"forced": false,
"compare": "https://git.stella-ops.org/compare/000001...000002",
"commits": [
{
"id": "0000000000000000000000000000000000000002",
"message": "[Local CI] Test commit on main branch",
"timestamp": "2025-01-01T00:00:00Z",
"author": {
"name": "Local CI User",
"email": "local-ci@stella-ops.org"
},
"committer": {
"name": "Local CI User",
"email": "local-ci@stella-ops.org"
},
"added": [],
"removed": [],
"modified": ["src/Scanner/StellaOps.Scanner.Core/Scanner.cs"]
}
],
"head_commit": {
"id": "0000000000000000000000000000000000000002",
"message": "[Local CI] Test commit on main branch",
"timestamp": "2025-01-01T00:00:00Z",
"author": {
"name": "Local CI User",
"email": "local-ci@stella-ops.org"
}
},
"repository": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org",
"default_branch": "main",
"private": true,
"owner": {
"login": "stellaops",
"type": "Organization"
}
},
"pusher": {
"name": "local-ci-user",
"email": "local-ci@stella-ops.org"
},
"sender": {
"login": "local-ci-user",
"type": "User"
}
}

View File

@@ -1,21 +0,0 @@
{
"ref": "refs/tags/suite-2026.04",
"ref_type": "tag",
"master_branch": "main",
"description": "StellaOps Suite Release 2026.04",
"pusher_type": "user",
"repository": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org",
"default_branch": "main",
"private": true,
"owner": {
"login": "stellaops",
"type": "Organization"
}
},
"sender": {
"login": "release-manager",
"type": "User"
}
}

View File

@@ -1,22 +0,0 @@
{
"schedule": [
{
"cron": "0 5 * * *"
}
],
"repository": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org",
"default_branch": "main",
"private": true,
"owner": {
"login": "stellaops",
"type": "Organization"
}
},
"sender": {
"login": "github-actions[bot]",
"type": "Bot"
},
"workflow": ".gitea/workflows/nightly-regression.yml"
}

View File

@@ -1,31 +0,0 @@
{
"action": "workflow_dispatch",
"inputs": {
"dry_run": "true",
"include_performance": "false",
"include_benchmark": "false",
"include_airgap": "false",
"include_chaos": "false",
"include_determinism": "false",
"include_resilience": "false",
"include_observability": "false",
"force_deploy": "false",
"environment": "local"
},
"ref": "refs/heads/main",
"repository": {
"name": "git.stella-ops.org",
"full_name": "stellaops/git.stella-ops.org",
"default_branch": "main",
"private": true,
"owner": {
"login": "stellaops",
"type": "Organization"
}
},
"sender": {
"login": "local-ci-user",
"type": "User"
},
"workflow": ".gitea/workflows/test-matrix.yml"
}

View File

@@ -1,150 +1,459 @@
# StellaOps Compose Profiles # Stella Ops Docker Compose Profiles
These Compose bundles ship the minimum services required to exercise the scanner pipeline plus control-plane dependencies. Every profile is pinned to immutable image digests sourced from `deploy/releases/*.yaml` and is linted via `docker compose config` in CI. Consolidated Docker Compose configuration for the StellaOps platform. All profiles use immutable image digests from `deploy/releases/*.yaml` and are validated via `docker compose config` in CI.
## Layout ## Quick Reference
| I want to... | Command |
|--------------|---------|
| Run the full platform | `docker compose -f docker-compose.stella-ops.yml up -d` |
| Add observability | `docker compose -f docker-compose.stella-ops.yml -f docker-compose.telemetry.yml up -d` |
| Run CI/testing infrastructure | `docker compose -f docker-compose.testing.yml --profile ci up -d` |
| Deploy with China compliance | See [China Compliance](#china-compliance-sm2sm3sm4) |
| Deploy with Russia compliance | See [Russia Compliance](#russia-compliance-gost) |
| Deploy with EU compliance | See [EU Compliance](#eu-compliance-eidas) |
---
## File Structure
### Core Stack Files
| File | Purpose |
|------|---------|
| `docker-compose.stella-ops.yml` | **Main stack**: PostgreSQL 18.1, Valkey 9.0.1, RustFS, Rekor v2, all StellaOps services |
| `docker-compose.telemetry.yml` | **Observability**: OpenTelemetry collector, Prometheus, Tempo, Loki |
| `docker-compose.testing.yml` | **CI/Testing**: Test databases, mock services, Gitea for integration tests |
| `docker-compose.dev.yml` | **Minimal dev infrastructure**: PostgreSQL, Valkey, RustFS only |
### Specialized Infrastructure
| File | Purpose |
|------|---------|
| `docker-compose.bsim.yml` | **BSim analysis**: PostgreSQL for Ghidra binary similarity corpus |
| `docker-compose.corpus.yml` | **Function corpus**: PostgreSQL for function behavior database |
| `docker-compose.sealed-ci.yml` | **Air-gapped CI**: Sealed testing environment with authority, signer, attestor |
| `docker-compose.telemetry-offline.yml` | **Offline observability**: Air-gapped Loki, Promtail, OTEL collector, Tempo, Prometheus |
### Regional Compliance Overlays
| File | Purpose | Jurisdiction |
|------|---------|--------------|
| `docker-compose.compliance-china.yml` | SM2/SM3/SM4 ShangMi crypto configuration | China (OSCCA) |
| `docker-compose.compliance-russia.yml` | GOST R 34.10-2012 crypto configuration | Russia (FSB) |
| `docker-compose.compliance-eu.yml` | eIDAS qualified trust services configuration | EU |
### Crypto Provider Overlays
| File | Purpose | Use Case |
|------|---------|----------|
| `docker-compose.crypto-sim.yml` | Universal crypto simulation | Testing without licensed crypto |
| `docker-compose.cryptopro.yml` | CryptoPro CSP (real GOST) | Production Russia deployments |
| `docker-compose.sm-remote.yml` | SM Remote service (real SM2) | Production China deployments |
### Additional Overlays
| File | Purpose | Use Case |
|------|---------|----------|
| `docker-compose.gpu.yaml` | NVIDIA GPU acceleration | Advisory AI inference with GPU |
| `docker-compose.cas.yaml` | Content Addressable Storage | Dedicated CAS with retention policies |
| `docker-compose.tile-proxy.yml` | Rekor tile caching proxy | Air-gapped Sigstore deployments |
### Supporting Files
| Path | Purpose | | Path | Purpose |
| ---- | ------- | |------|---------|
| `docker-compose.dev.yaml` | Edge/nightly stack tuned for laptops and iterative work. | | `env/*.env.example` | Environment variable templates per profile |
| `docker-compose.stage.yaml` | Stable channel stack mirroring pre-production clusters. | | `scripts/backup.sh` | Create deterministic volume snapshots |
| `docker-compose.prod.yaml` | Production cutover stack with front-door network hand-off and Notify events enabled. | | `scripts/reset.sh` | Stop stack and remove volumes (with confirmation) |
| `docker-compose.airgap.yaml` | Stable stack with air-gapped defaults (no outbound hostnames). |
| `docker-compose.mirror.yaml` | Managed mirror topology for `*.stella-ops.org` distribution (Concelier + Excititor + CDN gateway). |
| `docker-compose.rekor-v2.yaml` | Rekor v2 tiles overlay (MySQL-free) for bundled transparency logs. |
| `docker-compose.telemetry.yaml` | Optional OpenTelemetry collector overlay (mutual TLS, OTLP ingest endpoints). |
| `docker-compose.telemetry-storage.yaml` | Prometheus/Tempo/Loki storage overlay with multi-tenant defaults. |
| `docker-compose.gpu.yaml` | Optional GPU overlay enabling NVIDIA devices for Advisory AI web/worker. Apply with `-f docker-compose.<env>.yaml -f docker-compose.gpu.yaml`. |
| `env/*.env.example` | Seed `.env` files that document required secrets and ports per profile. |
| `scripts/backup.sh` | Pauses workers and creates tar.gz of Mongo/MinIO/Valkey volumes (deterministic snapshot). |
| `scripts/reset.sh` | Stops the stack and removes Mongo/MinIO/Valkey volumes after explicit confirmation. |
| `scripts/quickstart.sh` | Helper to validate config and start dev stack; set `USE_MOCK=1` to include `docker-compose.mock.yaml` overlay. |
| `docker-compose.mock.yaml` | Dev-only overlay with placeholder digests for missing services (orchestrator, policy-registry, packs, task-runner, VEX/Vuln stack). Use only with mock release manifest `deploy/releases/2025.09-mock-dev.yaml`. |
## Usage ---
## Usage Patterns
### Basic Development
```bash ```bash
cp env/dev.env.example dev.env # Copy environment template
docker compose --env-file dev.env -f docker-compose.dev.yaml config cp env/stellaops.env.example .env
docker compose --env-file dev.env -f docker-compose.dev.yaml up -d
# Validate configuration
docker compose -f docker-compose.stella-ops.yml config
# Start the platform
docker compose -f docker-compose.stella-ops.yml up -d
# View logs
docker compose -f docker-compose.stella-ops.yml logs -f scanner-web
``` ```
The stage and airgap variants behave the same way—swap the file names accordingly. All profiles expose 443/8443 for the UI and REST APIs, and they share a `stellaops` Docker network scoped to the compose project. ### With Observability
### Rekor v2 overlay (tiles)
Use the overlay below and set the Rekor env vars in your `.env` file (see
`env/dev.env.example`):
```bash
docker compose --env-file dev.env \
-f docker-compose.dev.yaml \
-f docker-compose.rekor-v2.yaml \
--profile sigstore up -d
```
> **Surface.Secrets:** set `SCANNER_SURFACE_SECRETS_PROVIDER`/`SCANNER_SURFACE_SECRETS_ROOT` in your `.env` and point `SURFACE_SECRETS_HOST_PATH` to the decrypted bundle path (default `./offline/surface-secrets`). The stack mounts that path read-only into Scanner Web/Worker so `secret://` references resolve without embedding plaintext.
> **Graph Explorer reminder:** If you enable Cartographer or Graph API containers alongside these profiles, update `etc/authority.yaml` so the `cartographer-service` client is marked with `properties.serviceIdentity: "cartographer"` and carries a tenant hint. The Authority host now refuses `graph:write` tokens without that marker, so apply the configuration change before rolling out the updated images.
### Telemetry collector overlay
The OpenTelemetry collector overlay is optional and can be layered on top of any profile:
```bash ```bash
# Generate TLS certificates for telemetry
./ops/devops/telemetry/generate_dev_tls.sh ./ops/devops/telemetry/generate_dev_tls.sh
docker compose -f docker-compose.telemetry.yaml up -d
python ../../ops/devops/telemetry/smoke_otel_collector.py --host localhost # Start platform with telemetry
docker compose -f docker-compose.telemetry-storage.yaml up -d docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.telemetry.yml up -d
``` ```
The generator script creates a development CA plus server/client certificates under ### CI/Testing Infrastructure
`deploy/telemetry/certs/`. The smoke test sends OTLP/HTTP payloads using the generated
client certificate and asserts the collector reports accepted traces, metrics, and logs.
The storage overlay starts Prometheus, Tempo, and Loki with multitenancy enabled so you
can validate the end-to-end pipeline before promoting changes to staging. Adjust the
configs in `deploy/telemetry/storage/` before running in production.
Mount the same certificates when running workloads so the collector can enforce mutual TLS.
For production cutovers copy `env/prod.env.example` to `prod.env`, update the secret placeholders, and create the external network expected by the profile:
```bash ```bash
# Start CI infrastructure only (different ports to avoid conflicts)
docker compose -f docker-compose.testing.yml --profile ci up -d
# Start mock services for integration testing
docker compose -f docker-compose.testing.yml --profile mock up -d
# Start Gitea for SCM integration tests
docker compose -f docker-compose.testing.yml --profile gitea up -d
# Start everything
docker compose -f docker-compose.testing.yml --profile all up -d
```
**Test Infrastructure Ports:**
| Service | Port | Purpose |
|---------|------|---------|
| postgres-test | 5433 | PostgreSQL 18 for tests |
| valkey-test | 6380 | Valkey for cache/queue tests |
| rustfs-test | 8180 | S3-compatible storage |
| mock-registry | 5001 | Container registry mock |
| gitea | 3000 | Git hosting for SCM tests |
---
## Regional Compliance Deployments
### China Compliance (SM2/SM3/SM4)
**For Testing (simulation):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-china.yml \
-f docker-compose.crypto-sim.yml up -d
```
**For Production (real SM crypto):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-china.yml \
-f docker-compose.sm-remote.yml up -d
```
**With OSCCA-certified HSM:**
```bash
# Set HSM connection details in environment
export SM_REMOTE_HSM_URL="https://sm-hsm.example.com:8900"
export SM_REMOTE_HSM_API_KEY="your-api-key"
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-china.yml \
-f docker-compose.sm-remote.yml up -d
```
**Algorithms:**
- SM2: Public key cryptography (GM/T 0003-2012)
- SM3: Hash function, 256-bit (GM/T 0004-2012)
- SM4: Block cipher, 128-bit (GM/T 0002-2012)
---
### Russia Compliance (GOST)
**For Testing (simulation):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-russia.yml \
-f docker-compose.crypto-sim.yml up -d
```
**For Production (CryptoPro CSP):**
```bash
# CryptoPro requires EULA acceptance
CRYPTOPRO_ACCEPT_EULA=1 docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-russia.yml \
-f docker-compose.cryptopro.yml up -d
```
**Requirements for CryptoPro:**
- CryptoPro CSP license files in `opt/cryptopro/downloads/`
- `CRYPTOPRO_ACCEPT_EULA=1` environment variable
- Valid CryptoPro container images
**Algorithms:**
- GOST R 34.10-2012: Digital signature (256/512-bit)
- GOST R 34.11-2012: Hash function (Streebog, 256/512-bit)
- GOST R 34.12-2015: Block cipher (Kuznyechik, Magma)
---
### EU Compliance (eIDAS)
**For Testing (simulation):**
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-eu.yml \
-f docker-compose.crypto-sim.yml up -d
```
**For Production:**
EU eIDAS deployments typically integrate with external Qualified Trust Service Providers (QTSPs) rather than hosting crypto locally. Configure your QTSP integration in the application settings.
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.compliance-eu.yml up -d
```
**Standards:**
- ETSI TS 119 312 compliant algorithms
- Qualified electronic signatures
- QTSP integration for qualified trust services
---
## Crypto Simulation Details
The `docker-compose.crypto-sim.yml` overlay provides a unified simulation service for all sovereign crypto profiles:
| Algorithm ID | Simulation | Use Case |
|--------------|------------|----------|
| `SM2`, `sm.sim` | HMAC-SHA256 | China testing |
| `GOST12-256`, `GOST12-512` | HMAC-SHA256 | Russia testing |
| `ru.magma.sim`, `ru.kuznyechik.sim` | HMAC-SHA256 | Russia testing |
| `DILITHIUM3`, `FALCON512`, `pq.sim` | HMAC-SHA256 | Post-quantum testing |
| `fips.sim`, `eidas.sim`, `kcmvp.sim` | ECDSA P-256 | FIPS/EU/Korea testing |
**Important:** Simulation is for testing only. Uses deterministic HMAC or static ECDSA keys—not suitable for production or compliance certification.
---
## Configuration Reference
### Infrastructure Services
| Service | Default Port | Purpose |
|---------|--------------|---------|
| PostgreSQL | 5432 | Primary database |
| Valkey | 6379 | Cache, queues, events |
| RustFS | 8080 | S3-compatible artifact storage |
| Rekor v2 | (internal) | Sigstore transparency log |
### Application Services
| Service | Default Port | Purpose |
|---------|--------------|---------|
| Authority | 8440 | OAuth2/OIDC identity provider |
| Signer | 8441 | Cryptographic signing |
| Attestor | 8442 | SLSA attestation |
| Scanner Web | 8444 | SBOM/vulnerability scanning API |
| Concelier | 8445 | Advisory aggregation |
| Notify Web | 8446 | Notification service |
| Issuer Directory | 8447 | CSAF publisher registry |
| Advisory AI Web | 8448 | AI-powered advisory analysis |
| Web UI | 8443 | Angular frontend |
### Environment Variables
Key variables (see `env/*.env.example` for complete list):
```bash
# Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=<secret>
POSTGRES_DB=stellaops_platform
# Authority
AUTHORITY_ISSUER=https://authority.example.com
# Scanner
SCANNER_EVENTS_ENABLED=false
SCANNER_OFFLINEKIT_ENABLED=false
# Crypto (for compliance overlays)
STELLAOPS_CRYPTO_PROFILE=default # or: china, russia, eu
STELLAOPS_CRYPTO_ENABLE_SIM=0 # set to 1 for simulation
# CryptoPro (Russia only)
CRYPTOPRO_ACCEPT_EULA=0 # must be 1 to use CryptoPro
# SM Remote (China only)
SM_SOFT_ALLOWED=1 # software-only SM2
SM_REMOTE_HSM_URL= # optional: OSCCA-certified HSM
```
---
## Networking
All profiles use a shared `stellaops` Docker network. Production deployments can attach a `frontdoor` network for reverse proxy integration:
```bash
# Create external network for load balancer
docker network create stellaops_frontdoor docker network create stellaops_frontdoor
docker compose --env-file prod.env -f docker-compose.prod.yaml config
# Set in environment
export FRONTDOOR_NETWORK=stellaops_frontdoor
``` ```
### Scanner event stream settings Only externally-reachable services (Authority, Signer, Attestor, Concelier, Scanner Web, Notify Web, UI) attach to the frontdoor network. Infrastructure services (PostgreSQL, Valkey, RustFS) remain on the private network.
Scanner WebService can emit signed `scanner.report.*` events to Redis Streams when `SCANNER__EVENTS__ENABLED=true`. Each profile ships environment placeholders you can override in the `.env` file: ---
- `SCANNER_EVENTS_ENABLED` toggle emission on/off (defaults to `false`). ## Sigstore Tools
- `SCANNER_EVENTS_DRIVER` currently only `redis` is supported.
- `SCANNER_EVENTS_DSN` Redis endpoint; leave blank to reuse the queue DSN when it uses `redis://`.
- `SCANNER_EVENTS_STREAM` stream name (`stella.events` by default).
- `SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS` per-publish timeout window (defaults to `5`).
- `SCANNER_EVENTS_MAX_STREAM_LENGTH` max stream length before Redis trims entries (defaults to `10000`).
Helm values mirror the same knobs under each services `env` map (see `deploy/helm/stellaops/values-*.yaml`). Enable Sigstore CLI tools (rekor-cli, cosign) with the `sigstore` profile:
### Scheduler worker configuration
Every Compose profile now provisions the `scheduler-worker` container (backed by the
`StellaOps.Scheduler.Worker.Host` entrypoint). The environment placeholders exposed
in the `.env` samples match the options bound by `AddSchedulerWorker`:
- `SCHEDULER_QUEUE_KIND` queue transport (`Nats` or `Redis`).
- `SCHEDULER_QUEUE_NATS_URL` NATS connection string used by planner/runner consumers.
- `SCHEDULER_STORAGE_DATABASE` PostgreSQL database name for scheduler state.
- `SCHEDULER_SCANNER_BASEADDRESS` base URL the runner uses when invoking Scanners
`/api/v1/reports` (defaults to the in-cluster `http://scanner-web:8444`).
Helm deployments inherit the same defaults from `services.scheduler-worker.env` in
`values.yaml`; override them per environment as needed.
### Advisory AI configuration
`advisory-ai-web` hosts the API/plan cache while `advisory-ai-worker` executes queued tasks. Both containers mount the shared volumes (`advisory-ai-queue`, `advisory-ai-plans`, `advisory-ai-outputs`) so they always read/write the same deterministic state. New environment knobs:
- `ADVISORY_AI_SBOM_BASEADDRESS` endpoint the SBOM context client hits (defaults to the in-cluster Scanner URL).
- `ADVISORY_AI_INFERENCE_MODE` `Local` (default) keeps inference on-prem; `Remote` posts sanitized prompts to the URL supplied via `ADVISORY_AI_REMOTE_BASEADDRESS`. Optional `ADVISORY_AI_REMOTE_APIKEY` carries the bearer token when remote inference is enabled.
- `ADVISORY_AI_WEB_PORT` host port for `advisory-ai-web`.
The Helm chart mirrors these settings under `services.advisory-ai-web` / `advisory-ai-worker` and expects a PVC named `stellaops-advisory-ai-data` so both deployments can mount the same RWX volume.
### Front-door network hand-off
`docker-compose.prod.yaml` adds a `frontdoor` network so operators can attach Traefik, Envoy, or an on-prem load balancer that terminates TLS. Override `FRONTDOOR_NETWORK` in `prod.env` if your reverse proxy uses a different bridge name. Attach only the externally reachable services (Authority, Signer, Attestor, Concelier, Scanner Web, Notify Web, UI) to that network—internal infrastructure (Mongo, MinIO, RustFS, NATS) stays on the private `stellaops` network.
### Updating to a new release
1. Import the new manifest into `deploy/releases/` (see `deploy/README.md`).
2. Update image digests in the relevant Compose file(s).
3. Re-run `docker compose config` to confirm the bundle is deterministic.
### Mock overlay for missing digests (dev only)
Until official digests land, you can exercise Compose packaging with mock placeholders:
```bash ```bash
# assumes docker-compose.dev.yaml as the base profile docker compose -f docker-compose.stella-ops.yml --profile sigstore up -d
USE_MOCK=1 ./scripts/quickstart.sh env/dev.env.example
``` ```
The overlay pins the missing services (orchestrator, policy-registry, packs-registry, task-runner, VEX/Vuln stack) to mock digests from `deploy/releases/2025.09-mock-dev.yaml` and starts their real entrypoints so integration flows can be exercised end-to-end. Replace the mock pins with production digests once releases publish; keep the mock overlay dev-only. ---
Keep digests synchronized between Compose, Helm, and the release manifest to preserve reproducibility guarantees. `deploy/tools/validate-profiles.sh` performs a quick audit. ## GPU Support for Advisory AI
### GPU toggle for Advisory AI GPU is disabled by default. To enable NVIDIA GPU inference:
GPU is disabled by default. To run inference on NVIDIA GPUs:
```bash ```bash
docker compose \ docker compose -f docker-compose.stella-ops.yml \
--env-file prod.env \ -f docker-compose.gpu.yaml up -d
-f docker-compose.prod.yaml \
-f docker-compose.gpu.yaml \
up -d
``` ```
The GPU overlay requests one GPU for `advisory-ai-worker` and `advisory-ai-web` and sets `ADVISORY_AI_INFERENCE_GPU=true`. Ensure the host has the NVIDIA container runtime and that the base compose file still sets the correct digests. **Requirements:**
- NVIDIA GPU with CUDA support
- nvidia-container-toolkit installed
- Docker configured with nvidia runtime
---
## Content Addressable Storage (CAS)
The CAS overlay provides dedicated RustFS instances with retention policies for different artifact types:
```bash
# Standalone CAS infrastructure
docker compose -f docker-compose.cas.yaml up -d
# Combined with main stack
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.cas.yaml up -d
```
**CAS Services:**
| Service | Port | Purpose |
|---------|------|---------|
| rustfs-cas | 8180 | Runtime facts, signals, replay artifacts |
| rustfs-evidence | 8181 | Merkle roots, hash chains, evidence bundles (immutable) |
| rustfs-attestation | 8182 | DSSE envelopes, in-toto attestations (immutable) |
**Retention Policies (configurable via `env/cas.env.example`):**
- Vulnerability DB: 7 days
- SBOM artifacts: 365 days
- Scan results: 90 days
- Evidence bundles: Indefinite (immutable)
- Attestations: Indefinite (immutable)
---
## Tile Proxy (Air-Gapped Sigstore)
For air-gapped deployments, the tile-proxy caches Rekor transparency log tiles locally from public Sigstore:
```bash
docker compose -f docker-compose.stella-ops.yml \
-f docker-compose.tile-proxy.yml up -d
```
**Tile Proxy vs Rekor v2:**
- Use `--profile sigstore` when running your own Rekor transparency log locally
- Use `docker-compose.tile-proxy.yml` when caching tiles from public Sigstore (rekor.sigstore.dev)
**Configuration:**
| Variable | Default | Purpose |
|----------|---------|---------|
| `REKOR_SERVER_URL` | `https://rekor.sigstore.dev` | Upstream Rekor to proxy |
| `TILE_PROXY_SYNC_ENABLED` | `true` | Enable periodic tile sync |
| `TILE_PROXY_SYNC_SCHEDULE` | `0 */6 * * *` | Sync every 6 hours |
| `TILE_PROXY_CACHE_MAX_SIZE_GB` | `10` | Local cache size limit |
The proxy syncs tiles on schedule and serves them to internal services for offline verification.
---
## Maintenance
### Backup
```bash
./scripts/backup.sh # Creates timestamped tar.gz of volumes
```
### Reset
```bash
./scripts/reset.sh # Stops stack, removes volumes (requires confirmation)
```
### Validate Configuration
```bash
docker compose -f docker-compose.stella-ops.yml config
```
### Update to New Release
1. Import new manifest to `deploy/releases/`
2. Update image digests in compose files
3. Run `docker compose config` to validate
4. Run `deploy/tools/validate-profiles.sh` for audit
---
## Troubleshooting
### Port Conflicts
Override ports in your `.env` file:
```bash
POSTGRES_PORT=5433
VALKEY_PORT=6380
SCANNER_WEB_PORT=8544
```
### Service Dependencies
Services declare `depends_on` with health checks. If a service fails to start, check its dependencies:
```bash
docker compose -f docker-compose.stella-ops.yml ps
docker compose -f docker-compose.stella-ops.yml logs postgres
docker compose -f docker-compose.stella-ops.yml logs valkey
```
### Crypto Provider Issues
For crypto simulation issues:
```bash
# Check sim-crypto service
docker compose logs sim-crypto
curl http://localhost:18090/keys
```
For CryptoPro issues:
```bash
# Verify EULA acceptance
echo $CRYPTOPRO_ACCEPT_EULA # must be 1
# Check CryptoPro service
docker compose logs cryptopro-csp
```
---
## Related Documentation
- [Deployment Upgrade Runbook](../../docs/operations/devops/runbooks/deployment-upgrade.md)
- [Local CI Guide](../../docs/technical/testing/LOCAL_CI_GUIDE.md)
- [Crypto Profile Configuration](../../docs/security/crypto-profile-configuration.md)
- [Regional Deployments](../../docs/operations/regional-deployments.md)

View File

@@ -1,403 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2-airgap"
com.stellaops.release.channel: "airgap"
com.stellaops.profile: "airgap"
networks:
stellaops:
driver: bridge
volumes:
valkey-data:
rustfs-data:
concelier-jobs:
nats-data:
scanner-surface-cache:
postgres-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d:ro
command:
- "postgres"
- "-c"
- "shared_preload_libraries=pg_stat_statements"
- "-c"
- "pg_stat_statements.track=all"
ports:
- "${POSTGRES_PORT:-25432}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-26379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-24222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:5551a3269b7008cd5aceecf45df018c67459ed519557ccbe48b093b926a39bcc
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:ddbbd664a42846cea6b40fca6465bc679b30f72851158f300d01a8571c5478fc
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:1ff0a3124d66d3a2702d8e421df40fbd98cc75cb605d95510598ebbae1433c50
restart: unless-stopped
depends_on:
- signer
- postgres
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:29e2e1a0972707e092cbd3d370701341f9fec2aa9316fb5d8100480f2a1c76b5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:3df8ca21878126758203c1a0444e39fd97f77ddacf04a69685cda9f1e5e94718
restart: unless-stopped
depends_on:
- postgres
- valkey
- concelier
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
# Surface.Env configuration (see docs/modules/scanner/design/surface-env.md)
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
SCANNER_SURFACE_CACHE_QUOTA_MB: "${SCANNER_SURFACE_CACHE_QUOTA_MB:-4096}"
SCANNER_SURFACE_PREFETCH_ENABLED: "${SCANNER_SURFACE_PREFETCH_ENABLED:-false}"
SCANNER_SURFACE_TENANT: "${SCANNER_SURFACE_TENANT:-default}"
SCANNER_SURFACE_FEATURES: "${SCANNER_SURFACE_FEATURES:-}"
SCANNER_SURFACE_SECRETS_PROVIDER: "${SCANNER_SURFACE_SECRETS_PROVIDER:-file}"
SCANNER_SURFACE_SECRETS_NAMESPACE: "${SCANNER_SURFACE_SECRETS_NAMESPACE:-}"
SCANNER_SURFACE_SECRETS_ROOT: "${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}"
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}"
SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:eea5d6cfe7835950c5ec7a735a651f2f0d727d3e470cf9027a4a402ea89c4fb5
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
# Surface.Env configuration (see docs/modules/scanner/design/surface-env.md)
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
SCANNER_SURFACE_CACHE_QUOTA_MB: "${SCANNER_SURFACE_CACHE_QUOTA_MB:-4096}"
SCANNER_SURFACE_PREFETCH_ENABLED: "${SCANNER_SURFACE_PREFETCH_ENABLED:-false}"
SCANNER_SURFACE_TENANT: "${SCANNER_SURFACE_TENANT:-default}"
SCANNER_SURFACE_FEATURES: "${SCANNER_SURFACE_FEATURES:-}"
SCANNER_SURFACE_SECRETS_PROVIDER: "${SCANNER_SURFACE_SECRETS_PROVIDER:-file}"
SCANNER_SURFACE_SECRETS_NAMESPACE: "${SCANNER_SURFACE_SECRETS_NAMESPACE:-}"
SCANNER_SURFACE_SECRETS_ROOT: "${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}"
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}"
SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__QUEUE__KIND: "${SCHEDULER_QUEUE_KIND:-Valkey}"
SCHEDULER__QUEUE__VALKEY__URL: "${SCHEDULER_QUEUE_VALKEY_URL:-valkey:6379}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.09.2}
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
DOTNET_ENVIRONMENT: Production
volumes:
- ../../etc/notify.airgap.yaml:/app/etc/notify.yaml:ro
ports:
- "${NOTIFY_WEB_PORT:-9446}:8446"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:65c0ee13f773efe920d7181512349a09d363ab3f3e177d276136bd2742325a68
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2-airgap
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
- stellaops
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2-airgap
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
volumes:
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
- stellaops
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:bee9668011ff414572131dc777faab4da24473fe12c230893f161cabee092a1d
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-9443}:8443"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,15 +1,14 @@
# Copyright (c) StellaOps. All rights reserved. # =============================================================================
# Licensed under BUSL-1.1. # BSIM - BINARY SIMILARITY ANALYSIS
# =============================================================================
# BSim PostgreSQL Database and Ghidra Headless Services # BSim PostgreSQL Database and Ghidra Headless Services for binary analysis.
# #
# Usage: # Usage:
# docker compose -f docker-compose.bsim.yml up -d # docker compose -f docker-compose.bsim.yml up -d
# #
# Environment variables: # Environment:
# BSIM_DB_PASSWORD - PostgreSQL password for BSim database # BSIM_DB_PASSWORD - PostgreSQL password for BSim database
# =============================================================================
version: '3.8'
services: services:
bsim-postgres: bsim-postgres:
@@ -22,9 +21,9 @@ services:
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
volumes: volumes:
- bsim-data:/var/lib/postgresql/data - bsim-data:/var/lib/postgresql/data
- ./scripts/init-bsim.sql:/docker-entrypoint-initdb.d/10-init-bsim.sql:ro - ../docker/ghidra/scripts/init-bsim.sql:/docker-entrypoint-initdb.d/10-init-bsim.sql:ro
ports: ports:
- "5433:5432" - "${BSIM_DB_PORT:-5433}:5432"
networks: networks:
- stellaops-bsim - stellaops-bsim
healthcheck: healthcheck:
@@ -34,10 +33,9 @@ services:
retries: 5 retries: 5
restart: unless-stopped restart: unless-stopped
# Ghidra Headless service for BSim analysis
ghidra-headless: ghidra-headless:
build: build:
context: . context: ../docker/ghidra
dockerfile: Dockerfile.headless dockerfile: Dockerfile.headless
image: stellaops/ghidra-headless:11.2 image: stellaops/ghidra-headless:11.2
container_name: stellaops-ghidra container_name: stellaops-ghidra
@@ -61,13 +59,11 @@ services:
limits: limits:
cpus: '4' cpus: '4'
memory: 8G memory: 8G
# Keep container running for ad-hoc analysis
entrypoint: ["tail", "-f", "/dev/null"] entrypoint: ["tail", "-f", "/dev/null"]
restart: unless-stopped restart: unless-stopped
volumes: volumes:
bsim-data: bsim-data:
driver: local
ghidra-projects: ghidra-projects:
ghidra-scripts: ghidra-scripts:
ghidra-output: ghidra-output:
@@ -75,4 +71,3 @@ volumes:
networks: networks:
stellaops-bsim: stellaops-bsim:
driver: bridge driver: bridge

View File

@@ -2,9 +2,11 @@
# Uses RustFS for S3-compatible immutable object storage # Uses RustFS for S3-compatible immutable object storage
# Aligned with best-in-class vulnerability scanner retention policies # Aligned with best-in-class vulnerability scanner retention policies
# #
# Usage: # Usage (standalone):
# docker compose -f docker-compose.cas.yaml up -d # docker compose -f docker-compose.cas.yaml up -d
# docker compose -f docker-compose.cas.yaml -f docker-compose.dev.yaml up -d #
# Usage (with main stack):
# docker compose -f docker-compose.stella-ops.yml -f docker-compose.cas.yaml up -d
x-release-labels: &release-labels x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge" com.stellaops.release.version: "2025.10.0-edge"

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: SM2, SM3, SM4 (ShangMi / Commercial Cipher - temporarily using NIST)
# Provider: offline-verification
# Jurisdiction: china, world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "china"
com.stellaops.crypto.profile: "china"
com.stellaops.crypto.provider: "offline-verification"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "china"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ../postgres-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:china
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:china
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:china
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:china
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:china
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,152 +0,0 @@
# =============================================================================
# LOCAL CI TESTING SERVICES
# =============================================================================
# Docker Compose profile for running CI tests locally.
# Uses different ports to avoid conflicts with development services.
#
# Usage:
# docker compose -f devops/compose/docker-compose.ci.yaml up -d
# docker compose -f devops/compose/docker-compose.ci.yaml down -v
#
# Services:
# - postgres-ci: PostgreSQL 18.1 for integration tests (port 5433)
# - valkey-ci: Valkey/Redis for caching tests (port 6380)
# - nats-ci: NATS JetStream for messaging tests (port 4223)
# - mock-registry: Local container registry for release testing (port 5001)
# - rekor-cli: Rekor CLI tool (profile: sigstore)
# - cosign: Cosign tool (profile: sigstore)
#
# =============================================================================
networks:
ci-net:
driver: bridge
name: stellaops-ci-net
volumes:
ci-postgres-data:
name: stellaops-ci-postgres
ci-valkey-data:
name: stellaops-ci-valkey
services:
# ---------------------------------------------------------------------------
# PostgreSQL 18.1 - Primary database for integration tests
# ---------------------------------------------------------------------------
postgres-ci:
image: postgres:18.1-alpine
container_name: stellaops-postgres-ci
environment:
POSTGRES_USER: stellaops_ci
POSTGRES_PASSWORD: ci_test_password
POSTGRES_DB: stellaops_test
# Performance tuning for tests
POSTGRES_INITDB_ARGS: "--data-checksums"
ports:
- "5433:5432" # Different port to avoid conflicts with dev
volumes:
- ci-postgres-data:/var/lib/postgresql/data
networks:
- ci-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stellaops_ci -d stellaops_test"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
restart: unless-stopped
# ---------------------------------------------------------------------------
# Valkey 9.0.1 - Redis-compatible cache for caching tests
# ---------------------------------------------------------------------------
valkey-ci:
image: valkey/valkey:9.0.1-alpine
container_name: stellaops-valkey-ci
command: ["valkey-server", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
ports:
- "6380:6379" # Different port to avoid conflicts
volumes:
- ci-valkey-data:/data
networks:
- ci-net
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
# ---------------------------------------------------------------------------
# Sigstore tools - Rekor CLI and Cosign (on-demand)
# ---------------------------------------------------------------------------
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- ci-net
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- ci-net
# ---------------------------------------------------------------------------
# NATS JetStream - Message queue for messaging tests
# ---------------------------------------------------------------------------
nats-ci:
image: nats:2.10-alpine
container_name: stellaops-nats-ci
command: ["-js", "-sd", "/data", "-m", "8222"]
ports:
- "4223:4222" # Client port (different from dev)
- "8223:8222" # Monitoring port
networks:
- ci-net
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8222/healthz"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
# ---------------------------------------------------------------------------
# Mock Container Registry - For release dry-run testing
# ---------------------------------------------------------------------------
mock-registry:
image: registry:2
container_name: stellaops-registry-ci
ports:
- "5001:5000"
environment:
REGISTRY_STORAGE_DELETE_ENABLED: "true"
networks:
- ci-net
restart: unless-stopped
# ---------------------------------------------------------------------------
# Mock S3 (MinIO) - For artifact storage tests
# ---------------------------------------------------------------------------
minio-ci:
image: minio/minio:latest
container_name: stellaops-minio-ci
command: server /data --console-address ":9001"
ports:
- "9100:9000" # S3 API port
- "9101:9001" # Console port
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
networks:
- ci-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

View File

@@ -0,0 +1,197 @@
# =============================================================================
# STELLA OPS - COMPLIANCE OVERLAY: CHINA
# =============================================================================
# SM2/SM3/SM4 ShangMi (Commercial Cipher) crypto overlay.
# This file extends docker-compose.stella-ops.yml with China-specific crypto.
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-china.yml up -d
#
# Cryptography:
# - SM2: Elliptic curve cryptography (signature, key exchange)
# - SM3: Hash function (256-bit digest)
# - SM4: Block cipher (128-bit)
#
# =============================================================================
x-crypto-env: &crypto-env
STELLAOPS_CRYPTO_PROFILE: "china"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
x-crypto-volumes: &crypto-volumes
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
services:
# ---------------------------------------------------------------------------
# Authority - China crypto overlay
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority:china
environment:
<<: *crypto-env
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Signer - China crypto overlay
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Attestor - China crypto overlay
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Concelier - China crypto overlay
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier:china
environment:
<<: *crypto-env
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Scanner Web - China crypto overlay
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web:china
environment:
<<: *crypto-env
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Scanner Worker - China crypto overlay
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker:china
environment:
<<: *crypto-env
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Scheduler Worker - China crypto overlay
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Notify Web - China crypto overlay
# ---------------------------------------------------------------------------
notify-web:
image: registry.stella-ops.org/stellaops/notify-web:china
environment:
<<: *crypto-env
volumes:
- ../../etc/notify:/app/etc/notify:ro
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Excititor - China crypto overlay
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor:china
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Advisory AI Web - China crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:china
environment:
<<: *crypto-env
volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Advisory AI Worker - China crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:china
environment:
<<: *crypto-env
volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
- ../../etc/appsettings.crypto.china.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "china"
# ---------------------------------------------------------------------------
# Web UI - China crypto overlay
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui:china
labels:
com.stellaops.crypto.profile: "china"

View File

@@ -0,0 +1,209 @@
# =============================================================================
# STELLA OPS - COMPLIANCE OVERLAY: EU
# =============================================================================
# eIDAS qualified trust services crypto overlay.
# This file extends docker-compose.stella-ops.yml with EU-specific crypto.
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-eu.yml up -d
#
# Cryptography:
# - eIDAS-compliant qualified electronic signatures
# - ETSI TS 119 312 compliant algorithms
# - Qualified Trust Service Provider (QTSP) integration
#
# =============================================================================
x-crypto-env: &crypto-env
STELLAOPS_CRYPTO_PROFILE: "eu"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
x-crypto-volumes: &crypto-volumes
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
services:
# ---------------------------------------------------------------------------
# Authority - EU crypto overlay
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Signer - EU crypto overlay
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Attestor - EU crypto overlay
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Concelier - EU crypto overlay
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier:eu
environment:
<<: *crypto-env
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Scanner Web - EU crypto overlay
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Scanner Worker - EU crypto overlay
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker:eu
environment:
<<: *crypto-env
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Scheduler Worker - EU crypto overlay
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Notify Web - EU crypto overlay
# ---------------------------------------------------------------------------
notify-web:
image: registry.stella-ops.org/stellaops/notify-web:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/notify:/app/etc/notify:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Excititor - EU crypto overlay
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Advisory AI Web - EU crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Advisory AI Worker - EU crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:eu
environment:
<<: *crypto-env
volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"
# ---------------------------------------------------------------------------
# Web UI - EU crypto overlay
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui:eu
labels:
com.stellaops.crypto.profile: "eu"
com.stellaops.compliance: "eidas"

View File

@@ -0,0 +1,216 @@
# =============================================================================
# STELLA OPS - COMPLIANCE OVERLAY: RUSSIA
# =============================================================================
# GOST R 34.10-2012, GOST R 34.11-2012 (Streebog) crypto overlay.
# This file extends docker-compose.stella-ops.yml with Russia-specific crypto.
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-russia.yml up -d
#
# With CryptoPro CSP:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-russia.yml \
# -f devops/compose/docker-compose.cryptopro.yml up -d
#
# Cryptography:
# - GOST R 34.10-2012: Digital signature
# - GOST R 34.11-2012: Hash function (Streebog, 256/512-bit)
# - GOST R 34.12-2015: Block cipher (Kuznyechik)
#
# Providers: openssl.gost, pkcs11.gost, cryptopro.gost
#
# =============================================================================
x-crypto-env: &crypto-env
STELLAOPS_CRYPTO_PROFILE: "russia"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
STELLAOPS_CRYPTO_PROVIDERS: "openssl.gost,pkcs11.gost,cryptopro.gost"
x-crypto-volumes: &crypto-volumes
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
services:
# ---------------------------------------------------------------------------
# Authority - Russia crypto overlay
# ---------------------------------------------------------------------------
authority:
image: registry.stella-ops.org/stellaops/authority:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Signer - Russia crypto overlay
# ---------------------------------------------------------------------------
signer:
image: registry.stella-ops.org/stellaops/signer:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Attestor - Russia crypto overlay
# ---------------------------------------------------------------------------
attestor:
image: registry.stella-ops.org/stellaops/attestor:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Concelier - Russia crypto overlay
# ---------------------------------------------------------------------------
concelier:
image: registry.stella-ops.org/stellaops/concelier:russia
environment:
<<: *crypto-env
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Scanner Web - Russia crypto overlay
# ---------------------------------------------------------------------------
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Scanner Worker - Russia crypto overlay
# ---------------------------------------------------------------------------
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker:russia
environment:
<<: *crypto-env
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Scheduler Worker - Russia crypto overlay
# ---------------------------------------------------------------------------
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Notify Web - Russia crypto overlay
# ---------------------------------------------------------------------------
notify-web:
image: registry.stella-ops.org/stellaops/notify-web:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/notify:/app/etc/notify:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Excititor - Russia crypto overlay
# ---------------------------------------------------------------------------
excititor:
image: registry.stella-ops.org/stellaops/excititor:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Advisory AI Web - Russia crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Advisory AI Worker - Russia crypto overlay
# ---------------------------------------------------------------------------
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:russia
environment:
<<: *crypto-env
volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
labels:
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost,pkcs11.gost,cryptopro.gost"
# ---------------------------------------------------------------------------
# Web UI - Russia crypto overlay
# ---------------------------------------------------------------------------
web-ui:
image: registry.stella-ops.org/stellaops/web-ui:russia
labels:
com.stellaops.crypto.profile: "russia"

View File

@@ -1,13 +1,14 @@
# Copyright (c) StellaOps. All rights reserved. # =============================================================================
# Licensed under BUSL-1.1. # CORPUS - FUNCTION BEHAVIOR DATABASE
# =============================================================================
# Function Behavior Corpus PostgreSQL Database # PostgreSQL database for function behavior corpus analysis.
# #
# Usage: # Usage:
# docker compose -f docker-compose.corpus.yml up -d # docker compose -f docker-compose.corpus.yml up -d
# #
# Environment variables: # Environment:
# CORPUS_DB_PASSWORD - PostgreSQL password for corpus database # CORPUS_DB_PASSWORD - PostgreSQL password for corpus database
# =============================================================================
services: services:
corpus-postgres: corpus-postgres:
@@ -20,10 +21,10 @@ services:
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C" POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
volumes: volumes:
- corpus-data:/var/lib/postgresql/data - corpus-data:/var/lib/postgresql/data
- ../../../docs/db/schemas/corpus.sql:/docker-entrypoint-initdb.d/10-corpus-schema.sql:ro - ../../docs/db/schemas/corpus.sql:/docker-entrypoint-initdb.d/10-corpus-schema.sql:ro
- ./scripts/init-test-data.sql:/docker-entrypoint-initdb.d/20-test-data.sql:ro - ../docker/corpus/scripts/init-test-data.sql:/docker-entrypoint-initdb.d/20-test-data.sql:ro
ports: ports:
- "5435:5432" - "${CORPUS_DB_PORT:-5435}:5432"
networks: networks:
- stellaops-corpus - stellaops-corpus
healthcheck: healthcheck:
@@ -35,9 +36,7 @@ services:
volumes: volumes:
corpus-data: corpus-data:
driver: local
networks: networks:
stellaops-corpus: stellaops-corpus:
driver: bridge driver: bridge

View File

@@ -0,0 +1,119 @@
# =============================================================================
# STELLA OPS - CRYPTO SIMULATION OVERLAY
# =============================================================================
# Universal crypto simulation service for testing sovereign crypto without
# licensed hardware or certified modules.
#
# This overlay provides the sim-crypto-service which simulates:
# - GOST R 34.10-2012 (Russia): GOST12-256, GOST12-512, ru.magma.sim, ru.kuznyechik.sim
# - SM2/SM3/SM4 (China): SM2, sm.sim, sm2.sim
# - Post-Quantum: DILITHIUM3, FALCON512, pq.sim
# - FIPS/eIDAS/KCMVP: fips.sim, eidas.sim, kcmvp.sim, world.sim
#
# Usage with China compliance:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with Russia compliance:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with EU compliance:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-eu.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# IMPORTANT: This is for TESTING/DEVELOPMENT ONLY.
# - Uses deterministic HMAC-SHA256 for SM/GOST/PQ (not real algorithms)
# - Uses static ECDSA P-256 key for FIPS/eIDAS/KCMVP
# - NOT suitable for production or compliance certification
#
# =============================================================================
x-crypto-sim-labels: &crypto-sim-labels
com.stellaops.component: "crypto-sim"
com.stellaops.profile: "simulation"
com.stellaops.production: "false"
x-sim-crypto-env: &sim-crypto-env
STELLAOPS_CRYPTO_ENABLE_SIM: "1"
STELLAOPS_CRYPTO_SIM_URL: "http://sim-crypto:8080"
networks:
stellaops:
external: true
name: stellaops
services:
# ---------------------------------------------------------------------------
# Sim Crypto Service - Universal sovereign crypto simulator
# ---------------------------------------------------------------------------
sim-crypto:
build:
context: ../services/crypto/sim-crypto-service
dockerfile: Dockerfile
image: registry.stella-ops.org/stellaops/sim-crypto:dev
container_name: stellaops-sim-crypto
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
ASPNETCORE_ENVIRONMENT: "Development"
ports:
- "${SIM_CRYPTO_PORT:-18090}:8080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/keys"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
labels: *crypto-sim-labels
# ---------------------------------------------------------------------------
# Override services to use sim-crypto
# ---------------------------------------------------------------------------
# Authority - Enable sim crypto
authority:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Signer - Enable sim crypto
signer:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Attestor - Enable sim crypto
attestor:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Scanner Web - Enable sim crypto
scanner-web:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Scanner Worker - Enable sim crypto
scanner-worker:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"
# Excititor - Enable sim crypto
excititor:
environment:
<<: *sim-crypto-env
labels:
com.stellaops.crypto.simulator: "enabled"

View File

@@ -0,0 +1,149 @@
# =============================================================================
# STELLA OPS - CRYPTOPRO CSP OVERLAY (Russia)
# =============================================================================
# CryptoPro CSP licensed provider overlay for compliance-russia.yml.
# Adds real CryptoPro CSP service for certified GOST R 34.10-2012 operations.
#
# IMPORTANT: Requires EULA acceptance before use.
#
# Usage (MUST be combined with stella-ops AND compliance-russia):
# CRYPTOPRO_ACCEPT_EULA=1 docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.cryptopro.yml up -d
#
# For development/testing without CryptoPro license, use crypto-sim.yml instead:
# docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Requirements:
# - CryptoPro CSP license files in opt/cryptopro/downloads/
# - CRYPTOPRO_ACCEPT_EULA=1 environment variable
# - CryptoPro container images with GOST engine
#
# GOST Algorithms Provided:
# - GOST R 34.10-2012: Digital signature (256/512-bit)
# - GOST R 34.11-2012: Hash function (Streebog, 256/512-bit)
# - GOST R 34.12-2015: Block cipher (Kuznyechik, Magma)
#
# =============================================================================
x-cryptopro-labels: &cryptopro-labels
com.stellaops.component: "cryptopro-csp"
com.stellaops.crypto.provider: "cryptopro"
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.certified: "true"
x-cryptopro-env: &cryptopro-env
STELLAOPS_CRYPTO_PROVIDERS: "cryptopro.gost"
STELLAOPS_CRYPTO_CRYPTOPRO_URL: "http://cryptopro-csp:8080"
STELLAOPS_CRYPTO_CRYPTOPRO_ENABLED: "true"
networks:
stellaops:
external: true
name: stellaops
services:
# ---------------------------------------------------------------------------
# CryptoPro CSP - Certified GOST cryptography provider
# ---------------------------------------------------------------------------
cryptopro-csp:
build:
context: ../..
dockerfile: devops/services/cryptopro/linux-csp-service/Dockerfile
args:
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
image: registry.stella-ops.org/stellaops/cryptopro-csp:2025.10.0
container_name: stellaops-cryptopro-csp
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
# GOST algorithm configuration
CRYPTOPRO_GOST_SIGNATURE_ALGORITHM: "GOST R 34.10-2012"
CRYPTOPRO_GOST_HASH_ALGORITHM: "GOST R 34.11-2012"
# Container and key store settings
CRYPTOPRO_CONTAINER_NAME: "${CRYPTOPRO_CONTAINER_NAME:-stellaops-signing}"
CRYPTOPRO_USE_MACHINE_STORE: "${CRYPTOPRO_USE_MACHINE_STORE:-true}"
CRYPTOPRO_PROVIDER_TYPE: "${CRYPTOPRO_PROVIDER_TYPE:-80}"
volumes:
- ../../opt/cryptopro/downloads:/opt/cryptopro/downloads:ro
- ../../etc/cryptopro:/app/etc/cryptopro:ro
# Optional: Mount key containers
- cryptopro-keys:/var/opt/cprocsp/keys
ports:
- "${CRYPTOPRO_PORT:-18080}:8080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
labels: *cryptopro-labels
# ---------------------------------------------------------------------------
# Override services to use CryptoPro
# ---------------------------------------------------------------------------
# Authority - Use CryptoPro for GOST signatures
authority:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Signer - Use CryptoPro for GOST signatures
signer:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Attestor - Use CryptoPro for GOST signatures
attestor:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Scanner Web - Use CryptoPro for verification
scanner-web:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Scanner Worker - Use CryptoPro for verification
scanner-worker:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
# Excititor - Use CryptoPro for VEX signing
excititor:
environment:
<<: *cryptopro-env
depends_on:
- cryptopro-csp
labels:
com.stellaops.crypto.provider: "cryptopro"
volumes:
cryptopro-keys:
name: stellaops-cryptopro-keys

View File

@@ -1,385 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "dev"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
restart: unless-stopped
depends_on:
- postgres
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority/plugins"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/authority:/app/etc/authority:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
restart: unless-stopped
depends_on:
- authority
- valkey
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
restart: unless-stopped
depends_on:
- signer
- valkey
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/app/etc/issuer-directory/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory:/app/etc/issuer-directory:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
restart: unless-stopped
depends_on:
- postgres
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:e0dfdb087e330585a5953029fb4757f5abdf7610820a085bd61b457dbead9a11
restart: unless-stopped
depends_on:
- postgres
- concelier
- rustfs
- nats
- valkey
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://nats:4222"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-valkey:6379}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
# Offline kit paths (for air-gap mode)
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-../../etc/certificates/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:92dda42f6f64b2d9522104a5c9ffb61d37b34dd193132b68457a259748008f37
restart: unless-stopped
depends_on:
- scanner-web
- rustfs
- nats
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "nats://nats:4222"
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- nats
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__QUEUE__KIND: "Nats"
SCHEDULER__QUEUE__NATS__URL: "nats://nats:4222"
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.10.0-edge}
restart: unless-stopped
depends_on:
- postgres
- authority
- valkey
environment:
DOTNET_ENVIRONMENT: Development
NOTIFY__STORAGE__DRIVER: "postgres"
NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
NOTIFY__QUEUE__DRIVER: "nats"
NOTIFY__QUEUE__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/notify:/app/etc/notify:ro
ports:
- "${NOTIFY_WEB_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/llm-providers:/app/etc/llm-providers:ro
# Runtime data
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
- stellaops
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
volumes:
# Configuration (consolidated under etc/)
- ../../etc/llm-providers:/app/etc/llm-providers:ro
# Runtime data
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
- stellaops
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:38b225fa7767a5b94ebae4dae8696044126aac429415e93de514d5dd95748dcf
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
cryptopro-csp:
build:
context: ../..
dockerfile: ops/cryptopro/linux-csp-service/Dockerfile
args:
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
volumes:
- ../../opt/cryptopro/downloads:/opt/cryptopro/downloads:ro
ports:
- "${CRYPTOPRO_PORT:-18080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -0,0 +1,73 @@
# =============================================================================
# DEVELOPMENT STACK - MINIMAL LOCAL DEVELOPMENT
# =============================================================================
# Minimal infrastructure for local development. Use this when you only need
# the core infrastructure without all application services.
#
# For full platform, use docker-compose.stella-ops.yml instead.
#
# Usage:
# docker compose -f docker-compose.dev.yml up -d
#
# This provides:
# - PostgreSQL 18.1 on port 5432
# - Valkey 9.0.1 on port 6379
# - RustFS on port 8080
# =============================================================================
services:
postgres:
image: postgres:18.1-alpine
container_name: stellaops-dev-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-stellaops}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-stellaops}
POSTGRES_DB: ${POSTGRES_DB:-stellaops_dev}
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT:-5432}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-stellaops}"]
interval: 10s
timeout: 5s
retries: 5
valkey:
image: valkey/valkey:9.0.1-alpine
container_name: stellaops-dev-valkey
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
container_name: stellaops-dev-rustfs
restart: unless-stopped
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_PORT:-8080}:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres-data:
valkey-data:
rustfs-data:

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: eIDAS-compliant qualified trust services (temporarily using NIST)
# Provider: offline-verification
# Jurisdiction: eu, world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "eu"
com.stellaops.crypto.profile: "eu"
com.stellaops.crypto.provider: "offline-verification"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "eu"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ../postgres-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:eu
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:eu
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:eu
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:eu
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:eu
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.eu.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,61 +0,0 @@
# docker-compose.gitea-test.yaml - Local Gitea instance for testing package registry
# Sprint: SPRINT_20251226_004_CICD
#
# Usage:
# docker compose -f devops/compose/docker-compose.gitea-test.yaml up -d
# # Wait for Gitea to start, then:
# # 1. Open http://localhost:3000 and complete initial setup
# # 2. Create a user and generate access token with package:write scope
# # 3. Test NuGet push:
# # dotnet nuget push pkg.nupkg --source http://localhost:3000/api/packages/owner/nuget/index.json --api-key YOUR_TOKEN
#
# Cleanup:
# docker compose -f devops/compose/docker-compose.gitea-test.yaml down -v
services:
gitea:
image: gitea/gitea:1.21
container_name: stellaops-gitea-test
environment:
- USER_UID=1000
- USER_GID=1000
# Enable package registry
- GITEA__packages__ENABLED=true
- GITEA__packages__CHUNKED_UPLOAD_PATH=/data/tmp/package-upload
# Enable NuGet
- GITEA__packages__NUGET_ENABLED=true
# Enable Container registry
- GITEA__packages__CONTAINER_ENABLED=true
# Database (SQLite for simplicity)
- GITEA__database__DB_TYPE=sqlite3
- GITEA__database__PATH=/data/gitea/gitea.db
# Server config
- GITEA__server__ROOT_URL=http://localhost:3000/
- GITEA__server__HTTP_PORT=3000
# Disable metrics/telemetry
- GITEA__metrics__ENABLED=false
# Session config
- GITEA__session__PROVIDER=memory
# Cache config
- GITEA__cache__ADAPTER=memory
# Log level
- GITEA__log__LEVEL=Warn
volumes:
- gitea-data:/data
- gitea-config:/etc/gitea
ports:
- "3000:3000" # Web UI
- "3022:22" # SSH (optional)
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
volumes:
gitea-data:
driver: local
gitea-config:
driver: local

View File

@@ -1,4 +1,18 @@
version: "3.9" # =============================================================================
# STELLA OPS GPU OVERLAY
# =============================================================================
# Enables NVIDIA GPU acceleration for Advisory AI inference services.
#
# Prerequisites:
# - NVIDIA GPU with CUDA support
# - nvidia-container-toolkit installed
# - Docker configured with nvidia runtime
#
# Usage:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.gpu.yaml up -d
#
# =============================================================================
services: services:
advisory-ai-worker: advisory-ai-worker:

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: Standard NIST algorithms (ECDSA, RSA, SHA-2)
# Provider: offline-verification
# Jurisdiction: world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "international"
com.stellaops.crypto.profile: "international"
com.stellaops.crypto.provider: "offline-verification"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "international"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ../postgres-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:international
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:international
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:international
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:international
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:international
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.international.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,152 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "mirror-managed"
networks:
mirror:
driver: bridge
volumes:
mongo-data:
minio-data:
concelier-jobs:
concelier-exports:
excititor-exports:
nginx-cache:
services:
mongo:
image: docker.io/library/mongo@sha256:c258b26dbb7774f97f52aff52231ca5f228273a84329c5f5e451c3739457db49
command: ["mongod", "--bind_ip_all"]
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: "${MONGO_INITDB_ROOT_USERNAME:-stellaops_mirror}"
MONGO_INITDB_ROOT_PASSWORD: "${MONGO_INITDB_ROOT_PASSWORD:-mirror-password}"
volumes:
- mongo-data:/data/db
networks:
- mirror
labels: *release-labels
minio:
image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
command: ["server", "/data", "--console-address", ":9001"]
restart: unless-stopped
environment:
MINIO_ROOT_USER: "${MINIO_ROOT_USER:-stellaops-mirror}"
MINIO_ROOT_PASSWORD: "${MINIO_ROOT_PASSWORD:-mirror-minio-secret}"
volumes:
- minio-data:/data
networks:
- mirror
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:dafef3954eb4b837e2c424dd2d23e1e4d60fa83794840fac9cd3dea1d43bd085
restart: unless-stopped
depends_on:
- mongo
- minio
environment:
ASPNETCORE_URLS: "http://+:8445"
CONCELIER__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME:-stellaops_mirror}:${MONGO_INITDB_ROOT_PASSWORD:-mirror-password}@mongo:27017/concelier?authSource=admin"
CONCELIER__STORAGE__S3__ENDPOINT: "http://minio:9000"
CONCELIER__STORAGE__S3__ACCESSKEYID: "${MINIO_ROOT_USER:-stellaops-mirror}"
CONCELIER__STORAGE__S3__SECRETACCESSKEY: "${MINIO_ROOT_PASSWORD:-mirror-minio-secret}"
CONCELIER__TELEMETRY__SERVICENAME: "stellaops-concelier-mirror"
CONCELIER__MIRROR__ENABLED: "true"
CONCELIER__MIRROR__EXPORTROOT: "/exports/json"
CONCELIER__MIRROR__LATESTDIRECTORYNAME: "${CONCELIER_MIRROR_LATEST_SEGMENT:-latest}"
CONCELIER__MIRROR__MIRRORDIRECTORYNAME: "${CONCELIER_MIRROR_DIRECTORY_SEGMENT:-mirror}"
CONCELIER__MIRROR__REQUIREAUTHENTICATION: "${CONCELIER_MIRROR_REQUIRE_AUTH:-true}"
CONCELIER__MIRROR__MAXINDEXREQUESTSPERHOUR: "${CONCELIER_MIRROR_INDEX_BUDGET:-600}"
CONCELIER__MIRROR__DOMAINS__0__ID: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_ID:-primary}"
CONCELIER__MIRROR__DOMAINS__0__DISPLAYNAME: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_NAME:-Primary Mirror}"
CONCELIER__MIRROR__DOMAINS__0__REQUIREAUTHENTICATION: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_AUTH:-true}"
CONCELIER__MIRROR__DOMAINS__0__MAXDOWNLOADREQUESTSPERHOUR: "${CONCELIER_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET:-3600}"
CONCELIER__MIRROR__DOMAINS__1__ID: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_ID:-community}"
CONCELIER__MIRROR__DOMAINS__1__DISPLAYNAME: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_NAME:-Community Mirror}"
CONCELIER__MIRROR__DOMAINS__1__REQUIREAUTHENTICATION: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_AUTH:-false}"
CONCELIER__MIRROR__DOMAINS__1__MAXDOWNLOADREQUESTSPERHOUR: "${CONCELIER_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET:-1800}"
CONCELIER__AUTHORITY__ENABLED: "${CONCELIER_AUTHORITY_ENABLED:-true}"
CONCELIER__AUTHORITY__ALLOWANONYMOUSFALLBACK: "${CONCELIER_AUTHORITY_ALLOW_ANON:-false}"
CONCELIER__AUTHORITY__ISSUER: "${CONCELIER_AUTHORITY_ISSUER:-https://authority.stella-ops.org}"
CONCELIER__AUTHORITY__METADATAADDRESS: "${CONCELIER_AUTHORITY_METADATA:-}"
CONCELIER__AUTHORITY__CLIENTID: "${CONCELIER_AUTHORITY_CLIENT_ID:-stellaops-concelier-mirror}"
CONCELIER__AUTHORITY__CLIENTSECRETFILE: "/run/secrets/concelier-authority-client"
CONCELIER__AUTHORITY__CLIENTSCOPES__0: "${CONCELIER_AUTHORITY_SCOPE:-concelier.mirror.read}"
CONCELIER__AUTHORITY__AUDIENCES__0: "${CONCELIER_AUTHORITY_AUDIENCE:-api://concelier.mirror}"
CONCELIER__AUTHORITY__BYPASSNETWORKS__0: "10.0.0.0/8"
CONCELIER__AUTHORITY__BYPASSNETWORKS__1: "127.0.0.1/32"
CONCELIER__AUTHORITY__BYPASSNETWORKS__2: "::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"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
- concelier-exports:/exports/json
- ./mirror-secrets:/run/secrets:ro
networks:
- mirror
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:d9bd5cadf1eab427447ce3df7302c30ded837239771cc6433b9befb895054285
restart: unless-stopped
depends_on:
- mongo
environment:
ASPNETCORE_URLS: "http://+:8448"
EXCITITOR__STORAGE__MONGO__CONNECTIONSTRING: "mongodb://${MONGO_INITDB_ROOT_USERNAME:-stellaops_mirror}:${MONGO_INITDB_ROOT_PASSWORD:-mirror-password}@mongo:27017/excititor?authSource=admin"
EXCITITOR__STORAGE__MONGO__DATABASENAME: "${EXCITITOR_MONGO_DATABASE:-excititor}"
EXCITITOR__ARTIFACTS__FILESYSTEM__ROOT: "/exports"
EXCITITOR__ARTIFACTS__FILESYSTEM__OVERWRITEEXISTING: "${EXCITITOR_FILESYSTEM_OVERWRITE:-false}"
EXCITITOR__MIRROR__DOMAINS__0__ID: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_ID:-primary}"
EXCITITOR__MIRROR__DOMAINS__0__DISPLAYNAME: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_NAME:-Primary Mirror}"
EXCITITOR__MIRROR__DOMAINS__0__REQUIREAUTHENTICATION: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_AUTH:-true}"
EXCITITOR__MIRROR__DOMAINS__0__MAXINDEXREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_INDEX_BUDGET:-300}"
EXCITITOR__MIRROR__DOMAINS__0__MAXDOWNLOADREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET:-2400}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__0__KEY: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_KEY:-consensus-json}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__0__FORMAT: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_FORMAT:-json}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__0__VIEW: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_VIEW:-consensus}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__1__KEY: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_KEY:-consensus-openvex}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__1__FORMAT: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_FORMAT:-openvex}"
EXCITITOR__MIRROR__DOMAINS__0__EXPORTS__1__VIEW: "${EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_VIEW:-consensus}"
EXCITITOR__MIRROR__DOMAINS__1__ID: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_ID:-community}"
EXCITITOR__MIRROR__DOMAINS__1__DISPLAYNAME: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_NAME:-Community Mirror}"
EXCITITOR__MIRROR__DOMAINS__1__REQUIREAUTHENTICATION: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_AUTH:-false}"
EXCITITOR__MIRROR__DOMAINS__1__MAXINDEXREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_INDEX_BUDGET:-120}"
EXCITITOR__MIRROR__DOMAINS__1__MAXDOWNLOADREQUESTSPERHOUR: "${EXCITITOR_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET:-600}"
EXCITITOR__MIRROR__DOMAINS__1__EXPORTS__0__KEY: "${EXCITITOR_MIRROR_SECONDARY_EXPORT_KEY:-community-consensus}"
EXCITITOR__MIRROR__DOMAINS__1__EXPORTS__0__FORMAT: "${EXCITITOR_MIRROR_SECONDARY_EXPORT_FORMAT:-json}"
EXCITITOR__MIRROR__DOMAINS__1__EXPORTS__0__VIEW: "${EXCITITOR_MIRROR_SECONDARY_EXPORT_VIEW:-consensus}"
volumes:
- excititor-exports:/exports
- ./mirror-secrets:/run/secrets:ro
expose:
- "8448"
networks:
- mirror
labels: *release-labels
mirror-gateway:
image: docker.io/library/nginx@sha256:208b70eefac13ee9be00e486f79c695b15cef861c680527171a27d253d834be9
restart: unless-stopped
depends_on:
- concelier
- excititor
ports:
- "${MIRROR_GATEWAY_HTTP_PORT:-8080}:80"
- "${MIRROR_GATEWAY_HTTPS_PORT:-9443}:443"
volumes:
- nginx-cache:/var/cache/nginx
- ./mirror-gateway/conf.d:/etc/nginx/conf.d:ro
- ./mirror-gateway/tls:/etc/nginx/tls:ro
- ./mirror-gateway/secrets:/etc/nginx/secrets:ro
networks:
- mirror
labels: *release-labels

View File

@@ -1,90 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2-mock"
com.stellaops.release.channel: "dev-mock"
com.stellaops.profile: "mock-overlay"
services:
orchestrator:
image: registry.stella-ops.org/stellaops/orchestrator@sha256:97f12856ce870bafd3328bda86833bcccbf56d255941d804966b5557f6610119
command: ["dotnet", "StellaOps.Orchestrator.WebService.dll"]
depends_on:
- mongo
- nats
labels: *release-labels
networks: [stellaops]
policy-registry:
image: registry.stella-ops.org/stellaops/policy-registry@sha256:c6cad8055e9827ebcbebb6ad4d6866dce4b83a0a49b0a8a6500b736a5cb26fa7
command: ["dotnet", "StellaOps.Policy.Engine.dll"]
depends_on:
- mongo
labels: *release-labels
networks: [stellaops]
vex-lens:
image: registry.stella-ops.org/stellaops/vex-lens@sha256:b44e63ecfeebc345a70c073c1ce5ace709c58be0ffaad0e2862758aeee3092fb
command: ["dotnet", "StellaOps.VexLens.dll"]
depends_on:
- mongo
labels: *release-labels
networks: [stellaops]
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory@sha256:67e8ef02c97d3156741e857756994888f30c373ace8e84886762edba9dc51914
command: ["dotnet", "StellaOps.IssuerDirectory.Web.dll"]
depends_on:
- mongo
- authority
labels: *release-labels
networks: [stellaops]
findings-ledger:
image: registry.stella-ops.org/stellaops/findings-ledger@sha256:71d4c361ba8b2f8b69d652597bc3f2efc8a64f93fab854ce25272a88506df49c
command: ["dotnet", "StellaOps.Findings.Ledger.WebService.dll"]
depends_on:
- postgres
- authority
labels: *release-labels
networks: [stellaops]
vuln-explorer-api:
image: registry.stella-ops.org/stellaops/vuln-explorer-api@sha256:7fc7e43a05cbeb0106ce7d4d634612e83de6fdc119aaab754a71c1d60b82841d
command: ["dotnet", "StellaOps.VulnExplorer.Api.dll"]
depends_on:
- findings-ledger
- authority
labels: *release-labels
networks: [stellaops]
packs-registry:
image: registry.stella-ops.org/stellaops/packs-registry@sha256:1f5e9416c4dc608594ad6fad87c24d72134427f899c192b494e22b268499c791
command: ["dotnet", "StellaOps.PacksRegistry.dll"]
depends_on:
- mongo
labels: *release-labels
networks: [stellaops]
task-runner:
image: registry.stella-ops.org/stellaops/task-runner@sha256:eb5ad992b49a41554f41516be1a6afcfa6522faf2111c08ff2b3664ad2fc954b
command: ["dotnet", "StellaOps.TaskRunner.WebService.dll"]
depends_on:
- packs-registry
- postgres
labels: *release-labels
networks: [stellaops]
cryptopro-csp:
build:
context: ../..
dockerfile: ops/cryptopro/linux-csp-service/Dockerfile
args:
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
environment:
ASPNETCORE_URLS: "http://0.0.0.0:8080"
CRYPTOPRO_ACCEPT_EULA: "${CRYPTOPRO_ACCEPT_EULA:-0}"
volumes:
- ../../opt/cryptopro/downloads:/opt/cryptopro/downloads:ro
ports:
- "${CRYPTOPRO_PORT:-18080}:8080"
labels: *release-labels
networks: [stellaops]

View File

@@ -1,34 +0,0 @@
# Rekor v2 tiles stack (MySQL-free).
# Usage:
# docker compose -f devops/compose/docker-compose.dev.yaml \
# -f devops/compose/docker-compose.rekor-v2.yaml --profile sigstore up -d
#
# Notes:
# - This overlay runs Rekor v2 (rekor-tiles) with a POSIX tiles volume.
# - Pin the image digest via REKOR_TILES_IMAGE in your env file.
# - Keep it on the internal stellaops network unless you explicitly need
# external access.
x-rekor-v2-labels: &rekor-v2-labels
com.stellaops.profile: "sigstore"
com.stellaops.component: "rekor-v2"
networks:
stellaops:
driver: bridge
volumes:
rekor-tiles-data:
services:
rekor-v2:
image: ${REKOR_TILES_IMAGE:-ghcr.io/sigstore/rekor-tiles:latest}
restart: unless-stopped
networks:
- stellaops
volumes:
- rekor-tiles-data:/var/lib/rekor-tiles
# Backend-specific flags/env are intentionally omitted here; follow the
# rekor-tiles documentation for POSIX backend defaults.
profiles: ["sigstore"]
labels: *rekor-v2-labels

View File

@@ -1,321 +0,0 @@
# StellaOps Docker Compose - International Profile
# Cryptography: GOST R 34.10-2012, GOST R 34.11-2012 (Streebog)
# Provider: openssl.gost, pkcs11.gost, cryptopro.gost
# Jurisdiction: world
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0-edge"
com.stellaops.release.channel: "edge"
com.stellaops.profile: "russia"
com.stellaops.crypto.profile: "russia"
com.stellaops.crypto.provider: "openssl.gost, pkcs11.gost, cryptopro.gost"
x-crypto-env: &crypto-env
# Crypto configuration
STELLAOPS_CRYPTO_PROFILE: "russia"
STELLAOPS_CRYPTO_CONFIG_PATH: "/app/etc/appsettings.crypto.yaml"
STELLAOPS_CRYPTO_MANIFEST_PATH: "/app/etc/crypto-plugins-manifest.json"
networks:
stellaops:
driver: bridge
volumes:
rustfs-data:
concelier-jobs:
nats-data:
valkey-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
postgres-data:
services:
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ../postgres-partitioning:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SIGNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor:russia
restart: unless-stopped
depends_on:
- signer
environment:
<<: *crypto-env
STELLAOPS_ATTESTOR__SIGNER__BASEURL: "http://signer:8441"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier:russia
restart: unless-stopped
depends_on:
- postgres
- rustfs
environment:
<<: *crypto-env
STELLAOPS_CONCELIER__STORAGE__DRIVER: "postgres"
STELLAOPS_CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_CONCELIER__STORAGE__RUSTFS__BASEURL: "http://rustfs:8080"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
- concelier-jobs:/app/jobs
ports:
- "${CONCELIER_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels
scanner:
image: registry.stella-ops.org/stellaops/scanner:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_SCANNER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCANNER_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_EXCITITOR__STORAGE__DRIVER: "postgres"
STELLAOPS_EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${EXCITITOR_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
policy:
image: registry.stella-ops.org/stellaops/policy:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_POLICY__STORAGE__DRIVER: "postgres"
STELLAOPS_POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${POLICY_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
scheduler:
image: registry.stella-ops.org/stellaops/scheduler:russia
restart: unless-stopped
depends_on:
- postgres
- nats
environment:
<<: *crypto-env
STELLAOPS_SCHEDULER__STORAGE__DRIVER: "postgres"
STELLAOPS_SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_SCHEDULER__MESSAGING__NATS__URL: "nats://nats:4222"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${SCHEDULER_PORT:-8447}:8447"
networks:
- stellaops
labels: *release-labels
notify:
image: registry.stella-ops.org/stellaops/notify:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_NOTIFY__STORAGE__DRIVER: "postgres"
STELLAOPS_NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${NOTIFY_PORT:-8448}:8448"
networks:
- stellaops
labels: *release-labels
zastava:
image: registry.stella-ops.org/stellaops/zastava:russia
restart: unless-stopped
depends_on:
- postgres
environment:
<<: *crypto-env
STELLAOPS_ZASTAVA__STORAGE__DRIVER: "postgres"
STELLAOPS_ZASTAVA__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${ZASTAVA_PORT:-8449}:8449"
networks:
- stellaops
labels: *release-labels
gateway:
image: registry.stella-ops.org/stellaops/gateway:russia
restart: unless-stopped
depends_on:
- authority
- concelier
- scanner
environment:
<<: *crypto-env
STELLAOPS_GATEWAY__AUTHORITY__BASEURL: "http://authority:8440"
STELLAOPS_GATEWAY__CONCELIER__BASEURL: "http://concelier:8443"
STELLAOPS_GATEWAY__SCANNER__BASEURL: "http://scanner:8444"
volumes:
- ../../etc/appsettings.crypto.russia.yaml:/app/etc/appsettings.crypto.yaml:ro
- ../../etc/crypto-plugins-manifest.json:/app/etc/crypto-plugins-manifest.json:ro
ports:
- "${GATEWAY_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels

View File

@@ -0,0 +1,121 @@
# =============================================================================
# SEALED CI - AIR-GAPPED TESTING ENVIRONMENT
# =============================================================================
# Sealed/air-gapped CI environment for testing offline functionality.
# All services run in isolated network with no external egress.
#
# Usage:
# docker compose -f docker-compose.sealed-ci.yml up -d
# =============================================================================
x-release-labels: &release-labels
com.stellaops.profile: 'sealed-ci'
com.stellaops.airgap.mode: 'sealed'
networks:
sealed-ci:
driver: bridge
volumes:
sealed-postgres-data:
sealed-valkey-data:
services:
postgres:
image: docker.io/library/postgres@sha256:8e97b8526ed19304b144f7478bc9201646acf0723cdc6e4b19bc9eb34879a27e
restart: unless-stopped
environment:
POSTGRES_USER: sealedci
POSTGRES_PASSWORD: sealedci-secret
POSTGRES_DB: stellaops
volumes:
- sealed-postgres-data:/var/lib/postgresql/data
networks:
- sealed-ci
healthcheck:
test: ["CMD-SHELL", "pg_isready -U sealedci -d stellaops"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
valkey:
image: docker.io/valkey/valkey:9.0.1-alpine
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- sealed-valkey-data:/data
networks:
- sealed-ci
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:a8e8faec44a579aa5714e58be835f25575710430b1ad2ccd1282a018cd9ffcdd
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:5088
STELLAOPS_AUTHORITY__ISSUER: http://authority.sealed-ci.local
STELLAOPS_AUTHORITY__STORAGE__DRIVER: postgres
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=authority;Username=sealedci;Password=sealedci-secret"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: /app/plugins
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: /app/plugins
STELLAOPS_AUTHORITY__SECURITY__SENDERCONSTRAINTS__DPOP__ENABLED: 'true'
STELLAOPS_AUTHORITY__SECURITY__SENDERCONSTRAINTS__MTLS__ENABLED: 'true'
STELLAOPS_AUTHORITY__AIRGAP__EGRESS__MODE: Sealed
volumes:
- ../services/sealed-mode-ci/authority.harness.yaml:/etc/authority.yaml:ro
- ../services/sealed-mode-ci/plugins:/app/plugins:ro
- ../../certificates:/certificates:ro
ports:
- '5088:5088'
networks:
- sealed-ci
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8bfef9a75783883d49fc18e3566553934e970b00ee090abee9cb110d2d5c3298
depends_on:
- authority
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:6088
SIGNER__AUTHORITY__BASEURL: http://authority:5088
SIGNER__POE__INTROSPECTURL: http://authority:5088/device-code
SIGNER__STORAGE__DRIVER: postgres
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=signer;Username=sealedci;Password=sealedci-secret"
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SIGNER__SEALED__MODE: Enabled
ports:
- '6088:6088'
networks:
- sealed-ci
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:5cc417948c029da01dccf36e4645d961a3f6d8de7e62fe98d845f07cd2282114
depends_on:
- signer
restart: unless-stopped
environment:
ASPNETCORE_URLS: http://+:7088
ATTESTOR__SIGNER__BASEURL: http://signer:6088
ATTESTOR__STORAGE__DRIVER: postgres
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=attestor;Username=sealedci;Password=sealedci-secret"
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ATTESTOR__SEALED__MODE: Enabled
ports:
- '7088:7088'
networks:
- sealed-ci
labels: *release-labels

View File

@@ -0,0 +1,153 @@
# =============================================================================
# STELLA OPS - SM REMOTE OVERLAY (China)
# =============================================================================
# SM Remote service overlay for compliance-china.yml.
# Provides SM2/SM3/SM4 (ShangMi) cryptographic operations via software provider
# or integration with OSCCA-certified hardware security modules.
#
# Usage (MUST be combined with stella-ops AND compliance-china):
# docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.sm-remote.yml up -d
#
# For development/testing without SM hardware, use crypto-sim.yml instead:
# docker compose \
# -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# SM Algorithms Provided:
# - SM2: Public key cryptography (ECDSA-like, 256-bit curve) - GM/T 0003-2012
# - SM3: Cryptographic hash function (256-bit output) - GM/T 0004-2012
# - SM4: Block cipher (128-bit key/block, AES-like) - GM/T 0002-2012
# - SM9: Identity-based cryptography - GM/T 0044-2016
#
# Providers:
# - cn.sm.soft: Software-only implementation using BouncyCastle
# - cn.sm.remote.http: Remote HSM integration via HTTP API
#
# OSCCA Compliance:
# - All cryptographic operations use SM algorithms exclusively
# - Hardware Security Modules should be OSCCA-certified
# - Certificates comply with GM/T 0015 (Certificate Profile)
#
# =============================================================================
x-sm-remote-labels: &sm-remote-labels
com.stellaops.component: "sm-remote"
com.stellaops.crypto.provider: "sm"
com.stellaops.crypto.profile: "china"
com.stellaops.crypto.jurisdiction: "china"
x-sm-remote-env: &sm-remote-env
STELLAOPS_CRYPTO_PROVIDERS: "cn.sm.soft,cn.sm.remote.http"
STELLAOPS_CRYPTO_SM_REMOTE_URL: "http://sm-remote:56080"
STELLAOPS_CRYPTO_SM_ENABLED: "true"
SM_SOFT_ALLOWED: "1"
networks:
stellaops:
external: true
name: stellaops
services:
# ---------------------------------------------------------------------------
# SM Remote Service - ShangMi cryptography provider
# ---------------------------------------------------------------------------
sm-remote:
build:
context: ../..
dockerfile: devops/services/sm-remote/Dockerfile
image: registry.stella-ops.org/stellaops/sm-remote:2025.10.0
container_name: stellaops-sm-remote
restart: unless-stopped
environment:
ASPNETCORE_URLS: "http://0.0.0.0:56080"
ASPNETCORE_ENVIRONMENT: "Production"
# Enable software-only SM2 provider (for testing/development)
SM_SOFT_ALLOWED: "${SM_SOFT_ALLOWED:-1}"
# Optional: Remote HSM configuration (for production with OSCCA-certified HSM)
SM_REMOTE_HSM_URL: "${SM_REMOTE_HSM_URL:-}"
SM_REMOTE_HSM_API_KEY: "${SM_REMOTE_HSM_API_KEY:-}"
SM_REMOTE_HSM_TIMEOUT: "${SM_REMOTE_HSM_TIMEOUT:-30000}"
# Optional: Client certificate authentication for HSM
SM_REMOTE_CLIENT_CERT_PATH: "${SM_REMOTE_CLIENT_CERT_PATH:-}"
SM_REMOTE_CLIENT_CERT_PASSWORD: "${SM_REMOTE_CLIENT_CERT_PASSWORD:-}"
volumes:
- ../../etc/sm-remote:/app/etc/sm-remote:ro
# Optional: Mount SM key containers
- sm-remote-keys:/var/lib/stellaops/sm-keys
ports:
- "${SM_REMOTE_PORT:-56080}:56080"
networks:
- stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:56080/status"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
labels: *sm-remote-labels
# ---------------------------------------------------------------------------
# Override services to use SM Remote
# ---------------------------------------------------------------------------
# Authority - Use SM Remote for SM2 signatures
authority:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Signer - Use SM Remote for SM2 signatures
signer:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Attestor - Use SM Remote for SM2 signatures
attestor:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Scanner Web - Use SM Remote for verification
scanner-web:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Scanner Worker - Use SM Remote for verification
scanner-worker:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
# Excititor - Use SM Remote for VEX signing
excititor:
environment:
<<: *sm-remote-env
depends_on:
- sm-remote
labels:
com.stellaops.crypto.provider: "sm"
volumes:
sm-remote-keys:
name: stellaops-sm-remote-keys

View File

@@ -1,389 +0,0 @@
x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2"
com.stellaops.release.channel: "stable"
com.stellaops.profile: "stage"
networks:
stellaops:
driver: bridge
volumes:
valkey-data:
rustfs-data:
concelier-jobs:
nats-data:
scanner-surface-cache:
postgres-data:
advisory-ai-queue:
advisory-ai-plans:
advisory-ai-outputs:
services:
valkey:
image: docker.io/valkey/valkey:9.0.1
restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"]
volumes:
- valkey-data:/data
ports:
- "${VALKEY_PORT:-6379}:6379"
networks:
- stellaops
labels: *release-labels
postgres:
image: docker.io/library/postgres:18.1
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
volumes:
- rustfs-data:/data
ports:
- "${RUSTFS_HTTP_PORT:-8080}:8080"
networks:
- stellaops
labels: *release-labels
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- stellaops
labels: *release-labels
nats:
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e
command:
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
authority:
image: registry.stella-ops.org/stellaops/authority@sha256:b0348bad1d0b401cc3c71cb40ba034c8043b6c8874546f90d4783c9dbfcc0bf5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins"
volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro
ports:
- "${AUTHORITY_PORT:-8440}:8440"
networks:
- stellaops
labels: *release-labels
signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8ad574e61f3a9e9bda8a58eb2700ae46813284e35a150b1137bc7c2b92ac0f2e
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${SIGNER_PORT:-8441}:8441"
networks:
- stellaops
labels: *release-labels
attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
restart: unless-stopped
depends_on:
- signer
- postgres
environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ports:
- "${ATTESTOR_PORT:-8442}:8442"
networks:
- stellaops
labels: *release-labels
issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes:
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro
ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks:
- stellaops
labels: *release-labels
concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
restart: unless-stopped
depends_on:
- postgres
- valkey
environment:
CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
volumes:
- concelier-jobs:/var/lib/concelier/jobs
ports:
- "${CONCELIER_PORT:-8445}:8445"
networks:
- stellaops
labels: *release-labels
scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:14b23448c3f9586a9156370b3e8c1991b61907efa666ca37dd3aaed1e79fe3b7
restart: unless-stopped
depends_on:
- postgres
- valkey
- concelier
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-}"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
SCANNER_SURFACE_CACHE_QUOTA_MB: "${SCANNER_SURFACE_CACHE_QUOTA_MB:-4096}"
SCANNER_SURFACE_PREFETCH_ENABLED: "${SCANNER_SURFACE_PREFETCH_ENABLED:-false}"
SCANNER_SURFACE_TENANT: "${SCANNER_SURFACE_TENANT:-default}"
SCANNER_SURFACE_FEATURES: "${SCANNER_SURFACE_FEATURES:-}"
SCANNER_SURFACE_SECRETS_PROVIDER: "${SCANNER_SURFACE_SECRETS_PROVIDER:-file}"
SCANNER_SURFACE_SECRETS_NAMESPACE: "${SCANNER_SURFACE_SECRETS_NAMESPACE:-}"
SCANNER_SURFACE_SECRETS_ROOT: "${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}"
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}"
SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
- ${SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH:-./offline/rekor-snapshot}:${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}:ro
ports:
- "${SCANNER_WEB_PORT:-8444}:8444"
networks:
- stellaops
labels: *release-labels
scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
- rustfs
environment:
SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}"
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
SCANNER_SURFACE_CACHE_QUOTA_MB: "${SCANNER_SURFACE_CACHE_QUOTA_MB:-4096}"
SCANNER_SURFACE_PREFETCH_ENABLED: "${SCANNER_SURFACE_PREFETCH_ENABLED:-false}"
SCANNER_SURFACE_TENANT: "${SCANNER_SURFACE_TENANT:-default}"
SCANNER_SURFACE_FEATURES: "${SCANNER_SURFACE_FEATURES:-}"
SCANNER_SURFACE_SECRETS_PROVIDER: "${SCANNER_SURFACE_SECRETS_PROVIDER:-file}"
SCANNER_SURFACE_SECRETS_NAMESPACE: "${SCANNER_SURFACE_SECRETS_NAMESPACE:-}"
SCANNER_SURFACE_SECRETS_ROOT: "${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}"
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}"
SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}"
volumes:
- scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
networks:
- stellaops
labels: *release-labels
scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge
restart: unless-stopped
depends_on:
- postgres
- valkey
- scanner-web
command:
- "dotnet"
- "StellaOps.Scheduler.Worker.Host.dll"
environment:
SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
SCHEDULER__QUEUE__KIND: "${SCHEDULER_QUEUE_KIND:-Valkey}"
SCHEDULER__QUEUE__VALKEY__URL: "${SCHEDULER_QUEUE_VALKEY_URL:-valkey:6379}"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks:
- stellaops
labels: *release-labels
notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.09.2}
restart: unless-stopped
depends_on:
- postgres
- authority
environment:
DOTNET_ENVIRONMENT: Production
volumes:
- ../../etc/notify.stage.yaml:/app/etc/notify.yaml:ro
ports:
- "${NOTIFY_WEB_PORT:-8446}:8446"
networks:
- stellaops
labels: *release-labels
excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
restart: unless-stopped
depends_on:
- postgres
- concelier
environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks:
- stellaops
labels: *release-labels
advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2
restart: unless-stopped
depends_on:
- scanner-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes:
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
- stellaops
labels: *release-labels
advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2
restart: unless-stopped
depends_on:
- advisory-ai-web
environment:
ADVISORYAI__AdvisoryAI__SbomBaseAddress: "${ADVISORY_AI_SBOM_BASEADDRESS:-http://scanner-web:8444}"
ADVISORYAI__AdvisoryAI__Queue__DirectoryPath: "/var/lib/advisory-ai/queue"
ADVISORYAI__AdvisoryAI__Storage__PlanCacheDirectory: "/var/lib/advisory-ai/plans"
ADVISORYAI__AdvisoryAI__Storage__OutputDirectory: "/var/lib/advisory-ai/outputs"
ADVISORYAI__AdvisoryAI__Inference__Mode: "${ADVISORY_AI_INFERENCE_MODE:-Local}"
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
volumes:
- advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs
networks:
- stellaops
labels: *release-labels
web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
restart: unless-stopped
depends_on:
- scanner-web
environment:
STELLAOPS_UI__BACKEND__BASEURL: "https://scanner-web:8444"
ports:
- "${UI_PORT:-8443}:8443"
networks:
- stellaops
labels: *release-labels

View File

@@ -1,29 +1,90 @@
# =============================================================================
# STELLA OPS - MAIN STACK
# =============================================================================
# Consolidated Docker Compose for the complete StellaOps platform.
# Infrastructure: PostgreSQL 18.1, Valkey 9.0.1, RustFS, Rekor v2
#
# Usage:
# docker compose -f devops/compose/docker-compose.stella-ops.yml up -d
#
# With Sigstore tools:
# docker compose -f devops/compose/docker-compose.stella-ops.yml --profile sigstore up -d
#
# With Telemetry:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.telemetry.yml up -d
#
# With Compliance overlay (e.g., China):
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.compliance-china.yml up -d
#
# =============================================================================
x-release-labels: &release-labels x-release-labels: &release-labels
com.stellaops.release.version: "2025.09.2" com.stellaops.release.version: "2025.10.0"
com.stellaops.release.channel: "stable" com.stellaops.release.channel: "stable"
com.stellaops.profile: "prod" com.stellaops.profile: "default"
x-postgres-connection: &postgres-connection
"Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}"
networks: networks:
stellaops: stellaops:
driver: bridge driver: bridge
name: stellaops
frontdoor: frontdoor:
external: true external: true
name: ${FRONTDOOR_NETWORK:-stellaops_frontdoor} name: ${FRONTDOOR_NETWORK:-stellaops_frontdoor}
volumes: volumes:
postgres-data:
valkey-data: valkey-data:
rustfs-data: rustfs-data:
rekor-tiles-data:
concelier-jobs: concelier-jobs:
nats-data:
scanner-surface-cache: scanner-surface-cache:
postgres-data:
advisory-ai-queue: advisory-ai-queue:
advisory-ai-plans: advisory-ai-plans:
advisory-ai-outputs: advisory-ai-outputs:
services: services:
# ===========================================================================
# INFRASTRUCTURE SERVICES
# ===========================================================================
# ---------------------------------------------------------------------------
# PostgreSQL 18.1 - Primary database
# ---------------------------------------------------------------------------
postgres:
image: docker.io/library/postgres:18.1
container_name: stellaops-postgres
restart: unless-stopped
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d:ro
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-stellaops} -d ${POSTGRES_DB:-stellaops_platform}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
labels: *release-labels
# ---------------------------------------------------------------------------
# Valkey 9.0.1 - Cache and message queue (Redis-compatible)
# ---------------------------------------------------------------------------
valkey: valkey:
image: docker.io/valkey/valkey:9.0.1 image: docker.io/valkey/valkey:9.0.1
container_name: stellaops-valkey
restart: unless-stopped restart: unless-stopped
command: ["valkey-server", "--appendonly", "yes"] command: ["valkey-server", "--appendonly", "yes"]
volumes: volumes:
@@ -32,10 +93,19 @@ services:
- "${VALKEY_PORT:-6379}:6379" - "${VALKEY_PORT:-6379}:6379"
networks: networks:
- stellaops - stellaops
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# RustFS - S3-compatible object storage
# ---------------------------------------------------------------------------
rustfs: rustfs:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2 image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
container_name: stellaops-rustfs
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"] command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
restart: unless-stopped restart: unless-stopped
environment: environment:
@@ -47,8 +117,32 @@ services:
- "${RUSTFS_HTTP_PORT:-8080}:8080" - "${RUSTFS_HTTP_PORT:-8080}:8080"
networks: networks:
- stellaops - stellaops
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Rekor v2 (tiles) - Sigstore transparency log
# ---------------------------------------------------------------------------
rekor-v2:
image: ${REKOR_TILES_IMAGE:-ghcr.io/sigstore/rekor-tiles:latest}
container_name: stellaops-rekor
restart: unless-stopped
volumes:
- rekor-tiles-data:/var/lib/rekor-tiles
networks:
- stellaops
profiles: ["sigstore"]
labels:
<<: *release-labels
com.stellaops.component: "rekor-v2"
# ---------------------------------------------------------------------------
# Sigstore CLI tools (on-demand)
# ---------------------------------------------------------------------------
rekor-cli: rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3 image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"] entrypoint: ["rekor-cli"]
@@ -67,37 +161,32 @@ services:
- stellaops - stellaops
labels: *release-labels labels: *release-labels
nats: # ===========================================================================
image: docker.io/library/nats@sha256:c82559e4476289481a8a5196e675ebfe67eea81d95e5161e3e78eccfe766608e # APPLICATION SERVICES
command: # ===========================================================================
- "-js"
- "-sd"
- /data
restart: unless-stopped
ports:
- "${NATS_CLIENT_PORT:-4222}:4222"
volumes:
- nats-data:/data
networks:
- stellaops
labels: *release-labels
# ---------------------------------------------------------------------------
# Authority - OAuth2/OIDC identity provider
# ---------------------------------------------------------------------------
authority: authority:
image: registry.stella-ops.org/stellaops/authority@sha256:b0348bad1d0b401cc3c71cb40ba034c8043b6c8874546f90d4783c9dbfcc0bf5 image: registry.stella-ops.org/stellaops/authority@sha256:b0348bad1d0b401cc3c71cb40ba034c8043b6c8874546f90d4783c9dbfcc0bf5
container_name: stellaops-authority
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres postgres:
- valkey condition: service_healthy
valkey:
condition: service_healthy
environment: environment:
STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}" STELLAOPS_AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres" STELLAOPS_AUTHORITY__STORAGE__DRIVER: "postgres"
STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" STELLAOPS_AUTHORITY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379" STELLAOPS_AUTHORITY__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins" STELLAOPS_AUTHORITY__PLUGINDIRECTORIES__0: "/app/plugins"
STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority.plugins" STELLAOPS_AUTHORITY__PLUGINS__CONFIGURATIONDIRECTORY: "/app/etc/authority/plugins"
volumes: volumes:
- ../../etc/authority.yaml:/etc/authority.yaml:ro - ../../etc/authority:/app/etc/authority:ro
- ../../etc/authority.plugins:/app/etc/authority.plugins:ro - ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
ports: ports:
- "${AUTHORITY_PORT:-8440}:8440" - "${AUTHORITY_PORT:-8440}:8440"
networks: networks:
@@ -105,17 +194,22 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Signer - Cryptographic signing service
# ---------------------------------------------------------------------------
signer: signer:
image: registry.stella-ops.org/stellaops/signer@sha256:8ad574e61f3a9e9bda8a58eb2700ae46813284e35a150b1137bc7c2b92ac0f2e image: registry.stella-ops.org/stellaops/signer@sha256:8ad574e61f3a9e9bda8a58eb2700ae46813284e35a150b1137bc7c2b92ac0f2e
container_name: stellaops-signer
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres
- authority - authority
- valkey
environment: environment:
SIGNER__AUTHORITY__BASEURL: "https://authority:8440" SIGNER__AUTHORITY__BASEURL: "https://authority:8440"
SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}" SIGNER__POE__INTROSPECTURL: "${SIGNER_POE_INTROSPECT_URL}"
SIGNER__STORAGE__DRIVER: "postgres" SIGNER__STORAGE__DRIVER: "postgres"
SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" SIGNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SIGNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports: ports:
- "${SIGNER_PORT:-8441}:8441" - "${SIGNER_PORT:-8441}:8441"
networks: networks:
@@ -123,16 +217,20 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Attestor - SLSA attestation service
# ---------------------------------------------------------------------------
attestor: attestor:
image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f image: registry.stella-ops.org/stellaops/attestor@sha256:0534985f978b0b5d220d73c96fddd962cd9135f616811cbe3bff4666c5af568f
container_name: stellaops-attestor
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- signer - signer
- postgres
environment: environment:
ATTESTOR__SIGNER__BASEURL: "https://signer:8441" ATTESTOR__SIGNER__BASEURL: "https://signer:8441"
ATTESTOR__STORAGE__DRIVER: "postgres" ATTESTOR__STORAGE__DRIVER: "postgres"
ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" ATTESTOR__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
ATTESTOR__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
ports: ports:
- "${ATTESTOR_PORT:-8442}:8442" - "${ATTESTOR_PORT:-8442}:8442"
networks: networks:
@@ -140,53 +238,47 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
postgres: # ---------------------------------------------------------------------------
image: docker.io/library/postgres:18.1 # Issuer Directory - CSAF publisher registry
restart: unless-stopped # ---------------------------------------------------------------------------
environment:
POSTGRES_USER: "${POSTGRES_USER:-stellaops}"
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-stellaops}"
POSTGRES_DB: "${POSTGRES_DB:-stellaops_platform}"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT:-5432}:5432"
networks:
- stellaops
labels: *release-labels
issuer-directory: issuer-directory:
image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0-edge image: registry.stella-ops.org/stellaops/issuer-directory-web:2025.10.0
container_name: stellaops-issuer-directory
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres - postgres
- authority - authority
environment: environment:
ISSUERDIRECTORY__CONFIG: "/etc/issuer-directory.yaml" ISSUERDIRECTORY__CONFIG: "/app/etc/issuer-directory/issuer-directory.yaml"
ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}" ISSUERDIRECTORY__AUTHORITY__ISSUER: "${AUTHORITY_ISSUER}"
ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440" ISSUERDIRECTORY__AUTHORITY__BASEURL: "https://authority:8440"
ISSUERDIRECTORY__STORAGE__DRIVER: "postgres" ISSUERDIRECTORY__STORAGE__DRIVER: "postgres"
ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" ISSUERDIRECTORY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}" ISSUERDIRECTORY__SEEDCSAFPUBLISHERS: "${ISSUER_DIRECTORY_SEED_CSAF:-true}"
volumes: volumes:
- ../../etc/issuer-directory.yaml:/etc/issuer-directory.yaml:ro - ../../etc/issuer-directory:/app/etc/issuer-directory:ro
ports: ports:
- "${ISSUER_DIRECTORY_PORT:-8447}:8080" - "${ISSUER_DIRECTORY_PORT:-8447}:8080"
networks: networks:
- stellaops - stellaops
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Concelier - Advisory aggregation service
# ---------------------------------------------------------------------------
concelier: concelier:
image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5 image: registry.stella-ops.org/stellaops/concelier@sha256:c58cdcaee1d266d68d498e41110a589dd204b487d37381096bd61ab345a867c5
container_name: stellaops-concelier
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres - postgres
- valkey - valkey
- rustfs
environment: environment:
CONCELIER__STORAGE__DRIVER: "postgres" CONCELIER__STORAGE__DRIVER: "postgres"
CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" CONCELIER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080" CONCELIER__STORAGE__S3__ENDPOINT: "http://rustfs:8080"
CONCELIER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
CONCELIER__AUTHORITY__BASEURL: "https://authority:8440" CONCELIER__AUTHORITY__BASEURL: "https://authority:8440"
CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true" CONCELIER__AUTHORITY__RESILIENCE__ALLOWOFFLINECACHEFALLBACK: "true"
CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}" CONCELIER__AUTHORITY__RESILIENCE__OFFLINECACHETOLERANCE: "${AUTHORITY_OFFLINE_CACHE_TOLERANCE:-00:30:00}"
@@ -199,8 +291,12 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Scanner Web - SBOM/vulnerability scanning API
# ---------------------------------------------------------------------------
scanner-web: scanner-web:
image: registry.stella-ops.org/stellaops/scanner-web@sha256:14b23448c3f9586a9156370b3e8c1991b61907efa666ca37dd3aaed1e79fe3b7 image: registry.stella-ops.org/stellaops/scanner-web@sha256:14b23448c3f9586a9156370b3e8c1991b61907efa666ca37dd3aaed1e79fe3b7
container_name: stellaops-scanner-web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres - postgres
@@ -209,24 +305,28 @@ services:
- rustfs - rustfs
environment: environment:
SCANNER__STORAGE__DRIVER: "postgres" SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379" SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs" SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1" SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts" SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30" SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}" # Queue configuration - Valkey only
SCANNER__QUEUE__BROKER: "valkey://valkey:6379"
# Event streaming
SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}" SCANNER__EVENTS__ENABLED: "${SCANNER_EVENTS_ENABLED:-false}"
SCANNER__EVENTS__DRIVER: "${SCANNER_EVENTS_DRIVER:-valkey}" SCANNER__EVENTS__DRIVER: "valkey"
SCANNER__EVENTS__DSN: "${SCANNER_EVENTS_DSN:-}" SCANNER__EVENTS__DSN: "valkey:6379"
SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}" SCANNER__EVENTS__STREAM: "${SCANNER_EVENTS_STREAM:-stella.events}"
SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}" SCANNER__EVENTS__PUBLISHTIMEOUTSECONDS: "${SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS:-5}"
SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}" SCANNER__EVENTS__MAXSTREAMLENGTH: "${SCANNER_EVENTS_MAX_STREAM_LENGTH:-10000}"
# Offline kit
SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}" SCANNER__OFFLINEKIT__ENABLED: "${SCANNER_OFFLINEKIT_ENABLED:-false}"
SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}" SCANNER__OFFLINEKIT__REQUIREDSSE: "${SCANNER_OFFLINEKIT_REQUIREDSSE:-true}"
SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}" SCANNER__OFFLINEKIT__REKOROFFLINEMODE: "${SCANNER_OFFLINEKIT_REKOROFFLINEMODE:-true}"
SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}" SCANNER__OFFLINEKIT__TRUSTROOTDIRECTORY: "${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}"
SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}" SCANNER__OFFLINEKIT__REKORSNAPSHOTDIRECTORY: "${SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY:-/var/lib/stellaops/rekor-snapshot}"
# Surface cache
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}" SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}" SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}" SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
@@ -240,6 +340,8 @@ services:
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}" SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER: "${SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER:-}"
SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}" SCANNER_SURFACE_SECRETS_ALLOW_INLINE: "${SCANNER_SURFACE_SECRETS_ALLOW_INLINE:-false}"
volumes: volumes:
- ../../etc/scanner:/app/etc/scanner:ro
- ../../etc/certificates/trust-roots:/etc/ssl/certs/stellaops:ro
- scanner-surface-cache:/var/lib/stellaops/surface - scanner-surface-cache:/var/lib/stellaops/surface
- ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro - ${SURFACE_SECRETS_HOST_PATH:-./offline/surface-secrets}:${SCANNER_SURFACE_SECRETS_ROOT:-/etc/stellaops/secrets}:ro
- ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro - ${SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH:-./offline/trust-roots}:${SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY:-/etc/stellaops/trust-roots}:ro
@@ -251,23 +353,28 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Scanner Worker - Background scanning jobs
# ---------------------------------------------------------------------------
scanner-worker: scanner-worker:
image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab image: registry.stella-ops.org/stellaops/scanner-worker@sha256:32e25e76386eb9ea8bee0a1ad546775db9a2df989fab61ac877e351881960dab
container_name: stellaops-scanner-worker
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres
- valkey
- scanner-web - scanner-web
- valkey
- rustfs - rustfs
environment: environment:
SCANNER__STORAGE__DRIVER: "postgres" SCANNER__STORAGE__DRIVER: "postgres"
SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" SCANNER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379" SCANNER__CACHE__REDIS__CONNECTIONSTRING: "valkey:6379"
SCANNER__ARTIFACTSTORE__DRIVER: "rustfs" SCANNER__ARTIFACTSTORE__DRIVER: "rustfs"
SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1" SCANNER__ARTIFACTSTORE__ENDPOINT: "http://rustfs:8080/api/v1"
SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts" SCANNER__ARTIFACTSTORE__BUCKET: "scanner-artifacts"
SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30" SCANNER__ARTIFACTSTORE__TIMEOUTSECONDS: "30"
SCANNER__QUEUE__BROKER: "${SCANNER_QUEUE_BROKER:-valkey://valkey:6379}" # Queue configuration - Valkey only
SCANNER__QUEUE__BROKER: "valkey://valkey:6379"
# Surface cache
SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}" SCANNER_SURFACE_FS_ENDPOINT: "${SCANNER_SURFACE_FS_ENDPOINT:-http://rustfs:8080}"
SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}" SCANNER_SURFACE_FS_BUCKET: "${SCANNER_SURFACE_FS_BUCKET:-surface-cache}"
SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}" SCANNER_SURFACE_CACHE_ROOT: "${SCANNER_SURFACE_CACHE_ROOT:-/var/lib/stellaops/surface}"
@@ -287,8 +394,12 @@ services:
- stellaops - stellaops
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Scheduler Worker - Background job scheduling
# ---------------------------------------------------------------------------
scheduler-worker: scheduler-worker:
image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0-edge image: registry.stella-ops.org/stellaops/scheduler-worker:2025.10.0
container_name: stellaops-scheduler-worker
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres - postgres
@@ -299,24 +410,35 @@ services:
- "StellaOps.Scheduler.Worker.Host.dll" - "StellaOps.Scheduler.Worker.Host.dll"
environment: environment:
SCHEDULER__STORAGE__DRIVER: "postgres" SCHEDULER__STORAGE__DRIVER: "postgres"
SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" SCHEDULER__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
SCHEDULER__QUEUE__KIND: "${SCHEDULER_QUEUE_KIND:-Valkey}" # Queue configuration - Valkey only
SCHEDULER__QUEUE__VALKEY__URL: "${SCHEDULER_QUEUE_VALKEY_URL:-valkey:6379}" SCHEDULER__QUEUE__KIND: "Valkey"
SCHEDULER__QUEUE__VALKEY__URL: "valkey:6379"
SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}" SCHEDULER__WORKER__RUNNER__SCANNER__BASEADDRESS: "${SCHEDULER_SCANNER_BASEADDRESS:-http://scanner-web:8444}"
networks: networks:
- stellaops - stellaops
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Notify Web - Notification service
# ---------------------------------------------------------------------------
notify-web: notify-web:
image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.09.2} image: ${NOTIFY_WEB_IMAGE:-registry.stella-ops.org/stellaops/notify-web:2025.10.0}
container_name: stellaops-notify-web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres - postgres
- authority - authority
- valkey
environment: environment:
DOTNET_ENVIRONMENT: Production DOTNET_ENVIRONMENT: Production
NOTIFY__STORAGE__DRIVER: "postgres"
NOTIFY__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
# Queue configuration - Valkey only
NOTIFY__QUEUE__DRIVER: "valkey"
NOTIFY__QUEUE__VALKEY__URL: "valkey:6379"
volumes: volumes:
- ../../etc/notify.prod.yaml:/app/etc/notify.yaml:ro - ../../etc/notify:/app/etc/notify:ro
ports: ports:
- "${NOTIFY_WEB_PORT:-8446}:8446" - "${NOTIFY_WEB_PORT:-8446}:8446"
networks: networks:
@@ -324,8 +446,12 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Excititor - VEX generation service
# ---------------------------------------------------------------------------
excititor: excititor:
image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa image: registry.stella-ops.org/stellaops/excititor@sha256:59022e2016aebcef5c856d163ae705755d3f81949d41195256e935ef40a627fa
container_name: stellaops-excititor
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- postgres - postgres
@@ -333,13 +459,17 @@ services:
environment: environment:
EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445" EXCITITOR__CONCELIER__BASEURL: "https://concelier:8445"
EXCITITOR__STORAGE__DRIVER: "postgres" EXCITITOR__STORAGE__DRIVER: "postgres"
EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres;Port=5432;Database=${POSTGRES_DB:-stellaops_platform};Username=${POSTGRES_USER:-stellaops};Password=${POSTGRES_PASSWORD:-stellaops}" EXCITITOR__STORAGE__POSTGRES__CONNECTIONSTRING: *postgres-connection
networks: networks:
- stellaops - stellaops
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Advisory AI Web - AI-powered advisory analysis API
# ---------------------------------------------------------------------------
advisory-ai-web: advisory-ai-web:
image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.09.2 image: registry.stella-ops.org/stellaops/advisory-ai-web:2025.10.0
container_name: stellaops-advisory-ai-web
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- scanner-web - scanner-web
@@ -354,6 +484,7 @@ services:
ports: ports:
- "${ADVISORY_AI_WEB_PORT:-8448}:8448" - "${ADVISORY_AI_WEB_PORT:-8448}:8448"
volumes: volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue - advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans - advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs - advisory-ai-outputs:/var/lib/advisory-ai/outputs
@@ -362,8 +493,12 @@ services:
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Advisory AI Worker - Background AI processing
# ---------------------------------------------------------------------------
advisory-ai-worker: advisory-ai-worker:
image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.09.2 image: registry.stella-ops.org/stellaops/advisory-ai-worker:2025.10.0
container_name: stellaops-advisory-ai-worker
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- advisory-ai-web - advisory-ai-web
@@ -376,6 +511,7 @@ services:
ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}" ADVISORYAI__AdvisoryAI__Inference__Remote__BaseAddress: "${ADVISORY_AI_REMOTE_BASEADDRESS:-}"
ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}" ADVISORYAI__AdvisoryAI__Inference__Remote__ApiKey: "${ADVISORY_AI_REMOTE_APIKEY:-}"
volumes: volumes:
- ../../etc/llm-providers:/app/etc/llm-providers:ro
- advisory-ai-queue:/var/lib/advisory-ai/queue - advisory-ai-queue:/var/lib/advisory-ai/queue
- advisory-ai-plans:/var/lib/advisory-ai/plans - advisory-ai-plans:/var/lib/advisory-ai/plans
- advisory-ai-outputs:/var/lib/advisory-ai/outputs - advisory-ai-outputs:/var/lib/advisory-ai/outputs
@@ -383,8 +519,12 @@ services:
- stellaops - stellaops
labels: *release-labels labels: *release-labels
# ---------------------------------------------------------------------------
# Web UI - Angular frontend
# ---------------------------------------------------------------------------
web-ui: web-ui:
image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23 image: registry.stella-ops.org/stellaops/web-ui@sha256:10d924808c48e4353e3a241da62eb7aefe727a1d6dc830eb23a8e181013b3a23
container_name: stellaops-web-ui
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- scanner-web - scanner-web
@@ -396,5 +536,3 @@ services:
- stellaops - stellaops
- frontdoor - frontdoor
labels: *release-labels labels: *release-labels

View File

@@ -0,0 +1,90 @@
# =============================================================================
# TELEMETRY OFFLINE - AIR-GAPPED OBSERVABILITY
# =============================================================================
# Offline-compatible telemetry stack for air-gapped deployments.
# Does not require external connectivity.
#
# Usage:
# docker compose -f docker-compose.telemetry-offline.yml up -d
#
# For online deployments, use docker-compose.telemetry.yml instead.
# =============================================================================
services:
loki:
image: grafana/loki:3.0.1
container_name: stellaops-loki-offline
command: ["-config.file=/etc/loki/local-config.yaml"]
volumes:
- loki-data:/loki
- ../offline/airgap/observability/loki-config.yaml:/etc/loki/local-config.yaml:ro
ports:
- "${LOKI_PORT:-3100}:3100"
networks:
- sealed
restart: unless-stopped
promtail:
image: grafana/promtail:3.0.1
container_name: stellaops-promtail-offline
command: ["-config.file=/etc/promtail/config.yml"]
volumes:
- promtail-data:/var/log
- ../offline/airgap/promtail-config.yaml:/etc/promtail/config.yml:ro
networks:
- sealed
restart: unless-stopped
otel-collector:
image: otel/opentelemetry-collector-contrib:0.97.0
container_name: stellaops-otel-offline
command: ["--config=/etc/otel/config.yaml"]
volumes:
- ../offline/airgap/otel-offline.yaml:/etc/otel/config.yaml:ro
- otel-data:/var/otel
ports:
- "${OTEL_GRPC_PORT:-4317}:4317"
- "${OTEL_HTTP_PORT:-4318}:4318"
networks:
- sealed
restart: unless-stopped
tempo:
image: grafana/tempo:2.4.1
container_name: stellaops-tempo-offline
command: ["-config.file=/etc/tempo/config.yaml"]
volumes:
- tempo-data:/var/tempo
- ../offline/airgap/observability/tempo-config.yaml:/etc/tempo/config.yaml:ro
ports:
- "${TEMPO_PORT:-3200}:3200"
networks:
- sealed
restart: unless-stopped
prometheus:
image: prom/prometheus:v2.51.0
container_name: stellaops-prometheus-offline
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=15d'
volumes:
- prometheus-data:/prometheus
- ../offline/airgap/observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- "${PROMETHEUS_PORT:-9090}:9090"
networks:
- sealed
restart: unless-stopped
networks:
sealed:
driver: bridge
volumes:
loki-data:
promtail-data:
otel-data:
tempo-data:
prometheus-data:

View File

@@ -1,57 +0,0 @@
version: "3.9"
services:
prometheus:
image: prom/prometheus:v2.53.0
container_name: stellaops-prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yaml"
volumes:
- ../telemetry/storage/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- prometheus-data:/prometheus
- ../telemetry/certs:/etc/telemetry/tls:ro
- ../telemetry/storage/auth:/etc/telemetry/auth:ro
environment:
PROMETHEUS_COLLECTOR_TARGET: stellaops-otel-collector:9464
ports:
- "9090:9090"
depends_on:
- tempo
- loki
tempo:
image: grafana/tempo:2.5.0
container_name: stellaops-tempo
command:
- "-config.file=/etc/tempo/tempo.yaml"
volumes:
- ../telemetry/storage/tempo.yaml:/etc/tempo/tempo.yaml:ro
- ../telemetry/storage/tenants/tempo-overrides.yaml:/etc/telemetry/tenants/tempo-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- tempo-data:/var/tempo
ports:
- "3200:3200"
environment:
TEMPO_ZONE: docker
loki:
image: grafana/loki:3.1.0
container_name: stellaops-loki
command:
- "-config.file=/etc/loki/loki.yaml"
volumes:
- ../telemetry/storage/loki.yaml:/etc/loki/loki.yaml:ro
- ../telemetry/storage/tenants/loki-overrides.yaml:/etc/telemetry/tenants/loki-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- loki-data:/var/loki
ports:
- "3100:3100"
volumes:
prometheus-data:
tempo-data:
loki-data:
networks:
default:
name: stellaops-telemetry

View File

@@ -1,42 +0,0 @@
version: "3.9"
services:
otel-collector:
image: otel/opentelemetry-collector:0.105.0
container_name: stellaops-otel-collector
command:
- "--config=/etc/otel-collector/config.yaml"
environment:
STELLAOPS_OTEL_TLS_CERT: /etc/otel-collector/tls/collector.crt
STELLAOPS_OTEL_TLS_KEY: /etc/otel-collector/tls/collector.key
STELLAOPS_OTEL_TLS_CA: /etc/otel-collector/tls/ca.crt
STELLAOPS_OTEL_PROMETHEUS_ENDPOINT: 0.0.0.0:9464
STELLAOPS_OTEL_REQUIRE_CLIENT_CERT: "true"
STELLAOPS_TENANT_ID: dev
STELLAOPS_TEMPO_ENDPOINT: https://stellaops-tempo:3200
STELLAOPS_TEMPO_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_TEMPO_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_TEMPO_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
STELLAOPS_LOKI_ENDPOINT: https://stellaops-loki:3100/loki/api/v1/push
STELLAOPS_LOKI_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_LOKI_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_LOKI_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
volumes:
- ../telemetry/otel-collector-config.yaml:/etc/otel-collector/config.yaml:ro
- ../telemetry/certs:/etc/otel-collector/tls:ro
ports:
- "4317:4317" # OTLP gRPC (mTLS)
- "4318:4318" # OTLP HTTP (mTLS)
- "9464:9464" # Prometheus exporter (mTLS)
- "13133:13133" # Health check
- "1777:1777" # pprof
healthcheck:
test: ["CMD", "curl", "-fsk", "--cert", "/etc/otel-collector/tls/client.crt", "--key", "/etc/otel-collector/tls/client.key", "--cacert", "/etc/otel-collector/tls/ca.crt", "https://localhost:13133/healthz"]
interval: 30s
start_period: 15s
timeout: 5s
retries: 3
networks:
default:
name: stellaops-telemetry

View File

@@ -0,0 +1,144 @@
# =============================================================================
# STELLA OPS - TELEMETRY STACK
# =============================================================================
# All-in-one observability: OpenTelemetry Collector, Prometheus, Tempo, Loki
#
# Usage:
# docker compose -f devops/compose/docker-compose.telemetry.yml up -d
#
# With main stack:
# docker compose -f devops/compose/docker-compose.stella-ops.yml \
# -f devops/compose/docker-compose.telemetry.yml up -d
#
# =============================================================================
x-telemetry-labels: &telemetry-labels
com.stellaops.component: "telemetry"
com.stellaops.profile: "observability"
networks:
stellaops-telemetry:
driver: bridge
name: stellaops-telemetry
stellaops:
external: true
name: stellaops
volumes:
prometheus-data:
tempo-data:
loki-data:
services:
# ---------------------------------------------------------------------------
# OpenTelemetry Collector - Unified telemetry ingestion
# ---------------------------------------------------------------------------
otel-collector:
image: otel/opentelemetry-collector:0.105.0
container_name: stellaops-otel-collector
restart: unless-stopped
command:
- "--config=/etc/otel-collector/config.yaml"
environment:
STELLAOPS_OTEL_TLS_CERT: /etc/otel-collector/tls/collector.crt
STELLAOPS_OTEL_TLS_KEY: /etc/otel-collector/tls/collector.key
STELLAOPS_OTEL_TLS_CA: /etc/otel-collector/tls/ca.crt
STELLAOPS_OTEL_PROMETHEUS_ENDPOINT: 0.0.0.0:9464
STELLAOPS_OTEL_REQUIRE_CLIENT_CERT: "true"
STELLAOPS_TENANT_ID: ${STELLAOPS_TENANT_ID:-default}
STELLAOPS_TEMPO_ENDPOINT: http://tempo:3200
STELLAOPS_TEMPO_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_TEMPO_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_TEMPO_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
STELLAOPS_LOKI_ENDPOINT: http://loki:3100/loki/api/v1/push
STELLAOPS_LOKI_TLS_CERT_FILE: /etc/otel-collector/tls/client.crt
STELLAOPS_LOKI_TLS_KEY_FILE: /etc/otel-collector/tls/client.key
STELLAOPS_LOKI_TLS_CA_FILE: /etc/otel-collector/tls/ca.crt
volumes:
- ../telemetry/otel-collector-config.yaml:/etc/otel-collector/config.yaml:ro
- ../telemetry/certs:/etc/otel-collector/tls:ro
ports:
- "${OTEL_GRPC_PORT:-4317}:4317" # OTLP gRPC
- "${OTEL_HTTP_PORT:-4318}:4318" # OTLP HTTP
- "${OTEL_PROMETHEUS_PORT:-9464}:9464" # Prometheus exporter
- "${OTEL_HEALTH_PORT:-13133}:13133" # Health check
- "${OTEL_PPROF_PORT:-1777}:1777" # pprof
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:13133/healthz"]
interval: 30s
start_period: 15s
timeout: 5s
retries: 3
networks:
- stellaops-telemetry
- stellaops
labels: *telemetry-labels
# ---------------------------------------------------------------------------
# Prometheus - Metrics storage
# ---------------------------------------------------------------------------
prometheus:
image: prom/prometheus:v2.53.0
container_name: stellaops-prometheus
restart: unless-stopped
command:
- "--config.file=/etc/prometheus/prometheus.yaml"
- "--storage.tsdb.path=/prometheus"
- "--storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-15d}"
- "--web.enable-lifecycle"
volumes:
- ../telemetry/storage/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro
- prometheus-data:/prometheus
- ../telemetry/certs:/etc/telemetry/tls:ro
- ../telemetry/storage/auth:/etc/telemetry/auth:ro
environment:
PROMETHEUS_COLLECTOR_TARGET: otel-collector:9464
ports:
- "${PROMETHEUS_PORT:-9090}:9090"
depends_on:
- otel-collector
networks:
- stellaops-telemetry
labels: *telemetry-labels
# ---------------------------------------------------------------------------
# Tempo - Distributed tracing backend
# ---------------------------------------------------------------------------
tempo:
image: grafana/tempo:2.5.0
container_name: stellaops-tempo
restart: unless-stopped
command:
- "-config.file=/etc/tempo/tempo.yaml"
volumes:
- ../telemetry/storage/tempo.yaml:/etc/tempo/tempo.yaml:ro
- ../telemetry/storage/tenants/tempo-overrides.yaml:/etc/telemetry/tenants/tempo-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- tempo-data:/var/tempo
environment:
TEMPO_ZONE: docker
ports:
- "${TEMPO_PORT:-3200}:3200"
networks:
- stellaops-telemetry
labels: *telemetry-labels
# ---------------------------------------------------------------------------
# Loki - Log aggregation
# ---------------------------------------------------------------------------
loki:
image: grafana/loki:3.1.0
container_name: stellaops-loki
restart: unless-stopped
command:
- "-config.file=/etc/loki/loki.yaml"
volumes:
- ../telemetry/storage/loki.yaml:/etc/loki/loki.yaml:ro
- ../telemetry/storage/tenants/loki-overrides.yaml:/etc/telemetry/tenants/loki-overrides.yaml:ro
- ../telemetry/certs:/etc/telemetry/tls:ro
- loki-data:/var/loki
ports:
- "${LOKI_PORT:-3100}:3100"
networks:
- stellaops-telemetry
labels: *telemetry-labels

View File

@@ -0,0 +1,327 @@
# =============================================================================
# STELLA OPS - TESTING STACK
# =============================================================================
# Consolidated CI, mock services, and Gitea for integration testing.
# Uses different ports to avoid conflicts with development/production services.
#
# Usage:
# docker compose -f devops/compose/docker-compose.testing.yml up -d
#
# CI infrastructure only:
# docker compose -f devops/compose/docker-compose.testing.yml --profile ci up -d
#
# Mock services only:
# docker compose -f devops/compose/docker-compose.testing.yml --profile mock up -d
#
# Gitea only:
# docker compose -f devops/compose/docker-compose.testing.yml --profile gitea up -d
#
# =============================================================================
x-testing-labels: &testing-labels
com.stellaops.profile: "testing"
com.stellaops.environment: "ci"
networks:
testing-net:
driver: bridge
name: stellaops-testing
volumes:
# CI volumes
ci-postgres-data:
name: stellaops-ci-postgres
ci-valkey-data:
name: stellaops-ci-valkey
ci-rustfs-data:
name: stellaops-ci-rustfs
# Gitea volumes
gitea-data:
gitea-config:
services:
# ===========================================================================
# CI INFRASTRUCTURE (different ports to avoid conflicts)
# ===========================================================================
# ---------------------------------------------------------------------------
# PostgreSQL 18.1 - Test database (port 5433)
# ---------------------------------------------------------------------------
postgres-test:
image: postgres:18.1-alpine
container_name: stellaops-postgres-test
profiles: ["ci", "all"]
environment:
POSTGRES_USER: stellaops_ci
POSTGRES_PASSWORD: ci_test_password
POSTGRES_DB: stellaops_test
POSTGRES_INITDB_ARGS: "--data-checksums"
ports:
- "${TEST_POSTGRES_PORT:-5433}:5432"
volumes:
- ci-postgres-data:/var/lib/postgresql/data
networks:
- testing-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U stellaops_ci -d stellaops_test"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# Valkey 9.0.1 - Test cache/queue (port 6380)
# ---------------------------------------------------------------------------
valkey-test:
image: valkey/valkey:9.0.1-alpine
container_name: stellaops-valkey-test
profiles: ["ci", "all"]
command: ["valkey-server", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
ports:
- "${TEST_VALKEY_PORT:-6380}:6379"
volumes:
- ci-valkey-data:/data
networks:
- testing-net
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# RustFS - Test artifact storage (port 8180)
# ---------------------------------------------------------------------------
rustfs-test:
image: registry.stella-ops.org/stellaops/rustfs:2025.09.2
container_name: stellaops-rustfs-test
profiles: ["ci", "all"]
command: ["serve", "--listen", "0.0.0.0:8080", "--root", "/data"]
environment:
RUSTFS__LOG__LEVEL: info
RUSTFS__STORAGE__PATH: /data
ports:
- "${TEST_RUSTFS_PORT:-8180}:8080"
volumes:
- ci-rustfs-data:/data
networks:
- testing-net
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# Mock Container Registry (port 5001)
# ---------------------------------------------------------------------------
mock-registry:
image: registry:2
container_name: stellaops-registry-test
profiles: ["ci", "all"]
ports:
- "${TEST_REGISTRY_PORT:-5001}:5000"
environment:
REGISTRY_STORAGE_DELETE_ENABLED: "true"
networks:
- testing-net
restart: unless-stopped
labels: *testing-labels
# ---------------------------------------------------------------------------
# Sigstore CLI tools (on-demand)
# ---------------------------------------------------------------------------
rekor-cli:
image: ghcr.io/sigstore/rekor-cli:v1.4.3
entrypoint: ["rekor-cli"]
command: ["version"]
profiles: ["sigstore"]
networks:
- testing-net
labels: *testing-labels
cosign:
image: ghcr.io/sigstore/cosign:v3.0.4
entrypoint: ["cosign"]
command: ["version"]
profiles: ["sigstore"]
networks:
- testing-net
labels: *testing-labels
# ===========================================================================
# MOCK SERVICES (for extended integration testing)
# ===========================================================================
# ---------------------------------------------------------------------------
# Orchestrator mock
# ---------------------------------------------------------------------------
orchestrator:
image: registry.stella-ops.org/stellaops/orchestrator@sha256:97f12856ce870bafd3328bda86833bcccbf56d255941d804966b5557f6610119
container_name: stellaops-orchestrator-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.Orchestrator.WebService.dll"]
depends_on:
- postgres-test
- valkey-test
environment:
ORCHESTRATOR__STORAGE__DRIVER: "postgres"
ORCHESTRATOR__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
ORCHESTRATOR__QUEUE__DRIVER: "valkey"
ORCHESTRATOR__QUEUE__VALKEY__URL: "valkey-test:6379"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Policy Registry mock
# ---------------------------------------------------------------------------
policy-registry:
image: registry.stella-ops.org/stellaops/policy-registry@sha256:c6cad8055e9827ebcbebb6ad4d6866dce4b83a0a49b0a8a6500b736a5cb26fa7
container_name: stellaops-policy-registry-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.Policy.Engine.dll"]
depends_on:
- postgres-test
environment:
POLICY__STORAGE__DRIVER: "postgres"
POLICY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# VEX Lens mock
# ---------------------------------------------------------------------------
vex-lens:
image: registry.stella-ops.org/stellaops/vex-lens@sha256:b44e63ecfeebc345a70c073c1ce5ace709c58be0ffaad0e2862758aeee3092fb
container_name: stellaops-vex-lens-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.VexLens.dll"]
depends_on:
- postgres-test
environment:
VEXLENS__STORAGE__DRIVER: "postgres"
VEXLENS__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Findings Ledger mock
# ---------------------------------------------------------------------------
findings-ledger:
image: registry.stella-ops.org/stellaops/findings-ledger@sha256:71d4c361ba8b2f8b69d652597bc3f2efc8a64f93fab854ce25272a88506df49c
container_name: stellaops-findings-ledger-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.Findings.Ledger.WebService.dll"]
depends_on:
- postgres-test
environment:
FINDINGSLEDGER__STORAGE__DRIVER: "postgres"
FINDINGSLEDGER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Vuln Explorer API mock
# ---------------------------------------------------------------------------
vuln-explorer-api:
image: registry.stella-ops.org/stellaops/vuln-explorer-api@sha256:7fc7e43a05cbeb0106ce7d4d634612e83de6fdc119aaab754a71c1d60b82841d
container_name: stellaops-vuln-explorer-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.VulnExplorer.Api.dll"]
depends_on:
- findings-ledger
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Packs Registry mock
# ---------------------------------------------------------------------------
packs-registry:
image: registry.stella-ops.org/stellaops/packs-registry@sha256:1f5e9416c4dc608594ad6fad87c24d72134427f899c192b494e22b268499c791
container_name: stellaops-packs-registry-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.PacksRegistry.dll"]
depends_on:
- postgres-test
environment:
PACKSREGISTRY__STORAGE__DRIVER: "postgres"
PACKSREGISTRY__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ---------------------------------------------------------------------------
# Task Runner mock
# ---------------------------------------------------------------------------
task-runner:
image: registry.stella-ops.org/stellaops/task-runner@sha256:eb5ad992b49a41554f41516be1a6afcfa6522faf2111c08ff2b3664ad2fc954b
container_name: stellaops-task-runner-mock
profiles: ["mock", "all"]
command: ["dotnet", "StellaOps.TaskRunner.WebService.dll"]
depends_on:
- packs-registry
- postgres-test
environment:
TASKRUNNER__STORAGE__DRIVER: "postgres"
TASKRUNNER__STORAGE__POSTGRES__CONNECTIONSTRING: "Host=postgres-test;Port=5432;Database=stellaops_test;Username=stellaops_ci;Password=ci_test_password"
networks:
- testing-net
labels: *testing-labels
# ===========================================================================
# GITEA (SCM integration testing)
# ===========================================================================
# ---------------------------------------------------------------------------
# Gitea - Git hosting with package registry
# ---------------------------------------------------------------------------
gitea:
image: gitea/gitea:1.21
container_name: stellaops-gitea-test
profiles: ["gitea", "all"]
environment:
- USER_UID=1000
- USER_GID=1000
# Enable package registry
- GITEA__packages__ENABLED=true
- GITEA__packages__CHUNKED_UPLOAD_PATH=/data/tmp/package-upload
# Enable NuGet
- GITEA__packages__NUGET_ENABLED=true
# Enable Container registry
- GITEA__packages__CONTAINER_ENABLED=true
# Database (SQLite for simplicity)
- GITEA__database__DB_TYPE=sqlite3
- GITEA__database__PATH=/data/gitea/gitea.db
# Server config
- GITEA__server__ROOT_URL=http://localhost:${TEST_GITEA_PORT:-3000}/
- GITEA__server__HTTP_PORT=3000
# Disable metrics/telemetry
- GITEA__metrics__ENABLED=false
# Session config
- GITEA__session__PROVIDER=memory
# Cache config
- GITEA__cache__ADAPTER=memory
# Log level
- GITEA__log__LEVEL=Warn
volumes:
- gitea-data:/data
- gitea-config:/etc/gitea
ports:
- "${TEST_GITEA_PORT:-3000}:3000"
- "${TEST_GITEA_SSH_PORT:-3022}:22"
networks:
- testing-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
labels: *testing-labels

View File

@@ -0,0 +1,80 @@
# =============================================================================
# STELLA OPS TILE PROXY OVERLAY
# =============================================================================
# Rekor tile caching proxy for air-gapped and offline deployments.
# Caches tiles from upstream Rekor (public Sigstore or private) locally.
#
# Use Cases:
# - Air-gapped deployments with periodic sync
# - Reduce latency by caching frequently-accessed tiles
# - Offline verification when upstream is unavailable
#
# Note: This is an ALTERNATIVE to running your own rekor-v2 instance.
# Use tile-proxy when you want to cache from public Sigstore.
# Use rekor-v2 (--profile sigstore) when running your own transparency log.
#
# Usage:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.tile-proxy.yml up -d
#
# =============================================================================
x-release-labels: &release-labels
com.stellaops.release.version: "2025.10.0"
com.stellaops.release.channel: "stable"
com.stellaops.component: "tile-proxy"
volumes:
tile-cache:
driver: local
tuf-cache:
driver: local
services:
tile-proxy:
build:
context: ../..
dockerfile: src/Attestor/StellaOps.Attestor.TileProxy/Dockerfile
image: registry.stella-ops.org/stellaops/tile-proxy:2025.10.0
container_name: stellaops-tile-proxy
restart: unless-stopped
ports:
- "${TILE_PROXY_PORT:-8090}:8080"
volumes:
- tile-cache:/var/cache/stellaops/tiles
- tuf-cache:/var/cache/stellaops/tuf
environment:
# Upstream Rekor configuration
TILE_PROXY__UPSTREAMURL: "${REKOR_SERVER_URL:-https://rekor.sigstore.dev}"
TILE_PROXY__ORIGIN: "${REKOR_ORIGIN:-rekor.sigstore.dev - 1985497715}"
# TUF configuration (optional - for checkpoint signature validation)
TILE_PROXY__TUF__ENABLED: "${TILE_PROXY_TUF_ENABLED:-false}"
TILE_PROXY__TUF__URL: "${TILE_PROXY_TUF_ROOT_URL:-}"
TILE_PROXY__TUF__VALIDATECHECKPOINTSIGNATURE: "${TILE_PROXY_TUF_VALIDATE_CHECKPOINT:-true}"
# Cache configuration
TILE_PROXY__CACHE__BASEPATH: /var/cache/stellaops/tiles
TILE_PROXY__CACHE__MAXSIZEGB: "${TILE_PROXY_CACHE_MAX_SIZE_GB:-10}"
TILE_PROXY__CACHE__CHECKPOINTTTLMINUTES: "${TILE_PROXY_CHECKPOINT_TTL_MINUTES:-5}"
# Sync job configuration (for air-gapped pre-fetching)
TILE_PROXY__SYNC__ENABLED: "${TILE_PROXY_SYNC_ENABLED:-true}"
TILE_PROXY__SYNC__SCHEDULE: "${TILE_PROXY_SYNC_SCHEDULE:-0 */6 * * *}"
TILE_PROXY__SYNC__DEPTH: "${TILE_PROXY_SYNC_DEPTH:-10000}"
# Request handling
TILE_PROXY__REQUEST__COALESCINGENABLED: "${TILE_PROXY_COALESCING_ENABLED:-true}"
TILE_PROXY__REQUEST__TIMEOUTSECONDS: "${TILE_PROXY_REQUEST_TIMEOUT_SECONDS:-30}"
# Logging
Serilog__MinimumLevel__Default: "${TILE_PROXY_LOG_LEVEL:-Information}"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/_admin/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
networks:
- stellaops
labels: *release-labels

View File

@@ -1,104 +0,0 @@
# Substitutions for docker-compose.airgap.yaml
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=airgap-postgres-password
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=25432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=26379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.airgap.local
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:45:00
# Signer
SIGNER_POE_INTROSPECT_URL=file:///offline/poe/introspect.json
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=valkey://valkey:6379
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env configuration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=file
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Valkey
SCHEDULER_QUEUE_VALKEY_URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=9446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=9443
# NATS
NATS_CLIENT_PORT=24222

View File

@@ -0,0 +1,48 @@
# =============================================================================
# STELLA OPS CHINA COMPLIANCE ENVIRONMENT
# =============================================================================
# Environment template for China (SM2/SM3/SM4) compliance deployments.
#
# Usage with simulation:
# cp env/compliance-china.env.example .env
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with SM Remote (production):
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-china.yml \
# -f docker-compose.sm-remote.yml up -d
#
# =============================================================================
# Crypto profile
STELLAOPS_CRYPTO_PROFILE=china
# =============================================================================
# SM REMOTE SERVICE CONFIGURATION
# =============================================================================
SM_REMOTE_PORT=56080
# Software-only SM2 provider (for testing/development)
SM_SOFT_ALLOWED=1
# OSCCA-certified HSM configuration (for production)
# Set these when using a certified hardware security module
SM_REMOTE_HSM_URL=
SM_REMOTE_HSM_API_KEY=
SM_REMOTE_HSM_TIMEOUT=30000
# Client certificate authentication for HSM (optional)
SM_REMOTE_CLIENT_CERT_PATH=
SM_REMOTE_CLIENT_CERT_PASSWORD=
# =============================================================================
# CRYPTO SIMULATION (for testing only)
# =============================================================================
# Enable simulation mode
STELLAOPS_CRYPTO_ENABLE_SIM=1
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
SIM_CRYPTO_PORT=18090

View File

@@ -0,0 +1,40 @@
# =============================================================================
# STELLA OPS EU COMPLIANCE ENVIRONMENT
# =============================================================================
# Environment template for EU (eIDAS) compliance deployments.
#
# Usage with simulation:
# cp env/compliance-eu.env.example .env
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-eu.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage for production:
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-eu.yml up -d
#
# Note: EU eIDAS deployments typically integrate with external Qualified Trust
# Service Providers (QTSPs) rather than hosting crypto locally.
#
# =============================================================================
# Crypto profile
STELLAOPS_CRYPTO_PROFILE=eu
# =============================================================================
# eIDAS / QTSP CONFIGURATION
# =============================================================================
# Qualified Trust Service Provider integration (configure in application settings)
# EIDAS_QTSP_URL=https://qtsp.example.eu
# EIDAS_QTSP_CLIENT_ID=
# EIDAS_QTSP_CLIENT_SECRET=
# =============================================================================
# CRYPTO SIMULATION (for testing only)
# =============================================================================
# Enable simulation mode
STELLAOPS_CRYPTO_ENABLE_SIM=1
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
SIM_CRYPTO_PORT=18090

View File

@@ -0,0 +1,51 @@
# =============================================================================
# STELLA OPS RUSSIA COMPLIANCE ENVIRONMENT
# =============================================================================
# Environment template for Russia (GOST R 34.10-2012) compliance deployments.
#
# Usage with simulation:
# cp env/compliance-russia.env.example .env
# docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.crypto-sim.yml up -d
#
# Usage with CryptoPro CSP (production):
# CRYPTOPRO_ACCEPT_EULA=1 docker compose -f docker-compose.stella-ops.yml \
# -f docker-compose.compliance-russia.yml \
# -f docker-compose.cryptopro.yml up -d
#
# =============================================================================
# Crypto profile
STELLAOPS_CRYPTO_PROFILE=russia
# =============================================================================
# CRYPTOPRO CSP CONFIGURATION
# =============================================================================
CRYPTOPRO_PORT=18080
# IMPORTANT: Set to 1 to accept CryptoPro EULA (required for production)
CRYPTOPRO_ACCEPT_EULA=0
# CryptoPro container settings
CRYPTOPRO_CONTAINER_NAME=stellaops-signing
CRYPTOPRO_USE_MACHINE_STORE=true
CRYPTOPRO_PROVIDER_TYPE=80
# =============================================================================
# GOST ALGORITHM CONFIGURATION
# =============================================================================
# Default GOST algorithms
CRYPTOPRO_GOST_SIGNATURE_ALGORITHM=GOST R 34.10-2012
CRYPTOPRO_GOST_HASH_ALGORITHM=GOST R 34.11-2012
# =============================================================================
# CRYPTO SIMULATION (for testing only)
# =============================================================================
# Enable simulation mode
STELLAOPS_CRYPTO_ENABLE_SIM=1
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
SIM_CRYPTO_PORT=18090

View File

@@ -1,91 +0,0 @@
# Substitutions for docker-compose.dev.yaml
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=dev-postgres-password
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.localtest.me
AUTHORITY_PORT=8440
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.svc.local/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=nats://nats:4222
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=valkey:6379
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env defaults keep worker/web service aligned with local RustFS and inline secrets
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080/api/v1
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_SECRETS_PROVIDER=inline
SCANNER_SURFACE_SECRETS_ROOT=
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
ZASTAVA_SURFACE_SECRETS_PROVIDER=${SCANNER_SURFACE_SECRETS_PROVIDER}
ZASTAVA_SURFACE_SECRETS_ROOT=${SCANNER_SURFACE_SECRETS_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Nats
SCHEDULER_QUEUE_NATS_URL=nats://nats:4222
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=8446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=8443
# NATS
NATS_CLIENT_PORT=4222
# CryptoPro (optional)
CRYPTOPRO_PORT=18080
CRYPTOPRO_ACCEPT_EULA=0

View File

@@ -1,64 +0,0 @@
# Managed mirror profile substitutions
# Core infrastructure credentials
MONGO_INITDB_ROOT_USERNAME=stellaops_mirror
MONGO_INITDB_ROOT_PASSWORD=mirror-password
MINIO_ROOT_USER=stellaops-mirror
MINIO_ROOT_PASSWORD=mirror-minio-secret
RUSTFS_HTTP_PORT=8080
# Scanner surface integration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080/api/v1
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_SECRETS_PROVIDER=file
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
# Mirror HTTP listeners
MIRROR_GATEWAY_HTTP_PORT=8080
MIRROR_GATEWAY_HTTPS_PORT=9443
# Concelier mirror configuration
CONCELIER_MIRROR_LATEST_SEGMENT=latest
CONCELIER_MIRROR_DIRECTORY_SEGMENT=mirror
CONCELIER_MIRROR_REQUIRE_AUTH=true
CONCELIER_MIRROR_INDEX_BUDGET=600
CONCELIER_MIRROR_DOMAIN_PRIMARY_ID=primary
CONCELIER_MIRROR_DOMAIN_PRIMARY_NAME=Primary Mirror
CONCELIER_MIRROR_DOMAIN_PRIMARY_AUTH=true
CONCELIER_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET=3600
CONCELIER_MIRROR_DOMAIN_SECONDARY_ID=community
CONCELIER_MIRROR_DOMAIN_SECONDARY_NAME=Community Mirror
CONCELIER_MIRROR_DOMAIN_SECONDARY_AUTH=false
CONCELIER_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET=1800
# Authority integration (tokens issued by production Authority)
CONCELIER_AUTHORITY_ENABLED=true
CONCELIER_AUTHORITY_ALLOW_ANON=false
CONCELIER_AUTHORITY_ISSUER=https://authority.stella-ops.org
CONCELIER_AUTHORITY_METADATA=
CONCELIER_AUTHORITY_CLIENT_ID=stellaops-concelier-mirror
CONCELIER_AUTHORITY_SCOPE=concelier.mirror.read
CONCELIER_AUTHORITY_AUDIENCE=api://concelier.mirror
# Excititor mirror configuration
EXCITITOR_MONGO_DATABASE=excititor
EXCITITOR_FILESYSTEM_OVERWRITE=false
EXCITITOR_MIRROR_DOMAIN_PRIMARY_ID=primary
EXCITITOR_MIRROR_DOMAIN_PRIMARY_NAME=Primary Mirror
EXCITITOR_MIRROR_DOMAIN_PRIMARY_AUTH=true
EXCITITOR_MIRROR_DOMAIN_PRIMARY_INDEX_BUDGET=300
EXCITITOR_MIRROR_DOMAIN_PRIMARY_DOWNLOAD_BUDGET=2400
EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_KEY=consensus-json
EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_FORMAT=json
EXCITITOR_MIRROR_PRIMARY_EXPORT_CONSENSUS_VIEW=consensus
EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_KEY=consensus-openvex
EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_FORMAT=openvex
EXCITITOR_MIRROR_PRIMARY_EXPORT_OPENVEX_VIEW=consensus
EXCITITOR_MIRROR_DOMAIN_SECONDARY_ID=community
EXCITITOR_MIRROR_DOMAIN_SECONDARY_NAME=Community Mirror
EXCITITOR_MIRROR_DOMAIN_SECONDARY_AUTH=false
EXCITITOR_MIRROR_DOMAIN_SECONDARY_INDEX_BUDGET=120
EXCITITOR_MIRROR_DOMAIN_SECONDARY_DOWNLOAD_BUDGET=600
EXCITITOR_MIRROR_SECONDARY_EXPORT_KEY=community-consensus
EXCITITOR_MIRROR_SECONDARY_EXPORT_FORMAT=json
EXCITITOR_MIRROR_SECONDARY_EXPORT_VIEW=consensus

View File

@@ -1,12 +0,0 @@
# Dev-only overlay env for docker-compose.mock.yaml
# Use together with dev.env.example:
# docker compose --env-file env/dev.env.example --env-file env/mock.env.example -f docker-compose.dev.yaml -f docker-compose.mock.yaml config
# Optional: override ports if you expose mock services
ORCHESTRATOR_PORT=8450
POLICY_REGISTRY_PORT=8451
VEX_LENS_PORT=8452
FINDINGS_LEDGER_PORT=8453
VULN_EXPLORER_API_PORT=8454
PACKS_REGISTRY_PORT=8455
TASK_RUNNER_PORT=8456

View File

@@ -1,109 +0,0 @@
# Substitutions for docker-compose.prod.yaml
# WARNING: Replace all placeholder secrets with values sourced from your secret manager.
# PostgreSQL Database
POSTGRES_USER=stellaops-prod
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.prod.stella-ops.org
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:30:00
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.prod.stella-ops.org/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=valkey://valkey:6379
# `true` enables signed scanner events for Notify ingestion.
SCANNER_EVENTS_ENABLED=true
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env configuration
SCANNER_SURFACE_FS_ENDPOINT=https://surfacefs.prod.stella-ops.org/api/v1
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=kubernetes
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=stellaops/scanner
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Valkey
SCHEDULER_QUEUE_VALKEY_URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=8446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=https://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=8443
# NATS
NATS_CLIENT_PORT=4222
# External reverse proxy (Traefik, Envoy, etc.) that terminates TLS.
FRONTDOOR_NETWORK=stellaops_frontdoor

View File

@@ -1,104 +0,0 @@
# Substitutions for docker-compose.stage.yaml
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=stage-postgres-password
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.stage.stella-ops.internal
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:30:00
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.stage.stella-ops.internal/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Rekor Configuration (Attestor/Scanner)
# Server URL - default is public Sigstore Rekor (use http://rekor-v2:3000 when running the Rekor v2 compose overlay)
REKOR_SERVER_URL=https://rekor.sigstore.dev
# Log version: Auto or V2 (V2 uses tile-based Sunlight format)
REKOR_VERSION=V2
# Tile base URL for V2 (optional, defaults to {REKOR_SERVER_URL}/tile/)
REKOR_TILE_BASE_URL=
# Log ID for multi-log environments (Sigstore production log ID)
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
# Rekor v2 tiles image (pin to digest when mirroring)
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Scanner
SCANNER_WEB_PORT=8444
SCANNER_QUEUE_BROKER=valkey://valkey:6379
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface.Env configuration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=kubernetes
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=stellaops/scanner
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# Zastava inherits Scanner defaults; override if Observer/Webhook diverge
ZASTAVA_SURFACE_FS_ENDPOINT=${SCANNER_SURFACE_FS_ENDPOINT}
ZASTAVA_SURFACE_CACHE_ROOT=${SCANNER_SURFACE_CACHE_ROOT}
# Scheduler
SCHEDULER_QUEUE_KIND=Valkey
SCHEDULER_QUEUE_VALKEY_URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# Notify
NOTIFY_WEB_PORT=8446
# Advisory AI
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# Web UI
UI_PORT=8443
# NATS
NATS_CLIENT_PORT=4222

171
devops/compose/env/stellaops.env.example vendored Normal file
View File

@@ -0,0 +1,171 @@
# =============================================================================
# STELLA OPS ENVIRONMENT CONFIGURATION
# =============================================================================
# Main environment template for docker-compose.stella-ops.yml
# Copy to .env and customize for your deployment.
#
# Usage:
# cp env/stellaops.env.example .env
# docker compose -f docker-compose.stella-ops.yml up -d
#
# =============================================================================
# =============================================================================
# INFRASTRUCTURE
# =============================================================================
# PostgreSQL Database
POSTGRES_USER=stellaops
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
POSTGRES_DB=stellaops_platform
POSTGRES_PORT=5432
# Valkey (Redis-compatible cache and messaging)
VALKEY_PORT=6379
# RustFS Object Storage
RUSTFS_HTTP_PORT=8080
# =============================================================================
# CORE SERVICES
# =============================================================================
# Authority (OAuth2/OIDC)
AUTHORITY_ISSUER=https://authority.example.com
AUTHORITY_PORT=8440
AUTHORITY_OFFLINE_CACHE_TOLERANCE=00:30:00
# Signer
SIGNER_POE_INTROSPECT_URL=https://licensing.example.com/introspect
SIGNER_PORT=8441
# Attestor
ATTESTOR_PORT=8442
# Issuer Directory
ISSUER_DIRECTORY_PORT=8447
ISSUER_DIRECTORY_SEED_CSAF=true
# Concelier
CONCELIER_PORT=8445
# Notify
NOTIFY_WEB_PORT=8446
# Web UI
UI_PORT=8443
# =============================================================================
# SCANNER CONFIGURATION
# =============================================================================
SCANNER_WEB_PORT=8444
# Queue configuration (Valkey only - NATS removed)
SCANNER__QUEUE__BROKER=valkey://valkey:6379
# Event streaming
SCANNER_EVENTS_ENABLED=false
SCANNER_EVENTS_DRIVER=valkey
SCANNER_EVENTS_DSN=valkey:6379
SCANNER_EVENTS_STREAM=stella.events
SCANNER_EVENTS_PUBLISH_TIMEOUT_SECONDS=5
SCANNER_EVENTS_MAX_STREAM_LENGTH=10000
# Surface cache configuration
SCANNER_SURFACE_FS_ENDPOINT=http://rustfs:8080
SCANNER_SURFACE_FS_BUCKET=surface-cache
SCANNER_SURFACE_CACHE_ROOT=/var/lib/stellaops/surface
SCANNER_SURFACE_CACHE_QUOTA_MB=4096
SCANNER_SURFACE_PREFETCH_ENABLED=false
SCANNER_SURFACE_TENANT=default
SCANNER_SURFACE_FEATURES=
SCANNER_SURFACE_SECRETS_PROVIDER=file
SCANNER_SURFACE_SECRETS_NAMESPACE=
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
SCANNER_SURFACE_SECRETS_FALLBACK_PROVIDER=
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
SURFACE_SECRETS_HOST_PATH=./offline/surface-secrets
# Offline Kit configuration
SCANNER_OFFLINEKIT_ENABLED=false
SCANNER_OFFLINEKIT_REQUIREDSSE=true
SCANNER_OFFLINEKIT_REKOROFFLINEMODE=true
SCANNER_OFFLINEKIT_TRUSTROOTDIRECTORY=/etc/stellaops/trust-roots
SCANNER_OFFLINEKIT_REKORSNAPSHOTDIRECTORY=/var/lib/stellaops/rekor-snapshot
SCANNER_OFFLINEKIT_TRUSTROOTS_HOST_PATH=./offline/trust-roots
SCANNER_OFFLINEKIT_REKOR_SNAPSHOT_HOST_PATH=./offline/rekor-snapshot
# =============================================================================
# SCHEDULER CONFIGURATION
# =============================================================================
# Queue configuration (Valkey only - NATS removed)
SCHEDULER__QUEUE__KIND=Valkey
SCHEDULER__QUEUE__VALKEY__URL=valkey:6379
SCHEDULER_SCANNER_BASEADDRESS=http://scanner-web:8444
# =============================================================================
# REKOR / SIGSTORE CONFIGURATION
# =============================================================================
# Rekor server URL (default: public Sigstore, use http://rekor-v2:3000 for local)
REKOR_SERVER_URL=https://rekor.sigstore.dev
REKOR_VERSION=V2
REKOR_TILE_BASE_URL=
REKOR_LOG_ID=c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d
REKOR_TILES_IMAGE=ghcr.io/sigstore/rekor-tiles:latest
# =============================================================================
# ADVISORY AI CONFIGURATION
# =============================================================================
ADVISORY_AI_WEB_PORT=8448
ADVISORY_AI_SBOM_BASEADDRESS=http://scanner-web:8444
ADVISORY_AI_INFERENCE_MODE=Local
ADVISORY_AI_REMOTE_BASEADDRESS=
ADVISORY_AI_REMOTE_APIKEY=
# =============================================================================
# CRYPTO CONFIGURATION
# =============================================================================
# Crypto profile: default, china, russia, eu
STELLAOPS_CRYPTO_PROFILE=default
# Enable crypto simulation (for testing)
STELLAOPS_CRYPTO_ENABLE_SIM=0
STELLAOPS_CRYPTO_SIM_URL=http://sim-crypto:8080
# CryptoPro (Russia only) - requires EULA acceptance
CRYPTOPRO_PORT=18080
CRYPTOPRO_ACCEPT_EULA=0
CRYPTOPRO_CONTAINER_NAME=stellaops-signing
CRYPTOPRO_USE_MACHINE_STORE=true
CRYPTOPRO_PROVIDER_TYPE=80
# SM Remote (China only)
SM_REMOTE_PORT=56080
SM_SOFT_ALLOWED=1
SM_REMOTE_HSM_URL=
SM_REMOTE_HSM_API_KEY=
SM_REMOTE_HSM_TIMEOUT=30000
# =============================================================================
# NETWORKING
# =============================================================================
# External reverse proxy network (Traefik, Envoy, etc.)
FRONTDOOR_NETWORK=stellaops_frontdoor
# =============================================================================
# TELEMETRY (optional)
# =============================================================================
OTEL_GRPC_PORT=4317
OTEL_HTTP_PORT=4318
OTEL_PROMETHEUS_PORT=9464
PROMETHEUS_PORT=9090
TEMPO_PORT=3200
LOKI_PORT=3100
PROMETHEUS_RETENTION=15d

45
devops/compose/env/testing.env.example vendored Normal file
View File

@@ -0,0 +1,45 @@
# =============================================================================
# STELLA OPS TESTING ENVIRONMENT CONFIGURATION
# =============================================================================
# Environment template for docker-compose.testing.yml
# Uses different ports to avoid conflicts with development/production.
#
# Usage:
# cp env/testing.env.example .env
# docker compose -f docker-compose.testing.yml --profile ci up -d
#
# =============================================================================
# =============================================================================
# CI INFRASTRUCTURE (different ports to avoid conflicts)
# =============================================================================
# PostgreSQL Test Database (port 5433)
TEST_POSTGRES_PORT=5433
TEST_POSTGRES_USER=stellaops_ci
TEST_POSTGRES_PASSWORD=ci_test_password
TEST_POSTGRES_DB=stellaops_test
# Valkey Test (port 6380)
TEST_VALKEY_PORT=6380
# RustFS Test (port 8180)
TEST_RUSTFS_PORT=8180
# Mock Registry (port 5001)
TEST_REGISTRY_PORT=5001
# =============================================================================
# GITEA CONFIGURATION
# =============================================================================
TEST_GITEA_PORT=3000
TEST_GITEA_SSH_PORT=3022
# =============================================================================
# SIGSTORE TOOLS
# =============================================================================
# Rekor CLI and Cosign versions (for sigstore profile)
REKOR_CLI_VERSION=v1.4.3
COSIGN_VERSION=v3.0.4

View File

@@ -1,13 +0,0 @@
# Mirror Gateway Assets
This directory holds the reverse-proxy configuration and TLS material for the managed
mirror profile:
- `conf.d/*.conf` nginx configuration shipped with the profile.
- `tls/` place environment-specific certificates and private keys
(`mirror-primary.{crt,key}`, `mirror-community.{crt,key}`, etc.).
- `secrets/` populate Basic Auth credential stores (`*.htpasswd`) that gate each
mirror domain. Generate with `htpasswd -B`.
The Compose bundle mounts these paths read-only. Populate `tls/` with the actual
certificates before invoking `docker compose config` or `docker compose up`.

View File

@@ -1,44 +0,0 @@
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
add_header X-Cache-Status $upstream_cache_status always;
location = /healthz {
default_type application/json;
return 200 '{"status":"ok"}';
}
location /concelier/exports/ {
proxy_pass http://concelier_backend/concelier/exports/;
proxy_cache mirror_cache;
proxy_cache_key $mirror_cache_key;
proxy_cache_valid 200 5m;
proxy_cache_valid 404 1m;
add_header Cache-Control "public, max-age=300, immutable" always;
}
location /concelier/ {
proxy_pass http://concelier_backend/concelier/;
proxy_cache off;
}
location /excititor/mirror/ {
proxy_pass http://excititor_backend/excititor/mirror/;
proxy_cache mirror_cache;
proxy_cache_key $mirror_cache_key;
proxy_cache_valid 200 5m;
proxy_cache_valid 404 1m;
add_header Cache-Control "public, max-age=300, immutable" always;
}
location /excititor/ {
proxy_pass http://excititor_backend/excititor/;
proxy_cache off;
}
location / {
return 404;
}

View File

@@ -1,51 +0,0 @@
proxy_cache_path /var/cache/nginx/mirror levels=1:2 keys_zone=mirror_cache:100m max_size=10g inactive=12h use_temp_path=off;
map $request_uri $mirror_cache_key {
default $scheme$request_method$host$request_uri;
}
upstream concelier_backend {
server concelier:8445;
keepalive 32;
}
upstream excititor_backend {
server excititor:8448;
keepalive 32;
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name mirror-primary.stella-ops.org;
ssl_certificate /etc/nginx/tls/mirror-primary.crt;
ssl_certificate_key /etc/nginx/tls/mirror-primary.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
auth_basic "StellaOps Mirror primary";
auth_basic_user_file /etc/nginx/secrets/mirror-primary.htpasswd;
include /etc/nginx/conf.d/mirror-locations.conf;
}
server {
listen 443 ssl http2;
server_name mirror-community.stella-ops.org;
ssl_certificate /etc/nginx/tls/mirror-community.crt;
ssl_certificate_key /etc/nginx/tls/mirror-community.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
auth_basic "StellaOps Mirror community";
auth_basic_user_file /etc/nginx/secrets/mirror-community.htpasswd;
include /etc/nginx/conf.d/mirror-locations.conf;
}

View File

@@ -1,69 +0,0 @@
-- ============================================================================
-- PostgreSQL initialization for StellaOps
-- This script runs automatically on first container start
-- ============================================================================
-- Enable pg_stat_statements extension for query performance analysis
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Enable other useful extensions
CREATE EXTENSION IF NOT EXISTS pg_trgm; -- Fuzzy text search
CREATE EXTENSION IF NOT EXISTS btree_gin; -- GIN indexes for scalar types
CREATE EXTENSION IF NOT EXISTS pgcrypto; -- Cryptographic functions
-- ============================================================================
-- Create schemas for all modules
-- Migrations will create tables within these schemas
-- ============================================================================
-- Core Platform
CREATE SCHEMA IF NOT EXISTS authority; -- Authentication, authorization, OAuth/OIDC
-- Data Ingestion
CREATE SCHEMA IF NOT EXISTS vuln; -- Concelier vulnerability data
CREATE SCHEMA IF NOT EXISTS vex; -- Excititor VEX documents
-- Scanning & Analysis
CREATE SCHEMA IF NOT EXISTS scanner; -- Container scanning, SBOM generation
-- Scheduling & Orchestration
CREATE SCHEMA IF NOT EXISTS scheduler; -- Job scheduling
CREATE SCHEMA IF NOT EXISTS taskrunner; -- Task execution
-- Policy & Risk
CREATE SCHEMA IF NOT EXISTS policy; -- Policy engine
CREATE SCHEMA IF NOT EXISTS unknowns; -- Unknown component tracking
-- Artifacts & Evidence
CREATE SCHEMA IF NOT EXISTS proofchain; -- Attestor proof chains
CREATE SCHEMA IF NOT EXISTS attestor; -- Attestor submission queue
CREATE SCHEMA IF NOT EXISTS signer; -- Key management
-- Notifications
CREATE SCHEMA IF NOT EXISTS notify; -- Notification delivery
-- Signals & Observability
CREATE SCHEMA IF NOT EXISTS signals; -- Runtime signals
-- Registry
CREATE SCHEMA IF NOT EXISTS packs; -- Task packs registry
-- Audit
CREATE SCHEMA IF NOT EXISTS audit; -- System-wide audit log
-- ============================================================================
-- Grant usage to application user (for single-user mode)
-- Per-module users are created in 02-create-users.sql
-- ============================================================================
DO $$
DECLARE
schema_name TEXT;
BEGIN
FOR schema_name IN SELECT unnest(ARRAY[
'authority', 'vuln', 'vex', 'scanner', 'scheduler', 'taskrunner',
'policy', 'unknowns', 'proofchain', 'attestor', 'signer',
'notify', 'signals', 'packs', 'audit'
]) LOOP
EXECUTE format('GRANT USAGE ON SCHEMA %I TO PUBLIC', schema_name);
END LOOP;
END $$;

View File

@@ -1,53 +0,0 @@
-- ============================================================================
-- Per-Module Database Users
-- ============================================================================
-- Creates isolated database users for each StellaOps module.
-- This enables least-privilege access control and audit trail per module.
--
-- Password format: {module}_dev (for development only)
-- In production, use secrets management and rotate credentials.
-- ============================================================================
-- Core Platform
CREATE USER authority_user WITH PASSWORD 'authority_dev';
-- Data Ingestion
CREATE USER concelier_user WITH PASSWORD 'concelier_dev';
CREATE USER excititor_user WITH PASSWORD 'excititor_dev';
-- Scanning & Analysis
CREATE USER scanner_user WITH PASSWORD 'scanner_dev';
-- Scheduling & Orchestration
CREATE USER scheduler_user WITH PASSWORD 'scheduler_dev';
CREATE USER taskrunner_user WITH PASSWORD 'taskrunner_dev';
-- Policy & Risk
CREATE USER policy_user WITH PASSWORD 'policy_dev';
CREATE USER unknowns_user WITH PASSWORD 'unknowns_dev';
-- Artifacts & Evidence
CREATE USER attestor_user WITH PASSWORD 'attestor_dev';
CREATE USER signer_user WITH PASSWORD 'signer_dev';
-- Notifications
CREATE USER notify_user WITH PASSWORD 'notify_dev';
-- Signals & Observability
CREATE USER signals_user WITH PASSWORD 'signals_dev';
-- Registry
CREATE USER packs_user WITH PASSWORD 'packs_dev';
-- ============================================================================
-- Log created users
-- ============================================================================
DO $$
BEGIN
RAISE NOTICE 'Created per-module database users:';
RAISE NOTICE ' - authority_user, concelier_user, excititor_user';
RAISE NOTICE ' - scanner_user, scheduler_user, taskrunner_user';
RAISE NOTICE ' - policy_user, unknowns_user';
RAISE NOTICE ' - attestor_user, signer_user';
RAISE NOTICE ' - notify_user, signals_user, packs_user';
END $$;

View File

@@ -1,153 +0,0 @@
-- ============================================================================
-- Per-Module Schema Permissions
-- ============================================================================
-- Grants each module user access to their respective schema(s).
-- Users can only access tables in their designated schemas.
-- ============================================================================
-- ============================================================================
-- Authority Module
-- ============================================================================
GRANT USAGE ON SCHEMA authority TO authority_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA authority TO authority_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA authority TO authority_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA authority GRANT ALL ON TABLES TO authority_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA authority GRANT ALL ON SEQUENCES TO authority_user;
-- ============================================================================
-- Concelier Module (uses 'vuln' schema)
-- ============================================================================
GRANT USAGE ON SCHEMA vuln TO concelier_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA vuln TO concelier_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA vuln TO concelier_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA vuln GRANT ALL ON TABLES TO concelier_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA vuln GRANT ALL ON SEQUENCES TO concelier_user;
-- ============================================================================
-- Excititor Module (uses 'vex' schema)
-- ============================================================================
GRANT USAGE ON SCHEMA vex TO excititor_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA vex TO excititor_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA vex TO excititor_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA vex GRANT ALL ON TABLES TO excititor_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA vex GRANT ALL ON SEQUENCES TO excititor_user;
-- ============================================================================
-- Scanner Module
-- ============================================================================
GRANT USAGE ON SCHEMA scanner TO scanner_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA scanner TO scanner_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA scanner TO scanner_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA scanner GRANT ALL ON TABLES TO scanner_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA scanner GRANT ALL ON SEQUENCES TO scanner_user;
-- ============================================================================
-- Scheduler Module
-- ============================================================================
GRANT USAGE ON SCHEMA scheduler TO scheduler_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA scheduler TO scheduler_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA scheduler TO scheduler_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA scheduler GRANT ALL ON TABLES TO scheduler_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA scheduler GRANT ALL ON SEQUENCES TO scheduler_user;
-- ============================================================================
-- TaskRunner Module
-- ============================================================================
GRANT USAGE ON SCHEMA taskrunner TO taskrunner_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA taskrunner TO taskrunner_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA taskrunner TO taskrunner_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA taskrunner GRANT ALL ON TABLES TO taskrunner_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA taskrunner GRANT ALL ON SEQUENCES TO taskrunner_user;
-- ============================================================================
-- Policy Module
-- ============================================================================
GRANT USAGE ON SCHEMA policy TO policy_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA policy TO policy_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA policy TO policy_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA policy GRANT ALL ON TABLES TO policy_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA policy GRANT ALL ON SEQUENCES TO policy_user;
-- ============================================================================
-- Unknowns Module
-- ============================================================================
GRANT USAGE ON SCHEMA unknowns TO unknowns_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA unknowns TO unknowns_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA unknowns TO unknowns_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA unknowns GRANT ALL ON TABLES TO unknowns_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA unknowns GRANT ALL ON SEQUENCES TO unknowns_user;
-- ============================================================================
-- Attestor Module (uses 'proofchain' and 'attestor' schemas)
-- ============================================================================
GRANT USAGE ON SCHEMA proofchain TO attestor_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA proofchain TO attestor_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA proofchain TO attestor_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA proofchain GRANT ALL ON TABLES TO attestor_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA proofchain GRANT ALL ON SEQUENCES TO attestor_user;
GRANT USAGE ON SCHEMA attestor TO attestor_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA attestor TO attestor_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA attestor TO attestor_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA attestor GRANT ALL ON TABLES TO attestor_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA attestor GRANT ALL ON SEQUENCES TO attestor_user;
-- ============================================================================
-- Signer Module
-- ============================================================================
GRANT USAGE ON SCHEMA signer TO signer_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA signer TO signer_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA signer TO signer_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA signer GRANT ALL ON TABLES TO signer_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA signer GRANT ALL ON SEQUENCES TO signer_user;
-- ============================================================================
-- Notify Module
-- ============================================================================
GRANT USAGE ON SCHEMA notify TO notify_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA notify TO notify_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA notify TO notify_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA notify GRANT ALL ON TABLES TO notify_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA notify GRANT ALL ON SEQUENCES TO notify_user;
-- ============================================================================
-- Signals Module
-- ============================================================================
GRANT USAGE ON SCHEMA signals TO signals_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA signals TO signals_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA signals TO signals_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA signals GRANT ALL ON TABLES TO signals_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA signals GRANT ALL ON SEQUENCES TO signals_user;
-- ============================================================================
-- Packs Registry Module
-- ============================================================================
GRANT USAGE ON SCHEMA packs TO packs_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA packs TO packs_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA packs TO packs_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA packs GRANT ALL ON TABLES TO packs_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA packs GRANT ALL ON SEQUENCES TO packs_user;
-- ============================================================================
-- Verification
-- ============================================================================
DO $$
DECLARE
v_user TEXT;
v_schema TEXT;
BEGIN
RAISE NOTICE 'Per-module permissions granted:';
RAISE NOTICE ' authority_user -> authority';
RAISE NOTICE ' concelier_user -> vuln';
RAISE NOTICE ' excititor_user -> vex';
RAISE NOTICE ' scanner_user -> scanner';
RAISE NOTICE ' scheduler_user -> scheduler';
RAISE NOTICE ' taskrunner_user -> taskrunner';
RAISE NOTICE ' policy_user -> policy';
RAISE NOTICE ' unknowns_user -> unknowns';
RAISE NOTICE ' attestor_user -> proofchain, attestor';
RAISE NOTICE ' signer_user -> signer';
RAISE NOTICE ' notify_user -> notify';
RAISE NOTICE ' signals_user -> signals';
RAISE NOTICE ' packs_user -> packs';
END $$;

View File

@@ -2,7 +2,7 @@
set -euo pipefail set -euo pipefail
echo "StellaOps Compose Backup" echo "StellaOps Compose Backup"
echo "This will create a tar.gz of Mongo, MinIO (object-store), and Redis data volumes." echo "This will create a tar.gz of PostgreSQL, RustFS (object-store), and Valkey data volumes."
read -rp "Proceed? [y/N] " ans read -rp "Proceed? [y/N] " ans
[[ ${ans:-N} =~ ^[Yy]$ ]] || { echo "Aborted."; exit 1; } [[ ${ans:-N} =~ ^[Yy]$ ]] || { echo "Aborted."; exit 1; }
@@ -17,9 +17,9 @@ docker compose pause scanner-worker scheduler-worker taskrunner-worker || true
echo "Backing up volumes..." echo "Backing up volumes..."
docker run --rm \ docker run --rm \
-v stellaops-mongo:/data/db:ro \ -v stellaops-postgres:/data/postgres:ro \
-v stellaops-minio:/data/minio:ro \ -v stellaops-rustfs:/data/rustfs:ro \
-v stellaops-redis:/data/redis:ro \ -v stellaops-valkey:/data/valkey:ro \
-v "$PWD/$OUT_DIR":/out \ -v "$PWD/$OUT_DIR":/out \
alpine sh -c "cd / && tar czf /out/stellaops-backup-$TS.tar.gz data" alpine sh -c "cd / && tar czf /out/stellaops-backup-$TS.tar.gz data"

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
echo "WARNING: This will stop the stack and wipe Mongo, MinIO, and Redis volumes." echo "WARNING: This will stop the stack and wipe PostgreSQL, RustFS, and Valkey volumes."
read -rp "Type 'RESET' to continue: " ans read -rp "Type 'RESET' to continue: " ans
[[ ${ans:-} == "RESET" ]] || { echo "Aborted."; exit 1; } [[ ${ans:-} == "RESET" ]] || { echo "Aborted."; exit 1; }
docker compose down docker compose down
for vol in stellaops-mongo stellaops-minio stellaops-redis; do for vol in stellaops-postgres stellaops-rustfs stellaops-valkey; do
echo "Removing volume $vol" echo "Removing volume $vol"
docker volume rm "$vol" || true docker volume rm "$vol" || true
done done

View File

@@ -1,161 +0,0 @@
# Tile Proxy Docker Compose
This directory contains the Docker Compose configuration for deploying the StellaOps Tile Proxy service.
## Overview
The Tile Proxy acts as a caching intermediary between StellaOps clients and upstream Rekor transparency logs. It provides:
- **Tile Caching**: Caches tiles locally for faster subsequent requests
- **Request Coalescing**: Deduplicates concurrent requests for the same tile
- **Offline Support**: Serves from cache when upstream is unavailable
- **TUF Integration**: Optional validation using TUF trust anchors
## Quick Start
```bash
# Start with default configuration
docker compose up -d
# Check health
curl http://localhost:8090/_admin/health
# View cache statistics
curl http://localhost:8090/_admin/cache/stats
```
## Configuration
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `REKOR_UPSTREAM_URL` | Upstream Rekor URL | `https://rekor.sigstore.dev` |
| `REKOR_ORIGIN` | Log origin identifier | `rekor.sigstore.dev - 1985497715` |
| `TUF_ENABLED` | Enable TUF integration | `false` |
| `TUF_ROOT_URL` | TUF repository URL | - |
| `TUF_VALIDATE_CHECKPOINT` | Validate checkpoint signatures | `true` |
| `CACHE_MAX_SIZE_GB` | Maximum cache size | `10` |
| `CHECKPOINT_TTL_MINUTES` | Checkpoint cache TTL | `5` |
| `SYNC_ENABLED` | Enable scheduled sync | `true` |
| `SYNC_SCHEDULE` | Sync cron schedule | `0 */6 * * *` |
| `SYNC_DEPTH` | Entries to sync tiles for | `10000` |
| `LOG_LEVEL` | Logging level | `Information` |
### Using a .env file
Create a `.env` file to customize configuration:
```bash
# .env
REKOR_UPSTREAM_URL=https://rekor.sigstore.dev
CACHE_MAX_SIZE_GB=20
SYNC_ENABLED=true
SYNC_SCHEDULE=0 */4 * * *
LOG_LEVEL=Debug
```
## API Endpoints
### Proxy Endpoints
| Endpoint | Description |
|----------|-------------|
| `GET /tile/{level}/{index}` | Get a tile (cache-through) |
| `GET /tile/{level}/{index}.p/{width}` | Get partial tile |
| `GET /checkpoint` | Get current checkpoint |
### Admin Endpoints
| Endpoint | Description |
|----------|-------------|
| `GET /_admin/cache/stats` | Cache statistics |
| `GET /_admin/metrics` | Proxy metrics |
| `POST /_admin/cache/sync` | Trigger manual sync |
| `DELETE /_admin/cache/prune` | Prune old tiles |
| `GET /_admin/health` | Health check |
| `GET /_admin/ready` | Readiness check |
## Volumes
| Volume | Path | Description |
|--------|------|-------------|
| `tile-cache` | `/var/cache/stellaops/tiles` | Cached tiles |
| `tuf-cache` | `/var/cache/stellaops/tuf` | TUF metadata |
## Integration with StellaOps
Configure your StellaOps Attestor to use the tile proxy:
```yaml
attestor:
rekor:
url: http://tile-proxy:8080
# or if running standalone:
# url: http://localhost:8090
```
## Monitoring
### Prometheus Metrics
The tile proxy exposes metrics at `/_admin/metrics`:
```bash
curl http://localhost:8090/_admin/metrics
```
Example response:
```json
{
"cacheHits": 12450,
"cacheMisses": 234,
"hitRatePercent": 98.15,
"upstreamRequests": 234,
"upstreamErrors": 2,
"inflightRequests": 0
}
```
### Health Checks
```bash
# Liveness (is the service running?)
curl http://localhost:8090/_admin/health
# Readiness (can it serve requests?)
curl http://localhost:8090/_admin/ready
```
## Troubleshooting
### Cache is not being used
1. Check cache stats: `curl http://localhost:8090/_admin/cache/stats`
2. Verify cache volume is mounted correctly
3. Check logs for write errors
### Upstream connection failures
1. Check network connectivity to upstream
2. Verify `REKOR_UPSTREAM_URL` is correct
3. Check for firewall/proxy issues
### High memory usage
1. Reduce `CACHE_MAX_SIZE_GB`
2. Trigger manual prune: `curl -X DELETE http://localhost:8090/_admin/cache/prune?targetSizeBytes=5368709120`
## Development
Build the image locally:
```bash
docker compose build
```
Run with local source:
```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
```

View File

@@ -1,64 +0,0 @@
# -----------------------------------------------------------------------------
# docker-compose.yml
# Sprint: SPRINT_20260125_002_Attestor_trust_automation
# Task: PROXY-008 - Docker Compose for tile-proxy stack
# Description: Docker Compose configuration for tile-proxy deployment
# -----------------------------------------------------------------------------
services:
tile-proxy:
build:
context: ../../..
dockerfile: src/Attestor/StellaOps.Attestor.TileProxy/Dockerfile
image: stellaops/tile-proxy:latest
container_name: stellaops-tile-proxy
ports:
- "8090:8080"
volumes:
- tile-cache:/var/cache/stellaops/tiles
- tuf-cache:/var/cache/stellaops/tuf
environment:
# Upstream Rekor configuration
- TILE_PROXY__UPSTREAMURL=${REKOR_UPSTREAM_URL:-https://rekor.sigstore.dev}
- TILE_PROXY__ORIGIN=${REKOR_ORIGIN:-rekor.sigstore.dev - 1985497715}
# TUF configuration (optional)
- TILE_PROXY__TUF__ENABLED=${TUF_ENABLED:-false}
- TILE_PROXY__TUF__URL=${TUF_ROOT_URL:-}
- TILE_PROXY__TUF__VALIDATECHECKPOINTSIGNATURE=${TUF_VALIDATE_CHECKPOINT:-true}
# Cache configuration
- TILE_PROXY__CACHE__BASEPATH=/var/cache/stellaops/tiles
- TILE_PROXY__CACHE__MAXSIZEGB=${CACHE_MAX_SIZE_GB:-10}
- TILE_PROXY__CACHE__CHECKPOINTTTLMINUTES=${CHECKPOINT_TTL_MINUTES:-5}
# Sync job configuration
- TILE_PROXY__SYNC__ENABLED=${SYNC_ENABLED:-true}
- TILE_PROXY__SYNC__SCHEDULE=${SYNC_SCHEDULE:-0 */6 * * *}
- TILE_PROXY__SYNC__DEPTH=${SYNC_DEPTH:-10000}
# Request handling
- TILE_PROXY__REQUEST__COALESCINGENABLED=${COALESCING_ENABLED:-true}
- TILE_PROXY__REQUEST__TIMEOUTSECONDS=${REQUEST_TIMEOUT_SECONDS:-30}
# Logging
- Serilog__MinimumLevel__Default=${LOG_LEVEL:-Information}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/_admin/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
restart: unless-stopped
networks:
- stellaops
volumes:
tile-cache:
driver: local
tuf-cache:
driver: local
networks:
stellaops:
driver: bridge

View File

@@ -1,32 +0,0 @@
version: "3.9"
services:
stella-postgres:
image: postgres:18.1
container_name: stella-postgres
restart: unless-stopped
environment:
POSTGRES_USER: stella
POSTGRES_PASSWORD: stella
POSTGRES_DB: stella
ports:
- "5432:5432"
volumes:
- stella-postgres-data:/var/lib/postgresql/data
- ./init:/docker-entrypoint-initdb.d:ro
command:
- "postgres"
- "-c"
- "shared_preload_libraries=pg_stat_statements"
- "-c"
- "pg_stat_statements.track=all"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
interval: 10s
timeout: 5s
retries: 5
volumes:
stella-postgres-data:
driver: local

View File

@@ -1,17 +0,0 @@
-- Enable pg_stat_statements extension for query performance analysis
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Enable other useful extensions
CREATE EXTENSION IF NOT EXISTS pg_trgm; -- Fuzzy text search
CREATE EXTENSION IF NOT EXISTS btree_gin; -- GIN indexes for scalar types
CREATE EXTENSION IF NOT EXISTS pgcrypto; -- Cryptographic functions
-- Create schemas for all modules
CREATE SCHEMA IF NOT EXISTS authority;
CREATE SCHEMA IF NOT EXISTS vuln;
CREATE SCHEMA IF NOT EXISTS vex;
CREATE SCHEMA IF NOT EXISTS scheduler;
CREATE SCHEMA IF NOT EXISTS notify;
CREATE SCHEMA IF NOT EXISTS policy;
CREATE SCHEMA IF NOT EXISTS concelier;
CREATE SCHEMA IF NOT EXISTS audit;

View File

@@ -1,16 +0,0 @@
# MongoDB Provenance Indexes
Indexes supporting Sprint 401 reachability/provenance queries.
## Available indexes
- `events_by_subject_kind_provenance`: `(subject.digest.sha256, kind, provenance.dsse.rekor.logIndex)` for subject/kind lookups with Rekor presence.
- `events_unproven_by_kind`: `(kind, trust.verified, provenance.dsse.rekor.logIndex)` to find unverified or missing-Rekor events per kind.
- `events_by_rekor_logindex`: `(provenance.dsse.rekor.logIndex)` to audit Rekor alignment.
## Apply
```js
// From mongo shell (connected to provenance database)
load('ops/mongo/indices/events_provenance_indices.js');
```
Indexes are idempotent; rerunning is safe.

View File

@@ -1,89 +0,0 @@
/**
* MongoDB indexes for DSSE provenance queries on the events collection.
* Run with: mongosh stellaops_db < events_provenance_indices.js
*
* These indexes support:
* - Proven VEX/SBOM/SCAN lookup by subject digest
* - Compliance gap queries (unverified events)
* - Rekor log index lookups
* - Backfill service queries
*
* Created: 2025-11-27 (PROV-INDEX-401-030)
* C# equivalent: src/StellaOps.Events.Mongo/MongoIndexes.cs
*/
// Switch to the target database (override via --eval "var dbName='custom'" if needed)
const targetDb = typeof dbName !== 'undefined' ? dbName : 'stellaops';
db = db.getSiblingDB(targetDb);
print(`Creating provenance indexes on ${targetDb}.events...`);
// Index 1: Lookup proven events by subject digest + kind
db.events.createIndex(
{
"subject.digest.sha256": 1,
"kind": 1,
"provenance.dsse.rekor.logIndex": 1
},
{
name: "events_by_subject_kind_provenance",
background: true
}
);
print(" - events_by_subject_kind_provenance");
// Index 2: Find unproven evidence by kind (compliance gap queries)
db.events.createIndex(
{
"kind": 1,
"trust.verified": 1,
"provenance.dsse.rekor.logIndex": 1
},
{
name: "events_unproven_by_kind",
background: true
}
);
print(" - events_unproven_by_kind");
// Index 3: Direct Rekor log index lookup
db.events.createIndex(
{
"provenance.dsse.rekor.logIndex": 1
},
{
name: "events_by_rekor_logindex",
background: true
}
);
print(" - events_by_rekor_logindex");
// Index 4: Envelope digest lookup (for backfill deduplication)
db.events.createIndex(
{
"provenance.dsse.envelopeDigest": 1
},
{
name: "events_by_envelope_digest",
background: true,
sparse: true
}
);
print(" - events_by_envelope_digest");
// Index 5: Timestamp + kind for compliance reporting time ranges
db.events.createIndex(
{
"ts": -1,
"kind": 1,
"trust.verified": 1
},
{
name: "events_by_ts_kind_verified",
background: true
}
);
print(" - events_by_ts_kind_verified");
print("\nProvenance indexes created successfully.");
print("Run 'db.events.getIndexes()' to verify.");

View File

@@ -1,67 +0,0 @@
/**
* MongoDB indexes for the shared reachability store collections used by Signals/Policy/Scanner.
* Run with: mongosh stellaops_db < reachability_store_indices.js
*
* Collections:
* - func_nodes: canonical function nodes keyed by graph + symbol ID and joinable by (purl, symbolDigest)
* - call_edges: canonical call edges keyed by graph and joinable by (purl, symbolDigest)
* - cve_func_hits: per-subject mapping of CVE -> affected/reachable functions with evidence pointers
*
* Created: 2025-12-13 (SIG-STORE-401-016)
*/
// Switch to the target database (override via --eval "var dbName='custom'" if needed)
const targetDb = typeof dbName !== 'undefined' ? dbName : 'stellaops';
db = db.getSiblingDB(targetDb);
print(`Creating reachability store indexes on ${targetDb}...`);
print(`- func_nodes`);
db.func_nodes.createIndex(
{ "graphHash": 1, "symbolId": 1 },
{ name: "func_nodes_by_graph_symbol", unique: true, background: true }
);
db.func_nodes.createIndex(
{ "purl": 1, "symbolDigest": 1 },
{ name: "func_nodes_by_purl_symboldigest", background: true, sparse: true }
);
db.func_nodes.createIndex(
{ "codeId": 1 },
{ name: "func_nodes_by_code_id", background: true, sparse: true }
);
print(`- call_edges`);
db.call_edges.createIndex(
{ "graphHash": 1, "sourceId": 1, "targetId": 1, "type": 1 },
{ name: "call_edges_by_graph_edge", unique: true, background: true }
);
db.call_edges.createIndex(
{ "graphHash": 1, "sourceId": 1 },
{ name: "call_edges_by_graph_source", background: true }
);
db.call_edges.createIndex(
{ "graphHash": 1, "targetId": 1 },
{ name: "call_edges_by_graph_target", background: true }
);
db.call_edges.createIndex(
{ "purl": 1, "symbolDigest": 1 },
{ name: "call_edges_by_purl_symboldigest", background: true, sparse: true }
);
print(`- cve_func_hits`);
db.cve_func_hits.createIndex(
{ "subjectKey": 1, "cveId": 1 },
{ name: "cve_func_hits_by_subject_cve", background: true }
);
db.cve_func_hits.createIndex(
{ "cveId": 1, "purl": 1, "symbolDigest": 1 },
{ name: "cve_func_hits_by_cve_purl_symboldigest", background: true, sparse: true }
);
db.cve_func_hits.createIndex(
{ "graphHash": 1 },
{ name: "cve_func_hits_by_graph", background: true, sparse: true }
);
print("\nReachability store indexes created successfully.");
print("Run db.func_nodes.getIndexes(), db.call_edges.getIndexes(), db.cve_func_hits.getIndexes() to verify.");

View File

@@ -1,125 +0,0 @@
// Task Runner baseline collections and indexes
// Mirrors docs/modules/taskrunner/migrations/pack-run-collections.md (last updated 2025-11-06)
function ensureCollection(name, validator) {
const existing = db.getCollectionNames();
if (!existing.includes(name)) {
db.createCollection(name, { validator, validationLevel: "moderate" });
} else if (validator) {
db.runCommand({ collMod: name, validator, validationLevel: "moderate" });
}
}
const runValidator = {
$jsonSchema: {
bsonType: "object",
required: ["planHash", "plan", "failurePolicy", "requestedAt", "createdAt", "updatedAt", "steps"],
properties: {
_id: { bsonType: "string" },
planHash: { bsonType: "string" },
plan: { bsonType: "object" },
failurePolicy: { bsonType: "object" },
requestedAt: { bsonType: "date" },
createdAt: { bsonType: "date" },
updatedAt: { bsonType: "date" },
steps: {
bsonType: "array",
items: {
bsonType: "object",
required: ["stepId", "status", "attempts"],
properties: {
stepId: { bsonType: "string" },
status: { bsonType: "string" },
attempts: { bsonType: "int" },
kind: { bsonType: "string" },
enabled: { bsonType: "bool" },
continueOnError: { bsonType: "bool" },
maxParallel: { bsonType: ["int", "null"] },
approvalId: { bsonType: ["string", "null"] },
gateMessage: { bsonType: ["string", "null"] },
lastTransitionAt: { bsonType: ["date", "null"] },
nextAttemptAt: { bsonType: ["date", "null"] },
statusReason: { bsonType: ["string", "null"] }
}
}
},
tenantId: { bsonType: ["string", "null"] }
}
}
};
const logValidator = {
$jsonSchema: {
bsonType: "object",
required: ["runId", "sequence", "timestamp", "level", "eventType", "message"],
properties: {
runId: { bsonType: "string" },
sequence: { bsonType: "long" },
timestamp: { bsonType: "date" },
level: { bsonType: "string" },
eventType: { bsonType: "string" },
message: { bsonType: "string" },
stepId: { bsonType: ["string", "null"] },
metadata: { bsonType: ["object", "null"] }
}
}
};
const artifactsValidator = {
$jsonSchema: {
bsonType: "object",
required: ["runId", "name", "type", "status", "capturedAt"],
properties: {
runId: { bsonType: "string" },
name: { bsonType: "string" },
type: { bsonType: "string" },
status: { bsonType: "string" },
capturedAt: { bsonType: "date" },
sourcePath: { bsonType: ["string", "null"] },
storedPath: { bsonType: ["string", "null"] },
notes: { bsonType: ["string", "null"] },
expression: { bsonType: ["object", "null"] }
}
}
};
const approvalsValidator = {
$jsonSchema: {
bsonType: "object",
required: ["runId", "approvalId", "requestedAt", "status"],
properties: {
runId: { bsonType: "string" },
approvalId: { bsonType: "string" },
requiredGrants: { bsonType: "array", items: { bsonType: "string" } },
stepIds: { bsonType: "array", items: { bsonType: "string" } },
messages: { bsonType: "array", items: { bsonType: "string" } },
reasonTemplate: { bsonType: ["string", "null"] },
requestedAt: { bsonType: "date" },
status: { bsonType: "string" },
actorId: { bsonType: ["string", "null"] },
completedAt: { bsonType: ["date", "null"] },
summary: { bsonType: ["string", "null"] }
}
}
};
ensureCollection("pack_runs", runValidator);
ensureCollection("pack_run_logs", logValidator);
ensureCollection("pack_artifacts", artifactsValidator);
ensureCollection("pack_run_approvals", approvalsValidator);
// Indexes for pack_runs
db.pack_runs.createIndex({ updatedAt: -1 }, { name: "pack_runs_updatedAt_desc" });
db.pack_runs.createIndex({ tenantId: 1, updatedAt: -1 }, { name: "pack_runs_tenant_updatedAt_desc", sparse: true });
// Indexes for pack_run_logs
db.pack_run_logs.createIndex({ runId: 1, sequence: 1 }, { unique: true, name: "pack_run_logs_run_sequence" });
db.pack_run_logs.createIndex({ runId: 1, timestamp: 1 }, { name: "pack_run_logs_run_timestamp" });
// Indexes for pack_artifacts
db.pack_artifacts.createIndex({ runId: 1, name: 1 }, { unique: true, name: "pack_artifacts_run_name" });
db.pack_artifacts.createIndex({ runId: 1 }, { name: "pack_artifacts_run" });
// Indexes for pack_run_approvals
db.pack_run_approvals.createIndex({ runId: 1, approvalId: 1 }, { unique: true, name: "pack_run_approvals_run_approval" });
db.pack_run_approvals.createIndex({ runId: 1, status: 1 }, { name: "pack_run_approvals_run_status" });

View File

@@ -1,15 +0,0 @@
# Deployment & Operations — Agent Charter
## Mission
Maintain deployment/upgrade/rollback workflows (Helm/Compose) per `docs/modules/devops/ARCHITECTURE.md` including environment-specific configs.
## Required Reading
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/airgap/airgap-mode.md`
## Working Agreement
- 1. Update task status to `DOING`/`DONE` inside the corresponding `docs/implplan/SPRINT_*.md` entry when you start or finish work.
- 2. Review this charter and the Required Reading documents before coding; confirm prerequisites are met.
- 3. Keep changes deterministic (stable ordering, timestamps, hashes) and align with offline/air-gap expectations.
- 4. Coordinate doc updates, tests, and cross-guild communication whenever contracts or workflows change.
- 5. Revert to `TODO` if you pause the task without shipping changes; leave notes in commit/PR descriptions for context.

View File

@@ -1,5 +0,0 @@
# Completed Tasks
| ID | Status | Owner(s) | Depends on | Description | Exit Criteria |
|----|--------|----------|------------|-------------|---------------|
| DEVOPS-OPS-14-003 | DONE (2025-10-26) | Deployment Guild | DEVOPS-REL-14-001 | Document and script upgrade/rollback flows, channel management, and compatibility matrices per architecture. | Helm/Compose guides updated with digest pinning, automated checks committed, rollback drill recorded. |

View File

@@ -1,91 +0,0 @@
# Advisory AI Deployment Runbook
## Scope
- Helm and Compose packaging for `advisory-ai-web` (API/plan cache) and `advisory-ai-worker` (inference/queue).
- GPU toggle (NVIDIA) for on-prem inference; defaults remain CPU-safe.
- Offline kit pickup instructions for including advisory AI artefacts.
## Helm
Values already ship in `deploy/helm/stellaops/values-*.yaml` under `services.advisory-ai-web` and `advisory-ai-worker`.
GPU enablement (example):
```yaml
services:
advisory-ai-worker:
runtimeClassName: nvidia
nodeSelector:
nvidia.com/gpu.present: "true"
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
resources:
limits:
nvidia.com/gpu: 1
advisory-ai-web:
runtimeClassName: nvidia
resources:
limits:
nvidia.com/gpu: 1
```
Apply:
```bash
helm upgrade --install stellaops ./deploy/helm/stellaops \
-f deploy/helm/stellaops/values-prod.yaml \
-f deploy/helm/stellaops/values-mirror.yaml \
--set services.advisory-ai-worker.resources.limits.nvidia\.com/gpu=1 \
--set services.advisory-ai-worker.runtimeClassName=nvidia
```
## Compose
- Base profiles: `docker-compose.dev.yaml`, `stage`, `prod`, `airgap` already include advisory AI services and shared volumes.
- GPU overlay: `docker-compose.gpu.yaml` (adds NVIDIA device reservations and `ADVISORY_AI_INFERENCE_GPU=true`). Use:
```bash
docker compose --env-file prod.env \
-f docker-compose.prod.yaml \
-f docker-compose.gpu.yaml up -d
```
## Offline kit pickup
- Ensure advisory AI images are mirrored to your registry (or baked into airgap tar) before running the offline kit build.
- Copy the following into `out/offline-kit/metadata/` before invoking the offline kit script:
- `advisory-ai-web` image tar
- `advisory-ai-worker` image tar
- SBOM/provenance generated by the release pipeline
- Verify `docs/24_OFFLINE_KIT.md` includes the advisory AI entries and rerun `tests/offline/test_build_offline_kit.py` if it changes.
## Runbook (prod quickstart)
1) Prepare secrets in ExternalSecret or Kubernetes secret named `stellaops-prod-core` (see helm values).
2) Run Helm install with prod values and GPU overrides as needed.
3) For Compose, use `prod.env` and optionally `docker-compose.gpu.yaml` overlay.
4) Validate health:
- `GET /healthz` on `advisory-ai-web`
- Check queue directories under `advisory-ai-*` volumes remain writable
- Confirm inference path logs when GPU is detected (log key `advisory.ai.inference.gpu=true`).
## Advisory Feed Packaging (DEVOPS-AIAI-31-002)
Package advisory feeds (SBOM pointers + provenance) for release/offline kit:
```bash
# Production (CI with COSIGN_PRIVATE_KEY_B64 secret)
./ops/deployment/advisory-ai/package-advisory-feeds.sh
# Development (uses tools/cosign/cosign.dev.key)
COSIGN_ALLOW_DEV_KEY=1 COSIGN_PASSWORD=stellaops-dev \
./ops/deployment/advisory-ai/package-advisory-feeds.sh
```
Outputs:
- `out/advisory-ai/feeds/advisory-feeds.tar.gz` - Feed bundle
- `out/advisory-ai/feeds/advisory-feeds.manifest.json` - Manifest with SBOM pointers
- `out/advisory-ai/feeds/advisory-feeds.manifest.dsse.json` - DSSE signed manifest
- `out/advisory-ai/feeds/provenance.json` - Build provenance
CI workflow: `.gitea/workflows/advisory-ai-release.yml`
## Evidence to attach (sprint)
- Helm release output (rendered templates for advisory AI)
- `docker-compose config` with/without GPU overlay
- Offline kit metadata listing advisory AI images + SBOMs
- Advisory feed package manifest with SBOM pointers

View File

@@ -1,165 +0,0 @@
#!/usr/bin/env bash
# Package advisory feeds (SBOM pointers + provenance) for release/offline kit
# Usage: ./package-advisory-feeds.sh
# Dev mode: COSIGN_ALLOW_DEV_KEY=1 COSIGN_PASSWORD=stellaops-dev ./package-advisory-feeds.sh
set -euo pipefail
ROOT=$(cd "$(dirname "$0")/../../.." && pwd)
OUT_DIR="${OUT_DIR:-$ROOT/out/advisory-ai/feeds}"
CREATED="${CREATED:-$(date -u +%Y-%m-%dT%H:%M:%SZ)}"
mkdir -p "$OUT_DIR"
# Key resolution (same pattern as tools/cosign/sign-signals.sh)
resolve_key() {
if [[ -n "${COSIGN_KEY_FILE:-}" && -f "$COSIGN_KEY_FILE" ]]; then
echo "$COSIGN_KEY_FILE"
elif [[ -n "${COSIGN_PRIVATE_KEY_B64:-}" ]]; then
local tmp_key="$OUT_DIR/.cosign.key"
echo "$COSIGN_PRIVATE_KEY_B64" | base64 -d > "$tmp_key"
chmod 600 "$tmp_key"
echo "$tmp_key"
elif [[ -f "$ROOT/tools/cosign/cosign.key" ]]; then
echo "$ROOT/tools/cosign/cosign.key"
elif [[ "${COSIGN_ALLOW_DEV_KEY:-0}" == "1" && -f "$ROOT/tools/cosign/cosign.dev.key" ]]; then
echo "[info] Using development key (non-production)" >&2
echo "$ROOT/tools/cosign/cosign.dev.key"
else
echo "[error] No signing key available. Set COSIGN_PRIVATE_KEY_B64 or COSIGN_ALLOW_DEV_KEY=1" >&2
return 1
fi
}
KEY_FILE=$(resolve_key)
# Collect advisory feed sources
FEED_SOURCES=(
"$ROOT/docs/samples/advisory-feeds"
"$ROOT/src/AdvisoryAI/feeds"
"$ROOT/out/feeds"
)
echo "==> Collecting advisory feeds..."
STAGE_DIR="$OUT_DIR/stage"
mkdir -p "$STAGE_DIR"
for src in "${FEED_SOURCES[@]}"; do
if [[ -d "$src" ]]; then
echo " Adding feeds from $src"
cp -r "$src"/* "$STAGE_DIR/" 2>/dev/null || true
fi
done
# Create placeholder if no feeds found (dev mode)
if [[ -z "$(ls -A "$STAGE_DIR" 2>/dev/null)" ]]; then
echo "[info] No feed sources found; creating placeholder for dev mode"
cat > "$STAGE_DIR/placeholder.json" <<EOF
{
"type": "advisory-feed-placeholder",
"created": "$CREATED",
"note": "Placeholder for development; replace with real feeds in production"
}
EOF
fi
# Create feed bundle
echo "==> Creating feed bundle..."
BUNDLE_TAR="$OUT_DIR/advisory-feeds.tar.gz"
tar -czf "$BUNDLE_TAR" -C "$STAGE_DIR" .
# Compute hashes
sha256() {
sha256sum "$1" | awk '{print $1}'
}
BUNDLE_HASH=$(sha256 "$BUNDLE_TAR")
# Generate manifest with SBOM pointers
echo "==> Generating manifest..."
MANIFEST="$OUT_DIR/advisory-feeds.manifest.json"
cat > "$MANIFEST" <<EOF
{
"schemaVersion": "1.0.0",
"created": "$CREATED",
"bundle": {
"path": "advisory-feeds.tar.gz",
"sha256": "$BUNDLE_HASH",
"size": $(stat -c%s "$BUNDLE_TAR" 2>/dev/null || stat -f%z "$BUNDLE_TAR")
},
"sbom": {
"format": "spdx-json",
"path": "advisory-feeds.sbom.json",
"note": "SBOM generated during CI; pointer only in manifest"
},
"provenance": {
"path": "provenance.json",
"builder": "stellaops-advisory-ai-release"
}
}
EOF
# Sign manifest with DSSE
echo "==> Signing manifest..."
DSSE_OUT="$OUT_DIR/advisory-feeds.manifest.dsse.json"
# Check for cosign
COSIGN="${COSIGN:-$ROOT/tools/cosign/cosign}"
if ! command -v cosign &>/dev/null && [[ ! -x "$COSIGN" ]]; then
echo "[warn] cosign not found; skipping DSSE signing" >&2
else
COSIGN_CMD="${COSIGN:-cosign}"
if command -v cosign &>/dev/null; then
COSIGN_CMD="cosign"
fi
COSIGN_PASSWORD="${COSIGN_PASSWORD:-}" "$COSIGN_CMD" sign-blob \
--key "$KEY_FILE" \
--bundle "$DSSE_OUT" \
--tlog-upload=false \
--yes \
"$MANIFEST" 2>/dev/null || echo "[warn] DSSE signing skipped (cosign error)"
fi
# Generate provenance
echo "==> Generating provenance..."
PROVENANCE="$OUT_DIR/provenance.json"
cat > "$PROVENANCE" <<EOF
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "advisory-feeds.tar.gz",
"digest": {"sha256": "$BUNDLE_HASH"}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://stella-ops.org/advisory-ai-release/v1",
"externalParameters": {},
"internalParameters": {
"created": "$CREATED"
}
},
"runDetails": {
"builder": {
"id": "https://stella-ops.org/advisory-ai-release"
},
"metadata": {
"invocationId": "$(uuidgen 2>/dev/null || echo "dev-$(date +%s)")",
"startedOn": "$CREATED"
}
}
}
}
EOF
# Cleanup temp key
[[ -f "$OUT_DIR/.cosign.key" ]] && rm -f "$OUT_DIR/.cosign.key"
echo "==> Advisory feed packaging complete"
echo " Bundle: $BUNDLE_TAR"
echo " Manifest: $MANIFEST"
echo " DSSE: $DSSE_OUT"
echo " Provenance: $PROVENANCE"

View File

@@ -1,107 +0,0 @@
# StellaOps CLI Release Packaging
## Scope
- Package and publish StellaOps CLI binaries for all supported OS/arch targets with checksums, signatures, completions, and a container image.
- Outputs feed three lanes: (1) public release mirrors, (2) air-gapped/offline kit, (3) internal regression runners.
- Source artefacts come from DevOps pipelines (`.gitea/workflows/cli-build.yml`, `.gitea/workflows/cli-chaos-parity.yml`).
## Inputs (expected layout)
```
out/cli/<version>/
stella-cli-linux-amd64.tar.gz
stella-cli-linux-arm64.tar.gz
stella-cli-darwin-arm64.tar.gz
stella-cli-windows-amd64.zip
completions/
bash/stella
zsh/_stella
fish/stella.fish
parity/
parity-report.json
sbom/
stella-cli.spdx.json
```
`<version>` must match the git tag and container tag (e.g., `2025.12.0`).
## Packaging steps (deterministic)
1) Set version and workdir
```bash
export CLI_VERSION=2025.12.0
export CLI_OUT=out/cli/$CLI_VERSION
```
2) Generate checksums (sorted, LF endings)
```bash
cd "$CLI_OUT"
find . -maxdepth 1 -type f \( -name 'stella-cli-*' -o -name '*.zip' \) \
-print0 | sort -z | xargs -0 sha256sum > SHA256SUMS
```
3) Sign checksum file (cosign keyless or key)
```bash
COSIGN_YES=true cosign sign-blob \
--key env://MIRROR_SIGN_KEY_B64 \
--output-signature SHA256SUMS.sig \
--output-certificate SHA256SUMS.pem \
SHA256SUMS
```
4) Build/push container image (optional if pipeline already produced)
```bash
docker build -t registry.local/stella/cli:$CLI_VERSION -f deploy/compose/cli/Dockerfile .
docker push registry.local/stella/cli:$CLI_VERSION
```
5) Produce offline image tar (for airgap kit)
```bash
docker pull registry.local/stella/cli:$CLI_VERSION
docker save registry.local/stella/cli:$CLI_VERSION \
| gzip -9 > stella-cli-image-$CLI_VERSION.tar.gz
```
6) Bundle completions
```bash
tar -C "$CLI_OUT/completions" -czf stella-cli-completions-$CLI_VERSION.tar.gz .
```
7) Publish artefact manifest (for mirrors/offline kit)
```bash
cat > release-manifest-$CLI_VERSION.json <<'EOF'
{
"version": "REPLACE_VERSION",
"binaries": [
"stella-cli-linux-amd64.tar.gz",
"stella-cli-linux-arm64.tar.gz",
"stella-cli-darwin-arm64.tar.gz",
"stella-cli-windows-amd64.zip"
],
"completions": "stella-cli-completions-REPLACE_VERSION.tar.gz",
"checksums": "SHA256SUMS",
"signatures": ["SHA256SUMS.sig", "SHA256SUMS.pem"],
"container": {
"image": "registry.local/stella/cli:REPLACE_VERSION",
"offline_tar": "stella-cli-image-REPLACE_VERSION.tar.gz"
}
}
EOF
sed -i "s/REPLACE_VERSION/$CLI_VERSION/g" release-manifest-$CLI_VERSION.json
```
## Distribution lanes
- **Mirror / public:** upload binaries, completions, SBOM, `SHA256SUMS*`, and `release-manifest-<version>.json` to the mirror bucket; expose via CDN.
- **Offline kit:** copy the same files plus `stella-cli-image-<version>.tar.gz` into `out/offline-kit/cli/` before running `ops/offline-kit/scripts/build_offline_kit.sh`.
- **Internal runners:** sync `SHA256SUMS` and `SHA256SUMS.sig` to the runner cache; store container tar in the runner image cache path.
## Verification
```bash
cd "$CLI_OUT"
sha256sum --check SHA256SUMS
cosign verify-blob --key env://MIRROR_SIGN_KEY_B64 --signature SHA256SUMS.sig --certificate SHA256SUMS.pem SHA256SUMS
```
## Rollback / re-spin
- To revoke a bad drop, delete the mirror path for that version and reissue `release-manifest-<version>.json` with `"revoked": true` field; keep signatures for audit.
- Re-spin by rerunning steps with a new version tag; never overwrite artefacts in-place.
## Evidence to attach in sprint
- `SHA256SUMS`, `SHA256SUMS.sig`, `release-manifest-<version>.json`, and offline image tar path uploaded to sprint evidence locker.

View File

@@ -1,35 +0,0 @@
# Export Center Helm Overlays (DEPLOY-EXPORT-35-001)
## Values files (download-only)
- `deploy/helm/stellaops/values-export.yaml` (add) with:
- `exportcenter:`
- `image.repository`: `registry.stella-ops.org/export-center`
- `image.tag`: set via pipeline
- `objectStorage.endpoint`: `http://minio:9000`
- `objectStorage.bucket`: `export-prod`
- `objectStorage.accessKeySecret`: `exportcenter-minio`
- `objectStorage.secretKeySecret`: `exportcenter-minio`
- `signing.kmsKey`: `exportcenter-kms`
- `signing.kmsRegion`: `us-east-1`
- `dsse.enabled`: true
## Secrets
- KMS signing: create secret `exportcenter-kms` with JSON key material (KMS provider specific). Example: `ops/deployment/export/secrets-example.yaml`.
- MinIO creds: `exportcenter-minio` with `accesskey`, `secretkey` keys (see example manifest).
## Rollout
- `helm upgrade --install export-center deploy/helm/stellaops -f deploy/helm/stellaops/values-export.yaml --set image.tag=$TAG`
- Pre-flight: `helm template ...` and `helm lint`.
- Post: verify readiness `kubectl rollout status deploy/export-center` and run `curl /healthz`.
## Rollback
- `helm rollback export-center <rev>`; ensure previous tag exists.
## Required artefacts
- Signed images + provenance (from release pipeline).
- SBOM attached via registry (cosign attestations acceptable).
## Acceptance
- Overlay renders without missing values.
- Secrets documented and referenced in template.
- Rollout/rollback steps documented.

View File

@@ -1,15 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: exportcenter-minio
stringData:
accesskey: REPLACE_ME
secretkey: REPLACE_ME
---
apiVersion: v1
kind: Secret
metadata:
name: exportcenter-kms
stringData:
key.json: |
{"kmsProvider":"awskms","keyId":"arn:aws:kms:...","region":"us-east-1"}

View File

@@ -1,28 +0,0 @@
# Notifier Helm Overlays (DEPLOY-NOTIFY-38-001)
## Values file
- `deploy/helm/stellaops/values-notify.yaml` (added) with:
- `notify:`
- `image.repository`: `registry.stella-ops.org/notify`
- `image.tag`: set by pipeline
- `smtp.host`, `smtp.port`, `smtp.usernameSecret`, `smtp.passwordSecret`
- `webhook.allowedHosts`: list
- `chat.webhookSecret`: secret name for chat tokens
- `tls.secretName`: optional ingress cert
## Secrets
- SMTP creds secret `notify-smtp` with keys `username`, `password` (see `ops/deployment/notify/secrets-example.yaml`).
- Chat/webhook secret `notify-chat` with key `token` (see example manifest).
## Rollout
- `helm upgrade --install notify deploy/helm/stellaops -f deploy/helm/stellaops/values-notify.yaml --set image.tag=$TAG`
- Pre-flight: `helm lint`, `helm template`.
- Post: `kubectl rollout status deploy/notify` and `curl /healthz`.
## Rollback
- `helm rollback notify <rev>`; confirm previous image tag exists.
## Acceptance
- Overlay renders without missing values.
- Secrets documented and referenced.
- Rollout/rollback steps documented.

View File

@@ -1,14 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: notify-smtp
stringData:
username: REPLACE_ME
password: REPLACE_ME
---
apiVersion: v1
kind: Secret
metadata:
name: notify-chat
stringData:
token: REPLACE_ME

View File

@@ -1,76 +0,0 @@
# Docker hardening blueprint (DOCKER-44-001)
Use this template for core services (API, Console, Orchestrator, Task Runner, Concelier, Excititor, Policy, Notify, Export, AdvisoryAI).
The reusable multi-stage scaffold lives at `ops/devops/docker/Dockerfile.hardened.template` and expects:
- .NET 10 SDK/runtime images provided via offline mirror (`SDK_IMAGE` / `RUNTIME_IMAGE`).
- `APP_PROJECT` path to the service csproj.
- `healthcheck.sh` copied from `ops/devops/docker/` (already referenced by the template).
- Optional: `APP_BINARY` (assembly name, defaults to `StellaOps.Service`) and `APP_PORT`.
Copy the template next to the service and set build args in CI (per-service matrix) to avoid maintaining divergent Dockerfiles.
```Dockerfile
# syntax=docker/dockerfile:1.7
ARG SDK_IMAGE=mcr.microsoft.com/dotnet/sdk:10.0-bookworm-slim
ARG RUNTIME_IMAGE=mcr.microsoft.com/dotnet/aspnet:10.0-bookworm-slim
ARG APP_PROJECT=src/Service/Service.csproj
ARG CONFIGURATION=Release
ARG APP_USER=stella
ARG APP_UID=10001
ARG APP_GID=10001
ARG APP_PORT=8080
FROM ${SDK_IMAGE} AS build
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1 SOURCE_DATE_EPOCH=1704067200
WORKDIR /src
COPY . .
RUN dotnet restore ${APP_PROJECT} --packages /.nuget/packages && \
dotnet publish ${APP_PROJECT} -c ${CONFIGURATION} -o /app/publish /p:UseAppHost=true /p:PublishTrimmed=false
FROM ${RUNTIME_IMAGE} AS runtime
RUN groupadd -r -g ${APP_GID} ${APP_USER} && \
useradd -r -u ${APP_UID} -g ${APP_GID} -d /var/lib/${APP_USER} ${APP_USER}
WORKDIR /app
COPY --from=build --chown=${APP_UID}:${APP_GID} /app/publish/ ./
COPY --chown=${APP_UID}:${APP_GID} ops/devops/docker/healthcheck.sh /usr/local/bin/healthcheck.sh
ENV ASPNETCORE_URLS=http://+:${APP_PORT} \
DOTNET_EnableDiagnostics=0 \
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 \
COMPlus_EnableDiagnostics=0
USER ${APP_UID}:${APP_GID}
EXPOSE ${APP_PORT}
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 CMD /usr/local/bin/healthcheck.sh
RUN chmod 500 /app && find /app -maxdepth 1 -type f -exec chmod 400 {} \; && find /app -maxdepth 1 -type d -exec chmod 500 {} \;
ENTRYPOINT ["sh","-c","exec ./\"$APP_BINARY\""]
```
Build stage (per service) should:
- Use `mcr.microsoft.com/dotnet/sdk:10.0-bookworm-slim` (or mirror) with `DOTNET_CLI_TELEMETRY_OPTOUT=1`.
- Restore from `/.nuget/` (offline) and run `dotnet publish -c Release -o /app/out`.
- Set `SOURCE_DATE_EPOCH` to freeze timestamps.
Required checks:
- No `root` user in final image.
- `CAP_NET_RAW` dropped (default with non-root).
- Read-only rootfs enforced at deploy time (`securityContext.readOnlyRootFilesystem: true` in Helm/Compose).
- Health endpoints exposed: `/health/liveness`, `/health/readiness`, `/version`, `/metrics`.
- Image SBOM generated (syft) in pipeline; attach cosign attestations (see DOCKER-44-002).
Service matrix & helper:
- Build args for the core services are enumerated in `ops/devops/docker/services-matrix.env` (API, Console, Orchestrator, Task Runner, Concelier, Excititor, Policy, Notify, Export, AdvisoryAI).
- `ops/devops/docker/build-all.sh` reads the matrix and builds/tag images from the shared template with consistent non-root/health defaults. Override `REGISTRY` and `TAG_SUFFIX` to publish.
Console (Angular) image:
- Use `ops/devops/docker/Dockerfile.console` for the UI (Angular v17). It builds with `node:20-bullseye-slim`, serves via `nginxinc/nginx-unprivileged`, includes `healthcheck-frontend.sh`, and runs as non-root UID 101. Build with `docker build -f ops/devops/docker/Dockerfile.console --build-arg APP_DIR=src/Web/StellaOps.Web .`.
SBOM & attestation helper (DOCKER-44-002):
- Script: `ops/devops/docker/sbom_attest.sh <image> [out-dir] [cosign-key]`
- Emits SPDX (`*.spdx.json`) and CycloneDX (`*.cdx.json`) with `SOURCE_DATE_EPOCH` pinned for reproducibility.
- Attaches both as cosign attestations (`--type spdx` / `--type cyclonedx`); supports keyless when `COSIGN_EXPERIMENTAL=1` or explicit PEM key.
- Integrate in CI after image build/push; keep registry creds offline-friendly (use local registry mirror during air-gapped builds).
Health endpoint verification (DOCKER-44-003):
- Script: `ops/devops/docker/verify_health_endpoints.sh <image> [port]` spins container, checks `/health/liveness`, `/health/readiness`, `/version`, `/metrics`, and warns if `/capabilities.merge` is not `false` (for Concelier/Excititor).
- Run in CI after publishing the image; requires `docker` and `curl` (or `wget`).
- Endpoint contract and ASP.NET wiring examples live in `ops/devops/docker/health-endpoints.md`; service owners should copy the snippet and ensure readiness checks cover DB/cache/bus.

Some files were not shown because too many files have changed in this diff Show More