Repository navigation
App Review: provision an isolated dedicated Jellyfin demo environment #280
Description
Activity
jlipworth commented
on Aug 22, 2026 OwnerAuthorMore actionsPublic-demo evaluation update (2026-08-22):
- The official stable demo at https://demo.jellyfin.org/stable/ is live on Jellyfin 10.11.11 and is explicitly offered by Jellyfin for evaluation/testing.
- A credential-ephemeral PMSKit live probe passed the shared views, items, and metadata wrappers (HTTP 200); no token/session/response body was retained and no timeline mutation was enabled.
- The account is passwordless, which exposed a Labstream UI defect now tracked in Support passwordless Jellyfin accounts #283. A separate Codex task is implementing that fix.
- The demo currently provides Movies, Shows, Music, Playlists, artwork, and playable public/open test media.
- It is not yet accepted as the final App Review dependency: shared preferences are mutable, downloads are disabled, historical Jellyfin guidance warns of resets, and marketing-use provenance for each visible poster/backdrop still needs to be established.
Decision: evaluate the public stable demo first and avoid provisioning new infrastructure unless it fails cross-platform sign-in/playback, rights, reliability, screenshot determinism, or complete reviewer-access gates. Keep this dedicated environment issue open as the fallback/likely final-review lane, but do not provision it yet.
Public-demo UI evaluation update (2026-08-22):
- Passwordless support is now merged on
mainthrough Support passwordless Jellyfin accounts #283 / PR Support passwordless Jellyfin accounts #284. - Clean iPhone and iPad simulator reviewer journeys both passed ordinary UI sign-in, Home browse, opening a live detail surface, and rendered playback against the official stable demo.
- The result is technically compatible but unsuitable as the final deterministic review/screenshot environment. The shared account exposed pre-existing progress and arbitrary Continue Watching state; identical fresh logins inherited that mutable state.
- Home artwork did not finish loading before the first semantically-ready capture even though metadata rails were present, while detail artwork loaded later. Store capture therefore needs explicit artwork-readiness gates and controlled assets.
- The public account disables downloads while Labstream's download-capable platforms still expose the feature, so it cannot demonstrate the complete submitted product contract.
- Catalog/artwork marketing-rights provenance remains unresolved.
Decision: the no-new-infrastructure experiment has now failed the determinism, complete-review-access, and rights gates even though compatibility passed. Proceed with this issue's minimal controlled environment. Prefer the smallest isolated container/LXC that meets the security and availability contract rather than a general-purpose VM.
Remaining device-family testing should be repeated against the controlled catalog once available; there is no value in treating further shared-demo success as closing the blockers above.
- Passwordless support is now merged on
Infrastructure progress: a dedicated GitOps merge request is open for an isolated, non-admin Jellyfin App Review environment. It includes a deterministic fictional Movies/Shows/Music catalog with playable video, audio, subtitles, chapters, and downloads; read-only regenerated media; nightly account-state reset; public-path health checks; bounded/redacted logging; backup/rotation/shutdown procedures; and machine-readable provenance for the procedural payload and candidate key art. The public hostname and all credentials remain outside Git.
Remaining human gates are: approve the candidate artwork for App Review/storefront use, enter the private secrets, create the publicly resolvable proxied DNS record for ordinary trusted HTTPS, merge/promote the infrastructure change, and complete the documented off-LAN TestFlight iPhone/iPad journey. No App Store Connect state was changed.
Infrastructure MR: https://gitlab.com/jlipworth/proxmox-project/-/merge_requests/321
Infrastructure update (sanitized): the Jellyfin review change is now on the GitOps deployment branch and Argo observed the deployed revision. The namespace, restricted policies/RBAC, both Longhorn PVCs, service, bounded CronJobs, monitoring rule, and checksum-pinned media seed reconciled. The live seed Job completed and verified the prepared Blender open-film release; the completed Job also remained stable across Argo retries rather than downloading it repeatedly. Target-based unit, Kustomize client/server dry-run, and isolated real-Jellyfin ingest/direct-play/byte-range integration checks passed before promotion.
The live close-loop is not complete.
ExternalSecret/jellyfin-review-credentialsisReady=False(SecretSyncedError) because the private Infisical entry/kubernetes/apps/jellyfin-reviewdoes not yet exist. No target Secret was created, so Argo correctly stopped before the Jellyfin Deployment and hostname-derived Certificate/IngressRoute. Consequently there is no live endpoint yet, and public DNS/TLS,/health, reviewer authentication, Movies/Shows/Music browse with the Blender artwork, actual live playback/download, reset, and off-LAN checks could not be run. Bounded Job/events/log inspection found this missing-secret gate and no media-seed failure.Exact human gate (values must remain private): create
ADMIN_PASSWORD,ADMIN_PASSWORD_PREVIOUS(initially equal),REVIEW_PASSWORD, andPUBLIC_HOSTNAMEat that Infisical path; then create the proxied publicly resolvable DNS record for the selected hostname. After External Secrets and Argo retry successfully, the live smoke/reset and off-LAN iPhone/iPad journey still must pass before this can be called closed.GitLab MR !321 is superseded by the owner-authorized direct deployment; its source is aligned with the deployment branch and has no intended merge delta.
Sanitized infrastructure close-loop update: the selected hostname now has an explicit Cloudflare-proxied public A record managed by the existing Kubernetes DDNS workflow. The protected API check confirmed the record is present and proxied without displaying its content. LAN resolvers now CNAME that same hostname to Cloudflare's public edge, so on-LAN traffic does not bypass the selected public path.
External Secrets reconciled the four private values (
Ready=True) without displaying them. Argo completed successfully at the deployment revision and both the Jellyfin and DDNS Applications areSynced/Healthy. The Jellyfin Deployment is 1/1 ready, the media seed remains complete, the Certificate is Ready, and the TLS IngressRoute is active. During live rollout validation I corrected three deployment-only issues found in the real environment: insufficient config-PVC headroom, the post-DNAT Kubernetes API egress port needed by the least-privileged edge reconciler, and Cloudflare rejecting urllib's generic default user agent. All fixes landed directly onk8s_deploymentand reconciled successfully.Deployed public-path validation passed: trusted TLS and
/health; reviewer authentication with the non-admin/download-enabled policy; hidden admin absent from the public user list; Movies, Shows, and Music browse; Spring and Wing It! presence and primary artwork loading; actual 64 KiB byte-range playback and download from Spring; video/audio/subtitle streams and chapters; and the public attribution page. A deliberately created reviewer favorite was then removed by the real reset Job, which reported nine catalog records restored, and a fresh sign-in confirmed clean state. The scheduled (not only manual) public smoke also completed successfully. Independent external probes in North America and Europe both received HTTP 200 with authorized TLS, providing an off-LAN path check.The deployed infrastructure validation loop is closed. A final physical TestFlight journey on the required iPhone/iPad families (including offline download playback and UI-level browse/detail/seek/subtitle behavior) remains a human device/App Review gate; this infrastructure result does not claim that device-level gate has run.
Reviewed screenshot/provenance branch 7f93e1e without merging: nine screenshot tooling tests pass; the plan distinguishes synthetic placeholders from final app captures and preserves required display-class, attribution and age-suitability gates. Actual screenshots, normal review-account login and exact TestFlight reviewer journeys remain open. Separate privacy follow-up #325 reconciles the public no-developer-backend claim with this project-operated review/demo service; infrastructure evidence alone does not approve privacy disclosures or close #280.
Goal
Provision a dedicated, isolated Jellyfin environment that gives Apple App Review a stable end-to-end Labstream path without exposing a personal media server, household account, private hostname, or real library.
Apple requires full review access for account-based features and says backend services must remain live and accessible during review. The current public Jellyfin project demo is useful for development but is third-party infrastructure outside our control; the release candidate should have a Labstream-owned fallback or primary review environment.
Proposed shape
Known Proxiesconfigured correctly.Security/privacy constraints
Review runbook
Acceptance
References
Operational privacy follow-up (from #325)
These checks apply only to the project-operated reviewer/demo service, not every user-selected server or the client's local diagnostic storage. #325 owns disclosure reconciliation; this issue owns the service facts it needs.
Verified read-only evidence is recorded in PR #329's sanitized audit: route access logs disabled; Jellyfin Warning logs use bounded file-count/size rotation; the scheduled reset clears catalog progress/favorites, not auth/device/activity records or backups. Configured retention is not proof of effective deletion.
These open operational checks do not invalidate the evidence that normal client diagnostics stay local until an explicit sharing action; they concern records held by the separately selected project-operated server.