@usegraft/auth 0.1.1 → 0.2.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.
Files changed (3) hide show
  1. package/README.md +47 -0
  2. package/dist/index.js +9 -1
  3. package/package.json +20 -5
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @usegraft/auth
2
+
3
+ > Graft verifies identity; it does not mint it. Turn a request into a scoped actor by verifying bearer JWTs against trusted issuers.
4
+
5
+ Part of [Graft](https://github.com/AndersonDesign1/graft), a CMS built so an AI agent is the primary operator.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm i @usegraft/auth
11
+ ```
12
+
13
+ ## Resolve an actor
14
+
15
+ ```ts
16
+ import { createActorResolver, betterAuthIssuer } from "@usegraft/auth";
17
+
18
+ const resolveActor = createActorResolver({
19
+ issuers: [betterAuthIssuer("https://example.com")],
20
+ });
21
+ ```
22
+
23
+ Hand that to `graft serve`, the MCP handler, or the functions handler. It verifies the bearer JWT against the issuer's JWKS via OIDC discovery and returns a `FunctionActor` carrying a stable id and the scopes from the standard `scope` claim.
24
+
25
+ Because it verifies rather than issues, an external IdP drops in unchanged. A Better Auth instance your app hosts and an enterprise IdP take the same path.
26
+
27
+ ## Require scopes
28
+
29
+ ```ts
30
+ import { requireScopes } from "@usegraft/auth";
31
+
32
+ export const listSubmissions = defineFunction({
33
+ name: "listSubmissions",
34
+ authorize: requireScopes("submissions:read"),
35
+ // …
36
+ });
37
+ ```
38
+
39
+ Being signed in earns nothing. An account gets scopes because something granted them, which is the whole point: open sign-up plus implicit scopes means one free registration reads everything.
40
+
41
+ ## Environment
42
+
43
+ `GRAFT_TRUSTED_ISSUERS` for OIDC issuers, `GRAFT_DEV_TOKEN` and `GRAFT_DEV_SCOPES` for a static local identity. Anonymous MCP is refused unless `GRAFT_MCP_ALLOW_ANONYMOUS=1`, which nothing sets for you.
44
+
45
+ ---
46
+
47
+ MIT. [Repository](https://github.com/AndersonDesign1/graft) · [Changelog](https://github.com/AndersonDesign1/graft/blob/feat/core/packages/auth/CHANGELOG.md) · [Security policy](https://github.com/AndersonDesign1/graft/blob/feat/core/SECURITY.md)
package/dist/index.js CHANGED
@@ -58,12 +58,20 @@ var IssuerVerifier = class {
58
58
  try {
59
59
  ({ payload } = await jwtVerify(token, getKey, {
60
60
  issuer: this.config.issuer,
61
- audience: this.config.audience
61
+ audience: this.config.audience,
62
+ // jose treats `sub` as optional, so a signature-valid token without one
63
+ // used to authenticate as an actor with `id: undefined` — which then
64
+ // collapsed into an IP-keyed rate bucket, wrote null actor ids to the
65
+ // audit log, and filed approvals nobody could be held to.
66
+ requiredClaims: ["sub"]
62
67
  }));
63
68
  } catch (err) {
64
69
  const code = err.code ?? "verification failed";
65
70
  throw tokenInvalid(`${code} (issuer "${this.config.issuer}")`);
66
71
  }
72
+ if (payload.sub === void 0) {
73
+ throw tokenInvalid(`token carries no "sub" claim (issuer "${this.config.issuer}")`);
74
+ }
67
75
  return {
68
76
  kind: this.config.actorKind ?? "agent",
69
77
  id: payload.sub,
package/package.json CHANGED
@@ -1,6 +1,22 @@
1
1
  {
2
2
  "name": "@usegraft/auth",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
+ "description": "Turn a request into a scoped actor by verifying bearer JWTs against trusted OIDC issuers. Graft verifies identity, it does not mint it.",
5
+ "keywords": [
6
+ "agent",
7
+ "ai",
8
+ "auth",
9
+ "better-auth",
10
+ "cms",
11
+ "graft",
12
+ "headless-cms",
13
+ "jwt",
14
+ "mcp",
15
+ "oidc",
16
+ "scopes",
17
+ "typescript"
18
+ ],
19
+ "homepage": "https://github.com/AndersonDesign1/graft#readme",
4
20
  "license": "MIT",
5
21
  "repository": {
6
22
  "type": "git",
@@ -24,8 +40,8 @@
24
40
  "access": "public"
25
41
  },
26
42
  "dependencies": {
27
- "@usegraft/contracts": "0.1.1",
28
- "@usegraft/core": "0.1.1",
43
+ "@usegraft/contracts": "0.2.0",
44
+ "@usegraft/core": "0.2.0",
29
45
  "jose": "^6.0.0"
30
46
  },
31
47
  "engines": {
@@ -35,7 +51,6 @@
35
51
  "build": "tsup src/index.ts --format esm --dts --clean",
36
52
  "dev": "tsup src/index.ts --format esm --watch",
37
53
  "typecheck": "tsc --noEmit",
38
- "test": "vitest run",
39
- "lint": "oxlint ."
54
+ "test": "vitest run"
40
55
  }
41
56
  }