Configuration: the .env and the overlay
Paracosm's configuration has two layers:
.envin the source root: every secret and every per-install value. It is git-ignored and never shipped;.env.exampleis the template. The Python tools load it throughtools/paracosm_env.py.- The templates in
config/: Paracosm's changes to OpenSimulator's own example files, with${NAME}placeholders filled from.env. Nothing secret lives in them.
tools/make_config.py joins the two into the server's bin/ (the build runs it; see quickstart.md
section 5):
python tools/make_config.py <bin> [--env <env file>] [--force]
writes (in <bin>) |
from |
|---|---|
OpenSim.ini |
OpenSim.ini.example + config/paracosm.ini |
config-include/StandaloneCommon.ini |
config-include/StandaloneCommon.ini.example + config/StandaloneCommon-overlay.ini |
config-include/FlotsamCache.ini, config-include/osslEnable.ini |
their .example files, unchanged (without them every boot logs a warning about a missing include) |
Regions/Regions.ini |
config/Regions.ini.template, with a region UUID made once |
OpenSim.exe.config |
config/OpenSim.exe.config, copied as it is: OpenSim's log4net config with OpenSim.log rolling at 20 MB, five old files kept (operations.md, Logs) |
- The merge: for each key in an overlay section, a line for that key in the same section of the example (active,
or commented out as
; key =) is replaced in place; a key the example lacks is added under the section header; a section it lacks is appended. - Existing files are kept.
--forcerewritesOpenSim.ini,StandaloneCommon.iniandRegions.ini, writing a.bakof each first;Regions.inikeeps itsRegionUUID, so a region never changes identity.FlotsamCache.iniandosslEnable.iniare never overwritten, so your edits to them survive. OpenSim.exe.config: every build has upstream's copy (its log grows forever), so a file byte-identical to upstream's is replaced (a.bakfirst). One that differs from both upstream's and ours is kept unless--force. It takes effect at OpenSim's next start.- Anything you add to
bin/OpenSim.iniby hand is lost on the next--force. Put it in.env(and, for a key the overlay does not have yet, inconfig/paracosm.ini) instead; the WorldBridge role tokens have.envkeys. - A placeholder whose key is missing from both the environment and
.envis written empty and reported:WARNING: not set in the environment/.env (left empty): .... An optional placeholder,${NAME?}, instead drops its whole line when the key is unset or empty, and is not reported: the role tokens use it. - The env file:
--env <file>, elsePARACOSM_ENV, else.envin the source root (the same rule as the other tools). An--envfile that cannot be read stops it; a missing default only prints a note. - It refuses to write anything if a role token is set but shorter than 16 characters, the retired demo token,
still a
change-meplaceholder, or holds a quote,;or whitespace.
How .env is read
KEY=VALUE per line; blank lines and lines starting with # are skipped; quotes around a value are stripped;
nothing is expanded. A variable already set in the process environment wins over the file. The tools find the file
at PARACOSM_ENV if set, else .env in the source root.
Every key in .env.example
"Change" says whether a new install must change the template's value.
Paths
| key | template value | read by | controls | change |
|---|---|---|---|---|
PARACOSM_ROOT |
commented out (C:/path/to/paracosm) |
tools/paths.py, so every tool |
the source root. Unset (or not an existing folder, with a warning), the repo the tools sit in | no |
PARACOSM_BIN |
commented out (C:/path/to/paracosm/opensim-src/bin) |
tools/paths.py: run_server.py, backup.py, wb.py, region_restart.py |
the server's bin/ folder: where OpenSim runs, its databases and logs. Unset, <source root>/opensim-src/bin |
yes: <build output>/bin |
The grid and the region (written into OpenSim's config)
| key | template value | becomes | controls | change |
|---|---|---|---|---|
PARACOSM_LOGIN_URI |
http://127.0.0.1:9000 |
(not config) | the login URI run_viewer.py and the test bot use; run_viewer.py accepts only a loopback one |
only with a different port |
PARACOSM_GRID_NAME |
Paracosm |
[GridInfoService] gridname |
the grid's name, as viewers show it | optional |
PARACOSM_GRID_NICK |
paracosm |
[GridInfoService] gridnick |
the grid's short name | optional |
PARACOSM_EXTERNAL_HOST |
127.0.0.1 |
[Const] BaseHostname; Regions.ini ExternalHostName |
the address in the login and service URLs, and where viewers send region traffic. 127.0.0.1 = this machine only |
for LAN or remote use (quickstart section 12) |
PARACOSM_PORT |
9000 |
[Const] PublicPort; [Network] http_listener_port; Regions.ini InternalPort |
the simulator's TCP port (login, capabilities) and the region's UDP port | only to run a second server on one machine |
PARACOSM_REGION_NAME |
Paracosm |
the Regions.ini section name |
the region's name | optional |
PARACOSM_REGION_LOCATION |
1000,1000 |
Regions.ini Location |
the region's grid coordinates, in 256 m cells | optional |
PARACOSM_REGION_SIZE |
256 |
Regions.ini SizeX, SizeY |
metres per side: 256, 512 (2x2 var region) or 768 (3x3); a multiple of 256, square |
optional; before the first start |
PARACOSM_ESTATE_NAME |
Paracosm Estate |
[Estates] DefaultEstateName |
the estate the first start creates | optional |
PARACOSM_ESTATE_OWNER_FIRST, PARACOSM_ESTATE_OWNER_LAST |
Resident, Spirit |
[Estates] DefaultEstateOwnerName |
the estate owner, created on the first start. Each part must be one word (OpenSim splits the name at the space). Also read by backup.py (the owner's IAR) |
yes |
PARACOSM_ESTATE_OWNER_PASSWORD |
change-me |
[Estates] DefaultEstateOwnerPassword |
the estate owner's password, used only when the first start creates the account. Also read by backup.py (save iar) |
yes; never empty |
PARACOSM_ESTATE_EMAIL |
[email protected] |
[Estates] DefaultEstateOwnerEMail |
the estate owner's email | optional |
The [Estates] values matter only on the first start. Later changes do not rename the owner or change the
password; use the console (reset user password <first> <last> <password>) and then update .env.
Accounts the tools log in with
| key | template value | read by | controls | change |
|---|---|---|---|---|
PARACOSM_RESIDENT_FIRST, _LAST, _PASSWORD |
Resident, Spirit, change-me |
run_viewer.py (the default, --as resident), backup.py (IAR) |
the AI resident's own avatar. The template makes it the estate owner; then its password must equal PARACOSM_ESTATE_OWNER_PASSWORD |
yes |
PARACOSM_OWNER_FIRST, _LAST, _PASSWORD |
empty | run_viewer.py --as owner |
a person's own avatar, launched through the same viewer build without the helper bridge | optional |
PARACOSM_BOT_FIRST, _LAST, _PASSWORD |
Test, Bot, change-me |
bot/Program.cs |
the LibreMetaverse test bot's account (create it first). The bot reads its process environment, not the .env file |
only if you use the bot |
OpenSim's REST console
| key | template value | becomes | controls | change |
|---|---|---|---|---|
PARACOSM_CONSOLE_USER |
empty | [Network] ConsoleUser |
the REST console's user name. Empty: the REST console refuses every session | set it (with a password) only when you need a console on a headless server |
PARACOSM_CONSOLE_PASS |
empty | [Network] ConsolePass |
its password. OpenSim checks only the user name for "off": with a user name set and this empty, an empty password logs in | set a strong one whenever the user is set |
PARACOSM_CONSOLE_PORT |
9001 |
[Network] console_port |
the REST console's port (plain HTTP, all interfaces) | optional; firewall it |
tools/run_server.py always starts OpenSim with -console=rest (a detached process has no terminal, and a local
console dies at startup). Connect with dotnet OpenSim.ConsoleClient.dll -host 127.0.0.1 -port <port> -user <user> -pass <password> from bin/.
WorldBridge
| key | template value | becomes / read by | controls | change |
|---|---|---|---|---|
WORLDBRIDGE_URL |
http://127.0.0.1:9002 |
wb.py |
where the tools reach WorldBridge | only with WORLDBRIDGE_PORT |
WORLDBRIDGE_PORT |
9002 |
[WorldBridge] Port |
WorldBridge's port (always on 127.0.0.1) | optional; keep it equal to the URL's port |
WORLDBRIDGE_ALLOW_CONSOLE |
false |
[WorldBridge] AllowConsole |
whether the console op may run server console commands (see Security) |
true only if the resident needs it, or for a backup with the OAR, IARs and terrain (without it backup.py copies only the databases and state) |
WORLDBRIDGE_FILE_ROOTS |
worldbridge-files |
[WorldBridge] FileRoots |
the folders a request may name files in (see Security) | optional |
WORLDBRIDGE_OBSERVER_TOKEN, WORLDBRIDGE_BUILDER_TOKEN, WORLDBRIDGE_GAIA_TOKEN |
commented out (change-me-...) |
[WorldBridge] TokenObserver, TokenBuilder, TokenGaia |
extra bearer tokens with a role (the table under the overlay). Each line is written only when its key is set; 16 characters or more (python -c "import secrets; print(secrets.token_hex(24))"). A client uses one as its WORLDBRIDGE_TOKEN |
optional; never the template's value (make_config.py refuses it) |
WORLDBRIDGE_TOKEN_FILE |
commented out (C:/path/to/paracosm/opensim-src/bin/WorldBridge.token) |
wb.py (so also run_server.py stop and backup.py) |
the token file WorldBridge writes on its first start. Unset or empty, wb.py uses <PARACOSM_BIN>/WorldBridge.token, which is where WorldBridge writes it |
only if the file is elsewhere; the MCP server needs it in its own env |
The viewer's helper bridge
| key | template value | read by | controls | change |
|---|---|---|---|---|
PARACOSM_VIEWER_TOKEN |
commented out | run_viewer.py, tools/leap_bridge.py, the MCP server |
the bearer token of the LEAP bridge on 127.0.0.1:9004. Unset, run_viewer.py makes a fresh random one per launch and the bridge writes it to a per-user token file the tools and the MCP read (tools/PORTABILITY.md) |
no; set it only to pin one token on purpose |
Optional environment variables (not in the template)
| variable | read by | default | does |
|---|---|---|---|
PARACOSM_ENV |
tools/paracosm_env.py (every tool), tools/make_config.py (when no --env) |
<source root>/.env |
the env file the tools load (the systemd unit sets it) |
PARACOSM_BACKUP_DIR |
backup.py |
<source root>/backups (git-ignored) |
where backups go |
WORLDBRIDGE_TOKEN |
wb.py, the MCP server |
none | a token given directly; wins over the token file |
WORLDBRIDGE_REGION |
wb.py, the MCP server |
none: the simulator's first region | on a simulator with several regions, the region (name or uuid) a call goes to when it names none itself; sent as ?region= (worldbridge.md, "Several regions") |
VIEWER_URL, VIEWER_TOKEN |
the MCP server | http://127.0.0.1:9004; VIEWER_TOKEN is a legacy name, read only when neither PARACOSM_VIEWER_TOKEN nor the bridge's token file gives one |
the viewer bridge the viewer_* tools call |
PARACOSM_VIEWER_EXE, PARACOSM_VIEWER_DATA |
run_viewer.py |
a development build under C:/fs/phoenix-firestorm |
the viewer exe, and the folder it runs in (a packaged viewer: its own folder) |
PARACOSM_VIEWER_PORT |
run_viewer.py, leap_bridge.py |
9004 |
the bridge's port |
PARACOSM_VIEWER_MUTE |
run_viewer.py |
unset | 1 starts the viewer muted |
PARACOSM_ASSET_INSTR |
OpenSim (the asset-instr patch) |
unset | 1 in OpenSim's environment logs every GetAssets request, miss and serve (GETASSET-INSTR in OpenSim.log) |
FS_ROOT, VCVARS, PY_SCRIPTS |
viewer-build/*.bat, package.py (FS_ROOT) |
C:\fs, VS 2022 Build Tools' vcvars64.bat, %APPDATA%\Python\Python312\Scripts |
the viewer build (packaging.md) |
The overlay, block by block
config/paracosm.ini (merged into OpenSim.ini)
| block | key = value | upstream default | what it does |
|---|---|---|---|
[Const] |
BaseHostname = "${PARACOSM_EXTERNAL_HOST}" |
"127.0.0.1" |
the host in BaseURL, which builds the login URI ([GridInfoService] login), the home and service URLs, and the map tile URL |
PublicPort = "${PARACOSM_PORT}" |
"9000" |
the port in those URLs | |
[Permissions] |
region_manager_is_god = true |
false | estate managers may use god powers (they still ask for them in the viewer each session) |
[Estates] |
DefaultEstateName, DefaultEstateOwnerName, DefaultEstateOwnerUUID = 00000000-0000-0000-0000-000000000000 (a random UUID), DefaultEstateOwnerEMail, DefaultEstateOwnerPassword |
commented out (the first start prompts for them) | the first start creates the estate and its owner with no prompt |
[Network] |
http_listener_port = ${PARACOSM_PORT} |
9000 | the simulator's HTTP port. OpenSim does not derive it from PublicPort; left at 9000, a second server on one machine cannot start |
ConsoleUser, ConsolePass, console_port |
commented out | the REST console (above) | |
[Groups] |
Enabled = true, LevelGroupCreate = 0, Module = "Groups Module V2", StorageProvider = OpenSim.Data.SQLite.dll, ConnectionString = "URI=file:groups.db,version=3", ServicesConnectorModule = "Groups Local Service Connector", LocalService = local, MessagingEnabled = true, MessagingModule = "Groups Messaging Module V2", MessageOnlineUsersOnly = true, NoticesEnabled = true |
groups off | Groups V2 stored in bin/groups.db. Needs the sqlite-groups patch (the build applies it). WorldBridge's group op and the shared-group editing model use it (sharing-and-inventory.md) |
[Messaging] |
OfflineMessageModule = "Offline Message Module V2", StorageProvider = OpenSim.Data.SQLite.dll, ConnectionString = "URI=file:offlineim.db,version=3" |
no offline messages | offline IM on (below). Needs the sqlite-offlineim patch: with an unpatched OpenSim.Data.SQLite.dll OpenSim stops at startup |
[UserProfiles] |
ProfileServiceURL = "${PARACOSM_PROFILE_SERVICE_URL?}" (written only when set) |
unset: basic profiles only | OFF by default: full profiles need PARACOSM_PROFILE_SERVICE_URL and PARACOSM_FULL_PROFILES=true in the .env, and then the profile service answers on the grid port without credentials (below) |
[WorldBridge] |
Enabled = true |
(module default true) | loads the control channel |
BindAddress = "127.0.0.1" |
127.0.0.1 | anything but 127.0.0.1 or localhost is logged as a warning and forced back to 127.0.0.1 |
|
Port = ${WORLDBRIDGE_PORT} |
9002 | the channel's port | |
MaxBodyBytes = 65536 |
65536 | the largest request body; a bigger one gets 413 | |
TokenFile = "WorldBridge.token" |
WorldBridge.token |
where the generated gaia token is kept (relative to OpenSim's working directory, bin/) |
|
AllowConsole = ${WORLDBRIDGE_ALLOW_CONSOLE} |
false | the console op |
|
FileRoots = "${WORLDBRIDGE_FILE_ROOTS}" |
worldbridge-files |
the file roots | |
TokenObserver = "${WORLDBRIDGE_OBSERVER_TOKEN?}", TokenBuilder = "${WORLDBRIDGE_BUILDER_TOKEN?}", TokenGaia = "${WORLDBRIDGE_GAIA_TOKEN?}" |
none | role tokens (below); each line only when its .env key is set |
WorldBridge also reads these keys; the overlay leaves them at their module defaults (commented out in
config/paracosm.ini), so add one to bin/OpenSim.ini (or uncomment it in the overlay) to change it. The request
queue is described in worldbridge.md ("The request queue"); the rate limit in worldbridge/HARDENING.md.
| key | module default | what it does |
|---|---|---|
MaxConcurrent |
1 (1..64) |
worker threads for the commands that change the world (the work lane): how many run at once. 1 keeps them one at a time, as they always ran; only spawn, spawn_mesh and list were load-tested side by side (at 4), so raise it only after testing your own workload |
QueueLimit |
64 |
work-lane requests that may WAIT for a worker; one more is answered 503 with Retry-After at once, and nothing runs |
ReadWorkers |
2 (1..64) |
worker threads for the read commands (state, list, heightmap, avatars, chat, inspect, worn, contents, anims, raycast, roam {status:true}), which never wait behind the work lane |
ReadQueueLimit |
256 |
read-lane requests that may wait; beyond it, 503 |
QueueWaitSec |
20 (at least 1) |
a request that has waited longer than this is answered 503 instead of run (its caller has probably given up) |
RateLimitPerSec, RateLimitBurst |
50, 100 |
the per-token rate limit (429); RateLimitPerSec = 0 turns it off |
DeleteSupersededScripts |
true |
set_script deletes the script asset it replaces when that asset is provably unused |
WorldBridge's token keys. The role tokens come from .env; AuthToken has no .env key and the overlay does not
set it (the token file is the intended way), so it would have to be added to bin/OpenSim.ini by hand, and again
after every make_config.py --force:
| key | .env key |
role | rule |
|---|---|---|---|
AuthToken |
none | gaia | used instead of the token file when set. Refused (with a warning) if shorter than 16 characters or equal to the retired demo token paracosm-worldbridge-token |
TokenObserver |
WORLDBRIDGE_OBSERVER_TOKEN |
observer | read only: state, list, heightmap, avatars, chat, inspect, worn, contents |
TokenBuilder |
WORLDBRIDGE_BUILDER_TOKEN |
builder | observer + spawn, recolor, rez_item, put_notecard |
TokenGaia |
WORLDBRIDGE_GAIA_TOKEN |
gaia | every command |
Each token must be 16 characters or more and not the retired demo value, or it is refused. A token listed twice
gets its best role. A request with a token whose role is too low gets 403 naming the role needed.
The gaia token: from AuthToken if valid; else read from TokenFile; else (missing, too short, or the demo value)
a new random 48-character token is generated and written to TokenFile. To rotate it, stop the server, delete the
file, start the server, and restart every MCP client (they read the token once).
config/StandaloneCommon-overlay.ini (merged into config-include/StandaloneCommon.ini)
| block | key | from |
|---|---|---|
[GridInfoService] |
gridname = "${PARACOSM_GRID_NAME}", gridnick = "${PARACOSM_GRID_NICK}" |
.env |
[UserProfilesService] |
Enabled = ${PARACOSM_FULL_PROFILES?} (written only when set; upstream: false), ConnectionString = "URI=file:profiles.db,version=3" (upstream: commented out, so OpenSim.db) |
the overlay: the local profiles service and its own database file, off unless the .env turns it on |
Offline messages and profiles
Both run inside the simulator and store to their own SQLite file in bin/ (tools/backup.py copies every *.db).
Offline IM ([Messaging], OpenSim's OpenSim/Addons/OfflineIM). An instant message, inventory offer, group
notice or group invitation to someone who is not logged in is stored in offlineim.db and delivered at their next
login; the sender of an IM sees "User is not logged in. Message saved." Up to 25 are kept per recipient
(MaxOfflineIMs; past it the sender sees "Message not saved"), and messages older than 14 days are dropped each
time OpenSim starts. Group notices and invitations are kept too (ForwardOfflineGroupMessages, default true).
OpenSim 0.9.3.0 has this storage for MySQL and PostgreSQL only; the sqlite-offlineim patch adds it for SQLite.
To turn offline IM off, remove the three [Messaging] lines from config/paracosm.ini and run
make_config.py --force.
Profiles ([UserProfiles] in OpenSim.ini, [UserProfilesService] in StandaloneCommon.ini) are OFF by
default: set PARACOSM_PROFILE_SERVICE_URL (e.g. http://127.0.0.1:9000) and PARACOSM_FULL_PROFILES=true in the
.env and run make_config.py to turn them on, only where the grid port is trusted (see the credentials note). With a
ProfileServiceURL the viewer's profile window gets the full set: About and First Life text and pictures, web
URL, interests, picks, classifieds, notes on other avatars, and the privacy preferences (IM to email, online
status). Without one it gets the basic profile only. The storage is profiles.db; the sqlite-profiles patch fixes
four upstream SQLite bugs (the preferences were never stored, a classified could not be deleted). ProfileServiceURL
is loopback on purpose: the region is the only caller for local avatars, and a loopback URL does not depend on
PARACOSM_EXTERNAL_HOST resolving or on the router reaching its own public address. OpenSim resolves the URL at
startup and stops if it cannot. [UserProfiles] AllowUserProfileWebURLs (default true) can stop profiles sending
people to web pages. To turn full profiles off, empty ProfileServiceURL and set [UserProfilesService] Enabled
false.
The profile service answers JSON-RPC on the simulator's HTTP port with no credentials of any kind (upstream's design; a grid's ROBUST server exposes the same methods). Anyone who can reach that port can read any local avatar's profile, including the email address that the preferences call returns, and can change it. On a world only you reach this changes nothing; on one other machines reach, see Security below and tls.md.
Tested offline (2026-09-27, opensim-patches/sqlite-offlineim/README.md and sqlite-profiles/README.md): the
config as make_config.py writes it, loaded by OpenSim's own ConfigurationLoader, starts the offline IM module
and the profiles service; messages store, cap and deliver once; profile, notes and preferences calls work over
HTTP through OpenSim's own JSON-RPC client. Not tested with a viewer on a running region.
config/Regions.ini.template (written to Regions/Regions.ini)
| key | value | notes |
|---|---|---|
| section name | [${PARACOSM_REGION_NAME}] |
the region's name |
RegionUUID |
made once by make_config.py |
kept on every later run; a fixed UUID would collide between installs |
Location |
${PARACOSM_REGION_LOCATION} |
grid cells of 256 m |
SizeX, SizeY |
${PARACOSM_REGION_SIZE} |
var regions: 512 or 768 |
InternalAddress |
0.0.0.0 |
the region's UDP socket listens on every interface |
InternalPort |
${PARACOSM_PORT} |
the UDP port |
AllowAlternatePorts |
False |
|
ExternalHostName |
${PARACOSM_EXTERNAL_HOST} |
the address viewers are told to send UDP to |
The template makes one region. For more, add a section per region to bin/Regions/Regions.ini by hand, AFTER the
existing one: its own name, a fresh RegionUUID, a free Location (a 512 region at 1001,1000 covers cells
1001-1002 x 1000-1001), and its own InternalPort. A new region joins the estate named by DefaultEstateName
(the overlay's [Estates] block). One WorldBridge channel serves them all; the first region loaded is the default
one and keeps the unsuffixed state files (worldbridge.md, "Several regions").
Security-relevant settings
| setting | default | risk | advice |
|---|---|---|---|
[WorldBridge] AllowConsole (WORLDBRIDGE_ALLOW_CONSOLE) |
false |
the console op runs ANY OpenSim console command: shutdown, create user, reset user password, load oar, terrain load of any path. Console commands are not confined by FileRoots |
leave it off unless the resident needs it. backup.py needs it on for the OAR, IARs and terrain (it copies the databases and state without it); run_server.py stop uses it for a clean shutdown and otherwise terminates the process |
[WorldBridge] FileRoots (WORLDBRIDGE_FILE_ROOTS) |
worldbridge-files (beside OpenSim) |
the file-taking ops read (or, for bundle, write) the server's disk |
a file outside every root is refused: spawn_mesh, upload_texture, upload_sound and store_anim answer 403 file outside FileRoots for their file; a spawn_mesh lods file outside fails the request (500); a physics file outside falls back to box physics; bundle skips writing its file. Roots are ;-separated; a relative root is resolved against bin/; each is created if missing |
the gaia token (bin/WorldBridge.token) |
generated on the first start | full control of the world | keep the file private; give an AI a lower role token (WORLDBRIDGE_OBSERVER_TOKEN, _BUILDER_TOKEN) when it does not need gaia |
| WorldBridge's bind address | 127.0.0.1 | none by default; any local process or user with the token can connect | never tunnel, proxy or port-forward 9002 (no TLS; the rate limit and the request queue bound load, not access; tls.md has the only shape to consider if an AI must run elsewhere) |
the REST console (PARACOSM_CONSOLE_USER/PASS, port 9001) |
off (empty user) | plain HTTP on all interfaces; the credentials travel in clear | leave it off unless you need it; if on, set a strong password and firewall 9001. It is off only while the USER is empty |
bin/OpenSim.ini |
written by make_config.py |
holds the estate owner's password and the console password in clear | treat it like .env: never share, commit or ship it |
[Permissions] region_manager_is_god |
true in the overlay |
any estate manager can god-edit anything on the region | make estate managers only of people you trust (grant_estate_manager) |
PARACOSM_VIEWER_TOKEN |
unset: a fresh random token per viewer launch, in a per-user file | the LEAP bridge (loopback) drives the viewer; /snapshot writes only inside its snapshot folder |
keep the token file private; pin a token only on purpose |
PARACOSM_EXTERNAL_HOST |
127.0.0.1 | changing it is what makes the world reachable from other machines | expose only port 9000 (TCP and UDP); tls.md |
the profile service ([UserProfilesService] Enabled) |
on | its JSON-RPC methods on the simulator port (9000, all interfaces) take no credentials: anyone who reaches the port can read and change any local avatar's profile and read the email in their preferences | on a world other machines reach, decide whether that is acceptable; turning full profiles off is above. The simulator port listens on every interface even while PARACOSM_EXTERNAL_HOST is 127.0.0.1, so a machine on the same network can reach it unless the firewall stops it |