patchwork-rb 0.1.1 → 0.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -8
  3. data/lib/patchwork/version.rb +1 -1
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02aaad7b12e53f7fd6eb119d03cb576a91cb80afa6d488eecd16dcd251839479
4
- data.tar.gz: 4743b0e1a4841078b6a85db01048bc9a888a76707e9b746b3098657b7f777785
3
+ metadata.gz: 108700913cae8170b5b159b176721c89622cdb953b05742faf9ea67412737efb
4
+ data.tar.gz: 265117f01f55ae9c4ed57aae204f4a1e1075bacfa89a7cada213d3d7d4dba2c6
5
5
  SHA512:
6
- metadata.gz: 865c4584db5879b87c9e6292ef356ec605e04667c072fa535bb2c715e3cfe1d5ee9e28199c06a71d943bb6a30f4dfc9ec1510c5b89cd080109763ceb4c18e40e
7
- data.tar.gz: 8711b23744bb966e445103a154a5f827bbdd7a149942b3ffcbe24c25b8358a990c455412a74b88bffe0775af6c97df2ec55aae069637ea27d67cf086253b4617
6
+ metadata.gz: f96ee8264f33daf9f0167a8dc9d3fcd5dcfd1152a595c2558a2b5902d1f89cbb82b648439043eccb4822fc6b75b3e869a9294c150220f6d10ddab4fdac4a3d01
7
+ data.tar.gz: b46c6776a18619c2b9cc0fc5cbb987a35ad32206445b7c28fdef6af60f0e38161632dca1d0dc18a720faaea50fc2f73786f480ccdd3b7100c76fa0042cf403ef
data/README.md CHANGED
@@ -91,9 +91,10 @@ If you decode several formats that share a delimiter, try the prefixed ones firs
91
91
 
92
92
  ```ruby
93
93
  # config/routes.rb
94
- post "patchwork/mint", to: "patchwork#mint"
95
- get "patchwork/jwks", to: "patchwork#jwks"
96
- post "patchwork/webhook", to: "patchwork#webhook"
94
+ post "patchwork/mint", to: "patchwork#mint" # section 3
95
+ get "patchwork/jwks", to: "patchwork#jwks" # section 3
96
+ post "patchwork/up", to: "patchwork#up" # section 5
97
+ post "patchwork/webhook", to: "patchwork#webhook" # section 6
97
98
  ```
98
99
 
99
100
  `mint` has two callers on one URL, and the signature tells them apart. Your frontend asks for a token for the signed-in user; Patchwork asks, server to server, for a token for a subject it already acts for — that covers relay connections and **every Playground run**. Patchwork's call is a signed `POST` carrying `{"subject": "..."}` and expects a bare `{ token, expires_in }` back. The [Session tokens guide](https://docs.usepatchwork.co/guides/session-tokens) has the wire format, and the [Mint endpoint guide](https://docs.usepatchwork.co/guides/mint-endpoint) covers both branches.
@@ -248,11 +249,13 @@ Rails.application.config.middleware.use Patchwork::Gateway,
248
249
 
249
250
  Use a cache that every app process shares. A per-process cache only stops replays that land on the same process.
250
251
 
251
- ## 5. Health check
252
+ ## 5. Verify the connection
252
253
 
253
- The gateway answers `POST /patchwork/up` (also when it's mounted under a prefix) with a proof that only the shared secret can produce. That's how **Test** on a connection in the Patchwork console reports **verified** rather than just reachable.
254
+ Patchwork POSTs a nonce to `/patchwork/up` and expects back a proof only your request secret can compute. Answering it is what makes **Test** on a connection report **verified** instead of merely **reachable**.
254
255
 
255
- Without the gateway, it is another action on the same controller. Route `post "patchwork/up", to: "patchwork#up"`:
256
+ The path is fixed, and resolved against the connection's `base_url`. If `base_url` is `https://api.acme.com`, Patchwork probes `https://api.acme.com/patchwork/up`.
257
+
258
+ The gateway answers it, including when mounted under a prefix. Without the gateway, it is another action on the same controller:
256
259
 
257
260
  ```ruby
258
261
  def up
@@ -262,7 +265,22 @@ rescue Patchwork::HealthCheck::BadRequest
262
265
  end
263
266
  ```
264
267
 
265
- Pass `health_check: false` if you want to own the route while still using the gateway for tool calls.
268
+ Pass `health_check: false` to own the route while still using the gateway for tool calls.
269
+
270
+ Leave the route unauthenticated. The proof is domain-separated from request signatures, so answering an unsigned probe cannot help anyone forge one.
271
+
272
+ | Test says | Means |
273
+ | --- | --- |
274
+ | **verified** | The proof matched your request secret. The only result that confirms the secret itself. |
275
+ | **reachable** | Something answered, but the proof was missing or wrong — or the connection's auth mode is not `minted`, which is the only mode that can be cryptographically verified. |
276
+ | **unreachable** | Nothing answered. |
277
+
278
+ Two things produce **reachable** when you expect **verified**:
279
+
280
+ - **A redirect.** Patchwork does not follow it, because the signature covers the original path. Point `base_url` at the final URL, and check https, `www`, and the trailing slash.
281
+ - **A 404**, which means `base_url` is not your API root.
282
+
283
+ Rotation does not break this. Your proof is computed with your current request secret, and Patchwork accepts a proof computed with either its current or its previous one — so `/patchwork/up` keeps reporting verified on both sides of a rotation.
266
284
 
267
285
  ## 6. Verify webhooks
268
286
 
@@ -299,7 +317,9 @@ end
299
317
 
300
318
  ## 7. Rotating secrets and keys
301
319
 
302
- **Request secret:** set the new value as `request_secret` and the old one as `previous_request_secret`. Deploy, update the connection in Patchwork, then remove the previous value.
320
+ **Request secret:** Patchwork generates this one, so you copy it rather than choose it. Rotate it in your workspace settings, set the new value as `request_secret`, move the value it replaced to `previous_request_secret`, and deploy.
321
+
322
+ Do the rotation and the deploy together. Patchwork starts signing with the new secret the moment you rotate, so a consumer still holding only the old one will refuse tool calls. `previous_request_secret` exists to cover requests that were already signed with the old secret, not to give you a long overlap. Drop it on your next deploy.
303
323
 
304
324
  **Signing key:** serve both public keys from your JWKS, and switch `signing_key` once Patchwork has fetched the new set. Never remove the old key first. With `signing_kid` unset, each key's `kid` is its thumbprint, so the two can't collide. To serve more than one key, build the document yourself from `Patchwork::SigningKey.public_jwk` plus the previous one.
305
325
 
@@ -1,3 +1,3 @@
1
1
  module Patchwork
2
- VERSION = "0.1.1".freeze
2
+ VERSION = "0.1.2".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: patchwork-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chromablue Labs