Feature Specification: Component peertube

Created: 2026-10-07

Status: Implemented

Input: Reconstructed from the code of core/components/operator/peertube/ and the shared operator component code at 14504f80d, pull requests #1384, #1597, #1651, #1694, #1724, #1753, #1835, #1853, #1911.

User Scenarios & Testing (mandatory)

User Story 1 - Run a PeerTube instance for a group (Priority: P1)

An operator enables peertube in the operator group. The component requests single sign-on, mail, cache, database, object storage, generated secrets, workload identity, TLS and public ports, and the setups route each request to a provider. The node serves PeerTube on its own subdomain and accepts RTMP and RTMPS live streams. The family spec ../spec.md gives what all operator applications share.

Why this priority: The component exists to deploy this application.

Independent Test: A VM test posts a video in the browser, finds it in garage, and backs up the database.

Acceptance Scenarios:

  1. Given the component is enabled, When it evaluates, Then it places all of its requests, with public web and stream ports. When it is disabled, it places none.

User Story 2 - Log in with the group's single sign-on (Priority: P1)

A user logs in with the account from the group directory. PeerTube has no declarative plugin option, and its plugin installer needs the network. So the component installs the OpenID Connect plugin offline, and writes the plugin record and its settings into the database.

Why this priority: SSO is the only path from the group directory to the application.

Independent Test: The VM test checks the client, the discovery, the issuer and the secret. No unit test covers the plugin install.

Acceptance Scenarios:

  1. Given PeerTube serves HTTP, When the plugin install runs, Then the live plugin store has the plugin, and the database has its record with the issuer, the client and the scopes.
  2. Given the client secret arrives empty, When the install fails, Then it retries after a short delay.

User Story 3 - Configure the instance policy (Priority: P2)

An operator sets the instance policy. The option type comes from the configuration schema that PeerTube ships, narrowed to a selection of keys.

Why this priority: The instance works with the defaults.

Independent Test: Unit tests cover the schema helpers. No check evaluates the selection of peertube itself.

Acceptance Scenarios:

  1. Given a security key, for example the SSRF protection of federation or the root login switch, When the operator sets it, Then the schema refuses the value.
  2. Given an operator value for a service option that the component also sets, When the node evaluates, Then the evaluation fails and names the option.

User Story 4 - Store media in garage and back up the database (Priority: P3)

PeerTube writes videos and playlists to garage and serves them from the bucket. The component backs up the database with restic.

Why this priority: Media in object storage keeps the node small, and recovery needs the database.

Independent Test: The storage and backup parts of the VM test.

Acceptance Scenarios:

  1. Given a routed postgresql provider, When the backup runs, Then the dump connects to the remote host with the rendered password and the TLS mode of the result.

Edge Cases

  • Without a redis or postgresql provider, a local Redis or PostgreSQL runs on the node.
  • A database result that asks to verify the server fails the evaluation, because the result gives no CA for the database client.
  • PeerTube starts after its passwords are rendered. A rotated password reaches PeerTube only on its next start.
  • The plugin install waits for the HTTP listener, because a storage directory that root makes first makes PeerTube fail on permissions.
  • The CORS rule of the buckets allows any origin. This is a design choice: the player of another PeerTube instance fetches the segments of a federated video with a script. The buckets need no credentials, so a script reads only what a direct request reads too.

Requirements (mandatory)

Functional Requirements

  • FR-001: The component MUST declare the PeerTube package and its icon, and MUST be optional in the group.
  • FR-002: The component MUST offer the shared options with the default subdomain peertube, and MUST expose only the settings of PeerTube.
  • FR-003: The component MUST type the settings with the pinned PeerTube schema, narrowed by an allow-list at the top level and by deny-lists of security keys in the federation, tracker, user and client sections.
  • FR-004: The component MUST request an oidc client with both plugin callbacks and the scopes openid, profile and email, and MUST give PeerTube the issuer.
  • FR-005: The plugin install MUST read the client secret only as its own credential, and MUST run after PeerTube without a hard dependency on it.
  • FR-006: The component MUST request smtp with a no-reply sender on its domain, MUST use STARTTLS, and MUST load the password as a credential.
  • FR-007: The component MUST request redis in its own namespace, with TLS and the CA of the result when the result says so, and MUST load the password as a credential. In a tenant deployment, the namespace carries the deployment namespace.
  • FR-008: The component MUST request a postgresql database and user for PeerTube, and MUST use TLS unless the result turns it off.
  • FR-009: The component MUST request garage website buckets for videos and playlists, whose CORS rule allows any origin, and MUST render the S3 keys at run time.
  • FR-010: The component MUST request spiffe, ssl for its domain, and public HTTP, HTTPS, RTMP and RTMPS ports from firewall.
  • FR-011: The nixos-module request MUST enable PeerTube behind nginx on HTTPS.
  • FR-012: The component MUST request a streaming backup of the database with restic.
  • FR-013: The redis and postgresql requests MUST contain only data. The node MUST render the clients from the contract results, and nothing when a result is absent.

Key Entities

  • Plugin install: The one-shot step that installs the offline plugin, built from a vendored lock file, and seeds its record.
  • Application secret: A generated secret, kept in OpenBao per deployment. PeerTube restarts when the agent renders a different value.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: The VM test passes. A posted video is in garage, and the backup works.
  • SC-002: The unit tests of the operator configuration and of the database and cache gates pass.
  • SC-003: After one plugin install, the plugin settings carry the display name of the project SSO.

Assumptions

  • The operator group has the shared valkey, smtp, lldap and authelia components.
  • The schema comes from a pin of the release that the package builds, and the evaluation stops when the two differ. Releases ship the schema from 8.3.0 on. A rename of a selected key fails the evaluation.
  • The mail overrides of PeerTube in the environment have no effect under NixOS, so mail goes through the settings.

Known Deviations

None.