"Tutorial: connect a connector"
The admin journey from browsing the marketplace to an enabled connector, including what Primary means for core capabilities and what the reconciler does next.
This walks one connector from "not connected" to "enabled and reconciling", naming the exact page at each step. The concepts behind each step live on Connectors; this page is the order of operations.
You need admin for everything except browsing.
1. Browse and Add
Open /marketplace. Any signed-in user can browse it; each card shows the
product, what it is for, and whether it is connected.
Find the product and hit Add.
Add is not connect. It writes a disabled, credential-less row: a pending instance. Nothing is live, nothing is reachable, and no credential exists yet. The card stays visible in that state deliberately, so an unfinished connector nags rather than disappearing.
2. Open the config page
Add takes you to /admin/org/connectors/<providerId>.
Note the URL: connectors are addressed by product, not by capability. The product names the page, and the capability is a small tag on it. This is why there is no provider switcher on an existing instance. A connection's product is fixed at creation, because turning an Azure connection into a Dokploy one is not an operation that exists.
If you later need a second zone or a second workspace, use Add another connection on the same page. That adds another instance of the same product.
3. Paste credentials
Each connector's page in these docs carries its own setup guide: what to create in the vendor's console, which least-privilege scopes to grant, and which values to copy back.
| Connector | Setup guide |
|---|---|
| Plunk | /docs/connectors/plunk |
| SMTP | /docs/connectors/smtp |
| Zitadel | /docs/connectors/zitadel |
| Microsoft Entra ID | /docs/connectors/entra |
| AWS Route 53 | /docs/connectors/route53 |
| Cloudflare DNS | /docs/connectors/cloudflare |
| LiteLLM | /docs/connectors/litellm |
| Sentry | /docs/connectors/sentry |
| Langfuse | /docs/connectors/langfuse |
| Dokploy | /docs/connectors/dokploy |
| Microsoft Azure | /docs/connectors/azure |
The same guide is rendered inline on the config panel, so you do not have to keep two tabs open.
Secret fields are encrypted at rest and never returned to you afterwards. You will see a mask instead of the value. That mask is meaningful on save: leaving it untouched preserves the stored secret, so you can edit a base URL later without re-typing the API key.
Some connectors also show a configure after connecting section. Those are access-policy fields, not credentials, and they are meant to be filled once the connection works.
4. Test connection
Hit Test connection before enabling. It runs the connector's declarative health check against the credentials you just entered.
Two things worth knowing:
- The test builds its config directly from the form, so it never round-trips through storage, and a secret you left masked is read from what is already stored rather than being wiped.
- A row missing a required field reads as not configured rather than half-wired. That is why a connector that looks saved can still behave as absent: check for missing required fields before assuming a bug.
5. Enable
Enable is the step that makes the connector live. Until then the reconciler skips it.
A capability with no enabled provider does not fail; it no-ops audibly. If you are debugging "nothing happened", an unenabled connector is the first thing to rule out.
6. Understand Primary, if this is a core capability
For the four core capabilities (notifications, identity, directory, DNS), Atrium asks a question and needs exactly one answer, so one instance is marked Primary.
What happens automatically:
- The first enabled instance of a capability adopts Primary, so connecting a single provider needs no second step.
- A second instance never steals it. Connecting another mail provider does not re-route your mail.
- If you disable or delete the Primary, the oldest remaining enabled instance succeeds it.
To change it deliberately, hit Make primary on another card. That is a flag flip, not a disable: the other instances stay live and addressable.
Primacy is never inferred from what you edited last. That rule exists because it once was: under an older tiebreak, editing an SMTP connector's label silently re-routed every outbound mail off Plunk, with no UI saying so.
For generic connectors (LLM gateway, observability, tracing, hosting) there is nothing to choose. They are one-way pushes, so every enabled instance receives them.
7. What the reconciler does next
Once enabled, the connector joins the normal reconcile path:
- Generic connectors receive the group-to-access-level push. When a member joins a mapped Atrium group, Atrium grants the corresponding access; when they leave, it revokes it. Membership stays the source of truth.
- Core capabilities are consulted by the platform: the Primary notification provider sends the mail, the Primary directory answers group lookups, the DNS connectors are enumerated when an app claims a subdomain.
One timing caveat. Core-capability config is memoized for 30 seconds per process. After you change a credential, a different process may keep using the old one for up to that long. If your first test send after an edit still uses the old provider, wait out the window before concluding the edit did not land. Fan-out and admin paths are uncached and do not have this window.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Card looks blank | Pending instance: added, never given credentials |
| Saved, but behaves as unconfigured | A required field is missing, so the row reads as absent |
| Nothing happens on membership change | Connector not enabled, or the group has no access-level mapping |
| Mail still goes to the old provider | The 30 second resolve memo, or Primary is on a different instance |
| Cannot switch a connection's product | By design. Add an instance of the right product instead |
Bringing your own
If the product you need is not one of the eleven built-ins, write one: Tutorial: build a connector walks an empty repo through manifest, module, import, certification and enable.
Two things differ from the journey above. An imported connector that ships code never receives your credential — it declares the requests it may cause and Atrium sends them. And it cannot be enabled until it passes a certification run against the real vendor: grant a throwaway subject, observe it, revoke it, observe it gone, and prove every call stayed inside the declared surface.
Concepts live on Connectors; the sandbox that executes them is Actions runtime.