@amodalai/amodal 0.3.70 → 0.3.72
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 +190 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,195 @@
|
|
|
1
1
|
# @amodalai/amodal
|
|
2
2
|
|
|
3
|
+
## 0.3.72
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [36837dd]
|
|
8
|
+
- Updated dependencies [158c851]
|
|
9
|
+
- @amodalai/studio@0.3.72
|
|
10
|
+
- @amodalai/core@0.3.72
|
|
11
|
+
- @amodalai/db@0.3.72
|
|
12
|
+
- @amodalai/runtime@0.3.72
|
|
13
|
+
- @amodalai/types@0.3.72
|
|
14
|
+
- @amodalai/runtime-app@0.3.72
|
|
15
|
+
|
|
16
|
+
## 0.3.71
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- bde01f0: Add config-driven auth on top of the `feat/auth-controller` Warden
|
|
21
|
+
primitive. Agent owners describe their auth in `amodal.json`; the
|
|
22
|
+
runtime parses, validates, and instantiates the right `AuthStrategy`
|
|
23
|
+
at boot.
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"auth": {
|
|
28
|
+
"type": "oidc",
|
|
29
|
+
"issuer": "https://acme.okta.com",
|
|
30
|
+
"clientId": "abc123",
|
|
31
|
+
"clientSecret": "env:OKTA_CLIENT_SECRET",
|
|
32
|
+
"callbackUrl": "https://hr-helper.acme.com/auth/callback",
|
|
33
|
+
"sessionSecret": "env:SESSION_SIGNING_SECRET"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import {
|
|
40
|
+
parseAuthConfig,
|
|
41
|
+
createAuthStrategy,
|
|
42
|
+
JwksAuthStrategy,
|
|
43
|
+
authenticate,
|
|
44
|
+
authRouter,
|
|
45
|
+
} from "@amodalai/runtime";
|
|
46
|
+
|
|
47
|
+
const userAuth = await createAuthStrategy(parseAuthConfig(agentConfig.auth));
|
|
48
|
+
const studioJwt = new JwksAuthStrategy({ jwksUrl: process.env.JWKS_URL });
|
|
49
|
+
|
|
50
|
+
app.use("/api/files", authenticate(studioJwt)); // Studio only
|
|
51
|
+
app.use("/chat", authenticate(studioJwt, userAuth)); // either
|
|
52
|
+
app.use(authRouter(userAuth)); // OAuth callbacks
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Five `auth.type` modes** covering the persona spectrum:
|
|
56
|
+
- `none` — synthesized anonymous identity (public chatbots / dev)
|
|
57
|
+
- `jwt_secret` — HMAC-verify JWTs minted by another server (ISV / server-mediated)
|
|
58
|
+
- `oidc` — full OAuth2.1/OIDC dance via `openid-client` (Okta, Azure AD, Google Workspace, Auth0 OIDC, Keycloak — anything OIDC-compliant). Handles login redirect, PKCE+state, callback exchange, signed-cookie sessions, JWKS verification.
|
|
59
|
+
- `header` — trusted upstream `X-Auth-User` (proxied auth)
|
|
60
|
+
- `custom` — `{module: './my-auth.ts'}` dynamically imports a user-supplied strategy class. The escape hatch for Auth0 SDK / Supabase `getUser` / any auth system that doesn't fit the four modes above.
|
|
61
|
+
|
|
62
|
+
**Validation**: `parseAuthConfig(raw)` (zod-backed) gives clear errors on
|
|
63
|
+
malformed configs at startup, not at first request.
|
|
64
|
+
|
|
65
|
+
**`OidcAuthStrategy`** is the meaty piece — ~270 LOC implementing the
|
|
66
|
+
OAuth dance via `openid-client` v6 (Web-standards), session signing via
|
|
67
|
+
HMAC, encrypted state cookie for the redirect round-trip. Self-contained;
|
|
68
|
+
no database needed; survives multi-instance fleets.
|
|
69
|
+
|
|
70
|
+
Adds `openid-client` as a runtime dependency.
|
|
71
|
+
|
|
72
|
+
This PR delivers the config-facing surface that makes the Warden
|
|
73
|
+
primitive useful to non-developers — agent owners edit JSON (or, in
|
|
74
|
+
follow-up PRs, a Studio UI / `amodal auth init` CLI), the runtime
|
|
75
|
+
wires up auth from there.
|
|
76
|
+
|
|
77
|
+
- bde01f0: Add a Warden-shape pluggable auth primitive: `authenticate(...strategies)`
|
|
78
|
+
returns Express middleware that runs the strategies in order, picks the
|
|
79
|
+
first that applies and authenticates, and attaches a canonical
|
|
80
|
+
`AuthSession` to `res.locals.session` (or 401s the request). Single-winner
|
|
81
|
+
chain — no merging across strategies, no implicit identity overrides.
|
|
82
|
+
|
|
83
|
+
Each strategy implements two methods (modeled on Rails' Warden):
|
|
84
|
+
- `valid(req): boolean` — cheap synchronous check, "does this strategy
|
|
85
|
+
apply at all?". Strategies that return false are skipped without
|
|
86
|
+
paying the `authenticate` cost.
|
|
87
|
+
- `authenticate(req): Promise<AuthResult>` — slow path. Returns a
|
|
88
|
+
discriminated union `{kind: 'authenticated', session}` or
|
|
89
|
+
`{kind: 'rejected', reason}`. No exceptions for control flow — plugin
|
|
90
|
+
authors can't accidentally bypass auth by throwing the wrong sentinel.
|
|
91
|
+
|
|
92
|
+
Per-route mounting solves the route-bifurcation problem cleanly:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const platformJwt = new JwksAuthStrategy({jwksUrl});
|
|
96
|
+
const endUser = new OidcStrategy({...}); // user-supplied or built-in
|
|
97
|
+
|
|
98
|
+
// Studio routes — only platform JWT is in the chain
|
|
99
|
+
app.use('/api/files', authenticate(platformJwt));
|
|
100
|
+
|
|
101
|
+
// Chat routes — accept platform JWT (Studio test chat) OR end-user auth
|
|
102
|
+
app.use('/chat', authenticate(platformJwt, endUser));
|
|
103
|
+
|
|
104
|
+
// Login-flow routes registered by strategies that need them
|
|
105
|
+
app.use(authRouter(endUser));
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A request hitting `/api/files` with an end-user token can't be
|
|
109
|
+
authenticated by accident — `endUser` isn't in that chain.
|
|
110
|
+
|
|
111
|
+
Ships five built-in strategies covering the common amodal personas:
|
|
112
|
+
- **`JwksAuthStrategy`** — Bearer JWT verified against a remote JWKS.
|
|
113
|
+
Pass-through to `jose.createRemoteJWKSet` options for ops visibility
|
|
114
|
+
into key rotation.
|
|
115
|
+
- **`ApiKeyAuthStrategy`** — `ak_*` Bearer tokens validated via a
|
|
116
|
+
caller-supplied callback. LRU-cached (configurable cap, default 10k
|
|
117
|
+
entries) so repeated requests skip the round-trip.
|
|
118
|
+
- **`HeaderAuthStrategy`** — trusted upstream header (default
|
|
119
|
+
`X-Auth-User`) for service-to-service / proxied auth.
|
|
120
|
+
- **`NoneAuthStrategy`** — synthesizes an anonymous session. Place last
|
|
121
|
+
in the chain for public agents / dev environments.
|
|
122
|
+
- **`CookieSessionStrategy`** — session JWT in a cookie (default
|
|
123
|
+
`amodal_session`), verified against JWKS. For SPA + runtime stacks
|
|
124
|
+
that don't sit behind a Bearer-injecting edge proxy.
|
|
125
|
+
|
|
126
|
+
Adds `jose` and `lru-cache` as runtime dependencies.
|
|
127
|
+
|
|
128
|
+
The `AuthSession` shape is canonical across all strategies: `{user: {id,
|
|
129
|
+
email?, name?}, method, agentId?, scopeId?, claims?}`. No `token` field
|
|
130
|
+
on the surface (avoids credential leaks via accidental log serialization);
|
|
131
|
+
strategies expose raw provider claims under `claims` for callers that
|
|
132
|
+
need them.
|
|
133
|
+
|
|
134
|
+
Per-mount `logger` option emits a structured `AuthLogEvent` per request
|
|
135
|
+
(`{strategy, outcome, durationMs, reason?}`) for observability.
|
|
136
|
+
|
|
137
|
+
External identity providers (Auth0, Supabase, custom OIDC, SAML) are
|
|
138
|
+
expected to ship as separate strategy classes — either inside an
|
|
139
|
+
agent's runtime code or as third-party packages — implementing the
|
|
140
|
+
`AuthStrategy` interface. No first-party provider packages in this PR;
|
|
141
|
+
the primitive layer is the contract.
|
|
142
|
+
|
|
143
|
+
- bde01f0: Add a Studio "Authentication" tab for editing the agent's `auth` block
|
|
144
|
+
in `amodal.json` form-style. Builds on the config-driven layer from the
|
|
145
|
+
`feat/auth-config` PR.
|
|
146
|
+
|
|
147
|
+
Agent owners pick the auth type from a card grid (Sign in with Amodal /
|
|
148
|
+
Public / Shared JWT secret / OIDC / Trusted header / Custom) and fill
|
|
149
|
+
in type-specific fields. Saves a draft through the existing
|
|
150
|
+
workspace-edit pipeline; the user commits via "Publish changes" to land
|
|
151
|
+
it on disk.
|
|
152
|
+
|
|
153
|
+
"Sign in with Amodal" is the zero-config option: visitors sign in with
|
|
154
|
+
their existing Amodal account, the runtime verifies the platform JWT
|
|
155
|
+
against Amodal's JWKS, no client setup or secrets required. Backed by a
|
|
156
|
+
new `AmodalAuthStrategy` (a thin `JwksAuthStrategy` wrapper preconfigured
|
|
157
|
+
with the Amodal cloud JWKS URL + issuer; both overridable for self-hosted
|
|
158
|
+
Amodal-equivalent platforms).
|
|
159
|
+
|
|
160
|
+
Implementation mirrors the `embed-config` pattern:
|
|
161
|
+
- `lib/auth-config.ts` — Studio-side editable draft shape +
|
|
162
|
+
read/write helpers for the `auth` block in `amodal.json`. Serializes
|
|
163
|
+
the draft back to the runtime's strict `AuthConfig` discriminated
|
|
164
|
+
union shape on save.
|
|
165
|
+
- `server/routes/auth-config.ts` — `GET/PUT /api/auth-config`,
|
|
166
|
+
same shape as `embed-config` (drafts, capability check, etc.).
|
|
167
|
+
Server-side validation rejects obvious problems before the file
|
|
168
|
+
lands on disk.
|
|
169
|
+
- `hooks/useAuthConfig.ts` — fetch + save hook for the page.
|
|
170
|
+
- `pages/AuthPage.tsx` — the form. Includes a `SecretField` atom that
|
|
171
|
+
highlights `env:` references and masks plain secret values, so
|
|
172
|
+
agent owners are nudged toward the right pattern.
|
|
173
|
+
- Wired into `router.tsx` + `StudioShell` config nav.
|
|
174
|
+
|
|
175
|
+
Secret fields default to `env:` reference values so secrets land in
|
|
176
|
+
the agent's secrets table (encrypted), not in `amodal.json` (in git).
|
|
177
|
+
|
|
178
|
+
The form covers every persona walked through in the auth design:
|
|
179
|
+
Public chatbots → `none`. ISV server-mediated → `jwt_secret`.
|
|
180
|
+
Internal ops SSO → `oidc` (login dance handled by the runtime).
|
|
181
|
+
Proxied auth → `header`. Anything else → `custom` module path.
|
|
182
|
+
|
|
183
|
+
- Updated dependencies [bde01f0]
|
|
184
|
+
- Updated dependencies [bde01f0]
|
|
185
|
+
- Updated dependencies [bde01f0]
|
|
186
|
+
- @amodalai/runtime@0.3.71
|
|
187
|
+
- @amodalai/core@0.3.71
|
|
188
|
+
- @amodalai/studio@0.3.71
|
|
189
|
+
- @amodalai/runtime-app@0.3.71
|
|
190
|
+
- @amodalai/types@0.3.71
|
|
191
|
+
- @amodalai/db@0.3.71
|
|
192
|
+
|
|
3
193
|
## 0.3.70
|
|
4
194
|
|
|
5
195
|
### Patch Changes
|