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
- One server that can already reach your PostgreSQL database on your own network. It does not have to be the database server itself, and it should not be someone's laptop — this is a service that runs all day.
-
Outbound HTTPS to
api.sonela.cloudon port 443. If the machine can browse the web, it can run the gateway. No inbound port, no VPN, no tunnel. - Windows Server / Windows 10 or later (x64), or a 64-bit Linux with glibc (Ubuntu 20.04+, Debian 11+, RHEL 8+ and their relatives). No runtime to install: the download is one self-contained file and carries its own.
-
On Linux only: the system's international components package,
libicu. Every ordinary desktop or server install already has it — the exception is a stripped-down container or minimal image, where it is one command (apt-get install -y libicu,dnf install -y libicu). Without it the gateway stops immediately; section 8 shows exactly what that looks like. - About 100 MB of free disk. The file is smaller than that; it unpacks itself into a temporary folder the first time it runs.
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
Get-FileHash -Algorithm SHA256 .\sonela-bridge-win-x64.exe
Compare the output with the SHA-256 shown beside the download. They must match exactly.
Linux
sha256sum sonela-bridge-linux-x64
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 Properties → Digital 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 — SmartScreen shows “Windows protected your PC”, and you have to choose More info → Run anyway.
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, at creation. Lost it? Create a new bridge data source and use its key
(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.cloud; 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.cloud 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'
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.
-
On the server. The log's first line is
polling https://api.sonela.cloud 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". - 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. Replacing the key
There is no "rotate" button, and the reason is the same reason the key is shown once: Sonela stores only its SHA-256 hash, so there is nothing on our side to re-issue or read back. Replacing a key means creating a new bridge data source:
- Add a new data source in Sonela Bridge mode, and copy its
ck_…key. - Update
SONELA_BRIDGE_KEYon the server with the new value. - Restart the gateway —
Restart-ScheduledTask -TaskName 'Sonela Gateway'orsudo systemctl restart sonela-bridge. - Introspect and approve the schema on the new data source, then point your workspace at it. The old source stops being polled and goes offline.
A data source stays on the rung it has climbed to, so an existing bridge source cannot be
re-issued a key in place. Treat the ck_… key like any other secret: if it
may have been seen by someone who should not have it, replace 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
sudo apt-get update && sudo apt-get install -y libicu
# 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.cloud. 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.cloud -Port 443
# Linux
curl -sS -o /dev/null -w '%{http_code}\n' https://api.sonela.cloud/health
If that fails, the machine needs outbound HTTPS to api.sonela.cloud 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.
SmartScreen blocks the download on Windows
If the build you took is unsigned, Windows will warn about an unknown publisher — More info → Run anyway. Before you do that, check the SHA-256 (section 2). A hash that matches is a stronger statement about the file than the warning is.
9. What the gateway never does
-
It never sends, logs or echoes back the values in
SONELA_DB_CONNECTION. They are used to open connections from that machine and nothing else. - Its log records job ids, what kind of job it was, how long it took and whether it succeeded — and connection state changes. Never your key, never your settings, never the SQL, never a row of data. Support reads that log over your shoulder, and it is written to be safe to show.
- It accepts no inbound connections. It is a client, and there is no port on it to reach.
- It runs only read-only queries. Every statement is validated as a single read-only SELECT over the schema you approved and rewritten with your tenant filter, on your machine, before it reaches your database — then executed in a READ ONLY transaction with a three-second statement timeout and a 500-row cap.