Skip to content

feat(playmatch): support self-hosted Playmatch instances#3827

Merged
gantoine merged 5 commits into
masterfrom
feat/playmatch-custom-url
Jul 19, 2026
Merged

feat(playmatch): support self-hosted Playmatch instances#3827
gantoine merged 5 commits into
masterfrom
feat/playmatch-custom-url

Conversation

@gantoine

@gantoine gantoine commented Jul 19, 2026

Copy link
Copy Markdown
Member

Description
Explain the changes or enhancements you are proposing with this pull request.

Adds a PLAYMATCH_API_URL environment variable so users can point RomM at a self-hosted Playmatch instance instead of the public one. This helps users on slow connections or those who prefer to run their own instance (as Playmatch encourages).

  • New PLAYMATCH_API_URL config, defaulting to the public instance (https://playmatch.retrorealm.dev/api/v2); trailing slashes are stripped so endpoint paths always join cleanly.
  • PlaymatchHandler now derives its identify, health, and suggestion endpoints from this configurable base URL.
  • Documented the override in env.template.

SSRF handling for private destinations

A typical self-hosted URL (http://playmatch:8000, localhost, or a LAN IP) points at a private/internal address, which the shared HTTP client's SSRF defense rejects before connecting, so health checks and lookups would fail. To support these deployments:

  • Added a narrowly scoped allowlist (SSRF_ALLOWED_INTERNAL_ORIGINS) derived only from admin-configured provider URLs (currently just PLAYMATCH_API_URL).
  • Both SSRF gates honor it: the static URL event hook and the connect-time network backend.
  • The exception is matched by exact host and port, so it does not open any other internal service, and the public default URL is unaffected (public addresses already pass).

Behavior is unchanged for existing users, since the default remains the public URL. Self-hosters just set PLAYMATCH_API_URL.

Fixes #3820

Checklist
Please check all that apply.

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Screenshots (if applicable)


AI assistance: this change was written with the help of Claude Code (Anthropic). All code was reviewed by the author.

🤖 Generated with Claude Code

Add a PLAYMATCH_API_URL env var (defaulting to the public instance) so
users can point RomM at a self-hosted Playmatch deployment. The handler
now derives all endpoints from this configurable base URL.

Fixes #3820

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 19, 2026 13:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes the Playmatch API base URL configurable. The main changes are:

  • Adds PLAYMATCH_API_URL with the existing public service as its default.
  • Builds Playmatch identify, health, and suggestion endpoints from that URL.
  • Documents the setting in env.template.

Confidence Score: 4/5

Common Docker and LAN Playmatch deployments remain unreachable through the changed configuration path.

  • The public default and endpoint construction remain compatible.
  • Private and loopback destinations are rejected before the Playmatch request connects.
  • The main self-hosting workflow can therefore fail for realistic deployments.

backend/config/init.py and the SSRF handling used by the Playmatch HTTP requests

Security Review

The configured destination still passes through SSRF protection, which blocks private and loopback addresses. Supporting self-hosted instances needs a narrow exception for the configured Playmatch origin without weakening checks for other requests or redirects.

Important Files Changed

Filename Overview
backend/config/init.py Adds the configurable Playmatch base URL, but common private self-hosted destinations remain blocked by outbound request validation.
backend/handler/metadata/playmatch_handler.py Uses the configured base URL consistently for all existing Playmatch endpoints.
env.template Documents the optional Playmatch API URL override.

Fix All in Claude Code

Reviews (1): Last reviewed commit: "feat(playmatch): support self-hosted Pla..." | Re-trigger Greptile

Comment thread backend/config/__init__.py
gantoine and others added 4 commits July 19, 2026 12:33
A self-hosted PLAYMATCH_API_URL on a LAN IP, localhost, or a Docker
service name is rejected by the shared HTTP client's SSRF defense before
connecting, so health checks and lookups fail. Add a narrowly scoped
allowlist, derived from the admin-configured provider URL, that both SSRF
gates (the static URL hook and the connect-time backend) honor. The
exception is matched by exact host and port, and the public default URL
is unaffected since public addresses already pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gantoine
gantoine merged commit 677937e into master Jul 19, 2026
10 checks passed
@gantoine
gantoine deleted the feat/playmatch-custom-url branch July 19, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] set playmatch hostname/IP to support selfhosted instances

2 participants