The umbrella term Security in Signal K server refers to the difference between running a server, that any one connected to the network can access and alter at will (unsecured) , and one with restrictions in place (secured).
The available security options relate to:
When Signal K Server does not have security enabled, the Login option at the top right corner of the Admin UI will not be available.
Security can be enabled in several ways:
Using the Admin UI, select Security -> Users and then:
Starting the server with the --securityenabled command line option
Adding the following section in the settings file
"security": {
"strategy": "./tokensecurity",
}
When security is enabled, the next time you access the Admin UI it will prompt you to create an administrator account.
Security configuration is stored in file called security.json which will be located in the server configuration directory.
In case the administrator user credentials are lost, removing the security.json file and restarting the server will restore access to the Admin UI.
Access control lists (acls) allow for fine grained access to specific data in Signal K. They specify the permissions assigned to users for resources within specifc contexts and are defined within the security.json file.
The following example defines acls for the self context allowing:
Anyone to read the paths "steering.*", "navigation.*", "name", "design.aisShipType" and grants the admin user permission to write (update) those paths.
The user john to read any data coming from the actisense.35 $source.
For all other paths, only the admin user to read and no one can write.
"acls": [
{
"context": "vessels.self",
"resources": [
{
"paths": ["steering.*", "navigation.*", "name", "design.aisShipType"],
"permissions": [
{
"subject": "any",
"permission": "read"
},
{
"subject": "admin",
"permission": "write"
}
]
},
{
"sources": [ "actisense.35" ],
"permissions": [
{
"subject": "john",
"permission": "read"
}
]
},
{
"paths": ["*"],
"permissions": [
{
"subject": "admin",
"permission": "read"
}
]
}
]
}
]
Note: If there is no match is found for a specific path in the acl list, then permission will be denied to that path!
Signal K Server's main network services are:
In addition the user may configure any number of TCP, UDP and Websocket connections, some of which allow write access to the server.
The security implication of these connections is that with no security options turned on devices connected to the network will have both read and write access to practically all of its data and settings.
People often dismiss local network access by saying that their boat's local network is secure enough. But one very common scenario is connecting your Signal K server (e.g. a Raspberry Pi) to a marina wifi. Many wifi networks allow communication between all connected computers, so your Signal K server will be advertising its services over MDNS to all other connected devices.
So in the case that your server has a manually configured connection for NMEA0183 over UDP, NMEA0183 data broadcast by other devices will be received and written into your SIgnal K data.
NMEA0183 connections over TCP and UDP are inherently unsafe. There are no options for authentication and / or secure communication. In comparison Signal K over TLS and HTTP / WebSockets can provide secure, authenticated read and write access to your data.
Signal K Server uses the helmet middleware to set security-related HTTP headers:
| Header | Value | Purpose |
|---|---|---|
| X-Content-Type-Options | nosniff | Prevents MIME type sniffing attacks |
| X-Frame-Options | SAMEORIGIN | Prevents clickjacking (allows same-origin iframes) |
| X-DNS-Prefetch-Control | off | Privacy protection |
| X-Download-Options | noopen | Prevents IE from executing downloads |
| X-Permitted-Cross-Domain-Policies | none | Blocks Flash/PDF cross-domain access |
| Referrer-Policy | no-referrer | Privacy protection |
| Strict-Transport-Security | max-age=15552000 | Forces HTTPS (only sent on HTTPS connections) |
The following helmet features are disabled to maintain compatibility with the SignalK ecosystem:
When running Signal K Server behind a reverse proxy (e.g., nginx, Apache, Traefik), the server needs to be configured to trust the X-Forwarded-For header to correctly identify client IP addresses.
Without this setting, when behind a reverse proxy:
127.0.0.1)When trustProxy is enabled, Signal K uses the X-Forwarded-For header (set by your proxy) to identify the real client IP address.
The trustProxy setting can be enabled in the Admin UI under Server Settings > Options > trustProxy.
For most setups behind a local reverse proxy, simply enabling trustProxy: true in the Admin UI is sufficient.
For advanced configurations (specific proxy IPs, hop counts), edit settings.json directly:
{
"settings": {
"trustProxy": "127.0.0.1"
}
}
The trustProxy setting accepts the following values:
| Value | Description |
|---|---|
true |
Trust all proxies (use with caution) |
false |
Don't trust any proxy (default) |
"loopback" |
Trust loopback addresses (127.0.0.1, ::1) |
"linklocal" |
Trust link-local addresses |
"uniquelocal" |
Trust unique local addresses |
| Number | Trust the first N proxies |
| IP/CIDR | Trust specific proxy addresses (e.g., "192.168.1.1" or "10.0.0.0/8") |
When using nginx as a reverse proxy, configure it to pass the client IP:
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
}
And set trustProxy to trust only the nginx server:
{
"settings": {
"trustProxy": "127.0.0.1"
}
}
trustProxy if you are actually running behind a reverse proxytrustProxy: true trusts all proxies, which could allow IP spoofing if your server is directly accessible