jetstream_bridge 7.1.1 → 7.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65a794cf3e9a17511c64f2ef29edc70d56214f4cfc1c63eed8148afb65e05505
4
- data.tar.gz: 44dea5d3d1900999fc788aad9e9d676a02315c18678256f4ce14d5443cb0b816
3
+ metadata.gz: 45dac84dd11b563f4f5b0b3d52d85722fdb5b7900923d85f7d6cb7af9b0fad95
4
+ data.tar.gz: a53400f90050c039fa8ac72109a99e3778911200fab983efa6f18549bcf5620f
5
5
  SHA512:
6
- metadata.gz: 360c547ece5e7443487c3796d18139843ea86a2ce7f29a775fd1245d6e084d76bec11df72cdafef78ac9fa383ad99eae680f9220dc9eef451f62ba012fe20de9
7
- data.tar.gz: 62e2100993ba1defc32df1ad744392148f4600527c5fab80db6cce2d211b80c79d6228c64497e61106ba13fdef9579300df1455d5caf3d4e75a83ccd896a5051
6
+ metadata.gz: 9e1790cb302107920d71736110db8bc19ae08ac111725614bb4221c73daddf4a992fea8c5c9913cc8dfeea7ebb4bcad359d189e691cd6cf45c1e7bb516b708c1
7
+ data.tar.gz: 60ee52e1c6943c8fb0c95cb7ea7f2b12d18d914fd2f03981134deaf6c5bef95680671d25ed66585914299216e70fc25f924dcf66925da7076687f95e6ee9b29d
data/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [7.1.2] - 2026-02-11
9
+
10
+ ### Fixed
11
+
12
+ - **Skip all JS.API calls when `auto_provision=false`** - `ensure_consumer!` and `auto_create_consumer_on_error` no longer issue `stream_info`, `consumer_info`, or `add_consumer` calls when `auto_provision=false`. This fixes failures in restricted NATS accounts where `$JS.API` permissions are not granted and the stream/consumer are pre-provisioned by an admin.
13
+
14
+ ### Changed
15
+
16
+ - **Restricted permissions docs** - Added missing `$JS.ACK.{stream}.{consumer}.>` publish permissions to all permission examples. Without this permission, consumers cannot acknowledge messages and they are redelivered until `max_deliver` is exhausted.
17
+
8
18
  ## [7.1.1] - 2026-02-02
9
19
 
10
20
  ### Changed
@@ -31,7 +31,7 @@ When you cannot modify NATS server permissions, you have **two options**:
31
31
 
32
32
  - **No JetStream API permissions required** at runtime
33
33
  - Messages delivered automatically to a subscription subject
34
- - Simpler permission model: only needs subscribe permission on delivery subject
34
+ - Simpler permission model: only needs subscribe on delivery subject + publish on `$JS.ACK` for acks
35
35
  - Best for restricted permission environments
36
36
 
37
37
  For both options, you need to:
@@ -82,7 +82,8 @@ end
82
82
  # NATS user permissions (e.g., pwas user)
83
83
  publish: {
84
84
  allow: [
85
- "pwas.>", # Your business subjects only
85
+ "pwas.>", # Your business subjects
86
+ "$JS.ACK.pwas-heavyworth-sync.pwas-workers.>", # Ack/nak messages (required)
86
87
  ]
87
88
  }
88
89
  subscribe: {
@@ -92,7 +93,7 @@ subscribe: {
92
93
  }
93
94
  ```
94
95
 
95
- **No `$JS.API.*` or `_INBOX.>` permissions needed!**
96
+ **No `$JS.API.*` or `_INBOX.>` permissions needed!** However, `$JS.ACK` publish permission is required for the consumer to acknowledge messages. Without it, messages will be redelivered until `max_deliver` is exhausted.
96
97
 
97
98
  ### Provisioning Push Consumers
98
99
 
@@ -122,11 +123,11 @@ nats consumer add pwas-heavyworth-sync pwas-workers \
122
123
  - Topology: **one shared stream per app pair**, with one durable consumer per app (each filters the opposite direction). Pre-provision via `bundle exec rake jetstream_bridge:provision` or NATS CLI.
123
124
  - NATS permissions for runtime creds:
124
125
  - **Pull consumers** (default):
125
- - publish allow: `">"` (or narrowed to your business subjects) and `$JS.API.CONSUMER.MSG.NEXT.{stream_name}.{app_name}-workers`
126
- - subscribe allow: `">"` (or narrowed) and `_INBOX.>` (responses for pull consumers)
126
+ - publish allow: `{app_name}.>`, `$JS.API.CONSUMER.MSG.NEXT.{stream_name}.{app_name}-workers`, and `$JS.ACK.{stream_name}.{app_name}-workers.>`
127
+ - subscribe allow: `{destination_app}.>` and `_INBOX.>` (responses for pull consumers)
127
128
  - **Push consumers** (recommended for restricted environments):
128
- - publish allow: `">"` (or narrowed to your business subjects only - e.g., `pwas.>`)
129
- - subscribe allow: `">"` (or narrowed to your business subjects only - e.g., `heavyworth.>`)
129
+ - publish allow: `{app_name}.>` and `$JS.ACK.{stream_name}.{app_name}-workers.>` (ack/nak)
130
+ - subscribe allow: `{destination_app}.>` (includes delivery subject)
130
131
  - No `$JS.API.*` or `_INBOX.>` permissions needed
131
132
  - Health check will only report connectivity (stream info skipped).
132
133
 
@@ -643,15 +644,15 @@ end
643
644
 
644
645
  ```conf
645
646
  # pwas user
646
- publish: { allow: ["pwas.>"] }
647
+ publish: { allow: ["pwas.>", "$JS.ACK.pwas-heavyworth-sync.pwas-workers.>"] }
647
648
  subscribe: { allow: ["heavyworth.>"] }
648
649
 
649
650
  # heavyworth user
650
- publish: { allow: ["heavyworth.>"] }
651
+ publish: { allow: ["heavyworth.>", "$JS.ACK.pwas-heavyworth-sync.heavyworth-workers.>"] }
651
652
  subscribe: { allow: ["pwas.>"] }
652
653
  ```
653
654
 
654
- **Note:** With push consumers, no `$JS.API.*` or `_INBOX.>` permissions are required.
655
+ **Note:** With push consumers, no `$JS.API.*` or `_INBOX.>` permissions are required. The `$JS.ACK` permission is needed so the consumer can acknowledge (ack/nak) delivered messages.
655
656
 
656
657
  ---
657
658
 
@@ -664,16 +665,17 @@ If you have any influence over NATS permissions, you have two options:
664
665
  Request minimal JetStream API permissions:
665
666
 
666
667
  ```conf
667
- # Minimal permissions needed for pull consumer
668
+ # Minimal permissions needed for pull consumer (e.g., pwas user)
668
669
  publish: {
669
670
  allow: [
670
- ">", # Your app subjects (narrow if desired)
671
- "$JS.API.CONSUMER.MSG.NEXT.{stream_name}.{app_name}-workers", # Fetch messages (required)
671
+ "pwas.>", # Your app subjects
672
+ "$JS.API.CONSUMER.MSG.NEXT.pwas-heavyworth-sync.pwas-workers", # Fetch messages (required)
673
+ "$JS.ACK.pwas-heavyworth-sync.pwas-workers.>", # Ack/nak messages (required)
672
674
  ]
673
675
  }
674
676
  subscribe: {
675
677
  allow: [
676
- ">", # Your app subjects (narrow if desired)
678
+ "heavyworth.>", # Destination app subjects
677
679
  "_INBOX.>", # Request-reply responses (required)
678
680
  ]
679
681
  }
@@ -683,16 +685,16 @@ These are read-only operations and don't allow creating/modifying streams or con
683
685
 
684
686
  ### Option 2: Push Consumers (Recommended)
685
687
 
686
- Use push consumers with business subject permissions only:
688
+ Use push consumers with business subject permissions plus ack:
687
689
 
688
690
  ```conf
689
691
  # For pwas app
690
- publish: { allow: ["pwas.>"] }
692
+ publish: { allow: ["pwas.>", "$JS.ACK.pwas-heavyworth-sync.pwas-workers.>"] }
691
693
  subscribe: { allow: ["heavyworth.>"] }
692
694
 
693
695
  # For heavyworth app
694
- publish: { allow: ["heavyworth.>"] }
696
+ publish: { allow: ["heavyworth.>", "$JS.ACK.pwas-heavyworth-sync.heavyworth-workers.>"] }
695
697
  subscribe: { allow: ["pwas.>"] }
696
698
  ```
697
699
 
698
- **No `$JS.API.*` or `_INBOX.>` permissions required!** This is the simplest and most restrictive permission model.
700
+ **No `$JS.API.*` or `_INBOX.>` permissions required!** The only extra permission beyond business subjects is `$JS.ACK` for acknowledging messages.
@@ -450,6 +450,14 @@ module JetstreamBridge
450
450
  end
451
451
 
452
452
  def auto_create_consumer_on_error(_error)
453
+ unless JetstreamBridge.config.auto_provision
454
+ Logging.info(
455
+ "Skipping consumer auto-creation (auto_provision=false) for #{@durable}",
456
+ tag: 'JetstreamBridge::Consumer'
457
+ )
458
+ return
459
+ end
460
+
453
461
  Logging.info(
454
462
  "Consumer not found error detected, attempting auto-creation for #{@durable}...",
455
463
  tag: 'JetstreamBridge::Consumer'
@@ -28,13 +28,13 @@ module JetstreamBridge
28
28
  @desired_cfg
29
29
  end
30
30
 
31
- # Ensure consumer exists, auto-creating if missing.
32
- #
33
- # @param force [Boolean] Kept for backward compatibility but no longer used.
34
- # Consumers are always auto-created regardless of this parameter.
31
+ # Ensure consumer exists; skips all JS.API calls when auto_provision is false.
35
32
  def ensure_consumer!(**_options)
36
- # Always auto-create consumer if it doesn't exist, regardless of auto_provision setting.
37
- # auto_provision only controls stream topology creation, not consumer creation.
33
+ unless @cfg.auto_provision
34
+ Logging.info("Skipping consumer validation (auto_provision=false); assuming '#{@durable}' exists.",
35
+ tag: 'JetstreamBridge::Consumer')
36
+ return
37
+ end
38
38
  create_consumer_if_missing!
39
39
  end
40
40
 
@@ -70,13 +70,7 @@ module JetstreamBridge
70
70
  false
71
71
  end
72
72
 
73
- # Create consumer only if it doesn't already exist.
74
- #
75
- # Fails if the stream doesn't exist - streams must be provisioned separately.
76
- #
77
- # This is a safer alternative to create_consumer! that won't fail
78
- # if the consumer was already created by another process.
79
- #
73
+ # Create consumer only if it doesn't already exist. Fails if stream is missing.
80
74
  # @raise [StreamNotFoundError] if the stream doesn't exist
81
75
  def create_consumer_if_missing!
82
76
  # In restricted environments (push + auto_provision=false), we still want fail-fast semantics.
@@ -4,5 +4,5 @@
4
4
  #
5
5
  # Version constant for the gem.
6
6
  module JetstreamBridge
7
- VERSION = '7.1.1'
7
+ VERSION = '7.1.2'
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jetstream_bridge
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.1
4
+ version: 7.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Attara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-02 00:00:00.000000000 Z
11
+ date: 2026-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord