Skip to content

JS_ENABLED, JetStreamBus, and GitHubWebhookJetStreamConsumer are fully implemented but never wired into cmd/api or cmd/worker — webhook delivery is always at-most-once, regardless of config #392

Description

@Jagadeeshftw

Description

The codebase contains a complete, tested JetStream durability subsystem for GitHub webhook events:

  • internal/config/config.go parses JS_ENABLED (JetStreamEnabled), JS_STREAM_NAME, JS_CONSUMER_NAME, JS_MAX_DELIVER, JS_ACK_WAIT, and JS_MAX_AGE.
  • internal/bus/natsbus/jetstream.go implements JetStreamBus/NewJetStreamBus, a bus.Bus backed by NATS JetStream with js.Publish (blocks for server ack — "prevents event loss on publish").
  • internal/worker/github_webhook_consumer.go implements GitHubWebhookJetStreamConsumer.SubscribeJetStream, a durable push consumer with explicit ack/nak, MaxDeliver-based dead-lettering, and configurable AckWait.

None of this is ever instantiated by a running binary. cfg.JetStreamEnabled is written into Config by Load() and then never read again — grep -rn "JetStreamEnabled" internal cmd outside config.go returns nothing. Both entrypoints unconditionally use the plain core-NATS path instead:

// cmd/api/main.go and cmd/worker/main.go
b, err := natsbus.Connect(cfg.NATSURL)   // always the plain core Bus, never JetStreamBus
// cmd/worker/main.go
consumer := &worker.GitHubWebhookConsumer{
    Ingest:          &ingest.GitHubWebhookIngestor{Pool: dbConn.Pool},
    LivenessTracker: livenessTracker,
}
if err := consumer.Subscribe(workerCtx, nbus.Conn(), worker.GitHubWebhookQueueGroup); err != nil {

consumer.Subscribe (the core, non-JetStream implementation) is a fire-and-forget queue-group subscription: natsbus.Bus.Publish calls plain nc.Publish, which has no persistence, no redelivery, and no dead-lettering. SubscribeJetStream/NewJetStreamBus are never called from any cmd/ package or from each other — they are reachable only from their own test files.

Requirements

  • cfg.JetStreamEnabled must actually gate which bus/consumer implementation cmd/api/main.go and cmd/worker/main.go construct.
  • When JS_ENABLED=true, the API process must publish GitHub webhook events via natsbus.NewJetStreamBus (or equivalent) instead of the plain core Bus, and the worker process must consume via GitHubWebhookJetStreamConsumer.SubscribeJetStream instead of the plain GitHubWebhookConsumer.Subscribe.
  • When JS_ENABLED=false (the default), current at-most-once behavior must be preserved so this is a strictly additive, opt-in change.

Suggested execution

  1. In cmd/api/main.go and cmd/worker/main.go, branch on cfg.JetStreamEnabled right after natsbus.Connect to construct either the plain *natsbus.Bus or a *natsbus.JetStreamBus (via NewJetStreamBus with cfg.JetStreamStreamName/cfg.JetStreamMaxAge).
  2. In cmd/worker/main.go, when JetStream is enabled, replace the worker.GitHubWebhookConsumer{...}.Subscribe(...) call with construction of a worker.GitHubWebhookJetStreamConsumer and a call to SubscribeJetStream using cfg.JetStreamConsumerName, cfg.JetStreamMaxDeliver, and cfg.JetStreamAckWait.
  3. Ensure internal/api (wherever it currently calls bus.Publish for events.SubjectGitHubWebhookReceived) works unchanged against either bus.Bus implementation (it already should, since both satisfy the same interface).
  4. Add an integration-style test (or extend internal/bus/natsbus/jetstream_test.go) that starts a worker with JS_ENABLED=true against a real/embedded NATS server and asserts a published event survives a simulated consumer restart (proving at-least-once delivery is actually active).
  5. Document in docs/deployment that JS_ENABLED=true is required for durable webhook delivery in production, since today it silently does nothing.

Acceptance criteria

  • Setting JS_ENABLED=true causes cmd/api to publish through JetStreamBus and cmd/worker to consume through GitHubWebhookJetStreamConsumer.SubscribeJetStream.
  • Setting JS_ENABLED=false (or leaving it unset) preserves today's plain core-NATS behavior exactly.
  • A test demonstrates a webhook event is redelivered after a consumer crash/restart when JetStream is enabled.

Security notes

This is a durability/data-integrity gap rather than a direct auth vulnerability: today, a worker crash or NATS hiccup between publish and consume permanently drops in-flight GitHub webhook events (issue/PR sync triggers, installation events) with no redelivery, regardless of how JS_ENABLED is configured — the operator has no way to actually turn on the durability guarantees this code was clearly built to provide.

Guidelines

  • Minimum 95% test coverage
  • Timeframe: 96 hours

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSGrantFox open-source programMaybe RewardedGrantFox: potentially rewarded contributionOfficial Campaign | FWC26GrantFox official campaign issuebackendBackend / API workbugSomething isn't workinginfra

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions