From b0c3925e62c3d8f4726bfbc3ab37299714bb7ab6 Mon Sep 17 00:00:00 2001 From: ParthrChandurkar Date: Fri, 13 Nov 2026 13:27:50 +0000 Subject: [PATCH 1/5] docs: add public event feed reference Signed-off-by: ParthrChandurkar --- content/en/cloud/reference/_index.md | 1 + .../cloud/reference/api-reference/_index.md | 2 + .../api-reference/public-event-feed.md | 186 ++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 content/en/cloud/reference/api-reference/public-event-feed.md diff --git a/content/en/cloud/reference/_index.md b/content/en/cloud/reference/_index.md index 314fbfc9642..5268362c681 100644 --- a/content/en/cloud/reference/_index.md +++ b/content/en/cloud/reference/_index.md @@ -18,6 +18,7 @@ These pages state facts about Layer5 Cloud: which plan includes a capability, wh | [Sessions]({{< ref "cloud/concepts/identity-and-security/sessions.md" >}}) | Check session lifetimes, cookies, and how to sign out a session. | | [Tokens]({{< ref "cloud/concepts/identity-and-security/tokens.md" >}}) | Create, list, rotate, and revoke API tokens. | | [Cloud API]({{< ref "cloud/reference/api-reference/_index.md" >}}) | Authenticate, set the organization, page through results, and handle errors. | +| [Public Event Feed]({{< ref "cloud/reference/api-reference/public-event-feed.md" >}}) | Retrieve publicly shared events and understand visibility, privacy, and sharing preferences. | | [Rate limits]({{< ref "cloud/reference/api-reference/rate-limits.md" >}}) | Check which API routes are rate limited, the limit for each route family, and how to handle HTTP 429. | ## Security permission keys {#permission-keys} diff --git a/content/en/cloud/reference/api-reference/_index.md b/content/en/cloud/reference/api-reference/_index.md index 32411ea04b3..617d32df965 100644 --- a/content/en/cloud/reference/api-reference/_index.md +++ b/content/en/cloud/reference/api-reference/_index.md @@ -12,6 +12,8 @@ Every endpoint lives under `/api` on the host of your Layer5 Cloud deployment. H Some route families are rate limited per caller. See [Rate limits]({{< ref "cloud/reference/api-reference/rate-limits.md" >}}) for the limits and how to handle HTTP 429. +For an unauthenticated endpoint that returns publicly shared events, see the [Public Event Feed]({{< ref "cloud/reference/api-reference/public-event-feed.md" >}}) reference. + ## Authenticating with the API In order to authenticate to Layer5 Cloud's REST API, you need to generate and use a [security token]({{< ref "cloud/concepts/identity-and-security/tokens.md" >}}). Visit your [user account's security tokens](https://cloud.layer5.io/security/tokens) and generate a long-lived token. Security tokens remain valid until you revoke them, and you can issue as many as you need. diff --git a/content/en/cloud/reference/api-reference/public-event-feed.md b/content/en/cloud/reference/api-reference/public-event-feed.md new file mode 100644 index 00000000000..e011103c823 --- /dev/null +++ b/content/en/cloud/reference/api-reference/public-event-feed.md @@ -0,0 +1,186 @@ +--- +title: Public Event Feed +weight: 10 +--- + + +The public event feed provides an unauthenticated, read-only view of +events that users have chosen to share publicly. + +## Get the public event feed + +`GET /api/events/feed` + +This endpoint does not require authentication. It returns eligible public +events in reverse chronological order, with the newest events first. + +An event appears in the feed only when: + +- Its visibility is set to `public`. +- Its owner's `shareActivityPublicly` preference is enabled. +- It meets the feed's required metadata checks. + +The preference is checked when the feed is requested. Disabling it hides +that user's previously public events from subsequent feed responses; it +does not rewrite those events. + +## Query parameters + +| Parameter | Type | Constraints | Default | Description | +|---|---|---|---|---| +| `page` | Integer | Minimum: `0` | — | Zero-based page number. | +| `pagesize` | Integer | 1–50 | `20` | Number of events per page. | +| `category` | String | Maximum length: `500` | — | Filters by category. | +| `action` | String | Maximum length: `500` | — | Filters by action. | + +The `category` and `action` filters are optional and can be used together. + +## Response + +A successful request returns a JSON object containing pagination metadata +and the event records. + +| Field | Type | Description | +|---|---|---| +| `page` | Integer | Current zero-based page number. | +| `pageSize` | Integer | Number of events requested per page. | +| `totalCount` | Integer | Total number of matching public events. | +| `data` | Array | Eligible event records for the current page. | + +Each event in `data` contains the following required fields: + +| Field | Type | Description | +|---|---|---| +| `id` | String | Event identifier. | +| `userId` | String | Identifier of the event owner. | +| `category` | String | Event category. | +| `action` | String | Event action. | +| `createdAt` | String | Event creation timestamp. | +| `visibility` | String | Visibility; feed records are `public`. | +| `platform` | String | Platform associated with the event. | +| `role` | String | Role associated with the event. | +| `line` | String | Line associated with the event. | + +The following fields are optional: + +| Field | Type | Description | +|---|---|---| +| `networks` | Array | Network information, when available. | +| `displayName` | String | Public display name, when available. | +| `avatarUrl` | String | Public avatar URL, when available. | +| `organizationName` | String | Organization name, when available. | +| `publicProfileUrl` | String | Public profile URL, when available. | + +### Example response + +```json +{ + "page": 0, + "pageSize": 20, + "totalCount": 1, + "data": [ + { + "id": "event-123", + "userId": "user-456", + "category": "deployment", + "action": "completed", + "createdAt": "2026-11-13T06:00:00Z", + "visibility": "public", + "platform": "Kubernetes", + "role": "Developer", + "line": "Production deployment completed", + "networks": [], + "displayName": "Alex", + "avatarUrl": "https://example.com/avatar.png", + "organizationName": "Example Organization", + "publicProfileUrl": "https://example.com/profile/alex" + } + ] +} +``` + +## Privacy and data visibility + +The feed exposes only a limited projection of public event data. + +- Only events with `visibility: "public"` are eligible. +- The owner's `shareActivityPublicly` preference is checked when the + feed is requested. +- The feed does not expose email addresses, first names, last names, + descriptions, providers, or raw event metadata. +- The `platform`, `role`, `line`, and `networks` fields are projected + from the event's schedule-completion metadata. +- Events without valid required metadata are omitted from the feed. +- Public profile information, when available, is resolved at request time. + +## Caching and rate limiting + +### Caching + +Responses may be cached publicly using the `Cache-Control` response header. + +The maximum cache lifetime is 30 seconds (`max-age` is no greater than +`30`). Because the owner's sharing preference is evaluated when the feed +is requested, a preference change may take up to the cache lifetime to +be reflected in cached responses. + +### Rate limiting + +Requests to the public event feed are rate-limited by client IP address. + +When the rate limit is exceeded, the API returns HTTP `429 Too Many +Requests` and includes a `Retry-After` header indicating when the client +can retry. + +## Sharing preference + +The `shareActivityPublicly` preference controls whether a user's public +events appear in the public event feed. + +It is an account-wide boolean preference that can be updated through: + +`PUT /api/identity/users/preferences` + +| Value | Behavior | +|---|---| +| `true` | The user's public events are eligible for the feed. | +| `false` | The user's events are hidden from the feed. | + +If the preference is absent, it defaults to `true`. + +The preference update accepts boolean values. Non-boolean values are +rejected with HTTP `400 Bad Request`. + +Changing the preference affects feed visibility at read time. Existing +events are not rewritten when the preference is changed. + +## Publishing public events + +Events are created through: + +`POST /api/events` + +The `visibility` field controls whether an event is private or public. + +| Value | Behavior | +|---|---| +| `private` | The event remains private. This is the default. | +| `public` | Eligible for the feed if the owner's preference allows it. | + +Example request: + +```json +{ + "category": "deployment", + "action": "completed", + "visibility": "public" +} +``` + +If `visibility` is omitted, the event defaults to `private`. Setting it +to `public` does not override the owner's `shareActivityPublicly` +preference. From e3fe97034a1be6fd0594fd57a08cd75623ab6163 Mon Sep 17 00:00:00 2001 From: ParthrChandurkar Date: Fri, 13 Nov 2026 16:51:11 +0000 Subject: [PATCH 2/5] docs: address public event feed review feedback Signed-off-by: ParthrChandurkar --- .../api-reference/public-event-feed.md | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/content/en/cloud/reference/api-reference/public-event-feed.md b/content/en/cloud/reference/api-reference/public-event-feed.md index e011103c823..19a3fb7f4a2 100644 --- a/content/en/cloud/reference/api-reference/public-event-feed.md +++ b/content/en/cloud/reference/api-reference/public-event-feed.md @@ -39,6 +39,9 @@ does not rewrite those events. The `category` and `action` filters are optional and can be used together. +The `pagesize` parameter must be between `1` and `50`. Values outside +this range are rejected with HTTP `400 Bad Request`. + ## Response A successful request returns a JSON object containing pagination metadata @@ -71,10 +74,9 @@ The following fields are optional: |---|---|---| | `networks` | Array | Network information, when available. | | `displayName` | String | Public display name, when available. | -| `avatarUrl` | String | Public avatar URL, when available. | +| `avatarUrl` | String | Avatar URL, if the user has a public profile. | | `organizationName` | String | Organization name, when available. | -| `publicProfileUrl` | String | Public profile URL, when available. | - +| `publicProfileUrl` | String | Profile URL, if the user has a public profile. | ### Example response ```json @@ -121,12 +123,15 @@ The feed exposes only a limited projection of public event data. ### Caching -Responses may be cached publicly using the `Cache-Control` response header. +Responses include the following `Cache-Control` header: + +```http +Cache-Control: public, max-age=30 +``` -The maximum cache lifetime is 30 seconds (`max-age` is no greater than -`30`). Because the owner's sharing preference is evaluated when the feed -is requested, a preference change may take up to the cache lifetime to -be reflected in cached responses. +This allows public caching for up to 30 seconds. Because the owner's +sharing preference is evaluated when the feed is requested, a preference +change may take up to the cache lifetime to be reflected in cached responses. ### Rate limiting @@ -141,10 +146,22 @@ can retry. The `shareActivityPublicly` preference controls whether a user's public events appear in the public event feed. -It is an account-wide boolean preference that can be updated through: +It is an account-wide boolean preference that can be updated through +the following endpoint using an authenticated session: `PUT /api/identity/users/preferences` +The request body is a JSON object containing the preferences to update. +Each field is optional, and omitted fields retain their existing values. + +Example request: + +```json +{ + "shareActivityPublicly": false +} +``` + | Value | Behavior | |---|---| | `true` | The user's public events are eligible for the feed. | @@ -166,6 +183,10 @@ Events are created through: The `visibility` field controls whether an event is private or public. +The event owner is determined by the authenticated calling session or +user token. The owner's `shareActivityPublicly` preference controls +whether the event can appear in the public feed. + | Value | Behavior | |---|---| | `private` | The event remains private. This is the default. | From c371a069c59576e7cb7a9ea645202cae92f2c0d2 Mon Sep 17 00:00:00 2001 From: Parth Chandurkar Date: Fri, 13 Nov 2026 22:29:24 +0530 Subject: [PATCH 3/5] Update content/en/cloud/reference/api-reference/public-event-feed.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Carlos Rîo Silva <209376648+carlosriosilva@users.noreply.github.com> Signed-off-by: Parth Chandurkar --- content/en/cloud/reference/api-reference/public-event-feed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/cloud/reference/api-reference/public-event-feed.md b/content/en/cloud/reference/api-reference/public-event-feed.md index 19a3fb7f4a2..95f14050ea5 100644 --- a/content/en/cloud/reference/api-reference/public-event-feed.md +++ b/content/en/cloud/reference/api-reference/public-event-feed.md @@ -33,7 +33,7 @@ does not rewrite those events. | Parameter | Type | Constraints | Default | Description | |---|---|---|---|---| | `page` | Integer | Minimum: `0` | — | Zero-based page number. | -| `pagesize` | Integer | 1–50 | `20` | Number of events per page. | +| `pagesize` | Integer | 1-50 | `20` | Number of events per page. A value outside 1-50 returns HTTP `400 Bad Request`. | | `category` | String | Maximum length: `500` | — | Filters by category. | | `action` | String | Maximum length: `500` | — | Filters by action. | From 42c524ef738652198e510d3900e6a54bbde9fa7a Mon Sep 17 00:00:00 2001 From: Parth Chandurkar Date: Fri, 13 Nov 2026 22:30:51 +0530 Subject: [PATCH 4/5] Update content/en/cloud/reference/api-reference/public-event-feed.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Carlos Rîo Silva <209376648+carlosriosilva@users.noreply.github.com> Signed-off-by: Parth Chandurkar --- content/en/cloud/reference/api-reference/public-event-feed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/cloud/reference/api-reference/public-event-feed.md b/content/en/cloud/reference/api-reference/public-event-feed.md index 95f14050ea5..467fb7d7fe6 100644 --- a/content/en/cloud/reference/api-reference/public-event-feed.md +++ b/content/en/cloud/reference/api-reference/public-event-feed.md @@ -181,7 +181,7 @@ Events are created through: `POST /api/events` -The `visibility` field controls whether an event is private or public. +The event's owner is always the authenticated caller; a client cannot set the owner. The `visibility` field controls whether an event is private or public. The event owner is determined by the authenticated calling session or user token. The owner's `shareActivityPublicly` preference controls From 80401d5db870a02ea4643c076f4b2229438e8925 Mon Sep 17 00:00:00 2001 From: ParthrChandurkar Date: Fri, 13 Nov 2026 17:32:15 +0000 Subject: [PATCH 5/5] docs: refine public event feed reference Signed-off-by: ParthrChandurkar --- .../api-reference/public-event-feed.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/content/en/cloud/reference/api-reference/public-event-feed.md b/content/en/cloud/reference/api-reference/public-event-feed.md index 19a3fb7f4a2..be9cc2264ea 100644 --- a/content/en/cloud/reference/api-reference/public-event-feed.md +++ b/content/en/cloud/reference/api-reference/public-event-feed.md @@ -33,7 +33,7 @@ does not rewrite those events. | Parameter | Type | Constraints | Default | Description | |---|---|---|---|---| | `page` | Integer | Minimum: `0` | — | Zero-based page number. | -| `pagesize` | Integer | 1–50 | `20` | Number of events per page. | +| `pagesize` | Integer | 1-50 | `20` | Number of events per page. A value outside 1-50 returns HTTP `400 Bad Request`. | | `category` | String | Maximum length: `500` | — | Filters by category. | | `action` | String | Maximum length: `500` | — | Filters by action. | @@ -77,6 +77,7 @@ The following fields are optional: | `avatarUrl` | String | Avatar URL, if the user has a public profile. | | `organizationName` | String | Organization name, when available. | | `publicProfileUrl` | String | Profile URL, if the user has a public profile. | + ### Example response ```json @@ -98,7 +99,6 @@ The following fields are optional: "networks": [], "displayName": "Alex", "avatarUrl": "https://example.com/avatar.png", - "organizationName": "Example Organization", "publicProfileUrl": "https://example.com/profile/alex" } ] @@ -123,15 +123,16 @@ The feed exposes only a limited projection of public event data. ### Caching -Responses include the following `Cache-Control` header: +Successful responses carry a `Cache-Control` header with a `max-age` +value of up to 30 seconds: -```http -Cache-Control: public, max-age=30 -``` +`Cache-Control: public, max-age=N` -This allows public caching for up to 30 seconds. Because the owner's -sharing preference is evaluated when the feed is requested, a preference -change may take up to the cache lifetime to be reflected in cached responses. +The value of `N` can range from `0` to `30`. Shared caches may serve a +response for the specified duration. Because the owner's sharing +preference is evaluated when the feed is requested, a preference +change may take up to the cache lifetime to be reflected in cached +responses. ### Rate limiting @@ -181,7 +182,7 @@ Events are created through: `POST /api/events` -The `visibility` field controls whether an event is private or public. +The event's owner is always the authenticated caller; a client cannot set the owner. The `visibility` field controls whether an event is private or public. The event owner is determined by the authenticated calling session or user token. The owner's `shareActivityPublicly` preference controls