Integration Catalog Architecture
Audience: engineers integrating Stella Ops with external registries, SCM, CI, runtime hosts, and feeds — plus operators configuring those connections. Module: Integrations (
src/Integrations/StellaOps.Integrations.WebService) Sprint: SPRINT_20251229_010_PLATFORM_integration_catalog_core Last Updated: 2025-12-30
Overview
The Integration Catalog is the centralized registry for managing external integrations in Stella Ops. It provides a unified API for configuring, testing, and monitoring connections to container registries, SCM providers, CI systems, runtime hosts, and feed sources.
Architecture Note: Integration Catalog is a dedicated service (src/Integrations), NOT part of Gateway. Gateway handles HTTP ingress/routing only. Integration domain logic, plugins, and persistence live in the Integrations module.
Directory Structure
src/Integrations/
├── StellaOps.Integrations.WebService/ # ASP.NET Core host
├── __Libraries/
│ ├── StellaOps.Integrations.Core/ # Domain models, enums, events
│ ├── StellaOps.Integrations.Contracts/ # Plugin contracts and DTOs
│ └── StellaOps.Integrations.Persistence/ # PostgreSQL repositories
└── __Plugins/
├── StellaOps.Integrations.Plugin.GitHubApp/
├── StellaOps.Integrations.Plugin.Harbor/
└── StellaOps.Integrations.Plugin.InMemory/
Plugin Architecture
Each integration provider is implemented as a plugin that implements IIntegrationConnectorPlugin:
public interface IIntegrationConnectorPlugin : IAvailabilityPlugin
{
IntegrationType Type { get; }
IntegrationProvider Provider { get; }
Task<TestConnectionResult> TestConnectionAsync(IntegrationConfig config, CancellationToken ct);
Task<HealthCheckResult> CheckHealthAsync(IntegrationConfig config, CancellationToken ct);
}
Plugins are loaded at startup from:
- The configured
PluginsDirectory(default:plugins/) - The WebService assembly (for built-in plugins)
Integration Types
| Type | Description | Examples |
|---|---|---|
| Registry | Container image registries | Docker Hub, Harbor, ECR, ACR, GCR, GHCR, Quay, Artifactory |
| SCM | Source code management | GitHub, GitLab, Gitea, Bitbucket, Azure DevOps |
| CI | Continuous integration | GitHub Actions, GitLab CI, Gitea Actions, Jenkins, CircleCI |
| Host | Runtime observation | Zastava (eBPF, ETW, dyld probes) |
| Feed | Vulnerability feeds | Concelier, Excititor mirrors |
| Artifact | SBOM/VEX uploads | Direct artifact submission |
Entity Schema
public sealed class Integration
{
// Identity
public Guid IntegrationId { get; init; }
public string TenantId { get; init; }
public string Name { get; init; }
public string? Description { get; set; }
// Classification
public IntegrationType Type { get; init; }
public IntegrationProvider Provider { get; init; }
// Configuration
public string? BaseUrl { get; set; }
public string? AuthRef { get; set; } // Never raw secrets
public JsonDocument Configuration { get; set; }
// Organization
public string? Environment { get; set; } // prod, staging, dev
public string? Tags { get; set; }
public string? OwnerId { get; set; }
// Lifecycle
public IntegrationStatus Status { get; private set; }
public bool Paused { get; private set; }
public string? PauseReason { get; private set; }
// Health
public DateTimeOffset? LastTestedAt { get; private set; }
public bool? LastTestSuccess { get; private set; }
public int ConsecutiveFailures { get; private set; }
// Audit
public DateTimeOffset CreatedAt { get; init; }
public string CreatedBy { get; init; }
public DateTimeOffset? ModifiedAt { get; private set; }
public string? ModifiedBy { get; private set; }
public int Version { get; private set; }
}
Lifecycle States
┌─────────┐
│ Draft │ ──── SubmitForVerification() ────►
└─────────┘
│
▼
┌───────────────────┐
│ PendingVerification│ ──── Test Success ────►
└───────────────────┘
│
▼
┌──────────┐
│ Active │ ◄──── Resume() ────┐
└──────────┘ │
│ │
Consecutive ┌─────────┐
Failures ≥ 3 │ Paused │
│ └─────────┘
▼ ▲
┌───────────┐ │
│ Degraded │ ──── Pause() ───────┘
└───────────┘
│
Failures ≥ 5
│
▼
┌──────────┐
│ Failed │
└──────────┘
API Endpoints
Base path: /api/v1/integrations
| Method | Path | Scope | Description |
|---|---|---|---|
| GET | / | integrations.read | List integrations with filtering |
| GET | /{id} | integrations.read | Get integration by ID |
| POST | / | integrations.admin | Create integration |
| PUT | /{id} | integrations.admin | Update integration |
| DELETE | /{id} | integrations.admin | Delete integration |
| POST | /{id}/test | integrations.admin | Test connection |
| POST | /{id}/pause | integrations.admin | Pause integration |
| POST | /{id}/resume | integrations.admin | Resume integration |
| POST | /{id}/activate | integrations.admin | Activate integration |
| GET | /{id}/health | integrations.read | Get health status |
AuthRef Pattern
Critical: The Integration Catalog never stores raw credentials. All secrets are referenced via AuthRef strings that point to Authority’s secret store.
AuthRef format: ref://<scope>/<provider>/<key>
Example: ref://integrations/github/acme-org-token
The AuthRef is resolved at runtime when making API calls to the integration provider. This ensures:
- Secrets are stored centrally with proper encryption
- Secret rotation doesn’t require integration updates
- Audit trails track secret access separately
- Offline bundles can use different AuthRefs
Event Pipeline
Integration lifecycle events are published for consumption by Scheduler and Orchestrator:
| Event | Trigger | Consumers |
|---|---|---|
integration.created | New integration | Scheduler (schedule health checks) |
integration.updated | Configuration change | Scheduler (reschedule) |
integration.deleted | Integration removed | Scheduler (cancel jobs) |
integration.paused | Operator paused | Orchestrator (pause jobs) |
integration.resumed | Operator resumed | Orchestrator (resume jobs) |
integration.healthy | Test passed | Signals (status update) |
integration.unhealthy | Test failed | Signals, Notify (alert) |
Audit Trail
All integration actions are logged:
- Create/Update/Delete with actor and timestamp
- Connection tests with success/failure
- Pause/Resume with reason and ticket reference
- Activate with approver
Audit logs are stored in the append-only audit store for compliance.
Determinism & Offline
- Integration lists are ordered deterministically by name
- Timestamps are UTC ISO-8601
- Pagination uses stable cursor semantics
- Health polling respects offline mode (skip network checks)
- Feed integrations support allowlists for air-gap environments
RBAC Scopes
| Scope | Permission |
|---|---|
integrations.read | View integrations and health |
integrations.admin | Create, update, delete, test, pause, resume |
Future Extensions
- Provider-specific testers: HTTP health checks, registry auth validation, SCM webhook verification.
- PostgreSQL persistence: Replace the in-memory repository for production deployments.
- Messaging events: Publish lifecycle events to Valkey Streams (or NATS JetStream where configured) instead of the current no-op sink.
- Health history: Track uptime percentage and latency over time.
- Bulk operations: Import/export integrations for environment promotion.
References
- Infrastructure dependencies — the Valkey/NATS messaging substrate that backs the event pipeline.
- Console Admin RBAC — the broader Authority scope and role taxonomy that
integrations.read/integrations.adminsit within. - Data flows — how integration-sourced data (registries, feeds, runtime signals) feeds the scan and policy pipelines.
