durable_streams-rails 0.4.0 → 0.5.0

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: 9fca76d28cee5e469a38766c7bec549acc60f5a6eddf5b840950ce96329dc31e
4
- data.tar.gz: 95b45e16b2a3d40024a71c7281b5f17da3009163145b54148dceb493db919b09
3
+ metadata.gz: bf65130284ea6d82ba8c5a96a6140d8d90b2a85644150d95e4cccc254e166da4
4
+ data.tar.gz: a9351da1b24a5a717ad3717eed8faa19f6079c99ef3e9d8300214a1e31558e19
5
5
  SHA512:
6
- metadata.gz: fc8227f3d31a0bbc46028c32f23c3cbdd29e5b09aa7a3ad378b69972fb25a1ed8b5e08b84020918dbdcb071a41329dc7f052ce6cc590f7cc112e7355156d9e39
7
- data.tar.gz: f8cd42dc4ec64c26415e9793646d84786e104adcfcfb292c82d5662b181a280668ea13408033742649453049e94453351fbe42a9436224ebad5262943380a9f6
6
+ metadata.gz: 48dce7b23beb7d4a5a8c7e37350d5790c25865f20cfebcd31bd80fad574c7179896fae4471289524556ea61836f739936c2e18fcc404fb7b810a4eee55a9f1c5
7
+ data.tar.gz: e1518c09eeaeaf28a6a92279bac1bc06b962aee73d89b8ead82b7651c7a6910f1a5eb9faa7210d3a4e3f97e2bf030c97df4c736a230e46d9dcf554c8ffc18375
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Durable Streams Rails
2
2
 
3
3
  Durable Streams integration for Rails. Stream State Protocol events from your models to clients
4
- over SSE with the same developer experience as Turbo Broadcasts — but with offset-based
4
+ over HTTP with the same developer experience as Turbo Broadcasts — but with offset-based
5
5
  resumability, persistent event logs, and no WebSocket infrastructure.
6
6
 
7
7
  ```ruby
@@ -31,7 +31,7 @@ bin/rails generate durable_streams:install
31
31
 
32
32
  This creates:
33
33
 
34
- - `config/initializers/durable_streams.rb` — sets the stream server URL
34
+ - `config/initializers/durable_streams.rb` — sets `client_url` and `server_url`
35
35
  - `config/durable_streams.yml` — server configuration (per environment)
36
36
  - `bin/durable-streams` — binstub that auto-downloads and runs the server binary
37
37
  - Updates `Procfile.dev` with a `streams:` entry
@@ -188,7 +188,7 @@ DurableStreams.broadcast_to(room, :presence,
188
188
 
189
189
  ### Signed stream URLs
190
190
 
191
- Generate signed, expirable URLs for client SSE connections:
191
+ Generate signed, expirable URLs for client streaming connections:
192
192
 
193
193
  ```ruby
194
194
  url = DurableStreams.signed_stream_url(room, :messages)
@@ -258,7 +258,7 @@ This gem mirrors `turbo-rails` 1:1 in structure and design:
258
258
  | `Turbo::Broadcastable::TestHelper` | `DurableStreams::Rails::Broadcastable::TestHelper` | Test assertions |
259
259
 
260
260
  The key architectural difference: Turbo broadcasts HTML fragments over WebSockets (Action Cable).
261
- This gem broadcasts JSON State Protocol events over HTTP/SSE (Durable Streams).
261
+ This gem broadcasts JSON State Protocol events over HTTP (Durable Streams).
262
262
 
263
263
  ## Dependencies
264
264
 
@@ -324,6 +324,50 @@ requirement from application code:
324
324
  Whichever path touches a stream first provisions it. The application developer never thinks
325
325
  about stream creation.
326
326
 
327
+ ## Security
328
+
329
+ ### Two URLs, two authentication channels
330
+
331
+ The gem separates client-facing and server-to-server communication:
332
+
333
+ ```ruby
334
+ # config/initializers/durable_streams.rb
335
+
336
+ # Client-facing — used by signed_stream_url to build URLs browsers connect to.
337
+ DurableStreams.client_url = ENV.fetch("DURABLE_STREAMS_CLIENT_URL", "http://localhost:4437/v1/streams")
338
+
339
+ # Server-to-server — used by Rails to POST broadcasts and PUT stream creation.
340
+ # Paired with server_api_key for authentication.
341
+ DurableStreams.server_url = ENV.fetch("DURABLE_STREAMS_SERVER_URL", "http://localhost:4437/v1/streams")
342
+ ```
343
+
344
+ In single-server deployments both point to the same address. In multi-server deployments
345
+ they diverge: `client_url` is the public domain (behind a CDN), `server_url` is the internal
346
+ network address.
347
+
348
+ `server_url` is never exposed to clients. `client_url` is never used for server-to-server
349
+ communication.
350
+
351
+ ### Client authentication — signed URLs
352
+
353
+ Browsers receive signed, expiring URLs via Inertia props (or any server-rendered response).
354
+ The token is generated by `MessageVerifier` and encodes the stream name, permissions
355
+ (`read`/`write`), and an expiration timestamp.
356
+
357
+ When a client connects, the Durable Streams server's `forward_auth` sends the request to
358
+ `AuthController#verify`, which validates the token's signature and expiration.
359
+
360
+ **The token is domain-agnostic.** It validates *what* (stream name + permissions + expiry),
361
+ not *where* (which host the request is hitting). Network-level controls (firewall/NSG rules)
362
+ must prevent clients from reaching `server_url` directly.
363
+
364
+ ### Server authentication — API key
365
+
366
+ Rails authenticates to the Durable Streams server with a Bearer token (`server_api_key`)
367
+ sent in the `Authorization` header. The key is auto-derived from
368
+ `Rails.application.key_generator` — consistent across all instances of the same app
369
+ without manual configuration.
370
+
327
371
  ## Future
328
372
 
329
373
  Brewing secretly — an async-backed durable streams server inside Rails.
@@ -14,7 +14,7 @@
14
14
  # end
15
15
  #
16
16
  # This broadcasts a State Protocol insert event to the stream derived from the post association.
17
- # All clients subscribed to that stream will receive the event as an SSE message.
17
+ # All clients subscribed to that stream will receive the event.
18
18
  #
19
19
  # There are four basic operations you can broadcast: <tt>insert</tt>, <tt>update</tt>, <tt>upsert</tt>,
20
20
  # and <tt>delete</tt>. As a rule, you should use the <tt>_later</tt> versions when broadcasting within
@@ -48,9 +48,9 @@ module DurableStreams
48
48
  config.durable_streams.server_api_key ||
49
49
  ::Rails.application.key_generator.generate_key("durable_streams/server_api_key").unpack1("H*")
50
50
 
51
- if DurableStreams.base_url.present?
51
+ if DurableStreams.server_url.present?
52
52
  DurableStreams.configure do |c|
53
- c.base_url = DurableStreams.base_url
53
+ c.base_url = DurableStreams.server_url
54
54
  c.default_headers = { "Authorization" => "Bearer #{DurableStreams.server_api_key}" }
55
55
  end
56
56
  end
@@ -1,5 +1,5 @@
1
1
  module DurableStreams
2
2
  module Rails
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -12,7 +12,8 @@ module DurableStreams
12
12
  extend DurableStreams::Rails::StreamProvisioner
13
13
  extend DurableStreams::Rails::Broadcasts
14
14
 
15
- mattr_accessor :base_url
15
+ mattr_accessor :client_url
16
+ mattr_accessor :server_url
16
17
  mattr_accessor :draw_routes, default: true
17
18
  mattr_accessor :signed_stream_url_expires_in, default: 24.hours
18
19
 
@@ -38,7 +39,7 @@ module DurableStreams
38
39
  { "stream" => path, "permissions" => permissions.map(&:to_s) },
39
40
  expires_in: expires_in
40
41
  )
41
- "#{base_url}/#{path}?token=#{token}"
42
+ "#{client_url}/#{path}?token=#{token}"
42
43
  end
43
44
 
44
45
  # Verifies the signed token embedded in a stream URL. Used by the auth controller
@@ -1 +1,7 @@
1
- DurableStreams.base_url = ENV.fetch("DURABLE_STREAMS_URL", "http://localhost:4437/v1/streams")
1
+ # Client-facing URL for signed stream URLs (what browsers connect to).
2
+ DurableStreams.client_url = ENV.fetch("DURABLE_STREAMS_CLIENT_URL", "http://localhost:4437/v1/streams")
3
+
4
+ # Server-to-server URL for broadcasts and stream provisioning.
5
+ # In single-server setups this matches client_url. In multi-server deployments
6
+ # this should point to the internal address of the Durable Streams server.
7
+ DurableStreams.server_url = ENV.fetch("DURABLE_STREAMS_SERVER_URL", "http://localhost:4437/v1/streams")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: durable_streams-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tokimonki
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '8.0'
40
40
  description: Stream State Protocol events from Active Record models with the same
41
41
  DX as Turbo Broadcasts — declarative streaming, automatic callbacks, and async jobs
42
- — but with offset-based resumability and persistent event logs over SSE.
42
+ — but with offset-based resumability and persistent event logs over HTTP.
43
43
  email: opensource@tokimonki.com
44
44
  executables: []
45
45
  extensions: []