Connectors
How Ductor dispatches work to 100+ third-party providers with credentials encrypted at rest.
Connectors are how the executed stage of the clearing lifecycle reaches the outside world — the action inventory a Route, a workflow step, or an agent draws on to actually do the work. Ductor ships with implementations for a large catalog of third-party providers (browse the live directory at ductor.io/connectors), and the same machinery lets you add your own. A step names a provider and an action; Ductor resolves the credentials, runs the action, and records the result as a durable attempt. Each action is governed, not just callable: it carries typed semantics (mutation class, idempotency, retry, approval) so the runtime — and any agent, human or automated — knows what is safe to retry and what needs a human.
This page is the summary; the deep reference is its own section
For the full treatment — every auth type, the credential encryption scheme, the management API with real payloads, triggers and polling, and how to author your own provider — see the Connectors section. This concept page is the one-screen mental model.
The registries
Connectors are described by two registries:
ProviderRegistrymaps aproviderKeyto a provider definition — what it is and how to authenticate to it.ActionRegistrymaps a(providerKey, actionKey)pair to anActionSpec, which carries the function that actually executes the action.
At dispatch time a step names a provider and an action; Ductor looks up the
ActionSpec and runs it with a resolved authentication context. Provider
implementations live under infrastructure/connector/providers/.
Connections and auth
A ConnectionService resolves the AuthContext for a connection when a step
is dispatched. Credentials are AEAD-encrypted at rest using
XChaCha20-Poly1305, keyed by the base64 32-byte key in
connector.encryption_key (infrastructure/connector/crypto/). Plaintext
secrets never touch the database — the row holds ciphertext, and decryption
happens in-process at dispatch time using the injected key.
Protect the encryption key
DUCTOR_CONNECTOR_ENCRYPTION_KEY decrypts every stored credential. Treat it
like a database password: inject it from your secret manager, rotate it
deliberately, and never commit it. Losing it means losing access to every
stored connection; leaking it means exposing all of them.
Dispatch is durable
A connector call is not a fire-and-forget SDK call — it's a workflow step, which
means it inherits the durable attempt model. The
Coordinator dispatches the action to a
Step Worker post-commit; the worker executes it and records the outcome as an
eec_workflow_step_attempt row (the eec_ prefix marks Ductor's durable
Enterprise Eventing Core tables). If the call fails, the step's retry policy
governs the retry, and the Coordinator folds the eventual result back into run
state. Because dispatch is at-least-once, a connector action can run more than
once across a crash — so provider actions that mutate downstream state should
pass an idempotency key where the provider supports one (see
Idempotency & Exactly-Once).
AI connectors
Two step types — ai_action (a single LLM inference call) and ai_agent (an
agentic tool-calling loop with execution bounds) — route through the same
connector machinery to an AI inference proxy. From the workflow's perspective an
AI call is just another durable, retryable step with encrypted credentials and
uniform observability.
Custom connectors
Adding a connector is a matter of implementing the action functions and
registering the provider — no changes to the core engine. Connectors contribute
to the runtime through fx option groups (for example, connector_interceptors),
which is the same extension pattern used by routing strategies and workflow
listeners. See Extension Points.
Why it's a connector, not an SDK call
Routing a step through the connector layer instead of calling a vendor SDK inline gives you four things for free:
- credentials are encrypted and resolved centrally, not scattered through code;
- every call is observable through the same metrics and tracing;
- retries are governed by the durable attempt model from Coordinator & Step Workers;
- and the call is tenant-scoped and rate-limited like everything else.
Where to go next
- Connectors: full reference — architecture, auth, connections, triggers, catalog, and provider authoring.
- Connector Architecture — the registries, dispatch, and the durable attempt and async-job models.
- Authentication & Credentials — auth types and XChaCha20-Poly1305 credential encryption.
- The DAG Workflow Model — where connector steps sit in a graph.
- Idempotency & Exactly-Once — making duplicate dispatch safe.