Skip to content

Commit 8c0f733

Browse files
authored
Merge pull request #952 from layer5io/docs/cloud-meshery-server-registration
docs(cloud): add Meshery Server Registration concept page
2 parents f3925d3 + 02b5fee commit 8c0f733

2 files changed

Lines changed: 112 additions & 14 deletions

File tree

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,12 @@
11
---
22
title: Concepts
33
weight: 2
4-
draft: true
54
description: >
65
An overview of Layer5 Cloud concepts and their relationships.
76
---
87

98
![concepts-overview](images/concepts-overview.svg "image-center-shadow")
109

11-
<!--
12-
{{% pageinfo %}}
13-
Page under construction.
14-
{{% /pageinfo %}}
10+
This section explains the underlying concepts of Layer5 Cloud — the building blocks that the rest of the documentation assumes you understand.
1511

16-
For many projects, users may not need much information beyond the information in the [Overview](/docs/overview/), so this section is **optional**. However if there are areas where your users will need a more detailed understanding of a given term or feature in order to do anything useful with your project (or to not make mistakes when using it) put that information in this section. For example, you may want to add some conceptual pages if you have a large project with many components and a complex architecture.
17-
18-
Remember to focus on what the user needs to know, not just what you think is interesting about your project! If they don’t need to understand your original design decisions to use or contribute to the project, don’t put them in, or include your design docs in your repo and link to them. Similarly, most users will probably need to know more about how features work when in use rather than how they are implemented. Consider a separate architecture page for more detailed implementation and system design information that potential project contributors can consult.
19-
20-
21-
{{ $context := . }}
22-
{{ range $taxo, $taxo_map := .Site.Taxonomies }}
23-
{{ partial "taxonomy_terms_article.html" (dict "context" $context "taxo" $taxo ) }}
24-
{{ end }} -->
12+
- [Meshery Server Registration](meshery-server-registration) — How a Meshery Server registers itself with Layer5 Cloud as its Remote Provider, how Cloud identifies an existing registration, and what fields are preserved across re-registration.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
title: Meshery Server Registration
3+
description: >
4+
How a Meshery Server registers itself with Layer5 Cloud as its Remote Provider, what data is recorded, and how re-registration is handled.
5+
weight: 1
6+
categories: [Concepts]
7+
tags: [connections, remote-provider, meshery-server]
8+
---
9+
10+
Layer5 Cloud is a [Meshery Remote Provider](https://docs.meshery.io/extensibility/providers). 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).
11+
12+
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.
13+
14+
## Why Registration Exists
15+
16+
The Meshery Server / Remote Provider boundary has two requirements:
17+
18+
1. **Identity** — Cloud needs to know *which* Meshery Server is calling, so multiple Meshery deployments can talk to the same Cloud tenant without colliding.
19+
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.
20+
21+
A registration record satisfies both: it associates a unique server identifier with a user and an Organization, and it survives across Meshery Server restarts.
22+
23+
## Identifying a Meshery Server
24+
25+
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.
26+
27+
Cloud's uniqueness rule for an existing Meshery registration is the triple:
28+
29+
```
30+
(kind = 'meshery', user_id, metadata.server_id)
31+
```
32+
33+
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.
34+
35+
## Registration Endpoint
36+
37+
Meshery Server registers by `POST`ing a connection payload to:
38+
39+
```
40+
POST /api/integrations/connections
41+
```
42+
43+
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`.
44+
45+
Required payload fields:
46+
47+
| Field | Description |
48+
|------------|-------------|
49+
| `kind` | Must be `meshery`. |
50+
| `metadata.server_id` | Stable UUID generated by the Meshery Server. |
51+
52+
Optional payload fields:
53+
54+
| Field | Description |
55+
|------------|-------------|
56+
| `name` | Human-readable display name. If omitted, Cloud generates `meshery-<random>`. |
57+
| `type` / `sub_type` | Free-form classification fields. |
58+
| `metadata` | Additional JSON metadata (e.g. server version, hostname). |
59+
| `status` | Initial status (defaults to the system's registered state). |
60+
61+
The handler chain is `RegisterConnection``MesheryConnectionUtilityHandlerRegistration` → either `CreateConnection` or `UpdateConnection`.
62+
63+
## What Happens on First Registration
64+
65+
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.
66+
2. `CheckMesheryServerExistence` looks for a row matching `(meshery, user_id, server_id)`.
67+
3. No match is found, so a new row is inserted via `CreateConnection`.
68+
4. The new Connection inherits the user's Organization for tenant isolation.
69+
70+
## What Happens on Re-Registration
71+
72+
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.
73+
74+
The handler:
75+
76+
1. Validates the session's `user_id` (same as first registration).
77+
2. Finds the existing row via `CheckMesheryServerExistence`.
78+
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.
79+
4. **Preserves the existing row's `created_at`**, sets `updated_at = now()`.
80+
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).
81+
6. Calls `UpdateConnection`, which updates every column except `status`.
82+
83+
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.
84+
85+
{{< alert type="info" title="Why status is excluded from updates" >}}
86+
Connection status transitions are managed through dedicated lifecycle endpoints (e.g. connect / disconnect, ignore, delete), not through registration. A re-registration call cannot reset a previously-disconnected Meshery Server's status by accident.
87+
{{< /alert >}}
88+
89+
## Validation and Error Cases
90+
91+
| Condition | Behavior |
92+
|-----------|----------|
93+
| Session has no resolvable user | Registration is rejected before any DAO call. The caller sees an HTTP 500 with an error describing the missing `user_id`. |
94+
| `kind` is not in the supported list | HTTP 500 with an "unsupported connection kind" error. |
95+
| `server_id` is missing from `metadata` | The 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`. |
96+
| DB error during lookup or write | Wrapped in a structured MeshKit error and returned to the caller. |
97+
98+
## Operator Guidance
99+
100+
If you operate a self-hosted Layer5 Cloud and see registration-related errors, the symptoms below map to the most common root causes:
101+
102+
- **`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.
103+
- **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.
104+
- **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).
105+
106+
## Where the Code Lives
107+
108+
- Handler: [`server/handlers/connections.go`](https://github.com/layer5io/meshery-cloud/blob/master/server/handlers/connections.go)`RegisterConnection`, `MesheryConnectionUtilityHandlerRegistration`
109+
- DAO: [`server/dao/connections.go`](https://github.com/layer5io/meshery-cloud/blob/master/server/dao/connections.go)`CheckMesheryServerExistence`, `CreateConnection`, `UpdateConnection`
110+
- Schema: [`meshery/schemas` — Connection](https://github.com/meshery/schemas)

0 commit comments

Comments
 (0)