Repository navigation
feat(auth): enforce media credentials on a tokened server (ADR-0176 Phase 4) - #482
Merged
Merged
Conversation
…hase 4) Point 8's trigger is met: app 1.7 (build 80), which sends the header on media (familiar-apple #267), is the only App Store build offered on iOS and macOS since 2026-11-11, and 1.5.1 had the same minimum OS. - MEDIA_ENFORCED is True: a media read needs the header, the media cookie or a server-signed URL. Tokenless servers are unchanged (ADR-0171). - Every media route answers Cache-Control: private (point 6), with a test that no route under app/ goes back to public. - The test that pinned the exemption now pins the refusal; both new tests fail against the Phase 3 code. - HEALTH row removed; ADR-0176 records Phase 4, and corrects Phase 3's "nothing calls the speaker route": Apple casting calls it. - SITE-CLAIMS: the site's "not the music" rows expire with this release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hase 4) An app from before 1.7 sends no credential on media and goes silent with no explanation. The server now logs a warning naming the client and the likely cause, once per client an hour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e release Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ADR-0176 Phase 4: media on a tokened server now requires one of the three credentials.
Trigger (point 8), checked on 2026-11-11. iOS and macOS 1.7 (build 80) were both released that day and read
READY_FOR_DISTRIBUTION. Build 80 was built from familiar-apple2649ca93, which contains #267 (the media header) and the re-vendored visualizer page. 1.5.1 had the same minimum OS (iOS 17.0 / macOS 14.4), so no device is offered it as a last compatible version.Consumers checked: the Apple engine, artwork, downloads and video send the header (#267). The web admin and
/embeduse the cookie. The visualizer uses a header plus adata:URL. Speakers get a signed URL fromPOST /outputs/{id}/play. ADR-0176 had recorded that nothing calls that route, but the Apple app's casting does (ServerCastOutputsSource.swift), so the signing is live and the route stays. Speaker metadata carries no artwork URL.Changes
MEDIA_ENFORCED = True.publictoCache-Control: private(streams already were).test_phase_4_ships_enforced,test_media_is_never_served_cache_control_public, andtest_the_middleware_refuses_media_with_no_credential, which replaces the test that pinned the exemption. All three fail against main.No schema change, so familiar-apple needs no re-vendor.
Old apps: when a media request is refused, the server logs a warning naming the client and the likely cause (an app older than 1.7), once per client per hour. Jeff's iPhone and Mac are both on 1.7 (80), checked.
Rollout: this reaches a listener only when their server upgrades. A tokened server on this code stops serving media to an app on 1.5.1 or an old TestFlight build. Deploying to the NAS is a separate step.
Not in this PR: the site's "Sign-in covers the library, not the music" (index.html) and the reverse-proxy answer (faq.html) become false with the release that ships this, and change with it: draft #483, to merge with that release.
Tests:
make checkpasses. Backend suite: 2665 passed, 18 skipped.🤖 Generated with Claude Code