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.
| Where | What it unlocks | |
|---|---|---|
| Repository credential | Dashboard → Clients → Repository Access (/<workspace-id>/repositoryAccess) | Downloading the software: apt, rpm, the container registry, the release host |
| API key | Dashboard → 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:
| Scope | Host |
|---|---|
apt:pull | apt.gen0sec.com |
rpm:pull | rpm.gen0sec.com |
registry:pull | registry.gen0sec.com |
release:pull | releases.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.
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:
| Agent | Runs on the host itself: telemetry, firewall enforcement and IDS. What most machines want. |
| Proxy | Terminates traffic you route through it and inspects it at L7 — WAF, rate limits, bot handling. |
-ml | Adds 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:
| Channel | How the role is chosen |
|---|---|
| apt / rpm | Four 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. |
| Binary | Not in the name. The tarball carries architecture and -ml only — there is no synapse-proxy tarball. |
| Docker | One image. The role comes from MODE; -ml is a tag suffix, not a separate repository. |
| Kubernetes | The stack chart mounts the same subchart twice, under the aliases proxy and agent. |
| Windows | One 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
install -d /root/.gnupg is in theregpg 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.
v prefixsynapse: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.
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
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
| OS | Linux, kernel 4.18 or newer for XDP; Windows with eBPF for Windows 1.1.0+ |
| Architecture | x86_64 / amd64 and aarch64 / arm64 |
| Privileges | CAP_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
- Configuration — every key, and which reload without a restart
- Helm Charts — every value in the three charts
- Synapse Operator — the Kubernetes control loop
- Kubernetes Ingress — Synapse as an Ingress and Gateway API controller
- Daemon Mode — running without systemd