i2gosignals
I2 GoSignals SSF Security Event Router bridging transmitters and receivers for CAEP, RISC, SCIM.
1.1K
A Security Event Router that bridges Push and Poll SET delivery across federation boundaries, with durable storage, replay, and fan-out.
independentid/i2gosignals is the official container image for the
community edition of goSignals — a Go-based, horizontally-scalable
server that implements the OpenID Shared Signals Framework (SSF) and the
IETF Security Event Token (SET) delivery RFCs. Use it to receive,
validate, persist, route, and re-emit security signals (CAEP, RISC, SCIM)
between identity providers, SaaS receivers, and platforms that live on
opposite sides of a firewall or trust boundary.
Source code, issues, and roadmap: https://github.com/i2-open/i2gosignals
The image is a Chainguard-based distroless bash runtime (non-root UID
1000) containing six statically-linked Go binaries:
| Binary | Purpose |
|---|---|
goSignalsServer (default CMD) | The SSF server — HTTP APIs for stream management, SET push receive, SET push transmit, SET poll, plus admin and cluster endpoints. |
goSignals | Admin CLI for configuring servers, streams, keys, and OAuth/SPIFFE identities. |
goSsfServer | Lightweight demo receiver used in the docker-compose walk-through. |
cluster-monitor | Live view of cluster lease ownership across nodes. |
genTlsKeys | Self-signed CA + server cert generator for local development. |
healthcheck | Probe binary suitable for Docker / Kubernetes liveness and readiness checks. |
The image also ships LICENSE.txt (Apache 2.0) and
THIRD-PARTY-NOTICES.txt for the Go dependencies it statically links.
| Spec | What goSignals does with it |
|---|---|
| RFC 8417 — Security Event Token (SET) | Creates, parses, signs, and verifies SETs end-to-end |
| RFC 8935 — Push delivery of SETs over HTTP | Acts as both push transmitter and push receiver |
| RFC 8936 — Poll delivery of SETs over HTTP | Acts as both poll transmitter and poll receiver |
| OpenID SSF 1.0 | Full stream lifecycle: discovery, registration, status, subject add/remove, verification |
| OpenID CAEP 1.0 | Session, credential, device-compliance, and assurance-level events |
| OpenID RISC 1.0 | Account credential, account-disabled, and identifier-change events |
| RFC 9967 (SCIM Events) | Provisioning-lifecycle SETs |
A key value of the router is protocol bridging: poll-only receivers can pull events from push-only transmitters, and inbound SETs can be re-validated, filtered, and re-signed for downstream audiences.
docker run -d --name gosignals \
-p 8888:8888 \
-e I2SIG_STORE_MONGO_URL=mongodb://mongo:27017 \
-e I2SIG_STORE_MONGO_DBNAME=gosignals \
-e I2SIG_ISSUER_DEFAULT=https://signals.example.com \
-e LOG_LEVEL=INFO \
independentid/i2gosignals:latest
Then use the admin CLI from inside the container, or download the
matching goSignals binary, to register streams.
The repository ships several docker-compose files that demonstrate
two-node clustering, MongoDB, Keycloak SSO, Prometheus/Grafana, and
SPIFFE/SPIRE-based mTLS. Clone the repo and bring one up:
git clone https://github.com/i2-open/i2gosignals.git
cd i2gosignals
docker compose up -d # standard 2-node demo
# or
docker compose -f docker-compose-spiffe.yml up -d # SPIFFE/mTLS variant
# or
docker compose -f docker-compose-cluster.yml up -d # Nginx-balanced cluster
See the project README for the full walk-through, including local DNS, trusting the dev CA, and Grafana SSO.
| Tag | Meaning |
|---|---|
latest | Most recent release build |
<version> (e.g. 0.11.1) | Pinned release; tag matches pkg/constants/version.txt and the org.opencontainers.image.version label |
Multi-arch manifest: linux/amd64 and linux/arm64.
Project status: active development. Suitable for evaluation, integration testing, and demos. Administration-API security and multi-node coordination are being finalised; not yet recommended for unattended production use.
| Port | Protocol | Purpose |
|---|---|---|
8888 | HTTP / HTTPS | All public APIs: SSF management, SET push receive, SET poll, admin, /_cluster/* |
Set I2SIG_TLS_ENABLED=true together with I2SIG_TLS_KEY_PATH /
I2SIG_TLS_CERT_PATH to terminate TLS in-process; otherwise terminate
upstream.
i2goSignals is fully environment-variable driven — there is no
config file. The taxonomy is I2SIG_<AREA>_<KEY>. The canonical
reference, with defaults and behavioural notes, is
docs/configuration_properties.md.
The variables you will almost always set:
| Variable | Purpose |
|---|---|
I2SIG_STORE_MONGO_URL | MongoDB connection string (replica set recommended) |
I2SIG_STORE_MONGO_DBNAME | Database name (default gosignals) |
I2SIG_ISSUER_DEFAULT | Default iss claim for SETs originating on this node |
I2SIG_AUTH_OAUTH_SERVERS | Comma-separated OIDC discovery URLs trusted for inbound bearer tokens |
I2SIG_CLUSTER_NODE_ID | Stable node identity for cluster leases (defaults to POD_NAME, then hostname) |
LOG_LEVEL | DEBUG / INFO / WARN / ERROR (default INFO) |
PORT | Listen port (default 8888) |
Tuning knobs worth knowing:
| Variable | Purpose |
|---|---|
I2SIG_PUSH_BACKFILL_INTERVAL, I2SIG_PUSH_BACKFILL_BATCH | Cadence and batch size of the push retry loop |
I2SIG_POLL_RETRY_BASE_DELAY, I2SIG_POLL_RETRY_MAX_DELAY, I2SIG_POLL_RETRY_BACKOFF_FACTOR, I2SIG_POLL_RETRY_LIMIT | Exponential backoff for the poll receiver |
I2SIG_STREAM_MIN_VERIFICATION_INTERVAL, I2SIG_STREAM_MAX_INACTIVITY_TIMEOUT | Stream verification cadence and inactivity guardrails |
I2SIG_TLS_ENABLED, I2SIG_TLS_KEY_PATH, I2SIG_TLS_CERT_PATH, I2SIG_TLS_CA_CERT | In-process TLS |
SPIFFE_ENDPOINT_SOCKET, I2SIG_SPIFFE_TRUST_DOMAIN, I2SIG_SPIFFE_MONGO_ENABLED | Enables SPIFFE workload identity / mTLS (also for MongoDB) |
I2SIG_BOOTSTRAP_TOKEN | One-shot admin bootstrap token for unattended provisioning |
Variables from pre-v0.11.0 releases still work via a compatibility
shim (one WARN per process) and will be removed in v0.12.0. See the
ADR 0011 taxonomy.
The server is largely stateless — durable state lives in MongoDB — but two paths are useful to mount:
| Path inside the image | When to mount |
|---|---|
/app/resources | MongoDB change-stream resume-token storage; mount a persistent volume if I2SIG_STORE_MONGO_WATCH_ENABLED=true (otherwise leave alone). Owned by UID 1000. |
/app/config (if you put TLS material there) | Server TLS key/cert and CA bundle when running with I2SIG_TLS_ENABLED=true. |
The image bundles a healthcheck binary that probes the server's HTTP
health endpoint and exits non-zero on failure. Example Compose snippet:
services:
gosignals:
image: independentid/i2gosignals:latest
healthcheck:
test: ["/app/healthcheck"]
interval: 15s
timeout: 3s
retries: 5
Multiple i2gosignals containers behind a load balancer form a cluster
without any extra coordination service — leases are held in MongoDB
(cluster_leases collection) with a 30-second TTL and 10-second
heartbeat. Push transmitters and poll receivers each take a per-stream
singleton lease; inbound traffic is served by every node. Nodes wake
each other for fresh events over an authenticated
POST /_cluster/wake-transmitter (shared HMAC via
I2SIG_CLUSTER_INTERNAL_TOKEN, or SPIFFE mTLS when enabled).
See docs/Cluster.md
for the design.
1000).make docker-sbom.I2SIG_AUTH_OAUTH_SERVERS), HMAC, and SPIFFE mTLS.docs/configuration_properties.mddocs/gosignals_tool.md, docs/cli_login.mddocs/security_model.mddocs/Cluster.mddocs/Metrics.md, docs/observability.mddocs/spiffe_support.mdThe image and source are released under the Apache License 2.0. See
LICENSE.txt and THIRD-PARTY-NOTICES.txt inside the image, or on
GitHub.
For commercial licensing, embedding, or the I2 administration server and planned hosted service: [email protected].
© Independent Identity Inc.
Content type
Image
Digest
sha256:fd99d491f…
Size
79.8 MB
Last updated
about 1 month ago
docker pull independentid/i2gosignals