Skip to main content

Installation Guide

Synapse is distributed from Gen0Sec's own repositories. They are authenticated, so the first step is always a credential.

Two credentials, not one

Synapse needs two different secrets, issued in two different places. Conflating them is the most common reason an install stalls at the first command.

WhereWhat it unlocks
Repository credentialDashboard → ClientsRepository Access (/<workspace-id>/repositoryAccess)Downloading the software: apt, rpm, the container registry, the release host
API keyDashboard → API keys (/<workspace-id>/apiKeys)The running agent talking to the platform — platform.api_key

The repository credential is minted on the Clients page rather than a settings screen because it is shown once and used immediately by the install commands beside it.

Repository credential scopes

A repository credential carries a scope per host. A key issued for APT alone will not authenticate a docker login, which fails as an authentication error rather than a permissions one:

ScopeHost
apt:pullapt.gen0sec.com
rpm:pullrpm.gen0sec.com
registry:pullregistry.gen0sec.com
release:pullreleases.gen0sec.com

Tick the scopes for the channels you actually install from.

It is presented as HTTP Basic credentials with the credential as the password. The username is ignored — the examples below use x.

One host takes Bearer instead

releases.gen0sec.com, which serves the tarballs and the Windows installer, accepts Authorization: Bearer. apt, rpm and the container registry accept Basic only.

Which build

Two independent choices — a role and whether the ML models are bundled:

AgentRuns on the host itself: telemetry, firewall enforcement and IDS. What most machines want.
ProxyTerminates traffic you route through it and inspects it at L7 — WAF, rate limits, bot handling.
-mlAdds the bundled models for on-host inference. A substantially larger download.

How that choice is expressed depends on the channel, which is the part that catches people out:

ChannelHow the role is chosen
apt / rpmFour packages — synapse-agent, synapse-proxy, and an -ml variant of each. They conflict, so one at a time. The systemd unit is named after the package.
BinaryNot in the name. The tarball carries architecture and -ml only — there is no synapse-proxy tarball.
DockerOne image. The role comes from MODE; -ml is a tag suffix, not a separate repository.
KubernetesThe stack chart mounts the same subchart twice, under the aliases proxy and agent.
WindowsOne installer. The role is set in the config file.

Where the artefact does not encode the role, configuration does: every package ships the same /usr/bin/synapse, and the proxy unit simply sets MODE=proxy. Agent is the default, so only the proxy needs stating.

The signing key

Every repository and every release artefact is signed with:

C1631499081A7146332D2038798FF49A6E9DA146

The public key is fetched from keyserver.ubuntu.com, not from a Gen0Sec host. That is deliberate — trust is not bootstrapped from the same place that serves the artefact, and fetching the key needs no credential.

Debian / Ubuntu

Three parts: the credential apt authenticates with, the key it verifies the repository against, and the source itself.

export GEN0SEC_KEY='<your repository credential>'

# apt reads credentials from auth.conf.d; root-only, since it holds a secret.
sudo install -d -m 0755 /etc/apt/auth.conf.d
printf 'machine apt.gen0sec.com login x password %s\n' "$GEN0SEC_KEY" \
| sudo tee /etc/apt/auth.conf.d/gen0sec.conf > /dev/null
sudo chmod 600 /etc/apt/auth.conf.d/gen0sec.conf

sudo install -d -m 0700 /root/.gnupg

sudo gpg --keyserver hkp://keyserver.ubuntu.com:80 --no-default-keyring \
--keyring /usr/share/keyrings/gen0sec.gpg \
--recv-keys C1631499081A7146332D2038798FF49A6E9DA146

echo "deb [signed-by=/usr/share/keyrings/gen0sec.gpg] https://apt.gen0sec.com stable main" \
| sudo tee /etc/apt/sources.list.d/gen0sec.list > /dev/null
Why install -d /root/.gnupg is in there

gpg needs its own home to exist before it will start dirmngr. On a minimal image it does not, and --recv-keys fails with No dirmngr.

Then install:

sudo apt-get update
sudo apt-get install -y synapse-agent # or synapse-proxy, or either -ml
sudo systemctl enable --now synapse-agent

Built for amd64 and arm64. The suite is stable and the component main on every distribution — there is no per-codename repository.

RHEL / Oracle / CentOS / Fedora

Both the packages and the repository metadata are signed, so gpgcheck and repo_gpgcheck can stay on. The credential goes in username/password rather than in the URL, which keeps it out of logs and out of anything that echoes baseurl back.

export GEN0SEC_KEY='<your repository credential>'

sudo tee /etc/yum.repos.d/gen0sec.repo > /dev/null <<EOF
[gen0sec]
name=Gen0Sec
baseurl=https://rpm.gen0sec.com/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xC1631499081A7146332D2038798FF49A6E9DA146
username=x
password=$GEN0SEC_KEY
EOF
sudo chmod 600 /etc/yum.repos.d/gen0sec.repo
# -y matters on the first call: dnf imports the repo key here, and without it
# the prompt fails a non-interactive run.
sudo dnf -y makecache --repo gen0sec

sudo dnf install -y synapse-agent # or synapse-proxy, or either -ml
sudo systemctl enable --now synapse-agent

Built for x86_64 and aarch64. Use yum in place of dnf on older releases. The repository is flat — no el8/el9 split, so one repo file covers every version.

Binary tarball

For hosts with no package manager, or an immutable filesystem.

export GEN0SEC_KEY='<your repository credential>'
export SYNAPSE_VERSION='<the release you want>'

# The release host names its tarballs with exactly what uname prints,
# so this is the same command on Intel and ARM.
ARCH="$(uname -m)"

curl -fsSL -H "Authorization: Bearer $GEN0SEC_KEY" -O \
https://releases.gen0sec.com/synapse/v${SYNAPSE_VERSION}/synapse-${ARCH}-linux-gnu.tar.gz

tar -xzf synapse-${ARCH}-linux-gnu.tar.gz
sudo install -m 0755 synapse /usr/local/bin/synapse
synapse --version

$ARCH resolves to x86_64 or aarch64. Append -ml before .tar.gz for the ML build. The name never carries the role — asking for a synapse-proxy tarball returns 404.

Verify it, optionally:

curl -fsSL -H "Authorization: Bearer $GEN0SEC_KEY" -O \
https://releases.gen0sec.com/synapse/v${SYNAPSE_VERSION}/synapse-${ARCH}-linux-gnu.tar.gz.asc

gpg --keyserver hkp://keyserver.ubuntu.com:80 \
--recv-keys C1631499081A7146332D2038798FF49A6E9DA146

gpg --verify synapse-${ARCH}-linux-gnu.tar.gz.asc synapse-${ARCH}-linux-gnu.tar.gz

Run it with synapse -c /etc/synapse/config.yaml. A tarball install ships no systemd unit — see Daemon Mode.

Docker

export GEN0SEC_KEY='<your repository credential>'
echo "$GEN0SEC_KEY" | docker login registry.gen0sec.com -u x --password-stdin

docker pull registry.gen0sec.com/gen0sec/synapse:latest
docker run \
--cap-add=SYS_ADMIN \
--cap-add=BPF \
--cap-add=NET_ADMIN \
-e MODE=proxy \
-v /etc/synapse:/etc/synapse \
registry.gen0sec.com/gen0sec/synapse:latest \
-c /etc/synapse/config.yaml

The entrypoint is synapse itself, so arguments after the image go straight to it. Drop -e MODE=proxy for an agent. Published for linux/amd64 and linux/arm64; the daemon picks the right one.

Image tags carry no v prefix

synapse:0.8.2, not synapse:v0.8.2 — the opposite of the release-host paths above. The ML build is the -ml tag suffix (synapse:0.8.2-ml), not a separate repository.

Required capabilities

SYS_ADMIN for eBPF program loading, BPF for map access, NET_ADMIN for XDP attachment and nftables/iptables management. Without them the agent starts but falls back off the eBPF path.

Kubernetes

helm repo add gen0sec https://helm.gen0sec.com
helm repo update
helm search repo gen0sec # gen0sec/synapse, gen0sec/synapse-stack

The cluster pulls from the private registry, so it needs the credential as a docker config. Without this, pods sit in ImagePullBackOff:

export GEN0SEC_KEY='<your repository credential>'

kubectl create namespace synapse-os --dry-run=client -o yaml | kubectl apply -f -

kubectl create secret docker-registry gen0sec-registry \
--docker-server=registry.gen0sec.com \
--docker-username=x \
--docker-password="$GEN0SEC_KEY" \
-n synapse-os

Values live under the proxy and agent aliases, not synapse — the stack chart mounts the same subchart twice:

# synapse-values.yaml
agent:
image:
repository: registry.gen0sec.com/gen0sec/synapse
tag: "0.8.2"
imagePullSecrets:
- name: gen0sec-registry
env:
API_KEY: "<your API key>"
helm upgrade --install synapse-stack gen0sec/synapse-stack \
-n synapse-os --create-namespace \
-f synapse-values.yaml

kubectl -n synapse-os rollout status deploy/synapse-proxy

Every chart value is documented in Helm Charts, the control loop in Synapse Operator, and routing in Kubernetes Ingress & Gateway API.

operator.imagePullSecrets needs synapse-stack 0.5.1+

Earlier charts have no such field on the operator deployments, so the flag is accepted and silently ignored — and the pods sit in ImagePullBackOff. On an older chart, attach the secret to the ServiceAccount instead, which Kubernetes applies to every pod using it:

kubectl -n synapse-os patch serviceaccount synapse-operator \
-p '{"imagePullSecrets":[{"name":"gen0sec-registry"}]}'

Windows

One installer, so the role is chosen in configuration rather than by the package. Run PowerShell 5+ as Administrator:

$env:GEN0SEC_KEY = "<your repository credential>"
$headers = @{ Authorization = "Bearer $env:GEN0SEC_KEY" }

Invoke-WebRequest -Headers $headers -OutFile synapse-setup.exe `
-Uri https://releases.gen0sec.com/synapse/v<version>/synapse-setup.exe
.\synapse-setup.exe

An MSI is published alongside it for unattended rollout through Intune, GPO or similar:

Invoke-WebRequest -Headers $headers -OutFile synapse.msi `
-Uri https://releases.gen0sec.com/synapse/v<version>/synapse.msi
msiexec /i synapse.msi /qn

Configuration lives at C:\ProgramData\Gen0Sec\Synapse\config.yaml. Manage the service with sc:

sc start Synapse
sc control Synapse paramchange # reload config without restart
synapse.exe --terminal # live TUI dashboard
Windows specifics

XDP/eBPF filtering needs eBPF for Windows v1.1.0+ with test signing — pass -WithEBPF to the installer to fetch it automatically. The ML builds are not published for Windows: there is no -ml installer, so the models are unavailable on this platform.

Connect it to the platform

Whichever channel you used, the running agent needs the API key — not the repository credential that fetched the software. It comes from the dashboard's API keys page:

# /etc/synapse/config.yaml
platform:
api_key: "<your API key>"

Add mode: "proxy" above it if you are running a proxy from a channel that does not encode the role — a tarball, a container, or Windows. See Configuration.

Manage the service

The unit is named after the package you installed:

sudo systemctl status synapse-agent
sudo systemctl restart synapse-agent
sudo journalctl -u synapse-agent -f

A healthy start logs the interfaces it attached to. If it attached to none, see the interface-selection notes in Access Rules — the default deliberately skips virtual and CNI devices.

Reload configuration without a restart:

sudo systemctl kill -s HUP synapse-agent

Not everything is hot-reloadable — listen addresses, interfaces and firewall mode need a restart. Configuration lists which is which.

System requirements

OSLinux, kernel 4.18 or newer for XDP; Windows with eBPF for Windows 1.1.0+
Architecturex86_64 / amd64 and aarch64 / arm64
PrivilegesCAP_BPF and CAP_NET_ADMIN, or root
BTF/sys/kernel/btf/vmlinux present, for the eBPF path

Without a usable eBPF path the agent still runs, falling back to nftables and then iptables. See Firewall Rules.

Next steps