Sonela

Installing the Sonela Gateway

One small service, on one server inside your network, next to your database. It dials out to Sonela over HTTPS and asks whether there is work. You open no inbound ports.

A note on the name. The download, its settings and its log all use the engineering name bridge — the file is sonela-bridge-… and its settings start with SONELA_. Gateway and bridge are the same component. Nothing below is a different product.

1. Before you start

You need one machine and one key. That is the whole list.

The machine

The key

In Sonela, open Data sources and add one in Sonela Bridge mode (or move an existing guidance-only source onto that rung). The moment it is created, the dashboard shows a key beginning ck_once. Sonela stores only a hash of it, so it cannot be shown again. The same panel prints the three settings below ready to paste, and — once a build is published — the download for each platform beside them.

2. Download and verify it

Take the file for the server's platform from the download panel in your dashboard, or from the gateway page. Each build publishes its SHA-256 next to it. Check it before you run anything — it is the one step that proves the file you have is the file we published.

Windows

Paste the SHA-256 from the download panel into the first line, then run both. PowerShell prints hashes in capitals and ours are lower case, so let the comparison handle it rather than reading 64 characters yourself:

$published = 'paste-the-sha-256-from-the-download-panel'
(Get-FileHash -Algorithm SHA256 .\sonela-bridge-win-x64.exe).Hash -eq $published.Trim().ToUpper()

It must print True. Anything else, see the warning below.

Linux

Paste the SHA-256 from the download panel in place of the placeholder:

echo 'paste-the-sha-256-from-the-download-panel  sonela-bridge-linux-x64' | sha256sum -c -

It must print sonela-bridge-linux-x64: OK. Note the two spaces before the file name — that is the format sha256sum expects. Every build also publishes that same line as a file, at the download's own URL with .sha256 on the end, so curl -O <download-url>.sha256 && sha256sum -c sonela-bridge-linux-x64.sha256 does the whole check without pasting anything.

Only once it says OK:

chmod +x sonela-bridge-linux-x64
./sonela-bridge-linux-x64 --version

--version prints the build and the protocol versions it speaks. It is the fastest proof that the file downloaded intact and runs on this machine, and it is the first thing support will ask for.

What the signature means on Windows

If the download panel showed a signature line for the file you took, the executable is code-signed: right-click it, choose PropertiesDigital Signatures, and Windows will name Sonela as the publisher. If the panel said the build is not signed, then it is not, and Windows will say so too — twice. Your browser may refuse the download before you ever see the file, and Windows shows “Windows protected your PC” the first time you run it. Both are expected on an unsigned build and neither means anything is wrong with the file; section 8 walks through exactly what each one looks like and what to click.

Either way, the SHA-256 is the check that matters. A signature tells you who published a file; the hash tells you that the exact bytes on your disk are the exact bytes we built. If the hash does not match, do not run the file — delete it and download it again.

3. The three settings

The gateway is configured entirely through environment variables. There is no config file by design: this runs on your machine, and putting your database sign-in into a file on your disk should be your decision, not our default.

Variable What it is
SONELA_BRIDGE_KEY Required. The ck_… key from the dashboard. Shown once, when it is minted. Lost it? Rotate the key on the data source in the dashboard and install the new one (section 6).
SONELA_DB_CONNECTION Required. The connection string for your own PostgreSQL, e.g. Host=localhost;Port=5432;Database=app;Username=app_reader;Password=…. Use a read-only login. It is used only to open connections from this machine and never leaves it.
SONELA_URL Optional. Where to poll. Defaults to https://api.sonela.ai; leave it unset unless you have been told otherwise.

The dashboard's key panel prints these ready to paste, with your key already filled in. Copy that block rather than typing the key by hand — a mistyped key is the most common first failure, and the gateway will not start on it.

Try it in the foreground first

Before making it a service, run it once in a terminal with the two required values set. You should see, within a second or two:

[09:14:22] polling https://api.sonela.ai for work

That line means it is connected and waiting for questions. Press Ctrl+C to stop it — that is the normal way this program ends, and it exits cleanly.

4. Run it as a service

The gateway should come back on its own after a reboot. Neither recipe below needs any third-party tool.

Windows — a scheduled task at startup

sc.exe create is the usual answer and it is the wrong one here: it expects a program written to be a Windows service, and this is a console application. Rather than ship a wrapper you would have to trust, the honest no-extra-software route on Windows is a scheduled task that runs at boot as SYSTEM and restarts if it stops.

Put the executable somewhere permanent, then, in an elevated PowerShell:

New-Item -ItemType Directory -Force "C:\Program Files\Sonela Gateway" | Out-Null
Move-Item .\sonela-bridge-win-x64.exe "C:\Program Files\Sonela Gateway\" -Force

# Machine-wide values, so the task sees them at boot with nobody logged in.
[Environment]::SetEnvironmentVariable('SONELA_BRIDGE_KEY', 'ck_…', 'Machine')
[Environment]::SetEnvironmentVariable(
  'SONELA_DB_CONNECTION',
  'Host=localhost;Port=5432;Database=app;Username=app_reader;Password=…',
  'Machine')

$action  = New-ScheduledTaskAction `
  -Execute 'C:\Program Files\Sonela Gateway\sonela-bridge-win-x64.exe'
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -RunLevel Highest
$settings  = New-ScheduledTaskSettingsSet `
  -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) `
  -ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew

Register-ScheduledTask -TaskName 'Sonela Gateway' `
  -Action $action -Trigger $trigger -Principal $principal -Settings $settings

Start-ScheduledTask -TaskName 'Sonela Gateway'

-ExecutionTimeLimit ([TimeSpan]::Zero) is load-bearing: without it Windows stops the task after three days, and the gateway would go quiet on a schedule nobody remembers setting.

Machine-wide variables are readable by local administrators. That is true of any service configuration on Windows, and it is the trade for not writing a file. Keep the database login read-only, and treat this machine as one that holds a database sign-in — because it does.

The task writes nothing to a log file of its own. To see what the gateway is saying, run it in the foreground once (section 3) — the messages are identical.

Linux — a systemd unit

Put the values in a file only root can read:

sudo install -m 0755 sonela-bridge-linux-x64 /usr/local/bin/sonela-bridge
sudo useradd --system --no-create-home --shell /usr/sbin/nologin sonela

sudo tee /etc/sonela-bridge.env >/dev/null <<'EOF'
SONELA_BRIDGE_KEY=ck_…
SONELA_DB_CONNECTION=Host=localhost;Port=5432;Database=app;Username=app_reader;Password=…
EOF
sudo chown root:root /etc/sonela-bridge.env
sudo chmod 0600 /etc/sonela-bridge.env

Then the unit:

sudo tee /etc/systemd/system/sonela-bridge.service >/dev/null <<'EOF'
[Unit]
Description=Sonela Gateway
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=sonela
EnvironmentFile=/etc/sonela-bridge.env
ExecStart=/usr/local/bin/sonela-bridge
Restart=always
RestartSec=10
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now sonela-bridge
sudo systemctl status sonela-bridge

systemd reads EnvironmentFile as root before dropping to the sonela user, so the file stays unreadable by the account the gateway runs as. Follow the log with:

journalctl -u sonela-bridge -f

5. Confirm it connected

Two places agree, and it is worth checking both the first time.

  1. On the server. The log's first line is polling https://api.sonela.ai for work. That is the whole success signal — the gateway is quiet when idle, on purpose, so an empty log after that line means "connected, nothing to do", not "stuck".
  2. In Sonela. On Data sources, the bridge source shows a green Bridge connected badge. It reports on every poll, so the badge turns green within about half a minute of starting.
Badge Meaning
Bridge connected Heard from in the last 2 minutes. This is the normal state.
Last seen n min ago Quiet for between 2 minutes and an hour. Brief amber after a restart is expected; amber that stays is worth looking at.
Bridge offline Not heard from for over an hour, or never. Start at section 8.

Once it is connected, run Introspect on the data source. The gateway reads your schema from inside your network and drafts a manifest for you to review and approve. Nothing is read from your tables until you approve it.

6. Rotating the key

Every bridge data source card in the dashboard carries a Rotate bridge key button. Pressing it mints a fresh ck_… key and kills the old one at that instant — Sonela stores only the key's SHA-256 hash, so there is nothing on our side to read back or re-issue; rotation is always a new key, shown exactly once, like the first one was.

Rotation is an outage you schedule. There is no grace period with two live keys: within about half a minute of the click, the running gateway's next poll is refused, it logs that the platform no longer recognises its key, and it exits. It stays down until you install the new key and restart it:

  1. In the dashboard, open the data source and press Rotate bridge key. Copy the new ck_… key from the one-time sheet.
  2. Update SONELA_BRIDGE_KEY on the server with the new value.
  3. Restart the gateway — Restart-ScheduledTask -TaskName 'Sonela Gateway' or sudo systemctl restart sonela-bridge.

Nothing else changes: the approved schema, the widget keys and the data source itself all stay exactly as they were — rotation replaces the credential, not the setup. Treat the ck_… key like any other secret: if it may have been seen by someone who should not have it, rotate it.

7. Stopping and removing it

Ctrl+C in the foreground, or:

# Windows
Stop-ScheduledTask     -TaskName 'Sonela Gateway'
Unregister-ScheduledTask -TaskName 'Sonela Gateway' -Confirm:$false
[Environment]::SetEnvironmentVariable('SONELA_BRIDGE_KEY',    $null, 'Machine')
[Environment]::SetEnvironmentVariable('SONELA_DB_CONNECTION', $null, 'Machine')
Remove-Item "C:\Program Files\Sonela Gateway" -Recurse -Force

# Linux
sudo systemctl disable --now sonela-bridge
sudo rm /etc/systemd/system/sonela-bridge.service /etc/sonela-bridge.env /usr/local/bin/sonela-bridge
sudo systemctl daemon-reload

Stopping the gateway is complete on your side: nothing of it remains running, and the only thing it ever held — your database sign-in — was in the environment you have just cleared. In Sonela the data source stays where it is and simply reads Bridge offline; a question routed to it answers that the database is unreachable rather than guessing.

8. When it does not work

It refuses to start and lists what is missing

The bridge cannot start. Missing configuration:
  SONELA_BRIDGE_KEY - The bridge key (ck_...). It is shown exactly once, …
  SONELA_DB_CONNECTION - The PostgreSQL connection string of YOUR database, …

Exactly what it says: one or both required values are not visible to the process. The usual cause is that they were set in a terminal but the service starts without one — on Windows they must be Machine variables, on Linux they must be in the unit's EnvironmentFile. Run --help for the full list.

On Linux, it exits at once mentioning ICU

Process terminated. Couldn't find a valid ICU package installed on the system.
Please install libicu using your package manager and try again.

The machine is missing libicu, the system package .NET uses for language and text handling. This is a minimal image or a stripped-down container, not a normal server install. Install it and start the gateway again:

# Debian / Ubuntu — there is no package called plain "libicu" here; the
# versions are numbered (libicu72, libicu74, …) and this one resolves on all of them
sudo apt-get update && sudo apt-get install -y libicu-dev

# RHEL / Rocky / Alma
sudo dnf install -y libicu

Nothing else changes — the file you downloaded, your key and your settings all stay as they are.

“the platform does not recognize this bridge key”

[09:14:22] the platform does not recognize this bridge key; check SONELA_BRIDGE_KEY …

The key is wrong, or it belongs to a data source that no longer exists. The gateway stops here rather than retrying, deliberately: polling forever on a bad key would hide a paste error behind a service that looks like it is running. Copy the key again from the dashboard's paste-ready block — the whole value, including ck_, with no trailing space — and restart. If the key was lost, section 6.

“platform unreachable”

[09:14:22] platform unreachable (…); retrying with backoff up to 60 s

It cannot reach api.sonela.ai. It keeps retrying and recovers on its own, logging platform connection restored when it does. This line is printed once per outage, not once per attempt — so silence after it means still trying, not fixed.

Usually outbound filtering. Confirm from that machine:

# Windows
Test-NetConnection api.sonela.ai -Port 443

# Linux
curl -sS -o /dev/null -w '%{http_code}\n' https://api.sonela.ai/health

If that fails, the machine needs outbound HTTPS to api.sonela.ai on port 443 — an allow-list entry on the proxy or firewall. Nothing inbound is ever required.

Questions come back with a database error

If the gateway is connected but a question answers with a message from PostgreSQL — authentication failed, relation does not exist, connection refused — that is your database talking, passed through word for word rather than replaced with something vaguer. The gateway is fine and keeps polling; the fix is in the database login or in what it is allowed to read. Check that the login in SONELA_DB_CONNECTION can connect from this machine and can read the tables you approved.

“This bridge is too old for the job it was offered.”

Sonela sent work in a newer format than this build understands, and the gateway refused it rather than guessing at it. Its own log says refused: the job speaks protocol … — update the Sonela Bridge. Download the current build, replace the file, restart the service. Your key and settings do not change.

Windows warns about the download, or blocks it

Expected on an unsigned build, and it happens at two different moments. Neither is a statement about this file: both are statements about a file Windows has not seen enough copies of yet. Check the SHA-256 first (section 2) — a hash that matches is a stronger statement about the bytes on your disk than either warning is.

In the browser, while downloading. Edge says the file “isn't commonly downloaded”, or “was blocked because it could harm your device”; Chrome says “isn't commonly downloaded. Make sure you trust…”. The file is usually already on disk, quarantined, rather than never fetched:

At first run. SmartScreen shows “Windows protected your PC” and names an unknown publisher: More infoRun anyway.

Both disappear once we code-sign the Windows build. Until then the download panel says plainly that the build is not signed, and never claims otherwise.

9. What the gateway never does


Something here wrong or missing? Write to hello@sonela.ai.