chore(module-uo): bootstrap repo with governance docs and templates

First commit for the UO module — the game-specific half of the Runic Gateway
website, extracted from core so that core can become game-agnostic. Phase 0 of
the module system plan (docs/website/MODULE_SYSTEM.md §2.7) calls for this repo
to get its initial commit before any module work starts.

Governance scaffolding only; no module code. The design of record settles the
API surface in Phase 1 and Phase 3 is what fills the repo, so writing module
code now would be writing against a contract that does not exist yet.

- README.md          what module-uo is, the phase table, the packaging layout,
                     and why an operator never builds anything
- CONTRIBUTING.md    planning status, the dev loop (a module is not runnable on
                     its own), the zero-internal-imports and one-path-segment
                     rules, schema fragments instead of migrations
- SECURITY.md        private reporting, plus the module-specific notes: the
                     module boundary is not a security boundary, access control
                     lives in core, and the uo-link token stays write-only
- CODE_OF_CONDUCT.md, CONTRIBUTORS.md, LICENSE.md (GPL-3.0-or-later),
  PR + issue templates — the same set every repo in the org carries
- .gitignore         Node-shaped; client/dist/ is ignored deliberately, since it
                     is a release artifact built by CI, not a source artifact

CI lands next, in a PR, mirroring how the installer repo was bootstrapped: an
empty repo cannot take a pull request, but everything after it can.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-10 02:39:23 -05:00
commit 26f2079cca
11 changed files with 1284 additions and 0 deletions

75
SECURITY.md Normal file
View File

@@ -0,0 +1,75 @@
# Security Policy
Thank you for helping keep Runic Gateway and its users safe.
## Reporting a vulnerability
**Please do not report security vulnerabilities through public issues, pull
requests, or the wiki.** A public report tips off attackers before a fix is
available.
Instead, report privately by email to:
**whitlocktech@gmail.com**
Please include as much of the following as you can:
- The repository and component affected.
- The type of issue (e.g. authentication bypass, injection, secret exposure,
remote code execution, denial of service).
- Step-by-step instructions to reproduce, and a proof-of-concept if you have one.
- The impact — what an attacker could do with it.
- Any suggested remediation.
You will receive an acknowledgement of your report, typically within a few days.
We will keep you informed as we investigate and work toward a fix, and we are
happy to credit you in the release notes once the issue is resolved (let us know
if you would prefer to remain anonymous).
## Scope
Runic Gateway is a self-hosted platform made up of several components:
| Component | Repo | Network exposure |
|---|---|---|
| Website core (site + admin + API) | `RunicGateway/website` | Internet-facing (behind a reverse proxy) |
| **module-uo** (this repo) | `RunicGateway/Module-uo` | No listener of its own — runs inside the website process |
| uo-link sidecar | `RunicGateway/link` | The only network-facing part of the game bridge |
| ServUO plugin | `RunicGateway/servuo-plugins` | Loopback only — dials the sidecar on `127.0.0.1` |
| Installer | `RunicGateway/installer` | Not a service — an operator-run deployment tool |
| Documentation | `RunicGateway/docs` | Content only |
Because instances are self-hosted, the security of any given deployment also
depends on how it is configured and operated — strong secrets (`JWT_SECRET`,
`SECRET_ENC_KEY`, database and admin passwords), a correctly configured reverse
proxy and `TRUST_PROXY`, and keeping the shard itself unreachable from the
internet (only the sidecar should be exposed). See each repo's README for the
security model.
### Module-specific notes
Three things follow from what a module *is*, and they are policy rather than
oversight:
- **The module boundary is not a security boundary.** A module runs in the same
Node process as core with the same privileges, and its schema fragment runs
against the same database. It is a code-organisation and distribution boundary.
Installing a module is the same trust decision as installing the site itself —
which is appropriate for a self-hosted operator choosing their own software, and
is why module installation is admin-only. "A module can reach core internals" is
therefore not a vulnerability report; "an unprivileged user can install or
enable a module" very much is.
- **Access control lives in core, not in the module and never in the sidecar.**
Route protection is core's `requireAuth` / `requireRole` middleware, and what a
visitor is allowed to see of live shard state is the website's admin-toggleable
visibility framework. A module route that reaches shard data without going
through those is a security bug worth reporting.
- **This module handles the uo-link auth token.** It is encrypted at rest with
core's `secretBox` and is **write-only** in the API — never returned to any
client, in any shape. Anything that would echo it back, log it, or expose it to
the browser is a security issue.
## Supported versions
This project is developed continuously and does not maintain long-term release
branches. Security fixes land on `main`; please run a recent build.