- Introduced DigestUpsertRequest for handling digest upsert requests with properties like ChannelId, Recipient, DigestKey, Events, and CollectUntil. - Created LockEntity to represent a lightweight distributed lock entry with properties such as Id, TenantId, Resource, Owner, ExpiresAt, and CreatedAt. feat: Implement ILockRepository interface and LockRepository class - Defined ILockRepository interface with methods for acquiring and releasing locks. - Implemented LockRepository class with methods to try acquiring a lock and releasing it, using SQL for upsert operations. feat: Add SurfaceManifestPointer record for manifest pointers - Introduced SurfaceManifestPointer to represent a minimal pointer to a Surface.FS manifest associated with an image digest. feat: Create PolicySimulationInputLock and related validation logic - Added PolicySimulationInputLock record to describe policy simulation inputs and expected digests. - Implemented validation logic for policy simulation inputs, including checks for digest drift and shadow mode requirements. test: Add unit tests for ReplayVerificationService and ReplayVerifier - Created ReplayVerificationServiceTests to validate the behavior of the ReplayVerificationService under various scenarios. - Developed ReplayVerifierTests to ensure the correctness of the ReplayVerifier logic. test: Implement PolicySimulationInputLockValidatorTests - Added tests for PolicySimulationInputLockValidator to verify the validation logic against expected inputs and conditions. chore: Add cosign key example and signing scripts - Included a placeholder cosign key example for development purposes. - Added a script for signing Signals artifacts using cosign with support for both v2 and v3. chore: Create script for uploading evidence to the evidence locker - Developed a script to upload evidence to the evidence locker, ensuring required environment variables are set.
Deployment Profiles
This directory contains deterministic deployment bundles for the core Stella Ops stack. All manifests reference immutable image digests and map 1:1 to the release manifests stored under deploy/releases/.
Structure
releases/– canonical release manifests (edge, stable, airgap) used to source image digests.compose/– Docker Compose bundles for dev/stage/airgap targets plus.envseed files.compose/docker-compose.mirror.yaml– managed mirror bundle for*.stella-ops.orgwith gateway cache and multi-tenant auth.compose/docker-compose.telemetry.yaml– optional OpenTelemetry collector overlay (mutual TLS, OTLP pipelines).compose/docker-compose.telemetry-storage.yaml– optional Prometheus/Tempo/Loki stack for observability backends.helm/stellaops/– multi-profile Helm chart with values files for dev/stage/airgap.telemetry/– shared OpenTelemetry collector configuration and certificate artefacts (generated via tooling).tools/validate-profiles.sh– helper that runsdocker compose configandhelm lint/templatefor every profile.
Workflow
- Update or add a release manifest under
releases/with the new digests. - Mirror the digests into the Compose and Helm profiles that correspond to that channel.
- Run
deploy/tools/validate-profiles.sh(requires Docker CLI and Helm) to ensure the bundles lint and template cleanly. - If telemetry ingest is required for the release, generate development certificates using
./ops/devops/telemetry/generate_dev_tls.shand run the collector smoke test withpython ./ops/devops/telemetry/smoke_otel_collector.pyto verify the OTLP endpoints. - Commit the change alongside any documentation updates (e.g. install guide cross-links).
Maintaining the digest linkage keeps offline/air-gapped installs reproducible and avoids tag drift between environments.
Surface.Env rollout warnings
- Compose (
deploy/compose/env/*.env.example) and Helm (deploy/helm/stellaops/values-*.yaml) now seedSCANNER_SURFACE_*andZASTAVA_SURFACE_*variables so Scanner Worker/WebService and Zastava Observer/Webhook resolve cache roots, Surface.FS endpoints, and secrets providers throughStellaOps.Scanner.Surface.Env. - During rollout, watch for structured log messages (and readiness output) prefixed with
surface.env.—for example,surface.env.cache_root_missing,surface.env.endpoint_unreachable, orsurface.env.secrets_provider_invalid. - Treat these warnings as deployment blockers: update the endpoint/cache/secrets values or permissions before promoting the environment, otherwise workers will fail fast at startup.
- Air-gapped bundles default the secrets provider to
filewith/etc/stellaops/secrets; connected clusters default tokubernetes. Adjust the provider/root pair if your secrets manager differs. - Secret provisioning workflows for Kubernetes/Compose/Offline Kit are documented in
ops/devops/secrets/surface-secrets-provisioning.md; follow that forSurface.Secretshandles and RBAC/permissions.
Mongo2Go OpenSSL prerequisites
- Linux runners that execute Mongo2Go-backed suites (Excititor, Scheduler, Graph, etc.) must expose OpenSSL 1.1 (
libcrypto.so.1.1,libssl.so.1.1). The canonical copies live undertests/native/openssl-1.1/linux-x64. - Export
LD_LIBRARY_PATH="$(git rev-parse --show-toplevel)/tests/native/openssl-1.1/linux-x64:${LD_LIBRARY_PATH:-}"before invokingdotnet test. Example:
LD_LIBRARY_PATH="$(pwd)/tests/native/openssl-1.1/linux-x64" dotnet test src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/StellaOps.Excititor.WebService.Tests.csproj --nologo. - CI agents or Dockerfiles that host these tests should either mount the directory into the container or copy the two
.sofiles into a directory that is already on the runtime library path.
Additional tooling
deploy/tools/check-channel-alignment.py– verifies that Helm/Compose profiles reference the exact images listed in a release manifest. Run it for each channel before promoting a release.ops/devops/telemetry/generate_dev_tls.sh– produces local CA/server/client certificates for Compose-based collector testing.ops/devops/telemetry/smoke_otel_collector.py– sends OTLP traffic and asserts the collector accepted traces, metrics, and logs.ops/devops/telemetry/package_offline_bundle.py– packages telemetry assets (config/Helm/Compose) into a signed tarball for air-gapped installs.docs/modules/devops/runbooks/deployment-upgrade.md– end-to-end instructions for upgrade, rollback, and channel promotion workflows (Helm + Compose).
CI smoke checks
The .gitea/workflows/build-test-deploy.yml pipeline includes a notify-smoke stage that validates scanner event propagation after staging deployments. Configure the following repository secrets (or environment-level secrets) so the job can connect to Redis and the Notify API:
NOTIFY_SMOKE_REDIS_DSN– Redis connection string (redis://user:pass@host:port/db).NOTIFY_SMOKE_NOTIFY_BASEURL– Base URL for the staging Notify WebService (e.g.https://notify.stage.stella-ops.internal).NOTIFY_SMOKE_NOTIFY_TOKEN– OAuth bearer token (service account) with permission to read deliveries.NOTIFY_SMOKE_NOTIFY_TENANT– Tenant identifier used for the smoke validation requests.- (Optional)
NOTIFY_SMOKE_NOTIFY_TENANT_HEADER– Override for the tenant header name (defaults toX-StellaOps-Tenant).
Define the following repository variables (or secrets) to drive the assertions performed by the smoke check:
NOTIFY_SMOKE_EXPECT_KINDS– Comma-separated event kinds the checker must observe (for examplescanner.report.ready,scanner.scan.completed).NOTIFY_SMOKE_LOOKBACK_MINUTES– Time window (in minutes) used when scanning the Redis stream for recent events (for example30).
All of the above values are required—the workflow fails fast with a descriptive error if any are missing or empty. Provide the variables at the organisation or repository scope before enabling the smoke stage.