@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.
- package/README.md +47 -0
- package/dist/index.js +9 -1
- 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.
|
|
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.
|
|
28
|
-
"@usegraft/core": "0.
|
|
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
|
}
|