INTHUB: Integration Hub

Purpose: Central management of all external integrations (SCM, CI, registries, vaults, targets).

Modules

Module: integration-manager

AspectSpecification
ResponsibilityCRUD for integration instances; plugin type registry
Dependenciesplugin-registry, authority (for credentials)
Data EntitiesIntegration, IntegrationType, IntegrationCredential
Events Producedintegration.created, integration.updated, integration.deleted, integration.health_changed
Events Consumedplugin.registered, plugin.unregistered

Key Operations:

CreateIntegration(type, name, config, credentials) → Integration
UpdateIntegration(id, config, credentials) → Integration
DeleteIntegration(id) → void
TestConnection(id) → ConnectionTestResult
DiscoverResources(id, resourceType) → Resource[]
GetIntegrationHealth(id) → HealthStatus
ListIntegrations(filter) → Integration[]

Integration Entity:

interface Integration {
  id: UUID;
  tenantId: UUID;
  type: string;                    // "scm.github", "registry.harbor"
  name: string;                    // user-defined name
  config: IntegrationConfig;       // type-specific config
  credentialId: UUID;              // reference to vault
  healthStatus: HealthStatus;
  lastHealthCheck: DateTime;
  createdAt: DateTime;
  updatedAt: DateTime;
}

interface IntegrationConfig {
  endpoint: string;
  authMode: "token" | "oauth" | "mtls" | "iam";
  timeout: number;
  retryPolicy: RetryPolicy;
  customHeaders?: Record<string, string>;
  // Type-specific fields added by plugin
  [key: string]: any;
}

Module: connection-profiles

AspectSpecification
ResponsibilityDefault settings management; “last used” pattern
Dependenciesintegration-manager
Data EntitiesConnectionProfile, ProfileTemplate

Behavior: When user adds a new integration instance:

  1. Wizard defaults to last used endpoint, auth mode, network settings
  2. Secrets are never auto-reused (explicit confirmation required)
  3. User can save as named profile for reuse

Profile Entity:

interface ConnectionProfile {
  id: UUID;
  tenantId: UUID;
  name: string;                    // "Production GitHub"
  integrationType: string;
  defaultConfig: Partial<IntegrationConfig>;
  isDefault: boolean;
  lastUsedAt: DateTime;
  createdBy: UUID;
}

Module: connector-runtime

AspectSpecification
ResponsibilityExecute plugin connector logic in controlled environment
Dependenciesplugin-loader, plugin-sandbox
ProtocolgRPC (preferred) or HTTP/REST

Connector Interface (implemented by plugins):

service Connector {
  // Connection management
  rpc TestConnection(TestConnectionRequest) returns (TestConnectionResponse);
  rpc GetHealth(HealthRequest) returns (HealthResponse);

  // Resource discovery
  rpc DiscoverResources(DiscoverRequest) returns (DiscoverResponse);
  rpc ListRepositories(ListReposRequest) returns (ListReposResponse);
  rpc ListBranches(ListBranchesRequest) returns (ListBranchesResponse);
  rpc ListTags(ListTagsRequest) returns (ListTagsResponse);

  // Registry operations
  rpc ResolveTagToDigest(ResolveRequest) returns (ResolveResponse);
  rpc FetchManifest(ManifestRequest) returns (ManifestResponse);
  rpc VerifyDigest(VerifyRequest) returns (VerifyResponse);

  // Secrets operations
  rpc GetSecretsRef(SecretsRequest) returns (SecretsResponse);
  rpc FetchSecret(FetchSecretRequest) returns (FetchSecretResponse);

  // Workflow step execution
  rpc ExecuteStep(StepRequest) returns (stream StepResponse);
  rpc CancelStep(CancelRequest) returns (CancelResponse);
}

Request/Response Types:

message TestConnectionRequest {
  string integration_id = 1;
  map<string, string> config = 2;
  string credential_ref = 3;
}

message TestConnectionResponse {
  bool success = 1;
  string error_message = 2;
  map<string, string> details = 3;
  int64 latency_ms = 4;
}

message ResolveRequest {
  string integration_id = 1;
  string image_ref = 2;  // "myapp:v2.3.1"
}

message ResolveResponse {
  string digest = 1;     // "sha256:abc123..."
  string manifest_type = 2;
  int64 size_bytes = 3;
  google.protobuf.Timestamp pushed_at = 4;
}

Module: doctor-checks

AspectSpecification
ResponsibilityIntegration health diagnostics; troubleshooting
Dependenciesintegration-manager, connector-runtime

Doctor Check Types:

CheckPurposePass Criteria
ConnectivityCan reach endpointTCP connect succeeds
TLSCertificate validChain validates, not expired
AuthenticationCredentials validAuth request succeeds
AuthorizationPermissions sufficientRequired scopes present
VersionAPI version supportedVersion in supported range
Rate LimitQuota available>10% remaining
LatencyResponse time acceptable<5s p99

Doctor Check Output:

interface DoctorHowToFix {
  summary: string;
  commands: string[];
}

interface DoctorCheckResult {
  checkType: string;
  status: "pass" | "warn" | "fail";
  message: string;
  details: Record<string, any>;
  suggestions: string[];
  howToFix?: DoctorHowToFix;
  runAt: DateTime;
  durationMs: number;
}

interface DoctorReport {
  integrationId: UUID;
  overallStatus: "healthy" | "degraded" | "unhealthy";
  checks: DoctorCheckResult[];
  evidenceLog?: {
    jsonlPath: string;
    dssePath?: string;
  };
  generatedAt: DateTime;
}

Doctor JSON output for CLI/agents uses how_to_fix (snake case) as the alias of howToFix to preserve verbatim fix commands. Doctor fix executes only non-destructive commands; destructive steps are manual and never executed by Doctor. Evidence logs include doctor_command, and DSSE summaries include the same operator-invoked command note.

Declarative Packs (YAML):

Sample manifest:

Evidence Artifacts:


Cache Eviction Policies

Integration health status and connector results are cached to reduce load on external systems. All caches MUST have bounded size and TTL-based eviction:

Cache TypePurposeTTLMax SizeEviction Strategy
Health ChecksIntegration health status5 minutes1,000 entriesSliding expiration
Connection TestsTest connection results2 minutes500 entriesSliding expiration
Resource DiscoveryDiscovered resources (repos, tags)10 minutes5,000 entriesSliding expiration
Tag ResolutionTag → digest mappings1 hour10,000 entriesAbsolute expiration

Implementation:

public class IntegrationHealthCache
{
    private readonly MemoryCache _cache;

    public IntegrationHealthCache()
    {
        _cache = new MemoryCache(new MemoryCacheOptions
        {
            SizeLimit = 1_000  // Max 1,000 integration health entries
        });
    }

    public void CacheHealthStatus(Guid integrationId, HealthStatus status)
    {
        _cache.Set(integrationId, status, new MemoryCacheEntryOptions
        {
            Size = 1,
            SlidingExpiration = TimeSpan.FromMinutes(5)  // 5-minute TTL
        });
    }

    public HealthStatus? GetCachedHealthStatus(Guid integrationId)
        => _cache.Get<HealthStatus>(integrationId);
}

Reference: See Implementation Guide for cache implementation patterns.


Integration Types

The following integration types are supported (via plugins):

SCM Integrations

TypePluginCapabilities
scm.githubBuilt-inrepos, branches, commits, webhooks, status
scm.gitlabBuilt-inrepos, branches, commits, webhooks, pipelines
scm.bitbucketPluginrepos, branches, commits, webhooks
scm.azure_reposPluginrepos, branches, commits, pipelines

Registry Integrations

TypePluginCapabilities
registry.harborBuilt-inrepos, tags, digests, scanning status
registry.ecrPluginrepos, tags, digests, IAM auth
registry.gcrPluginrepos, tags, digests
registry.dockerhubPluginrepos, tags, digests
registry.ghcrPluginrepos, tags, digests
registry.acrPluginrepos, tags, digests

Vault Integrations

TypePluginCapabilities
vault.hashicorpBuilt-inKV, transit, PKI
vault.aws_secretsPluginsecrets, IAM auth
vault.azure_keyvaultPluginsecrets, certificates
vault.gcp_secretsPluginsecrets, IAM auth

CI Integrations

TypePluginCapabilities
ci.github_actionsBuilt-inworkflows, runs, artifacts, status
ci.gitlab_ciBuilt-inpipelines, jobs, artifacts
ci.jenkinsPluginjobs, builds, artifacts
ci.azure_pipelinesPluginpipelines, runs, artifacts

Router Integrations (for Progressive Delivery)

TypePluginCapabilities
router.nginxPluginupstream config, reload
router.haproxyPluginbackend config, reload
router.traefikPlugindynamic config
router.aws_albPlugintarget groups, listener rules

Database Schema

-- Integration types (populated by plugins)
CREATE TABLE release.integration_types (
    id TEXT PRIMARY KEY,                    -- "scm.github"
    plugin_id UUID REFERENCES release.plugins(id),
    display_name TEXT NOT NULL,
    description TEXT,
    icon_url TEXT,
    config_schema JSONB NOT NULL,           -- JSON Schema for config
    capabilities TEXT[] NOT NULL,           -- ["repos", "webhooks", "status"]
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Integration instances
CREATE TABLE release.integrations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id),
    type_id TEXT NOT NULL REFERENCES release.integration_types(id),
    name TEXT NOT NULL,
    config JSONB NOT NULL,
    credential_ref TEXT NOT NULL,           -- vault reference
    health_status TEXT NOT NULL DEFAULT 'unknown',
    last_health_check TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    created_by UUID NOT NULL REFERENCES users(id),
    UNIQUE(tenant_id, name)
);

-- Connection profiles
CREATE TABLE release.connection_profiles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id),
    name TEXT NOT NULL,
    integration_type TEXT NOT NULL,
    default_config JSONB NOT NULL,
    is_default BOOLEAN NOT NULL DEFAULT false,
    last_used_at TIMESTAMPTZ,
    created_by UUID NOT NULL REFERENCES users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE(tenant_id, name)
);

-- Doctor check history
CREATE TABLE release.doctor_checks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    integration_id UUID NOT NULL REFERENCES release.integrations(id),
    check_type TEXT NOT NULL,
    status TEXT NOT NULL,
    message TEXT,
    details JSONB,
    duration_ms INTEGER NOT NULL,
    run_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX idx_doctor_checks_integration ON release.doctor_checks(integration_id, run_at DESC);

API Endpoints

See API Documentation for full specification.

GET    /api/v1/integration-types              # List available types
GET    /api/v1/integration-types/{type}       # Get type details

GET    /api/v1/integrations                   # List integrations
POST   /api/v1/integrations                   # Create integration
GET    /api/v1/integrations/{id}              # Get integration
PUT    /api/v1/integrations/{id}              # Update integration
DELETE /api/v1/integrations/{id}              # Delete integration
POST   /api/v1/integrations/{id}/test         # Test connection
GET    /api/v1/integrations/{id}/health       # Get health status
POST   /api/v1/integrations/{id}/doctor       # Run doctor checks
GET    /api/v1/integrations/{id}/resources    # Discover resources

GET    /api/v1/connection-profiles            # List profiles
POST   /api/v1/connection-profiles            # Create profile
GET    /api/v1/connection-profiles/{id}       # Get profile
PUT    /api/v1/connection-profiles/{id}       # Update profile
DELETE /api/v1/connection-profiles/{id}       # Delete profile