Skip to content

Provider Connections ​

Initiative 2 adds Customer-Owned Model Credentials: managed execution must run against a tenant's own provider account, never against CARC's (Giggle AI Innovation's) own credentials. This page explains the credential/ownership half of that architecture; see Execution Profiles (Initiative 3) for the execution- configuration half — model, inference parameters, timeouts/retries — which no longer lives here.

The commercial model this enforces ​

Bring your model. Bring your provider account. CARC adds runtime control.

CARC does not pay for customer model usage, does not store provider credentials in plaintext, and remains provider-agnostic. Giggle AI Innovation's own provider credentials exist only for internal development, testing, and controlled product demonstrations — never as a fallback for a real tenant's workload.

Four separate concepts, permanently ​

Registered AgentExecution ProfileProvider ConnectionAdapter Registry
AnswersWhat may this agent do?How should the model execute?Whose account/credentials are used?How does CARC talk to a provider protocol?
EntityRegisteredAgentExecutionProfileProviderConnectionRegisteredAdapterSummary
Linked from—agent's execution_profile_idprofile's provider_connection_idprofile's adapter_id
Tenant-scoped?YesYesYes — always looked up under the requesting agent's own tenantNo — shared across tenants

A ProviderConnection never contains model, temperature, timeout, or retry configuration — that's exclusively ExecutionProfile's concern (see Execution Profiles for the full resolution order a managed execution goes through). A single connection may back many execution profiles — e.g. one tenant OpenAI account behind both a fast-screening profile and a structured-review profile using different models.

Target architecture ​

text
Business Application
  |
  Agent Registry              <- governs whether the agent may run
  |
  Execution Profile             <- resolves HOW execution happens (model, params, timeouts)
  |
  Provider Connection            <- resolves WHOSE credentials are used
  |
  CredentialStore                 <- resolves the raw credential (never logged/returned)
  |
  ProviderAdapterFactory            <- builds a TRANSIENT, tenant-credentialed adapter instance
  |
  External Model Provider (the tenant's own account)
  |
  Standardized execution result (text + citations + safe metadata)
  |
  Runtime Control Engine      <- UNCHANGED evidence/policy/risk/Decision Controller

The Adapter Registry's own registered instance is never used to execute a customer's request — it only reports capabilities/status. Every managed execution builds a fresh adapter instance from the resolved ProviderConnection's credentials and the resolved ExecutionProfile's model/parameters, uses it exactly once, and discards it.

Provider Connection lifecycle ​

text
pending  ──validate (ok)──>  valid  ──disable──> disabled ──enable──> valid
   ▲                            │
   └──────rotate-credential─────┘
                (back to pending — must be re-validated)

any status ──delete──> deleting (transient, then removed)
  • pending — just created or just rotated; not yet usable.
  • valid — passed validation; may serve managed execution.
  • invalid — last validation failed (see last_validation_error_code).
  • disabled — operator-paused; reversible via /enable.
  • deleting — deletion in progress; rejected if any ExecutionProfile still references the connection via provider_connection_id.

Validation is presence/shape-only (confirms a managed-execution factory exists for the provider, and that the stored credential is retrievable and non-blank) — it never makes a live call to the provider, and it no longer checks anything model-related (there is no model at this level — see Execution Profiles for where model compatibility is actually checked, at managed-execution time).

Credential storage ​

Raw credentials are never stored on the ProviderConnection record — credential_reference is an opaque pointer into a CredentialStore (@giggle-ai/credential-store):

  • gcp_secret_manager (production) — backed by Google Secret Manager. Secret names use only system-generated opaque identifiers, never a raw tenant string, display name, or credential fragment: carc-provider-{opaque-tenant-id}-{opaque-connection-id}. The secret name stays stable across credential rotations — rotation adds a new Secret Manager version under the same name. Labels are limited to managed-by=carc, resource-type=provider-connection, provider, and environment, never a tenant name or subject data.
  • in_memory (dev/test only) — unencrypted process memory; the engine refuses to boot with this backend when ENVIRONMENT looks production-like (see Operations).

Configuration and security considerations ​

  • credential/RotateCredentialInput.credential are write-only — no response from any endpoint ever echoes them back, and the request logger never logs request bodies at all (see Security).
  • GET /runtime/provider-connections* responses only ever return the ProviderConnection shape, which has no field that could hold a raw credential.
  • Deleting a connection also deletes its underlying stored credential.
  • There is no public endpoint that can create a connection flagged as Giggle-owned/internal — that seeding happens only in the engine's own composition root at boot, scoped to the configured default tenant.

APIs ​

text
POST   /runtime/provider-connections
GET    /runtime/provider-connections
GET    /runtime/provider-connections/{id}
PATCH  /runtime/provider-connections/{id}
DELETE /runtime/provider-connections/{id}
POST   /runtime/provider-connections/{id}/validate
POST   /runtime/provider-connections/{id}/rotate-credential
POST   /runtime/provider-connections/{id}/enable
POST   /runtime/provider-connections/{id}/disable

SDK usage ​

ts
const connection = await runtime.createProviderConnection({
  provider: "openai",
  displayName: "Acme Health — OpenAI Production",
  credential: process.env.ACME_OPENAI_API_KEY!,
});
await runtime.validateProviderConnection(connection.connection_id);

Continue in Execution Profiles — a connection alone doesn't make an agent executable; it must be referenced from an ExecutionProfile, which the agent then references via executionProfileId.

See SDK Guide and REST API Guide for full reference.

Developer Platform v1: Consequential Agent Runtime Control Platform