Meshery Server Registration

How a Meshery Server registers itself with Layer5 Cloud as its Remote Provider, what data is recorded, and how re-registration is handled.

Layer5 Cloud is a Meshery Remote Provider. When a Meshery Server is configured to use Layer5 Cloud (SaaS or self-hosted), the server registers itself with Cloud on behalf of the authenticated user. Registration is what makes a particular Meshery Server visible inside Cloud β€” it appears as a meshery Connection on the user’s account, scoped to their Organization, and becomes the anchor point for everything else the user does through that server (designs, environments, workspaces, events, capabilities).

This page documents the registration behavior implemented by Layer5 Cloud: what the server sends, how Cloud identifies an existing registration vs a new one, and what fields are preserved across re-registration.

The Meshery Server / Remote Provider boundary has two requirements:

  1. Identity β€” Cloud needs to know which Meshery Server is calling, so multiple Meshery deployments can talk to the same Cloud tenant without colliding.
  2. Ownership β€” Every Meshery Server registration is owned by exactly one user (and therefore one Organization). All subsequent activity through that server is attributed to that user for audit, RBAC, and tenancy.

A registration record satisfies both: it associates a unique server identifier with a user and an Organization, and it survives across Meshery Server restarts.

A Meshery Server is identified by a stable server_id it generates on first start and persists locally. The server_id travels in the Connection’s metadata payload.

Cloud’s uniqueness rule for an existing Meshery registration is the triple:

(kind = 'meshery', user_id, metadata.server_id)

The lookup is implemented in ConnectionDAO.CheckMesheryServerExistence. A given user can register many Meshery Servers, and the same Meshery Server can register for many users β€” but a given (user, server_id) pair maps to exactly one Connection row.

Meshery Server registers by POSTing a connection payload to:

POST /api/integrations/connections

The request must carry a valid Cloud session (Kratos browser session or JWT). The handler resolves the caller from session context and uses that user’s ID as the owning user_id.

Required payload fields:

FieldDescription
kindMust be meshery.
metadata.server_idStable UUID generated by the Meshery Server.

Optional payload fields:

FieldDescription
nameHuman-readable display name. If omitted, Cloud generates meshery-<random>.
type / sub_typeFree-form classification fields.
metadataAdditional JSON metadata (e.g. server version, hostname).
statusInitial status (defaults to the system’s registered state).

The handler chain is RegisterConnection β†’ MesheryConnectionUtilityHandlerRegistration β†’ either CreateConnection or UpdateConnection.

  1. The handler validates that the resolved session has a non-nil user_id. The connections.user_id column is NOT NULL; a missing user at this point is a hard error and the request is rejected.
  2. CheckMesheryServerExistence looks for a row matching (meshery, user_id, server_id).
  3. No match is found, so a new row is inserted via CreateConnection.
  4. The new Connection inherits the user’s Organization for tenant isolation.

A re-registration is any subsequent call from the same Meshery Server (same server_id) for the same user β€” typically after a Meshery Server restart, a new browser session, or a Cloud reconnect.

The handler:

  1. Validates the session’s user_id (same as first registration).
  2. Finds the existing row via CheckMesheryServerExistence.
  3. Preserves the existing row’s stable identity fields β€” name, kind, type, sub_type, status β€” so a freshly-minted random name from a payload that omitted name cannot rename the existing Meshery Server, and missing type / sub_type cannot blank them.
  4. Preserves the existing row’s created_at, sets updated_at = now().
  5. Preserves a previously-set user_id: if the row already has an owner, the existing owner wins; if the row’s user_id is somehow nil, the validated incoming user_id is kept (this guard exists because a historical narrow SELECT id, metadata projection in the DAO could leave the in-memory row’s UserID nil, which would otherwise UPDATE the row to a null user_id and violate the NOT NULL constraint).
  6. Calls UpdateConnection, which updates every column except status.

The net effect: re-registering a Meshery Server is safe and idempotent with respect to identity. Only metadata and updated_at are intended to change across re-registrations.

ConditionBehavior
Session has no resolvable userRegistration is rejected before any DAO call. The caller sees an HTTP 500 with an error describing the missing user_id.
kind is not in the supported listHTTP 500 with an “unsupported connection kind” error.
server_id is missing from metadataThe lookup degenerates to metadata->>'server_id' IS NULL, which will not match any prior registration; a fresh row will be created. Always send a stable server_id.
DB error during lookup or writeWrapped in a structured MeshKit error and returned to the caller.

If you operate a self-hosted Layer5 Cloud and see registration-related errors, the symptoms below map to the most common root causes:

  • Postgres 23502 / meshery-server-1345 during auth completion β€” the registration call reached the DAO with a nil user_id. This is now caught by the handler-level guard described above; if you see it on a build that pre-dates that guard, upgrade. If you see it on a post-guard build, the session resolution itself is failing β€” check the logs around the request for missing JWT / Kratos session context.
  • A Meshery Server appears under the wrong user β€” check whether the operator authenticated as a different account against the Cloud session. The user_id is taken from the session, not the payload.
  • A Meshery Server’s display name keeps changing β€” pre-fix builds would rename existing rows when the payload omitted name. Upgrade to a build that preserves stable identity fields on re-registration (the behavior documented above).