diff --git a/openvidu-dashboard/openspec/changes/redact-custom-base-url/.openspec.yaml b/openvidu-dashboard/openspec/changes/redact-custom-base-url/.openspec.yaml deleted file mode 100644 index 97e364202..000000000 --- a/openvidu-dashboard/openspec/changes/redact-custom-base-url/.openspec.yaml +++ /dev/null @@ -1,2 +0,0 @@ -schema: spec-driven -created: 2026-10-27 diff --git a/openvidu-dashboard/openspec/changes/redact-custom-base-url/design.md b/openvidu-dashboard/openspec/changes/redact-custom-base-url/design.md deleted file mode 100644 index 5748cda4f..000000000 --- a/openvidu-dashboard/openspec/changes/redact-custom-base-url/design.md +++ /dev/null @@ -1,37 +0,0 @@ -# Design - -## Context - -- The codec copies a field of a protocol message only when the allow-list names it, with a rule per field. `redactURL` - rewrites a URL to scheme, host and path with the last segment replaced by `***`. -- `custom_base_url` has the rule `keep` in `RoomCompositeEgressRequest` and `TemplateSource`. The egress request - summary redacts it on its own, so only raw payloads hold the full value. - -## Goals / Non-Goals - -**Goals:** -- No stored payload holds the query string, userinfo or last path segment of a custom base URL. - -**Non-Goals:** -- Rewriting stored events. The read side of an edition may redact them again. - -## Decisions - -### Same rule as the web URL - -`custom_base_url` gets `redactURL`, the rule of `WebEgressRequest.url` and `WebSource.url`. A layout page under a -custom base URL is as likely as a web egress page to take a token in its query string or path. - -Alternative rejected: `stripURLCredentials`, which keeps the path. A token in the last path segment would survive. - -### Data model - -- Collections: `events` (payloads of `EGRESS_*` events). No field, type, index or retention change; no schema-version - change. -- Migration from legacy events: the legacy migration encodes with the same codec, so migrated payloads are redacted too. -- Performance: none. - -## Risks / Trade-offs - -- [The redacted value no longer opens the layout] → The value is shown for reference only; the request summary was - already redacted. diff --git a/openvidu-dashboard/openspec/changes/redact-custom-base-url/proposal.md b/openvidu-dashboard/openspec/changes/redact-custom-base-url/proposal.md deleted file mode 100644 index cc8350272..000000000 --- a/openvidu-dashboard/openspec/changes/redact-custom-base-url/proposal.md +++ /dev/null @@ -1,37 +0,0 @@ -# Proposal - -## Why - -The writer stores the `custom_base_url` of room composite requests and of the template source of unified egress -requests unchanged in raw event payloads. A custom base URL can carry a token in its query string, while the request -summary of the egress document already stores it redacted. - -## What Changes - -- Raw event payloads store `custom_base_url` redacted like the web URL: no userinfo, query string or fragment, and the - last path segment replaced by `***`. - -Scope excludes the following: -- Raw events already stored, which keep the value until they expire. -- Any other field of the allow-list. - -Edition: CE and PRO (writer). Repositories: openvidu-livekit (`openvidu/analytics/schema/allowlist.go`) and the specs -of the dashboard. - -CHANGELOG: none. The analytics data model has not shipped in a release. - -## Capabilities - -### New Capabilities - -None. - -### Modified Capabilities - -- `server-analytics-writer`: the secrets allow-list redacts custom base URLs. - -## Impact - -- Writer: the allow-list rule of `custom_base_url` in `RoomCompositeEgressRequest` and `TemplateSource`, and the codec - tests. -- Dashboard: none; the request summary is unchanged. diff --git a/openvidu-dashboard/openspec/changes/redact-custom-base-url/specs/server-analytics-writer/spec.md b/openvidu-dashboard/openspec/changes/redact-custom-base-url/specs/server-analytics-writer/spec.md deleted file mode 100644 index 110066e26..000000000 --- a/openvidu-dashboard/openspec/changes/redact-custom-base-url/specs/server-analytics-writer/spec.md +++ /dev/null @@ -1,22 +0,0 @@ -## MODIFIED Requirements - -### Requirement: Secrets allow-list -Edition: CE and PRO. Projectors SHALL copy only fields named in an explicit allow-list into any document, -including raw payloads; every other field, present or future, SHALL be dropped. Egress stream, web, websocket and -custom base URLs SHALL be stored without userinfo, query string and fragment and with their last path segment replaced -by `***`; the ingress URL SHALL be stored without userinfo, query string and fragment. - -#### Scenario: Fully populated messages -- **GIVEN** an `AnalyticsEvent` of every type with every string field set to a unique sentinel, including `room.turn_password`, egress storage credentials, webhook signing keys, egress tokens, `ingress.stream_key`, `ingress.url`, SIP credentials and `api_call` request bodies -- **WHEN** each is projected with `store_metadata` and IP storage enabled -- **THEN** the sentinels found in all write models are exactly those of the allow-list paths - -#### Scenario: Stream URL redacted -- **GIVEN** an egress with stream URL `rtmps://user:pw@live.example.com/app/live_123?token=abc` -- **WHEN** it is projected -- **THEN** the stored output URL is `rtmps://live.example.com/app/***` - -#### Scenario: Custom base URL redacted -- **GIVEN** a room composite egress, and a unified egress with a template source, both with custom base URL `https://layouts.example.com/app/index.html?token=abc` -- **WHEN** their `EGRESS_STARTED` events are stored -- **THEN** each raw payload holds `custom_base_url: "https://layouts.example.com/app/***"` diff --git a/openvidu-dashboard/openspec/changes/redact-custom-base-url/tasks.md b/openvidu-dashboard/openspec/changes/redact-custom-base-url/tasks.md deleted file mode 100644 index b5f38da8f..000000000 --- a/openvidu-dashboard/openspec/changes/redact-custom-base-url/tasks.md +++ /dev/null @@ -1,19 +0,0 @@ -# Tasks - -## 1. Writer (openvidu-livekit) - -- [x] 1.1 Give `custom_base_url` the `redactURL` rule in `RoomCompositeEgressRequest` and `TemplateSource` of - `openvidu/analytics/schema/allowlist.go`. Verify with a codec test that encodes both requests with a custom base - URL carrying a token, and with the codec suite. -- [x] 1.2 Add a custom base URL with a secret to the room composite egress of the writer test builders, so that the - integration suite's no-secret check covers it. Verify with the analytics integration tests and the lint of the - fork. - -## 2. Docs and CHANGELOG - -- [x] 2.1 No CHANGELOG line: the analytics data model has not shipped. No `AGENTS.md` changes. Verify by reading the - change against both files. - -## 3. Integration check - -- [x] 3.1 Run the spec validation and the format check of the dashboard. Verify that they pass. diff --git a/openvidu-dashboard/openspec/specs/server-analytics-writer/spec.md b/openvidu-dashboard/openspec/specs/server-analytics-writer/spec.md index bf14bf0c1..256635587 100644 --- a/openvidu-dashboard/openspec/specs/server-analytics-writer/spec.md +++ b/openvidu-dashboard/openspec/specs/server-analytics-writer/spec.md @@ -92,9 +92,9 @@ nanoseconds and microseconds; `rttMs` stays in milliseconds, `jitterMs` is deriv ### Requirement: Secrets allow-list Edition: CE and PRO. Projectors SHALL copy only fields named in an explicit allow-list into any document, -including raw payloads; every other field, present or future, SHALL be dropped. Egress stream, web and websocket -URLs SHALL be stored without userinfo, query string and fragment and with their last path segment replaced by `***`; -the ingress URL SHALL be stored without userinfo, query string and fragment. +including raw payloads; every other field, present or future, SHALL be dropped. Egress stream, web, websocket and +custom base URLs SHALL be stored without userinfo, query string and fragment and with their last path segment replaced +by `***`; the ingress URL SHALL be stored without userinfo, query string and fragment. #### Scenario: Fully populated messages - **GIVEN** an `AnalyticsEvent` of every type with every string field set to a unique sentinel, including `room.turn_password`, egress storage credentials, webhook signing keys, egress tokens, `ingress.stream_key`, `ingress.url`, SIP credentials and `api_call` request bodies @@ -106,6 +106,11 @@ the ingress URL SHALL be stored without userinfo, query string and fragment. - **WHEN** it is projected - **THEN** the stored output URL is `rtmps://live.example.com/app/***` +#### Scenario: Custom base URL redacted +- **GIVEN** a room composite egress, and a unified egress with a template source, both with custom base URL `https://layouts.example.com/app/index.html?token=abc` +- **WHEN** their `EGRESS_STARTED` events are stored +- **THEN** each raw payload holds `custom_base_url: "https://layouts.example.com/app/***"` + ### Requirement: Personal data flags Edition: CE and PRO. `anonymize_ip` SHALL remove the client IP addresses (`client_info.address` and `client_meta.client_addr`) from every document, and `store_metadata` SHALL gate room metadata, participant metadata