Managed connections
Opt a connection into managed mode so the control plane can silently re-apply and revert its records with a stored, encrypted grant.
Most connections are use-once: a rail writes the desired records a single time and the platform keeps no credential. Managed mode is the opt-in exception. When a connection is managed, the control plane holds a durable, encrypted async grant — issued through the provider-hosted one-click protocol — for the customer's provider, so it can re-apply or revert the template server-side — without asking the customer to re-consent.
What "managed" means
- Opt-in only. A connection is never managed by default. It becomes managed
when the customer completes the async one-click consent flow — start it
with
POST /v1/connections/{id}/domainconnect:startwith{"managed": true}(equivalently{"rail":"async"}). When the provider supports the async variant, the response is an async consent URL; otherwise the call falls through to the ordinary syncapply_urland the connection stays use-once. - Encrypted grant, pinned base. The async callback
(
GET /v1/connect/dc/callback) exchanges the code for a durable grant against the provider API base that was pinned into the signedstateat start — never re-derived from fresh discovery — and stores it encrypted at rest. The customer's browser token from the sync/OAuth rails is not this; those are discarded immediately. - Silent re-apply. With the grant in hand the platform can recompute the connection's authoritative desired records and push any drift through the provider's async one-click API on demand, with no customer interaction.
- Auto-heal-ready. Because re-apply is a single server-side call, managed
connections are the substrate for automatic drift healing: when
Monitor reports that a record was
removed or repointed, a managed connection can be pushed back to its desired
state instead of only emitting a
domain.record_missingalert.
The connection detail response
carries a managed boolean so your dashboard can tell the two kinds apart
(false is omitted on the wire). You enable managed mode by running the async
consent flow above. You can turn it back off in two ways: keep the domain
connected but drop the grant with disable managed
(DELETE /v1/connections/{id}/grant), or take the domain off entirely by
disconnecting it.
Re-apply on demand
curl -X POST http://localhost:8080/v1/connections/<ID>:reapply \
-H "Authorization: Bearer <WIDGET_JWT>"
# → 200 { "connection_id": "<ID>", "reapplied": true, "records": [ … ] }
# (records re-written at the provider; connection re-verified)The 200 body is a re-apply receipt, not a connection object: it carries
connection_id (not id) plus the record set that was written. Fetch
GET /v1/connections/{id} if you need the connection itself.
POST /v1/connections/{id}:reapply is managed mode only. It recomputes the
desired record set, writes any drift through the stored grant, re-verifies the
connection, and emits connection.records.updated. If the connection is not
managed or has no stored grant, it responds 409.
If the push fails it emits connection.reapply.failed. When the provider reports
the grant was revoked (a 401 kill-switch — the customer withdrew consent at
their provider), the platform clears the stored grant and flags the connection for
re-consent; the next :reapply returns 409 until the customer re-authorizes.
A 401 isn't automatically treated as a revocation, though: an expired access
token looks identical to a revoked one. Before giving up, the platform rotates
the grant's access token (grant_type=refresh_token against the provider) and
retries the push once with the fresh token. Only a 401 that survives a refresh
(or a grant with no refresh token) is treated as a real revocation. This means a
managed connection keeps re-applying silently across ordinary token expiry, and
only asks the customer to re-consent when access was actually withdrawn.
Fleet-wide re-apply (drift after an edge change)
Separately from per-connection :reapply, an operator can run a fleet-wide
reconciliation pass that re-drives every connection still on an older
"desired-record" generation — for example after the edge's target hostname
changes. For a managed connection this re-applies the template through the
stored grant with no customer interaction, exactly like :reapply above. A
non-managed connection has no stored credential to push through, so instead
it emits a connection.records_outdated webhook
carrying a prefilled heal/reconnect link — it does not rewrite the customer's DNS
for you. This pass is operator-triggered, not a background guarantee: treat
connection.records_outdated as a real event your integration can receive, not
as something that fires on a fixed schedule.
Managed lifecycle events
Subscribe to these on a webhook endpoint to track the managed lifecycle:
| Event | Fires when |
|---|---|
connection.records.updated | A :reapply succeeded — the desired records were (re-)written and the connection re-verified. |
connection.reapply.failed | A :reapply push failed; if the grant was revoked, the connection is flagged for re-consent. |
connection.disconnected | The connection was disconnected — for a managed connection the template was reverted through the grant first. |
connection.records_outdated | A fleet-wide reconciliation pass found a non-managed connection on an older desired-record generation; carries a heal/reconnect link since the platform has no credential to push the update itself. |
Disabling managed mode
To stop managing a connection without disconnecting it, drop the stored grant:
curl -X DELETE http://localhost:8080/v1/connections/<ID>/grant \
-H "Authorization: Bearer <WIDGET_JWT>"
# → 200 { "connection_id": "<ID>", "managed": false }DELETE /v1/connections/{id}/grant deletes the encrypted async grant and
clears the connection's managed flag, leaving the connection and its
applied records in place. The records the provider already wrote stay live; the
platform simply stops holding a credential to re-apply or revert them, so the
connection reverts to the default use-once posture. A later async consent can
re-enable managed mode.
This is deliberately not DELETE /v1/connections/{id} — that path reverts the
template at the provider and removes the whole connection (see below). Here nothing
is reverted and the connection survives. The call is idempotent: a connection
that is already unmanaged returns 200 with managed: false. It does not emit
a webhook event.
Ending a managed connection
To take a managed domain off your product, disconnect it
with DELETE /v1/connections/{id}. For a managed connection the platform first
reverts the applied template through the stored grant, then deletes the
connection and all its child state (records, origin, monitor watch, and the grant
itself), and emits connection.disconnected.