Decision Gate Provider Integration + Capability Registry Architecture
Audience: Engineers implementing provider integration or capability validation for checks, conditions, and evidence queries.
Table of Contents
- Executive Overview
- Provider Configuration
- Capability Registry
- External Provider Contracts
- Evidence Provider Federation
- Tool-Level Enforcement
- Typed REST/OpenAPI V3 Contract Lock
- File-by-File Cross Reference
Executive Overview
Decision Gate supports three provider types:
- Built-in providers (compiled into the binary)
- External MCP providers (stdio or HTTP transport)
- Typed providers (precompiled capability + runtime profile artifacts)
Provider capability contracts are the authoritative schema for check parameters, results, and allowed comparators. The capability registry validates scenario specs and evidence queries before evaluation. Evidence federation routes queries to providers and enforces trust policies. F:crates/decision-gate-config/src/config.rs L1883-L1990 F:crates/decision-gate-mcp/src/capabilities.rs L229-L379 F:crates/decision-gate-mcp/src/evidence.rs L138-L210
Provider Configuration
Provider configuration is defined in ProviderConfig:
type:builtin,mcp, ortypedcommand/url: transport selection for MCP providerscapabilities_path: contract JSON path (required for MCP/typed providers)runtime_profile_path: typed runtime profile JSON path (required for typed providers)typed_protocol: typed runtime protocol selector (openapi_httporgrpc)auth.bearer_token: optional provider authtrust: per-provider trust overrideallow_raw: opt-in for raw evidence disclosuretimeouts: HTTP connect and request timeouts
Discovery controls are defined in provider_discovery:
allowlist/denylist: restrict which provider contracts are disclosedmax_response_bytes: cap discovery response size
Validation enforces:
- MCP providers must specify
commandorurlandcapabilities_path. - Typed providers must specify
capabilities_path,runtime_profile_path, andtyped_protocol. allow_insecure_httpis required forhttp://URLs.- Provider names are unique and trimmed.
- Built-in identifiers (
time,env,json,http,rest) are reserved; MCP providers cannot use them. - Built-ins must use a reserved identifier and reject MCP-only fields (
command,url,allow_insecure_http,auth,capabilities_path). - MCP providers reject typed-only fields (
runtime_profile_path,typed_protocol). - Typed providers reject MCP-only fields (
command,url,allow_insecure_http,auth) and built-inconfigpayloads.
F:crates/decision-gate-config/src/config.rs L1883-L1990
Capability Registry
The capability registry loads provider contracts and compiles JSON schemas for check params and results. It validates:
- Provider and check existence
- Required params presence
- Params schema conformance
- Expected-value schema conformance
- Comparator allow-lists
- Anchor types declared by provider contracts (e.g.,
file_path_rootedfor the built-injsonprovider) - Duplicate
check_idrejection (fail-closed; no silent overwrite semantics)
F:crates/decision-gate-mcp/src/capabilities.rs L313-L379 F:crates/decision-gate-mcp/src/capabilities.rs L598-L636
Capability registry queries are used by both scenario definition and evidence query tools. F:crates/decision-gate-mcp/src/tools/router.rs L2029-L2050 F:crates/decision-gate-mcp/src/tools/router.rs L979-L1017
External Provider Contracts
External providers must supply a contract JSON file that:
- Matches the configured provider id
- Declares transport matching provider type:
- MCP providers:
transport = "mcp" - Typed providers:
transport = "typed"
- MCP providers:
- Defines checks with allowed comparator lists
Contracts are size-limited and path validated; invalid contracts fail closed.
For typed OpenAPI imports, check allowed_comparators are synthesized from the
normalized result schema using the strict comparator type-class matrix and
canonical comparator ordering.
F:crates/decision-gate-mcp/src/capabilities.rs L533-L591
F:crates/decision-gate-typed/src/openapi/check_synthesis.rs L34-L109
F:crates/decision-gate-typed/src/openapi/comparator_derivation.rs L52-L114
Evidence Provider Federation
Evidence federation combines built-in providers and MCP providers:
- Built-ins are registered via the provider registry.
- MCP providers are instantiated with stdio or HTTP transport.
- Typed providers are instantiated from runtime profile artifacts and execute profile-defined checks via the typed runtime provider.
- Provider registry rejects duplicate registrations to prevent silent overrides.
- Stdio provider processes are terminated on drop to avoid orphaned provider runtimes during shutdown or test teardown.
- Provider policies (trust + allow_raw) are applied per provider.
- Evidence results may include structured error metadata (
code,message,details) to support deterministic recovery loops. - HTTP evidence providers enforce timeouts, disallow redirects, apply response size limits, fail closed on truncated bodies (Content-Length mismatch), pin DNS resolution per request, and deny private/link-local peers by default unless explicitly opted in.
- The built-in REST provider reuses the same HTTP security controls and adds
GET-only extraction checks (
json_path,header) plus header/auth hygiene enforcement for auth-managed and reserved header names. - The typed runtime provider applies the same hardened HTTP controls for
openapi_httpexecution, enforces profile digest integrity, validates response status/content-type against profile policy, and emits deterministic anchors using profile metadata. - Typed lifecycle catalog semantics now exist in OSS compile tooling to support
profile version registration, activation, rollback, and digest drift
detection (
decision-gate-typed), and OSS lifecycle tool plumbing is active viatyped_providers_import,typed_providers_register,typed_providers_list,typed_providers_get,typed_providers_activate, andtyped_providers_deprecate. - Typed runtime resolution now includes a resolver seam
(
TypedProfileResolver) keyed by(tenant_id, namespace_id, provider_id). Default OSS behavior resolves from scoped in-memory lifecycle state and falls back to static typed profile config entries. Resolver calls now snapshot the resolver handle before invocation so runtime resolution does not execute while holding the internal resolver mutex. - Built-in REST runtime now includes policy evaluator seams
(
RestPolicyEvaluator) for egress host/scheme decisions and auth-scheme decisions. Deny paths return deterministic reason codes.
F:crates/decision-gate-mcp/src/evidence.rs L138-L210 F:crates/decision-gate-mcp/src/evidence.rs L248-L266 F:crates/decision-gate-providers/src/http.rs L82-L239 F:crates/decision-gate-providers/src/rest.rs L124-L570 F:crates/decision-gate-typed/src/lifecycle.rs L1-L286
Trust policy enforcement (signature verification) runs per provider response. F:crates/decision-gate-mcp/src/evidence.rs L636-L677
Tool-Level Enforcement
Tool behavior enforces capability and disclosure policy:
scenario_definevalidates the spec against capabilities before registering.evidence_queryvalidates queries and applies raw evidence redaction policy.evidence_queryexecution is offloaded to a blocking task to isolate blocking providers (HTTP) from the async MCP runtime.provider_contract_get/provider_check_schema_getapply disclosure policy and return canonical provider contracts or check schemas.- Typed lifecycle tools (
typed_providers_import/register/list/get/activate/deprecate) require explicittenant_id+namespace_idscope fields and provide deterministic scoped artifact registration, active-version selection, rollback-aware deprecation, digest drift status inspection, and bounded typed import/runtime security limits (timeout_ms,max_response_bytes,outbound_max_inflight, retry bounds, and allowlist cardinality).typed_providers_importrequires an explicitcredential_bindingsfield on every request ({}for unauthenticated imports) and explicit secured-scheme-to-credential_bindingmappings for secured OpenAPI imports. Each secured mapping requires both locator and wire-value render metadata. - Provider-scoped authz context now includes
provider_idfor typed lifecycle tools andevidence_query, enabling provider-level enterprise authorization policy at the tenant-authz seam. - Comparator allow-lists are enforced from provider contracts;
json.pathexposes the full comparator surface area for deterministic JSON evidence.
F:crates/decision-gate-mcp/src/tools/router.rs L1106-L1236 F:crates/decision-gate-mcp/src/tools/router.rs L1238-L1298 F:crates/decision-gate-mcp/src/tools/router.rs L3173-L3940 F:crates/decision-gate-mcp/src/tools/typed/lifecycle.rs L127-L210 F:crates/decision-gate-mcp/src/tools/typed/lifecycle.rs L213-L452 F:crates/decision-gate-mcp/src/tools/typed/lifecycle.rs L455-L544
Typed REST/OpenAPI V4 Contract Lock
This section is the architecture-level decision lock for OSS typed REST/OpenAPI provider behavior. It is intentionally stable so roadmap/archive movement does not change the active contract.
Import boundary lock (OSS V4):
- OpenAPI version policy accepts
3.0.xand3.1.x; other versions fail closed. - External ref mode is
local_file_onlyin OSS runtime behavior. Network ref execution paths are parsed for policy classification but rejected. - Unsupported or ambiguous constructs must fail closed with deterministic taxonomy mapping/remediation metadata.
- Unsupported taxonomy and remediation metadata are single-source and enum-backed
(
OpenapiUnsupportedCode+OpenapiImportErrorKind), not message-substring coupled. - Unsupported taxonomy fixture parity is enforced by typed importer unit contract tests, blocking fixture/implementation drift in CI.
F:crates/decision-gate-typed/src/openapi/mod.rs L144-L301 F:crates/decision-gate-typed/src/openapi/refs.rs L22-L394 F:crates/decision-gate-typed/src/openapi/errors.rs L12-L212 F:crates/decision-gate-typed/src/openapi/errors.rs L447-L558 F:crates/decision-gate-typed/tests/openapi_unsupported_taxonomy_contract.rs L1-L105
Synthesis/runtime lock (OSS V4):
- Projection-first synthesis is mandatory for JSON object/array-complex
responses: schemas must declare
x-decision-gate.projections. - OpenAPI import emits one check per declared projection entry per
status/media tuple; legacy
response_projection_modeinput is removed. json_onlymedia support remains default unless explicit overrides are provided.- Runtime request binding supports
path,query,header,cookie, and optionalbodytargets with fail-closed conflict and hygiene checks. - Runtime extraction remains status/content-type gated and fail-closed.
- Runtime profile
profile_versionis hard-locked totyped-runtime-v4; older profile versions are rejected. TypedOperationProfilealways carries required operation-effective auth alternatives; provider-level auth fallback is not part of the runtime model.
F:crates/decision-gate-typed/src/openapi/mod.rs L144-L248 F:crates/decision-gate-typed/src/openapi/check_synthesis.rs L34-L242 F:crates/decision-gate-typed/src/runtime_codegen.rs L42-L93 F:crates/decision-gate-providers/src/typed.rs L687-L799
Auth + credential lock (OSS V4):
- Effective security is resolved per operation:
operation.securityoverrides top-levelsecurity.security: []means unauthenticated operation.- Empty requirement object (
{}) contributes an unauthenticated alternative.
- Supported requirement shapes:
- One requirement containing one supported scheme.
- Multiple alternatives where each alternative contains exactly one supported scheme.
- Supported schemes remain
httpbearer/basic andapiKeyinheader|query|cookie. - Credential locators are explicit and scheme-locked:
secret://...resolves through the local encrypted OSS secret backend.env://...is development-only and disabled unlessdev.allow_dev_env_credentials=true.- Bare env variable names and unknown locator schemes are rejected.
- Credential values are canonical raw secrets; runtime applies explicit
value_rendermetadata (identityor deterministicprefix) before header/query/cookie injection. apiKeyalternatives retain exact OpenAPI-derivednameandlocation; no synthetic fixed API-key names are used at runtime.- Import requires an explicit
credential_bindingsfield and explicitcredential_bindingmapping input for every referenced secured scheme; missing fields/mappings fail closed. - Unsupported security types/schemes and unsupported requirement shapes
(
oauth2,openIdConnect, unsupportedhttpschemes, unsupportedapiKeylocations, multi-schemeAND, missing scheme refs, malformed security objects) fail closed with deterministic taxonomy.
F:crates/decision-gate-typed/src/openapi/security_mapping.rs L11-L216 F:crates/decision-gate-typed/src/openapi/errors.rs L125-L155 F:crates/decision-gate-providers/src/typed.rs L789-L904 F:crates/decision-gate-mcp/src/tools/typed/lifecycle.rs L55-L163
Outbound resilience + limits lock (OSS V3):
- Runtime security policy includes per-provider outbound inflight caps and
bounded retry policy (
max_attempts,initial_backoff_ms,max_backoff_ms). - Runtime retries are deterministic and limited to timeout/
429/503, with boundedRetry-Aftersupport when encoded as seconds. - Import/registration rejects malformed outbound limit/retry bounds.
F:crates/decision-gate-contract/src/types.rs L403-L439 F:crates/decision-gate-providers/src/typed.rs L448-L463 F:crates/decision-gate-providers/src/typed.rs L958-L980 F:crates/decision-gate-mcp/src/tools/typed/lifecycle.rs L586-L663
Change-control requirement:
- Any change to the above lock values requires same-change updates to:
- this section,
- OpenAPI conformance fixtures (
system-tests/tests/fixtures/openapi_compat/), - typed REST coverage policy/report contracts (
system-tests/tests/fixtures/coverage/), - and threat-model deltas when trust boundaries expand.
File-by-File Cross Reference
| Area | File | Notes |
|---|---|---|
| Provider config + validation | crates/decision-gate-config/src/config.rs | Provider type, transport, contract path, timeouts, discovery allow/deny. |
| Capability registry | crates/decision-gate-mcp/src/capabilities.rs | Contract loading, schema compilation, validation. |
| Evidence federation | crates/decision-gate-mcp/src/evidence.rs | Provider registry + trust enforcement. |
| Typed runtime provider | crates/decision-gate-providers/src/typed.rs | Runtime profile loading and typed check execution. |
| Typed IR + adapters | crates/decision-gate-typed/src/lib.rs | Protocol-agnostic typed import/codegen foundation. |
| Typed lifecycle catalog | crates/decision-gate-typed/src/lifecycle.rs | OSS profile versioning, activation/rollback, and digest drift status primitives. |
| OpenAPI adapter facade | crates/decision-gate-typed/src/adapter_openapi.rs | Compatibility re-export for openapi module API. |
| OpenAPI adapter internals | crates/decision-gate-typed/src/openapi/ | Module split for options/errors/conformance/refs/schema/security/check/comparator logic. |
| Typed lifecycle tool orchestration | crates/decision-gate-mcp/src/tools/typed/lifecycle.rs | Typed import/register/list/get/activate/deprecate parsing and lifecycle state wiring. |
| Tool integration | crates/decision-gate-mcp/src/tools/router.rs | Tool dispatch, auth/disclosure gates, and async handler envelope. |