A native connector is one where every tool is a single bounded HTTP request, Obol holds the vaulted vendor credential, and the gateway itself issues the call. It is the strongest observation boundary Obol has, and the only tier where the immediate observation is stamped gateway_observed. Native is reserved for connectors whose receipt is the product: prod-destructive writes, identity, money, and infrastructure mutations, and the official high-risk set named in ADR-0030. It is not a breadth exercise — long-tail coverage stays federated. The reviewed native cut-list and its Gate 0 reasoning live in packages/connectors/NATIVE.md.

What you author

An OpenAPI document is an input, never the contract. The contract is the reviewed overlay plus the hand-authored bundle.

The x-obol-effect extension

The importer does not guess an effect kind for mutations. A missing extension fails the import with "{method} operation requires x-obol-effect" (apps/gateway/crates/obol-httpx/src/spec.rs). That is a stop condition, not a warning. The extension’s value is deserialized and validated at import time. destructive is a separate signal that feeds Cedar and approvals: it is method == "delete" || x-obol-destructive == true. It is not the effect kind, and nothing cross-checks the two. A conservative EffectSpec gates nothing on its own — if a POST mutation must require approval in prod, set destructive: true or write a Cedar rule.

Request body encoding

TargetSpec::OpenApi, the bundle, and the overlay all carry body_encoding (ADR-0034), and a single tool may override it under annotations.openapi.body_encoding. It is declared in the reviewed overlay and never inferred from the vendor’s OpenAPI document — a spec that lists several media types, or simply gets it wrong, must not silently decide what the gateway sends. This changes only how the body is serialized. Credential injection, the host allowlist, idempotency binding, and evidence trust are unaffected: a native form-encoded call is gateway_observed exactly as a JSON one is.

Dispatch annotations

annotations on a tool is executor dispatch config only — never a place to park effect data.

Egress and probe targets

The bundle declares its own egress policy and any probe target a readback stage names.
EgressPolicy::validate checks very little: that hosts are non-empty and schemes are in {https, http}. ports is declared and not validated, and nothing cross-checks a probe target’s base_url against egress.hosts. Author both by hand and review them deliberately. Egress and SSRF enforcement at dispatch is separate — see Egress and SSRF.

How a native call executes

1

Admission

The Obol virtual key authenticates, CEL prefilters visibility, and Cedar decides permission against the concrete tool and its arguments. Default-deny. tools/list never shows a tool the key cannot call. A destructive tool in prod requires approval unless policy explicitly grants it.
2

Invocation identity

One stable InvocationId and one Obol idempotency key are minted before dispatch and retained across approval, transport retries, and safe redispatch (ADR-0019). Idempotency is coordinated atomically in Redis, keyed by workspace, resolved connection, tool, and key. A request-hash conflict never dispatches.
3

Request construction

Arguments are validated against the tool’s input schema before any dispatch. Bad arguments mean the vendor receives nothing. Path, query, header, and body are filled from the schema mapping; the body is serialized per body_encoding.
4

Egress check and credential injection

Netguard resolves and screens the destination — loopback, private, link-local, multicast, and metadata ranges are refused — pins the resolved address, and revalidates every redirect. The vaulted vendor credential is unwrapped inside the gateway process only (invariant 1) and injected on the outbound hop. See Credential brokering.
5

Idempotency propagation

If the EffectSpec declares a header or body_pointer binding, the Obol key is propagated outbound under it. unsupported propagates nothing — and forecloses automatic redispatch after an ambiguous attempt.
6

Observation

The executor normalizes the result into a non-serializable DispatchObservation stamped EvidenceTrust::GatewayObserved (obol-httpx/src/lib.rs). The numeric vendor status is preserved on every failure path, including an off-schema 2xx, which becomes inconclusive rather than a client-side schema error.
7

Verification and receipt

The deterministic verifier applies the EffectSpec’s response binding and produces a versioned InvocationReceipt plus an append-only VerificationEvent. Raw bodies, credentials, and compared values never enter a receipt or a log — an assertion result carries a name and an outcome (passed, failed, missing, invalid) and nothing else. See Receipts.

Evidence a native route can carry

Native is the only tier that reaches the top of the trust vocabulary on its own.
  • Immediate transport facts and derived fields are both gateway_observed (ADR-0025).
  • An HTTP readback against an Obol-custodied connection is gateway_observed.
  • An MCP readback is broker_attested even here, because an MCP server is by construction an authenticated intermediary rather than the originating vendor.
  • A directly verified vendor webhook is vendor_signed.
Only gateway_observed and vendor_signed evidence may assert contradicted. See Evidence classes.

Readback and webhook stages

A native pack’s overlay is where asynchronous evidence is declared, because a VerificationPlan may only live in an overlay or bundle — never on a published ToolSnapshot (see EffectSpec for why that rule is load-bearing).

Readback

A readback probe never carries a host, URL, or connection string. It names a ProbeTargetId declared in the pinned bundle, and its inputs are restricted to the invocation’s safe upstream id, a bundle-authored literal, or — for HTTP path and query parameters only — a JSON Pointer into the canonical arguments resolving to a scalar (ADR-0025).
The probe union is closed to http and mcp — the two transports the gateway already speaks. Database, message-broker, filesystem, gRPC, and object-store probes are refused permanently, not deferred (ADR-0025). An HTTP path_template must be origin-relative and start with /; that is what rejects an absolute URL. An MCP probe admits no request-derived argument at all. absent assertions are legal only on kind: delete, and only against a decisive negative the probe declares — HttpProbe.decisive_negative, restricted to 404 and 410 (ADR-0035). An errored probe yields missing, never a passing absence. The gateway serves readbacks at /internal/v1/verification/readback, driven by the control worker’s scheduler with a short-lived single-use capability bound to workspace, invocation, connection, stage, plan digest, and nonce. The caller can never supply a destination or a selector.

Webhook

A webhook stage is the only route to vendor_signed. The bundle pins the signature profile, header, timestamp tolerance, and declared event types; only signature schemes in the closed SignatureProfile registry can be expressed.
Vendor webhooks terminate at a generic gateway endpoint (/webhooks/{workspace}/{connection}/{subscription}, aliased at /hooks/…). The gateway verifies the original bytes, timestamp, and replay identity before parsing. An invalid signature produces security telemetry only — never evidence, and never a contradiction. If a vendor’s scheme is not in the registry, author "webhook": null and say so in CONNECTOR.md; several shipped packs do exactly that.

Traps worth knowing before you author

  • Never publish a VerificationPlan on a ToolSnapshot. The runtime verifier matches only response_binding. A published tool carries verification: none (reads) or a bare response_binding (mutations); plans stay in the overlay or bundle.
  • destructive is set by hand. Nothing derives BundleTool.destructive from effect.kind, so a mutation with the flag unset skips prod approval.
  • Do not write tautologies. An assertion derivable from dispatch_statusesexists over http_status against accepted: [200..=299] — mints a green check from no evidence. Nothing enforces this rule; it is on the author and the reviewer. If a tool genuinely has no evidence path, declare it (ADR-0036) rather than fabricating one.
  • Author the real idempotency binding. Never default to unsupported because the vendor brief was thin; unsupported forecloses automatic redispatch and is a real product limitation worth writing down.