@panaversity/ksor 0.0.45 → 0.0.46

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @panaversity/ksor
2
2
 
3
+ ## 0.0.46
4
+
5
+ ### Patch Changes
6
+
7
+ - a28fac9: **The Auth0 recipe now names the trap that costs the afternoon it warns about.**
8
+ Walked end to end against a live Auth0 tenant and a deployed door for the first
9
+ time (2026-08-26), and the recipe was right about what to type and silent about
10
+ the two things that actually go wrong.
11
+
12
+ The API **Identifier** must equal `KSOR_MCP_RESOURCE_URL` character for
13
+ character, `/mcp` path included — and **Auth0 does not let you edit it after the
14
+ API is created**, so a wrong one is fixed by making a new API, not by correcting
15
+ the field. Neither fact was written down.
16
+
17
+ Two Auth0 errors now have a table, because both arrive as a failed token request
18
+ and they mean opposite things: `Service not enabled within domain` is no API
19
+ with that Identifier, while `Client "…" is not authorized to access resource
20
+ server` means the Identifier is right and the grant from step 5 is missing.
21
+ Moving from the first to the second is progress.
22
+
23
+ And "Verify it" gains a step 0: ask the PROVIDER for a token before touching the
24
+ door. Half of these failures never reach ksor, and one `curl` at the token
25
+ endpoint separates the halves — which is how this diagnosis was actually made,
26
+ after several rounds of reasoning about dashboard toggles that turned out not to
27
+ be the cause.
28
+
29
+ **And it now says you need more than one Application.** The recipe never
30
+ mentioned the site's own sign-in control, never said its Application is a
31
+ different TYPE from an assistant's, and never said the two cannot be the same
32
+ registration — a public client with no secret and a confidential client that
33
+ sends one are different things, and using one for both returns a bare `401` at
34
+ the token endpoint that names nothing. A table at the top of the recipe now
35
+ gives one row per caller: what type, what token-endpoint auth, what callback,
36
+ and whether it needs the grant from step 5.
37
+
3
38
  ## 0.0.45
4
39
 
5
40
  ### Patch Changes
@@ -298,6 +298,25 @@ Nothing else in this recipe makes sense until that lands. You are not building
298
298
  an API; you are describing the one you already have so Auth0 can mint tokens
299
299
  aimed at it.
300
300
 
301
+ **You will need MORE THAN ONE Application, and they are different types.** This
302
+ is the single thing most likely to waste your afternoon, because one application
303
+ configured for one caller returns a plain `401` to the other with nothing
304
+ naming the mismatch (found the hard way, 2026-08-26). One API, one caller per
305
+ row:
306
+
307
+ | The caller | Auth0 Application Type | Token endpoint auth | Callback | Needs step 5 |
308
+ | ------------------------------------------------- | --------------------------- | -------------------------- | ------------------------------------------------------------------- | ------------ |
309
+ | the SITE's sign-in control (`NEXT_PUBLIC_KSOR_*`) | **Single Page Application** | **None** — PKCE, no secret | `https://your-site/auth/callback` | no |
310
+ | an assistant a person logs into (Claude, an IDE) | **Regular Web Application** | client secret | the assistant's own, e.g. `https://claude.ai/api/mcp/auth_callback` | **yes** |
311
+ | a script, worker or backend agent | **Machine to Machine** | client secret | none | **yes** |
312
+
313
+ The site row is a different flow and not really part of this page: it requests
314
+ `openid profile email` and **no audience**, so it never touches your API and
315
+ needs no grant. It is here only so you do not try to serve it and an assistant
316
+ from one application — a public client with no secret and a confidential client
317
+ that sends one cannot be the same registration, and the failure is a `401` at
318
+ the token endpoint that says nothing about why.
319
+
301
320
  ### 1. Describe the door
302
321
 
303
322
  **Applications → APIs → Create API.** The **Identifier** you type becomes the
@@ -309,6 +328,24 @@ Name: my-record
309
328
  Identifier: https://your-host.example.com/mcp
310
329
  ```
311
330
 
331
+ **Type the whole URL, `/mcp` included, and get it right the first time.** The
332
+ Identifier must equal `KSOR_MCP_RESOURCE_URL` character for character — the host
333
+ alone is not enough, because that is not what the door will compare against. And
334
+ **Auth0 does not let you edit an Identifier after the API is created**: a wrong
335
+ one is fixed by creating a NEW API with the right string and granting your
336
+ application access to that one instead.
337
+
338
+ Two Auth0 errors tell you exactly where you are, and they are easy to confuse
339
+ because both arrive as a failed token request (reported by an adopter,
340
+ 2026-08-26):
341
+
342
+ | Auth0 says | Means |
343
+ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
344
+ | `Service not enabled within domain: https://…/mcp` | **no API has that Identifier.** Yours was created with a different string — make a new one |
345
+ | `Client "…" is not authorized to access resource server "https://…/mcp"` | the API is right and the **grant** is missing — step 5 |
346
+
347
+ Moving from the first message to the second is progress, not a new problem.
348
+
312
349
  Creating it also creates a machine-to-machine **test application** named
313
350
  `<API> (Test Application)`. That is your first caller — you do not need to make
314
351
  one.
@@ -447,9 +484,25 @@ Use the commands below when it did NOT work, or when the caller is a script
447
484
  rather than a person. A token from your provider proves the provider works; it
448
485
  does not prove the door does. Both halves matter, and the refusal matters more.
449
486
 
487
+ **0. Ask the provider for a token FIRST, before you touch the door.** Half the
488
+ failures on this page never reach ksor at all, and this one command separates
489
+ the two halves in a second:
490
+
491
+ ```sh
492
+ curl -s -X POST https://YOUR_TENANT.us.auth0.com/oauth/token \
493
+ -H 'content-type: application/json' \
494
+ -d '{"grant_type":"client_credentials","client_id":"…","client_secret":"…",
495
+ "audience":"https://your-host.example.com/mcp"}'
496
+ ```
497
+
498
+ An `error` here is the PROVIDER refusing, and no amount of ksor configuration
499
+ will change it — see the table in step 1 for what each message means. An
500
+ `access_token` here means the provider works, and anything still failing is the
501
+ door or the token's contents, which is what the rest of this section is for.
502
+
450
503
  **1. Decode the token before using it.** This is the single most useful
451
- debugging step on this page, because a valid token audienced at the wrong thing
452
- looks identical to a broken one:
504
+ debugging step once you have one, because a valid token audienced at the wrong
505
+ thing looks identical to a broken one:
453
506
 
454
507
  ```sh
455
508
  echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq '{iss, aud, exp}'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panaversity/ksor",
3
- "version": "0.0.45",
3
+ "version": "0.0.46",
4
4
  "description": "Knowledge System of Record — compile governed markdown into a static site for people and an MCP server for AI agents, with citations and measured abstention.",
5
5
  "keywords": [
6
6
  "abstention",