Integrations
The Integrations module is the central catalog and connector hub for managing external-tool integrations across the Stella Ops platform. It is the reference for operators registering connectors and for engineers consuming the integration catalog from other modules.
Purpose
Integrations provides a unified API for registering, configuring, and health-checking third-party service connectors such as GitHub, GitLab, and Harbor. It is the single source of truth for all external-tool configurations, letting other modules discover and consume integration details without embedding provider-specific logic.
Quick Links
- Architecture - Technical design and implementation details
- API Reference - Endpoint and DTO reference
Status
| Attribute | Value |
|---|---|
| Maturity | Production |
| Source | src/Integrations/ |
Quarantined surfaces (not shippable in this release)
Two SCM-feedback surfaces are built but quarantined per PLAN_20260704 findings A4/A5 and decision D3 (quarantine, not delete) — they are preserved for a future SCM-feedback initiative but are not wired and must not be presented as available:
- Commit-/PR-time webhook scanning (
StellaOps.Scanner.Sourcestriggers). The scanner webhook endpoints return a deterministic501 source_scan_not_availablebecause the dispatcher’sIScanJobQueuehas no production registration. - Outbound SCM annotations / SARIF push —
GitHubAppAnnotationClient/GitLabAnnotationClient(markedinternal) and thestella githubCLI verbs, which exit with a cleannot available in this releaseerror (noIGitHubCodeScanningClientis DI-registered).
The sanctioned scan ingress and feedback path is CLI-in-CI: emit SBOM/SARIF with the scanner (stella sbom generate / stella sbom attach, stella scan image --format sarif) in your pipeline and upload with the platform’s own action (e.g. github/codeql-action/upload-sarif).
Key Features
- Plugin-based connector architecture: Extensible provider system whose host-compiled connector set is now limited to host-local S3-compatible object storage and feed mirrors. GitHub App, GitLab, Gitea, Harbor, Docker Registry / GitLab Container Registry, Jenkins, Nexus, Vault, Consul, and the eBPF Agent are no longer compiled into
StellaOps.Integrations.WebService; they require signed/profile-mounted connector bundles before they appear in provider discovery. TheIntegrationProviderenum additionally declares providers without bespoke plugins yet (ECR, GCR, ACR, Docker Hub, Quay, Artifactory, Bitbucket, Azure DevOps, CI/CD systems, package-repo sources, symbol/feed mirrors, and a genericCustomprovider). The in-memory double (InMemoryprovider) stays in explicit test harnesses. - Fail-closed external plugin admission: Directory-loaded connector DLLs are disabled by default and must pass configured signature verification before they are considered. Production also requires a healthy
stellaops.pluginhost.process.v1runner handshake plus fail-closed operation IPC. Signed process-backed connectors can execute allowlistedintegration:test-connection,integration:health-check, andintegration:discoveryoperations in a child runner; authref-backed operations use a one-use named-pipe secret broker so the generic IPC carries only opaque handles. Dead runner paths return deterministic lifecycle evidence, and broader execution still waits on long-lived supervision, platform hard resource controls, process-tree accounting, and broker channel peer-identity hardening. - Signed connector bundle manifests: Optional connector payloads can be mounted as directory bundles containing
stellaops.integration-plugin.json. The manifest declaresid,version, relativeassembly, provider/type aliases, capability ids (integration:test-connection,integration:health-check,integration:discovery, andintegration:credential-materializationwhen brokered authref materialization is needed), detached signature metadata, trust-root labels, and profile membership. - Cloud registry token exchange (in-connector, offline-first): The Docker Registry connector bundle performs the provider-native credential exchange for the AWS ECR, Google Artifact Registry / GCR, and Azure Container Registry descriptors before authenticating against the OCI
/v2/surface. ECR SigV4-signs aGetAuthorizationTokenrequest from a raw IAM key pair; GCR mints an RS256 service-account JWT bearer grant; ACR runs an AAD client-credentials +/oauth2/exchangeround-trip. All signing is BCL-only (System.Security.Cryptography— no AWS/Google/Azure SDK is referenced, preserving the air-gap and supply-chain posture). Every exchange endpoint is overridable through the integration’sExtendedConfig(ecrTokenEndpoint/awsRegion,gcpTokenEndpoint,aadAuthority/azureTenantId/azureScope) so the exchange works air-gapped and can be pointed at a private STS/token mirror; pre-exchanged credentials (AWS:<pwd>,oauth2accesstoken:<token>,00000000-…:<rt>) and non-cloud descriptors pass through unchanged. A failed exchange surfaces as a failed test/health/discover — never a silent anonymous fall-through. The forwardable (non-secret)ExtendedConfigendpoint keys are propagated to the process-isolated runner so overrides apply under process isolation. Implementation:StellaOps.Integrations.Plugin.DockerRegistry.CloudRegistryTokenExchange. - Health checks: Per-integration health probing with durable latest-status tracking
- Explicit credential backends: Every integration declares its credential backend explicitly —
inline(Stella-managed AEAD-sealed ciphertext),authref(URI reference to an external vault), ornone(anonymous integration). The legacynone + non-null auth_ref_uriback-compat shape was dropped in Sprint 032; registration rejects it with HTTP 400 and the DB enforces the canonical shape via a CHECK constraint. See architecture.md for the resolution model and the canonical operator workflow (devops/agents-targets/scripts/customer-onboarding/01b-register-inline-integrations.sh). - Tenant isolation: All integrations are scoped to a tenant; cross-tenant access is prohibited
- AiCodeGuard pipeline support: Integrations participate in AI-assisted code review pipelines
- Plugin discovery: Automatic detection and registration of available connector plugins
API Surface
All catalog endpoints are mounted under /api/v1/integrations, require a valid tenant (RequireTenant()), and are authorized by the integration scopes below. (Grounded in IntegrationEndpoints.MapIntegrationEndpoints.)
| Method | Route | Scope | Purpose |
|---|---|---|---|
GET | /api/v1/integrations | integration:read | List integrations (filter by type/provider/status/search; paged, sortable) |
GET | /api/v1/integrations/{id} | integration:read | Get integration by id |
POST | /api/v1/integrations | integration:write | Create integration |
PUT | /api/v1/integrations/{id} | integration:write | Update integration |
DELETE | /api/v1/integrations/{id} | integration:write | Soft-delete integration |
POST | /api/v1/integrations/{id}/test | integration:operate | Test connection (audited) |
POST | /api/v1/integrations/{id}/resolve-credentials | integration:operate | Resolve an AEAD-sealed credential envelope for trusted in-cluster callers (audited; plaintext is never returned or logged) |
POST | /api/v1/integrations/{id}/discover | integration:operate | Discover provider resources (audited) |
GET | /api/v1/integrations/{id}/health | integration:read | Latest durable health status |
GET | /api/v1/integrations/{id}/impact | integration:read | Impact map |
GET | /api/v1/integrations/providers | integration:read | Supported providers (includeTestOnly opt-in) |
POST | /api/v1/integrations/ai-code-guard/run | integration:operate | Standalone AI Code Guard run (deterministic secret/attribution/license scan) |
Adjacent route groups:
- Secret Authority (
/api/v1/secret-authority) —GET /targets(integration:read) lists secrets-manager integrations that can stage authref bundles;PUT /bundles/{bundleId}(integration:write) writes a credential bundle and returns authref bindings. - Internal crypto re-seal (
/internal/crypto/...) — installation-wide KEK rotation endpoints fanned out by Platform. Population/progress reads require an authenticated principal withcrypto:kek:read,crypto:kek:rotate, orops.admin; start/abort require an authenticated principal withcrypto:kek:rotateorops.admin. Platform forwards a validated operator Bearer token or relays the gateway-signed identity envelope after local verification, and Integrations verifies/re-authorizes it. Network bypass alone cannot satisfy these policies. The default internal HTTP transport is not mTLS; certificate-bound transport remains pending and must not be inferred from the/internalpath. - Health probes —
GET /health,/health/liveness,/health/readiness(anonymous, for the Router gateway and orchestrator).
The Integrations service does not currently host any background workers.
Dependencies
Upstream (this module depends on)
- Authority - Authentication and authorization for API access
- Plugin Framework - Plugin lifecycle and discovery infrastructure
Downstream (modules that depend on this)
Cross-module consumers do not read the Integrations database directly. They depend only on StellaOps.Integrations.Contracts and resolve entries through the read-only IIntegrationCatalog seam, whose HTTP implementation calls GET /api/v1/integrations/{id} with the caller’s bearer (tenant resolved from the stellaops:tenant claim, integration:read enforced). When no base address is configured, each consumer falls back to a fail-closed NullIntegrationCatalog.
- Scanner - SCM bulk import resolves SCM integrations via
HttpIntegrationCatalog(registered whenScanner:Integrations:BaseAddressis set). - Release Orchestrator - Registry version sync and deployment-bundle registry credentials resolve registry integrations via
HttpIntegrationCatalog(registered whenReleaseOrchestrator:Integrations:BaseAddressis set).
Note: as of the source reviewed,
Signals(SCM webhooks) and the Job Engine / Orchestrator do not consume the Integrations catalog seam. Earlier drafts listing them as downstream consumers were inaccurate.
Configuration
Key settings (grounded in Program.cs):
- PostgreSQL connection:
ConnectionStrings:IntegrationsDb(falls back toConnectionStrings:Default, thenHost=localhost;Database=stellaops_integrations;...). Schema isintegrations; EF Core auto-migrates on startup viaAddStartupMigrations(SQL migration files are authoritative). - Authority resource-server authentication (
AddStellaOpsResourceServerAuthentication). - Plugin discovery directory:
Integrations:PluginsDirectory(defaults to<baseDir>/plugins); external directory plugins are gated by theIntegrations:PluginAdmissionoptions (IntegrationPluginAdmissionOptions). - Profile-mounted connector bundle roots:
Integrations:PluginProfileRootsis an ordered set of optional directories. Each existing root is loaded in deterministic path order; the root directory name must appear in each bundle manifest’sprofiles[]membership. - Inline credential master KEK:
Integrations:SecretProtectionKey→Platform:Setup:SecretProtectionKey→STELLAOPS_SECRETS_ENCRYPTION_KEY→STELLAOPS_BOOTSTRAP_KEY(AEADaadPrefixintegration-cred,kdfLabelstellaops-integration-credentials-v1). - Vault AuthRef resolver address:
VAULT_ADDR(defaults tohttp://vault.stella-ops.local:8200). - External connector pagination / API-version options are owned by their signed bundles and mounted profile configuration under
devops/etc/plugins/integrations/. The WebService still owns the shared resilient-HTTP pipeline (retry-with-jitter + circuit breaker + timeout) and host-local connector defaults.
Current packaged connector profiles:
recommended: Vault, Harbor, GitHubApp, DockerRegistry / GitLab Container Registry.harness: InMemory test connector only.integrations-scm-ci: Gitea, Jenkins, Nexus, and GitLab Server / GitLab CI.secrets-optional: Consul.runtime-host: eBPF Agent.
The recommended overlay intentionally leaves Integrations:PluginsDirectory empty and uses Integrations:PluginProfileRoots for the recommended root; base mirror/storage connectors remain host-owned in this migration slice.
Scopes (Authority)
The service registers exactly three integration scopes (StellaOpsScopes):
integration:read— list/get/health/impact/providers, and the Secret Authority read surface.integration:write— create/update/delete, and Secret Authority bundle staging.integration:operate— test-connection, resolve-credentials, discovery, and AI Code Guard runs.
IDE Extensions (VS Code, JetBrains)
As of Sprint 214, the IDE extension plugins (previously src/Extensions/) are housed under src/Integrations/__Extensions/. These are non-.NET projects (TypeScript for VS Code, Kotlin for JetBrains) that act as thin API clients for the Orchestrator and Authority services. See the Architecture doc for details.
Related Documentation
- Plugin Framework - Underlying plugin infrastructure
- Scanner - SCM bulk-import consumer of the integration catalog
- Release Orchestrator - Registry version-sync and deployment-bundle credential consumer of the integration catalog
