@owlmeans/server-auth 0.1.18-rc.1 → 0.1.18-rc.11
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/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/server-auth",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-08-
|
|
4
|
+
"version": "0.1.18-rc.11",
|
|
5
|
+
"generatedAt": "2026-08-24T21:14:00.116Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
"category": "package-specific",
|
|
12
12
|
"file": "skills/server-auth/SKILL.md",
|
|
13
13
|
"canonicalPath": ".agents/skills/server-auth/SKILL.md"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"kind": "skill",
|
|
17
|
+
"name": "supervisor-auth",
|
|
18
|
+
"category": "multi-package",
|
|
19
|
+
"file": "skills/supervisor-auth/SKILL.md",
|
|
20
|
+
"canonicalPath": ".agents/skills/supervisor-auth/SKILL.md"
|
|
14
21
|
}
|
|
15
22
|
]
|
|
16
23
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supervisor-auth
|
|
3
|
+
description: PK-based supervisor authentication — a development-only login where a holder of one of the project's trusted private keys mints a token for any user id/email (registering them on first use), bypassing external IdPs. Primary use is end-to-end tests. Covers appendSupervisorAuth (server + web), the supervisor plugin, and the @owlmeans/test-ui helpers. Use when wiring or testing supervisor auth.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
|
+
|
|
8
|
+
# PK-Based Supervisor Authentication
|
|
9
|
+
|
|
10
|
+
**Layer:** Server (`@owlmeans/server-auth`) + Web (`@owlmeans/web-auth`) + Tests (`@owlmeans/test-ui`)
|
|
11
|
+
|
|
12
|
+
A privileged, **development-only** auth path: a holder of one of the project's trusted private keys
|
|
13
|
+
(the allowlisted "supervisors") signs a server challenge to mint a valid owlmeans token for an
|
|
14
|
+
arbitrary user id / email — **without** Google/OIDC. Unknown users are **registered** on first use.
|
|
15
|
+
The primary purpose is deterministic **end-to-end tests** that authenticate against real environments.
|
|
16
|
+
|
|
17
|
+
It reuses the existing flow end-to-end: the plugin only **verifies the supervisor signature and
|
|
18
|
+
resolves/registers the user**, then hands the credential back to `makeAuthModel` (which signs the
|
|
19
|
+
credential envelope) and the project's auth service (which exchanges it for the final
|
|
20
|
+
`Ed25519BasicToken` bearer). No new token-minting code.
|
|
21
|
+
|
|
22
|
+
## Type & payload
|
|
23
|
+
|
|
24
|
+
- `AuthenticationType.Supervisor = 'pk-supervisor'` (in `@owlmeans/auth`).
|
|
25
|
+
- Shared signed payload: `buildSupervisorPayload(challenge, userId, salt)` (in `@owlmeans/auth`) —
|
|
26
|
+
binds the signature to the **single-use server challenge** (replay protection), the target
|
|
27
|
+
`userId`, and a fresh client `salt`. The front-end packs `{ salt, signature }` (JSON) into
|
|
28
|
+
`AuthCredentials.credential`.
|
|
29
|
+
|
|
30
|
+
## Server: `appendSupervisorAuth` (from `@owlmeans/server-auth/manager`)
|
|
31
|
+
|
|
32
|
+
Call once on the **auth-manager** context (the one that serves `AUTHEN_INIT`/`AUTHEN_AUTHEN` and holds
|
|
33
|
+
`AUTH_SRV_KEY`), beside other plugin appends (e.g. `appendOtpPlugin`).
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { appendSupervisorAuth } from '@owlmeans/server-auth/manager'
|
|
37
|
+
|
|
38
|
+
appendSupervisorAuth(context, {
|
|
39
|
+
supervisors: ['master-key', 'super-user', 'shared-key'], // TRUSTED record `name`s allowed to sign
|
|
40
|
+
resolveUser: async (userId, ctx, { register }) => { // find-or-create the target identity
|
|
41
|
+
// wire to your identity store; return { userId, profileId?, entityId?, role?, scopes? }
|
|
42
|
+
},
|
|
43
|
+
allowRegistration: true, // default true
|
|
44
|
+
enabled: undefined, // default: development only (cfg.debug.all || cfg.debug.supervisor)
|
|
45
|
+
acceptInternalTokens: true, // default true — see below
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Options:
|
|
50
|
+
- `supervisors` — TRUSTED-record `name`s authorized to sign. Default `['master','superuser']`. The
|
|
51
|
+
matching **public** key must be in the project's TRUSTED config; the **private** key is what the
|
|
52
|
+
front-end signs with. Pick aliases whose private keys you actually have (e.g. in `.env.dev.secrets`).
|
|
53
|
+
- `resolveUser` — `(userId, context, { register }) => Promise<SupervisorUserResolution>`. Default:
|
|
54
|
+
trust the id as-is. Wire to `@owlmeans/server-auth-identity`'s `IdentityLinkingService`
|
|
55
|
+
(`getLinkedProfile` / `linkProfile`) to find-or-create a real profile + entity.
|
|
56
|
+
- `enabled` — force on/off. Default is development only. **Never enable in real production.**
|
|
57
|
+
- `acceptInternalTokens` (requirement: understand internal tokens even when OIDC is the primary
|
|
58
|
+
guard) — when `true`, ensures the internal `Ed25519BasicToken` guard (`DEFAULT_GUARD`) is accepted
|
|
59
|
+
as a coguard on already-guarded modules. Also exposed standalone as
|
|
60
|
+
`setupInternalTokenCoguard(modules, guard?)`. Set `false` when modules already use `DEFAULT_GUARD`
|
|
61
|
+
as the primary guard (internal tokens already work).
|
|
62
|
+
|
|
63
|
+
## Web: `appendSupervisorAuth` (from `@owlmeans/web-auth`)
|
|
64
|
+
|
|
65
|
+
Call once on the web client context. Registers the self-contained login form plugin; the form renders
|
|
66
|
+
at the standard typed route `SUPERVISOR_LOGIN_PATH` = `/authentication/login/pk-supervisor`.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { appendSupervisorAuth } from '@owlmeans/web-auth'
|
|
70
|
+
|
|
71
|
+
appendSupervisorAuth(context) // dev-only by default; or appendSupervisorAuth(context, { enabled })
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The form (`data-testid="supervisor-auth-form"`, inputs `supervisor-user-id`, `supervisor-pk`, button
|
|
75
|
+
`supervisor-submit`) fetches a challenge, signs it, exchanges it for a bearer, stores it, and
|
|
76
|
+
redirects HOME — mirroring the Google plugin. (Alternatively, the side-effect import
|
|
77
|
+
`@owlmeans/web-auth/auth/plugins` always-registers it.)
|
|
78
|
+
|
|
79
|
+
## Tests: `@owlmeans/test-ui` helpers
|
|
80
|
+
|
|
81
|
+
- `authenticateViaSupervisorApi({ apiBaseUrl, userId, pk })` — drives the live API
|
|
82
|
+
(`/authentication/init` → sign → `/authentication/authenticate` → `/authenticate`) and returns the
|
|
83
|
+
final bearer. **No browser**; registers the user on first use. The "set a token directly via API" path.
|
|
84
|
+
- `loginViaSupervisorForm(page, { baseUrl, userId, pk })` — Playwright: drives the real login form
|
|
85
|
+
end-to-end (faithful path that exercises the plugin + registration).
|
|
86
|
+
- `loginViaDispatcher(page, baseUrl, token)` — inject a pregenerated bearer via the standard
|
|
87
|
+
`/dispatcher?token=` route (apps that override DISPATCHER, e.g. for a forced IdP, can't use this —
|
|
88
|
+
use the form).
|
|
89
|
+
- `pregenerateAuthToken({ userId, pk, ... })` — offline mint via `@owlmeans/test-auth`'s `makeBearer`
|
|
90
|
+
using the project's **own** trusted signing key (lowest-level primitive).
|
|
91
|
+
|
|
92
|
+
## Security
|
|
93
|
+
|
|
94
|
+
- Development/stage only. Gate on `cfg.debug`; never ship enabled to real production.
|
|
95
|
+
- Anyone with a supervisor **private** key can impersonate/register any user — treat those keys as
|
|
96
|
+
highly sensitive.
|
|
97
|
+
|
|
98
|
+
## Depends On
|
|
99
|
+
- `@owlmeans/auth` (type + `buildSupervisorPayload`), `@owlmeans/basic-keys` (sign/verify),
|
|
100
|
+
`@owlmeans/auth-common` (`DEFAULT_GUARD`, `TrustedRecord`), `@owlmeans/config` (`TRUSTED`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-auth",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -37,29 +37,29 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@noble/hashes": "^1.5.0",
|
|
40
|
-
"@owlmeans/api": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/api-config-server": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
43
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
44
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
45
|
-
"@owlmeans/basic-ids": "^0.1.18-rc.
|
|
46
|
-
"@owlmeans/basic-keys": "^0.1.18-rc.
|
|
47
|
-
"@owlmeans/client-config": "^0.1.18-rc.
|
|
48
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
49
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
50
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
51
|
-
"@owlmeans/kluster": "^0.1.18-rc.
|
|
52
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
53
|
-
"@owlmeans/redis-resource": "^0.1.18-rc.
|
|
54
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
55
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
56
|
-
"@owlmeans/server-api": "^0.1.18-rc.
|
|
57
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
58
|
-
"@owlmeans/server-entrypoint": "^0.1.18-rc.
|
|
59
|
-
"@owlmeans/server-route": "^0.1.18-rc.
|
|
60
|
-
"@owlmeans/server-socket": "^0.1.18-rc.
|
|
61
|
-
"@owlmeans/socket": "^0.1.18-rc.
|
|
62
|
-
"@owlmeans/static-resource": "^0.1.18-rc.
|
|
40
|
+
"@owlmeans/api": "^0.1.18-rc.7",
|
|
41
|
+
"@owlmeans/api-config-server": "^0.1.18-rc.11",
|
|
42
|
+
"@owlmeans/auth": "^0.1.18-rc.6",
|
|
43
|
+
"@owlmeans/auth-common": "^0.1.18-rc.7",
|
|
44
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.7",
|
|
45
|
+
"@owlmeans/basic-ids": "^0.1.18-rc.6",
|
|
46
|
+
"@owlmeans/basic-keys": "^0.1.18-rc.7",
|
|
47
|
+
"@owlmeans/client-config": "^0.1.18-rc.7",
|
|
48
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.7",
|
|
49
|
+
"@owlmeans/config": "^0.1.18-rc.7",
|
|
50
|
+
"@owlmeans/context": "^0.1.18-rc.6",
|
|
51
|
+
"@owlmeans/kluster": "^0.1.18-rc.7",
|
|
52
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.7",
|
|
53
|
+
"@owlmeans/redis-resource": "^0.1.18-rc.7",
|
|
54
|
+
"@owlmeans/resource": "^0.1.18-rc.7",
|
|
55
|
+
"@owlmeans/route": "^0.1.18-rc.6",
|
|
56
|
+
"@owlmeans/server-api": "^0.1.18-rc.11",
|
|
57
|
+
"@owlmeans/server-context": "^0.1.18-rc.7",
|
|
58
|
+
"@owlmeans/server-entrypoint": "^0.1.18-rc.7",
|
|
59
|
+
"@owlmeans/server-route": "^0.1.18-rc.6",
|
|
60
|
+
"@owlmeans/server-socket": "^0.1.18-rc.11",
|
|
61
|
+
"@owlmeans/socket": "^0.1.18-rc.6",
|
|
62
|
+
"@owlmeans/static-resource": "^0.1.18-rc.7",
|
|
63
63
|
"@scure/base": "^2.3.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@owlmeans/dep-config": "workspace:*",
|
|
70
|
-
"@owlmeans/test-auth": "^0.1.18-rc.
|
|
70
|
+
"@owlmeans/test-auth": "^0.1.18-rc.7",
|
|
71
71
|
"@types/bun": "^1.3.14",
|
|
72
72
|
"@types/node": "^26.1.0",
|
|
73
73
|
"nodemon": "^3.1.14",
|