Deliver to endpoints with no public URL
payments.default.svc.cluster.local without that name ever resolving from outside.- 01What a connector is and where it runs
- 02Enrolling replicas so one restart is not an outage
- 03Pointing a destination at an in-cluster URL
- 04Reading connector and replica health honestly
- 05Rotation, disabling, deletion and plan limits
How it works
A connector represents one of your networks. It belongs to the organization rather than a project, so a single cluster connector serves every project you run. Inside that network you run one or more agent replicas. Each dials out to the overlay and stays there.
When a delivery is due, SolidHooks hands it to the connector by name and the agent makes the actual HTTP request from inside your network. Your service sees a request from a local address and needs no changes at all.
Set it up
- 1
Provision the connector
The response carries an
enrollmentKey(cbt_…). It is shown here and on regeneration and nowhere else, so store it before you move on. It does not expire.curlcurl -s "$API/v1/connectors" \ -H "authorization: Bearer $SDHK_KEY" \ -H 'content-type: application/json' \ -d '{ "name": "prod-cluster", "description": "EU production" }' → { "id": "cntr_...", "enrollmentKey": "cbt_...", "provisionedAt": "2026-08-18T09:14:02.000Z" }# The enrollment key is shown once here. Store it now.# provisionedAt reads null only if you read the connector back while this call is still in flight.
- 2
Run the agent in your network
The dashboard prints the exact
docker runorhelm installline with your token in it. Each replica self-enrolls by calling the the SolidHooks bootstrap endpoint, receives a per-replica heartbeat token, and joins the connector.curl# Install using helmhelm repo add interstellar-labs https://interstellar-labs.github.io/charts/helm repo updatehelm install solidhooks-connector interstellar-labs/solidhooks-connector \ --set enrollmentKey="cbt_..." # Install using dockerdocker run -e ENROLLMENT_KEY="cbt_..." \ -v solidhooks-connector:/ziti \ interstellarlabs/solidhooks-connector:latest
- 3
Add replicas for availability
Run the same command again elsewhere. Replicas are independent members of one connector, so a rolling restart never leaves the connector with nothing to dial.
- 4
Create a private destination
Set
type: "private"and name the connector. The URL is still validated as a URL, it simply does not have to resolve publicly.curlcurl -s "$API/v1/destinations" \ -H "authorization: Bearer $SDHK_KEY" \ -H 'content-type: application/json' \ -d '{ "name": "In-cluster payments service", "type": "private", "connectorId": "cntr_...", "url": "http://payments.default.svc.cluster.local:8080/hooks", "method": "POST" }'
provisionedAt: null until its overlay infrastructure exists. During that window, creating a private destination against it returns 400 and deleting it returns 409 CONNECTOR_PROVISIONING. Both are retryable by design.Reading health without guessing
A connector reports a status aggregated over its replicas, and the four values are chosen so that our uncertainty is never reported as your outage.
# Aggregate across replicascurl -s "$API/v1/connectors/cntr_..." -H "authorization: Bearer $SDHK_KEY"→ { "status": "connected", "connectedReplicas": 2, "totalReplicas": 3 } # Which one is missingcurl -s "$API/v1/connectors/cntr_.../replicas" -H "authorization: Bearer $SDHK_KEY"
Rotation, disabling and revocation
regenerate-enrollment mints a new bootstrap token and invalidates the previous one. Replicas that already enrolled keep running, so rotating a leaked token is not an outage.
toggle-disabled stops new private destinations being created against the connector. Enrolled replicas keep beating, because disabling is an administrative switch rather than revocation. Deleting a connector is blocked with 400 while any destination still points at it.
A replica is revoked automatically only when it has both been silent past the stale-heartbeat window and failed to appear on the overlay. That window defaults to 24 hours and is set per deployment, so check your own before treating it as a fixed number. Requiring both conditions is what keeps a healthy agent alive when it can serve traffic but cannot reach our API. A revoked replica gets 403 with a machine-readable reason and stops. An unrecognised token gets an opaque 401, so the endpoint cannot be used to probe which credentials are live.
Plan limits and prerequisites
- Connectors are capped by
maxConnectors. Exceeding it returns 403CONNECTOR_LIMIT_REACHEDwith the current count. - Replicas per connector are capped by
maxReplicasPerConnector, enforced at bootstrap. Shrinking a plan never evicts replicas that are already enrolled. - Private delivery is an optional platform capability. On a deployment without the overlay configured, connector mutations return 400.
Practices worth adopting
- Run at least two replicas in different failure domains. One connector with one replica is a single point of failure wearing a plural noun.
- Store the enrollment key in your secret manager the moment you create the connector. It is never shown again, and the recovery path is regeneration.
- Alert on
connectedReplicasfalling below your intended count rather than on the aggregate status. A connector readsconnectedwith one replica of three alive. - Treat
unknownas a read to retry rather than a page to send. It describes our view of the overlay, not your agent. - One connector per network, reused across projects. They are organization-scoped for exactly this reason.
Questions
Reach the service that was never meant to be public
Provision a connector, run the agent, and point a destination at a cluster-local URL.