Skip to main content

Configuration

GEM's server configuration lives in gem.json at the install root, loaded at startup. The standard installer writes a working gem.json for you; this page explains the settings you're most likely to change.

Where settings live

gem.json holds server bootstrap settings — how to reach the database, which ports to bind, whether HTTPS and the remote tunnel are on. Everything else (devices, zones, users, macros, attributes) is stored in the database and configured through the admin interface, not this file.

Database connection

{
"data": {
"connection": {
"host": "localhost",
"port": 5432,
"user": "gem_user",
"password": "gempass",
"database": "gem_db"
},
"sequelize": {
"dialect": "postgres",
"schema": "gem",
"timezone": "America/Chicago"
}
}
}
  • connection — how GEM reaches PostgreSQL. The installer creates this database and user; change these values only if you point GEM at a different database.
  • sequelize.schema — GEM keeps all of its tables in the gem schema.
  • sequelize.timezone — set this to the site's local timezone so schedules and history line up with wall-clock time.

Ports and HTTPS

{
"port": 3000,
"ssl": {
"enabled": false,
"port": 8443,
"http_port": 8080,
"auto_regenerate": true
}
}
  • port — the HTTP port GEM serves on (default 3000).
  • ssl.enabled — turn on HTTPS. When enabled, GEM serves HTTPS on ssl.port and HTTP on ssl.http_port.

Remote access (tunnel)

{
"tunnel": { "enabled": true },
"external_url": "https://your-site.example.com"
}

When the tunnel is enabled, GEM establishes a secure outbound connection for remote access — no inbound firewall ports need to be opened.

You can also turn the tunnel on or off at runtime — without editing gem.json or restarting — by setting a tunnel system attribute (a JSON value such as {"enabled": true} or {"enabled": false}) from the admin System Attributes grid. The attribute overrides the gem.json value and replaces the whole tunnel object, so include every field you need. Live connection status is shown by the Orchestrator Tunnel dashboard widget.

Authentication is always on

There is no configuration that turns authentication off. Every socket event, every REST call and every camera stream connection is checked against a signed-in session, on every deployment, and there is no key you can set to change that.

Earlier versions carried a bypass_auth flag intended for unusual installations. It did far more than its name suggested — one boolean skipped the session check on every socket packet, the session-token comparison, session ownership, remote-access restrictions, the REST surface and the camera stream guard, and marked every incoming connection as already authenticated. Anything that could reach the controller's port had full control of the building. It has been removed.

If your gem.json still contains the key it is simply ignored, and the server log says so once at boot:

ignoring retired config key: bypass_auth - authentication is now always enforced — remove this key from gem.json

Delete the line. If a panel or kiosk was relying on it to skip signing in, give that device its own account — a PIN login on a role scoped to just the UIs it needs is the supported way to run an unattended screen, and unlike the old flag it applies to that one device rather than to everyone who can reach the port.

Real-time connection origins

GEM checks the browser Origin on every real-time (socket) connection so a page on another site can't open a socket against your controller. Nothing needs configuring for a normal install — the check accepts any page GEM itself served, which covers LAN access by IP or hostname, HTTPS, the tunnel hostname, and the mobile apps. Non-browser clients, which send no origin at all, are unaffected.

One deployment shape needs a hint: a reverse proxy in front of GEM that rewrites the Host header and doesn't set X-Forwarded-Host. The configured internal_url and external_url are already accepted, so set those first. For anything else — a kiosk or dashboard served from a different hostname — list the extra origins:

{
"socket_origins": ["https://kiosk.example.com"]
}

If real-time updates stop working after an upgrade and the server log shows socket handshake rejected, cross-origin:, the logged origin is the value to add. As a last resort the check can be turned off entirely with "socket_origin_check": false, but adding the origin is the better fix.

Camera stream connections

Camera thumbnails and live tiles are delivered over a separate real-time channel, and that channel authenticates every connection against the signed-in session before it will hand over a frame. Nothing needs configuring — the apps and the admin interface present the right credentials automatically.

If camera tiles go black and the server log shows rtsp connection rejected, the connecting client has no valid session; signing in again is the fix. The check can be turned off with "rtsp_auth_check": false, but be aware of what that means: camera frames become available to anything that can reach the controller's port, including devices on a guest or IoT network. Leave it on.

How cameras are delivered is a separate choice: "rtsp_stream_mode": "video" sends the camera's own H.264 to the browser instead of decoding it into stills on the server, which costs the controller far less and gives the camera's real frame rate. The default stays on stills. See ONVIF → Stream mode: stills or video.

Camera audio is a separate opt-in again: "rtsp_stream_audio": true carries the microphone of every video-mode camera through to the browser, where it stays muted until a viewer presses the speaker button on a tile. It is off by default because it changes what the system discloses about a room, not because of what it costs — set it per camera with the stream_audio attribute where only some cameras should carry it. See ONVIF → Audio.

Notifications

gem.json carries the transport settings for outbound email (mail) and SMS (sms) used by alerts and notification profiles. Configure the recipients and rules themselves in the admin interface under notification profiles.

Updates

{
"update_url": "https://updates.mygem.us",
"update_key": "<your-key>"
}

These control where GEM pulls updates from. The installer sets them; you normally won't touch them.

The Encryption Key (.encryption_key)

GEM encrypts secure attributes (passwords, API keys, private keys) at rest using a key stored in a file named .encryption_key at the install root. It is generated automatically the first time the server starts.

danger
Back up .encryption_key — losing it is unrecoverable

This file is the key to every encrypted attribute in your database. If you lose it, those values cannot be decrypted and must be re-entered by hand.

  • Back it up somewhere secure, separately from the database.
  • Never commit it to source control (it is git-ignored by default).
  • When migrating a system to new hardware, copy .encryption_key along with the database.

GEM exposes secure download/upload of the encryption keys from the admin interface for backup and migration. See Concepts → Secure Attributes.