SignalBridge Configuration Guide
Files and commands
| Mechanism | Purpose |
|---|---|
YAML (-c / --config) | Anonymisation, filters, optional inputs / outputs, optional encryption_key. |
CLI (run) | Override or supply input/output when not taken from YAML; set metrics bind; TCP loop + hot reload. |
signalbridge validate -c /path/to/conduit.yaml # must parse as YAML the loader accepts
signalbridge run -c /path/to/conduit.yaml # use YAML + any CLI overridesvalidate only checks that the file loads successfully (see 12:66:src/config/config_loader.cc). It does not verify that PCAP paths exist or that remote URLs are reachable. Invalid YAML or parse failures return “Invalid config file” (135:138:apps/signalbridge.cc).
If run cannot load the config file, it prints a warning and continues with in-memory defaults (176:180:apps/signalbridge.cc).
YAML top-level structure
Supported keys (see 53:60:include/signalbridge/config.h and 12:66:src/config/config_loader.cc):
| Key | Type | Description |
|---|---|---|
encryption_key | string | If non-empty, hex-encoded 32-byte key; used for AES-256-GCM on HTTP(S) streaming output. |
anonymisation | map | IMSI handling and optional mapping file. |
filter | map | Protocol, procedure, IP rules; encrypted NAS handling. |
inputs | list of maps | Declarative inputs (see below). |
outputs | list of maps | Declarative outputs (see below). |
encryption_key
encryption_key- Root-level string, loaded into
ConduitConfig::encryption_key(60:61:src/config/config_loader.cc). - When the resolved output is an HTTP(S) URL, it is passed into the HTTP stream writer (
221:223:apps/signalbridge.cc). - Example format (64 hex chars = 32 bytes): see
126:134:test/unit/config_loader_test.cc.
anonymisation
anonymisation| Field | Type | Default if omitted (see loader / struct) |
|---|---|---|
enabled | bool | If the anonymisation map is present: true when enabled is omitted (as<bool>(true)). If the whole section is missing, the struct default is enabled true (30:38:include/signalbridge/config.h, 17:18:src/config/config_loader.cc, 63:64:test/unit/config_loader_test.cc). |
mcc | string | "999" if key missing after section exists (19:19:src/config/config_loader.cc). |
mnc | string | "99". |
imsi_map_path | string | Optional path for original → anonymised mapping output when processing completes (35:36:include/signalbridge/config.h). |
replacement_byte | int (0–255) | Only applied when the key is present; used in legacy zero-fill mode when MCC is empty (37:38:include/signalbridge/config.h, 22:23:src/config/config_loader.cc). |
The sample file at 7:12:config/conduit.yaml sets enabled: false for local experimentation; production behaviour depends on your policy and whether you omit or include the section.
filter
filter| Field | Type | Default |
|---|---|---|
protocol_include | list of strings | Empty → no protocol include restriction (all pass include stage). Values are compared case-insensitively as S1AP / NGAP (26:31:src/pipeline/protocol_filter.cc). |
protocol_exclude | list of strings | Empty → nothing excluded by protocol. Exclude is evaluated before include (40:44:src/pipeline/protocol_filter.cc). |
procedure_include | list of ints | Empty → all procedure codes allowed through the include stage. |
procedure_exclude | list of ints | Per-procedure in a frame: excluded codes are skipped; if any remaining procedure matches include rules, the frame passes (21:33:src/pipeline/procedure_filter.cc). |
ip_allow | list of strings | Empty with empty deny → IP filter allows all. |
ip_deny | list of strings | If either IP matches deny → drop. |
drop_encrypted_nas | bool | If the filter map is present but key omitted → true (39:39:src/config/config_loader.cc). If the entire filter section is missing → struct default true (27:27:include/signalbridge/config.h, 71:71:test/unit/config_loader_test.cc). |
IP allow semantics: when ip_allow is non-empty, both src_ip and dst_ip must appear in the allow set, else the packet fails (25:27:src/pipeline/ip_filter.cc). Deny is checked first (24:24:src/pipeline/ip_filter.cc).
Encrypted NAS: when drop_encrypted_nas is true and the frame has encrypted NAS, the pipeline drops it (36:36:src/pipeline/pipeline.cc—exact condition line referenced).
inputs (list)
inputs (list)Each item:
| Field | Role |
|---|---|
type | String; loader default "file" (45:45:src/config/config_loader.cc). |
path | Used for type: file. |
address | Used for TCP-style listeners (host:port). |
What run actually uses from YAML (when you do not pass -i, -l, or --stdin):
- Stdin: first entry with
type: stdin(109:114:apps/signalbridge.cc). - TCP listen: first entry with
type: **tcp**ortype: **tcp_listen**and a non-emptyaddress(101:106:apps/signalbridge.cc). - File: first entry with
type: fileand non-emptypath(93:98:apps/signalbridge.cc).
Precedence when multiple modes could apply: the binary checks stdin → TCP listen → file in that order (303:342:apps/signalbridge.cc).
The header comments mention types like grpc, kafka, etc. (41:45:include/signalbridge/config.h). Those strings may load from YAML, but run does not resolve them into an input source—you would still need a matching CLI input or an implementation that reads them.
outputs (list)
outputs (list)Each item:
| Field | Role |
|---|---|
type | Default "file". For streaming, use http, https, tcp, udp as in tests (117:121:test/unit/config_loader_test.cc). |
path | File path for file, or full URL for HTTP in samples (50:52:config/conduit.yaml). |
address | Alternative for http / https / tcp / udp (e.g. full https://… URL). |
Resolution when -o is omitted (79:90:apps/signalbridge.cc): walk outputs in order and take the first match:
type: filewith non-emptypathtype: tcpwith non-emptyaddress→ becomestcp://…type: udpwith non-emptyaddress→ becomesudp://…type: httporhttps→ URL isaddressif set, otherwisepath
So only one output destination is chosen from the list for a given run. Extra list entries are not multiplexed in the current run implementation.
The final string is classified by URL scheme: http(s):// → HTTP stream; tcp:// → TCP PCAP stream; udp:// → UDP; else treated as PCAP file path (221:287:apps/signalbridge.cc).
CLI options (run)
run)From 41:48:apps/signalbridge.cc:
| Option | Effect |
|---|---|
-i / --input | PCAP path; overrides config file input resolution. |
-l / --listen | TCP listen address; overrides config. |
--stdin | Read PCAP from stdin; overrides config stdin flag. |
-o / --output | Destination string; overrides config output resolution. |
-c / --config | YAML path. |
-m / --metrics | Prometheus bind address (default 127.0.0.1:9090 if omitted). Not in YAML. |
--loop | TCP: accept multiple connections; if -c is set, reload config from disk when the file’s mtime changes between accepts (315:332:apps/signalbridge.cc). |
Related files
- Example / template:
config/conduit.yaml(comments show common patterns). - Ingest server routes (reference receiver):
config/ingest_endpoints.yaml— documents paths like/frames/{uuid}for the Python ingest server, not the C++ parser itself.
# SignalBridge configuration
# Anonymises, filters, and forwards S1AP/NGAP signalling
# When set (hex-encoded 32-byte key), HTTP output is encrypted with AES-256-GCM.
encryption_key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
anonymisation:
enabled: false
mcc: "999"
mnc: "99"
# imsi_map_path: "" # Optional: write "original -> anonymised" mapping when done
replacement_byte: 0 # Legacy: used when mcc empty (zero-fill mode)
filter:
# Include only these protocols (empty = all). Values: S1AP, NGAP
protocol_include: []
# Exclude these protocols
protocol_exclude: []
# Include only these procedure codes (empty = all)
procedure_include: []
# Exclude these procedure codes
procedure_exclude: []
# IP allow list (empty = allow all)
ip_allow: []
# IP deny list
ip_deny: []
# Drop encrypted NAS (cannot anonymise without keys)
drop_encrypted_nas: false
# Example: S1AP only
# filter:
# protocol_include: [S1AP]
# protocol_exclude: []
#
# Example: exclude NGAP
# filter:
# protocol_exclude: [NGAP]
#
# Example: mobility procedures only
# filter:
# procedure_include: [0, 1, 2, 3, 4] # Handover procedures
# drop_encrypted_nas: true
inputs:
- type: file
path: ""
# For TCP: type: tcp, address: "0.0.0.0:50051"
# For gRPC: type: grpc, address: "0.0.0.0:50052"
outputs:
- type: "http"
path: "http://127.0.0.1:9876/frames/550e8400-e29b-41d4-a716-446655440000"
# Set to file path, or use type: https with address for HTTP streaming
# For HTTP streaming: type: https, address: "https://ingest.example.com/frames/{uuid}"
# For TCP output: type: tcp, address: "host:port"
# For UDP output: type: udp, address: "host:port"Quick reference: defaults from an empty YAML document
From unit test expectations (54:73:test/unit/config_loader_test.cc): empty file still loads; anonymisation enabled; no filter lists; drop_encrypted_nas: true.
Updated 3 days ago
