TLS terminates at the edge
Certificates come from Let's Encrypt and renew automatically on a timer. HSTS is set with preload and subdomains, so browsers refuse to speak plain HTTP to this host at all.
This host exists so that Roleplay Project's own game servers, Discord and telemetry can talk to the platform over one deliberately small, heavily filtered surface. It is not a public developer API and no keys are issued to third parties.
Every request that reaches this host is counted at the edge, including the ones we refuse. Figures refresh every 20 seconds.
The whole public surface fits in one table. If a path is not listed, nginx returns 404 without contacting the application.
| Method | Path | Purpose | Auth | Limit | Body |
|---|---|---|---|---|---|
| POST | /v1/health | Heartbeat from an authorised game server.Registers the server, its addresses and version; unknown origins are flagged to operations. | shared key | 10 r/s, burst 20 | 256 KB |
| POST | /v1/event | Operational telemetry event.Structured events only. Free-form payloads are rejected. | shared key | 10 r/s, burst 20 | 256 KB |
| GET | /v1/config | Runtime configuration for an authorised server.Read-only. Contents depend on the caller's standing. | shared key | 10 r/s, burst 20 | 256 KB |
| POST | /discord/interactions | Discord interaction webhook.Only accepted with a valid Ed25519 signature from Discord over the timestamp and raw body. | signature | 30 r/s, burst 10 | 2 MB |
| ANY | /admin/* | Operator surface.Blocked at the edge with 403. Inside the application it is additionally bound to localhost, so a misconfigured proxy still cannot reach it. | — | — | — |
| ANY | /* | Everything else.404 from nginx. No application code runs. Plain HTTP on port 80 is also a flat 404, not a redirect. | — | — | — |
Each stage can refuse a request. The further left a refusal happens, the less it costs us and the less an attacker learns.
Certificates come from Let's Encrypt and renew automatically on a timer. HSTS is set with preload and subdomains, so browsers refuse to speak plain HTTP to this host at all.
nginx only knows four locations. Anything else, including probes for admin panels, environment files and old CMS paths, ends at the edge with a 404 or 403 and is logged for the watchdog.
Two independent limit zones keyed on the client address, with small bursts. A misbehaving integration or a flood is slowed to a trickle before it reaches the application.
Telemetry routes require a shared secret header known only to our own servers. Discord traffic is verified against Discord's public key with Ed25519; unsigned or stale requests get 401.
A valid key proves the caller has our software, not that it is allowed to run it. Reported and observed addresses are matched against an allowlist maintained by operations; unknown servers are surfaced to staff for a decision.
Bodies are capped at the edge and parsed as JSON with strict limits. The application never trusts client-supplied forwarding headers: the real address is rewritten by nginx on the way in.
Defence in depth: no single control is load-bearing. Each layer assumes the one before it has already failed.
max-age=31536000; includeSubDomains; preload.10 r/s on /v1/* and 30 r/s on Discord, each with a small burst. Exceeding them returns 429 with our own error page, not a stack trace.256 KB for telemetry, 2 MB for Discord, enforced before the request is proxied.X-Frame-Options: DENY, nosniff, Referrer-Policy: no-referrer, Cross-Origin-Resource-Policy: same-site, a locked-down Permissions-Policy, and a Content-Security-Policy on this page with frame-ancestors 'none'.no-store, so error states leak nothing about the upstream.127.0.0.1 inside a container. The only way in is through nginx; there is no exposed port./admin/* is refused by nginx and, independently, accepted by the application only from localhost.Most people who land here were looking for something else. This should save you a support ticket.
The shared key on this host is issued to Roleplay Project's own infrastructure only. Requests for it are declined.
Building something that signs people in with their RPP account? That is a different service: register an OAuth application in the UCP developer portal. You get a client id and secret, a standard authorisation-code flow against ucp.roleplayproject.net/api/oauth2, and users see exactly what your app may read before they approve it.
This host holds no player records. Characters, vehicles, properties, factions and support live on the User Control Panel, behind your own login, 2FA and audit trail.
Server population and platform health are published on the status page. This host answers only to authorised machines.
# heartbeat from an authorised game server curl -X POST https://api.roleplayproject.net/v1/health \ -H "x-telemetry-key: <issued to our servers only>" \ -H "Content-Type: application/json" \ --data '{"version":"…","ips":["…"],"hostname":"…"}' # and what everyone else gets curl -i https://api.roleplayproject.net/v1/config HTTP/2 403 curl -i https://api.roleplayproject.net/admin/servers HTTP/2 403 (from nginx, never proxied) curl -i https://api.roleplayproject.net/anything HTTP/2 404 (from nginx, never proxied)
Found a weakness? Tell us privately through a support ticket on the UCP marked "security", and give us a reasonable window to fix it before talking about it publicly. We do not pursue good-faith researchers.