Skip to content

Commit aba6c4b

Browse files
committed
chore(objectos): bump @objectstack 12.4 -> 14.7 and refresh docs for the 13/14 releases
apps/objectos/package.json pins all @objectstack/* to 14.7.0 (was 12.4.0). Verified: pnpm resolves 14.7.0 everywhere, 'objectstack compile' passes the new ADR-0090 security-posture gate, tsc --noEmit is clean, and the runtime smoke test boots and serves /api/v1/health. The 12.1 projectResolution workaround in objectstack.config.ts is still required on 14.7 (verified against the shipped validator) — comment updated accordingly. Docs (en + zh-Hans; other locales await the translation sync): - configure/permissions: Roles page renamed to Positions (roles/profiles converged per Permission Model v2, ADR-0090) with everyone/guest anchors, effective-dated grants and delegation; overview/permission-sets/ record-access updated for private-by-default sharing, adminScope delegated administration, the explain engine and object-qualified FLS keys - build/data-model: enforced enable.* capability flags (v14) and the lifecycle retention contract (ADR-0057) - configure/authentication: phone/SMS OTP sign-in and admin user management/bulk import (14.3) - configure/api-access: self-serve OAuth 2.1 for MCP clients and the scope-derived permission ceiling (13.0/14.5) - reference/security, cli, environment-variables: Permission Model v2 layering, security lints and access-matrix gate, os db clean, OS_LIFECYCLE_DISABLED / OS_TELEMETRY_DB - resources/changelog: 12.x-14.x release-train highlights, support windows and compatibility matrix moved to 14.x Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LTAZUKc9W5BFjPtctGeZwd
1 parent 81c04e5 commit aba6c4b

48 files changed

Lines changed: 1354 additions & 863 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
## Unreleased
44

5+
- Bumped `@objectstack/*` from 12.4.0 to **14.7.0** in `apps/objectos`, so the
6+
runtime image ships the 14.x train (Permission Model v2, enforced object
7+
capability flags, data-lifecycle contract, phone/SMS auth, MCP scope
8+
ceiling). Verified: `objectstack compile`, `tsc --noEmit`, and the runtime
9+
smoke test all pass on 14.7.0.
10+
- Refreshed the docs site for the ObjectStack 13/14 releases: the
11+
Roles page became [Positions](content/docs/configure/permissions/positions.mdx)
12+
(roles/profiles converged per ADR-0090), permissions/record-access/security
13+
pages document private-by-default sharing, audience anchors, delegated
14+
administration and the explain engine, and the changelog page now covers the
15+
12.x–14.x release trains. English + Simplified Chinese updated; other
16+
locales pending the next translation sync.
517
- Repository re-initialized as the **ObjectOS reference runtime distribution**.
618
- Previous codebase preserved on branch `legacy/v1` and tag `v1-final`.
719
- Adopted pnpm + Turborepo monorepo layout: `apps/objectos`, `apps/docs`, `packages/*`.

apps/objectos/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This package intentionally contains **no protocol code**. All schemas,
1010
the kernel, drivers and official plugins come from `@objectstack/*`
1111
packages on npm. Enterprise plugins maintained in this monorepo live under `../../packages/`
1212
and are composed into the runtime stack returned by
13-
[`createObjectOSStack`](https://www.npmjs.com/package/@objectstack/runtime)
13+
[`createStandaloneStack`](https://www.npmjs.com/package/@objectstack/runtime)
1414
in [`objectstack.config.ts`](./objectstack.config.ts).
1515

1616
See the repository [README](../../README.md) for positioning and the

apps/objectos/objectstack.config.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,12 @@ const stack = await createStandaloneStack({
5252
databaseUrl,
5353
});
5454

55-
// @objectstack 12.1 workaround: createStandaloneStack hard-codes
56-
// `api.projectResolution: 'none'` for the single-tenant standalone case, but the
57-
// 12.1 protocol validator's `api.projectResolution` enum only accepts
58-
// required|optional|auto (the field is optional). Since standalone runs with
59-
// `enableProjectScoping: false`, drop the field so compile/validate passes.
55+
// @objectstack workaround (12.1, still required as of 14.7):
56+
// createStandaloneStack hard-codes `api.projectResolution: 'none'` for the
57+
// single-tenant standalone case, but the protocol validator's
58+
// `api.projectResolution` enum only accepts required|optional|auto (the field
59+
// is optional). Since standalone runs with `enableProjectScoping: false`,
60+
// drop the field so compile/validate passes.
6061
const { projectResolution: _drop, ...api } = stack.api as {
6162
projectResolution?: string;
6263
} & Record<string, unknown>;

apps/objectos/package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@
1313
"type-check": "tsc --noEmit"
1414
},
1515
"dependencies": {
16-
"@objectstack/cli": "12.4.0",
17-
"@objectstack/cloud-connection": "12.4.0",
18-
"@objectstack/console": "12.4.0",
19-
"@objectstack/core": "12.4.0",
20-
"@objectstack/driver-memory": "12.4.0",
21-
"@objectstack/driver-sql": "12.4.0",
22-
"@objectstack/metadata": "12.4.0",
23-
"@objectstack/objectql": "12.4.0",
24-
"@objectstack/runtime": "12.4.0",
25-
"@objectstack/spec": "12.4.0",
16+
"@objectstack/cli": "14.7.0",
17+
"@objectstack/cloud-connection": "14.7.0",
18+
"@objectstack/console": "14.7.0",
19+
"@objectstack/core": "14.7.0",
20+
"@objectstack/driver-memory": "14.7.0",
21+
"@objectstack/driver-sql": "14.7.0",
22+
"@objectstack/metadata": "14.7.0",
23+
"@objectstack/objectql": "14.7.0",
24+
"@objectstack/runtime": "14.7.0",
25+
"@objectstack/spec": "14.7.0",
2626
"pg": "^8.0.0"
2727
},
2828
"devDependencies": {

content/docs/build/data-model.mdx

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,21 +206,54 @@ ObjectSchema.create({
206206
});
207207
```
208208

209-
## Lifecycle & ownership
209+
## Capability flags & ownership
210210

211211
```ts
212212
ObjectSchema.create({
213213
name: 'task',
214214
ownership: 'own', // 'own' | 'shared' | 'system'
215+
sharingModel: 'private', // OWD — custom objects default to private (v13)
215216
enable: {
216217
apiEnabled: true, // generated REST endpoints
217-
trackHistory: true, // audit log of field changes
218-
feeds: true, // sys_comment / sys_activity / @mentions
218+
trackHistory: true, // History tab + field-level diffs (default true)
219+
feeds: true, // sys_comment / @mentions (default true)
220+
activities: true, // mirror CRUD to sys_activity timeline (default true)
221+
files: true, // Attachments panel (opt-in, default false)
219222
softDelete: true, // tombstone instead of hard delete
220223
},
221224
});
222225
```
223226

227+
Since ObjectStack 14 the `enable.*` flags are **enforced**, not
228+
advisory: `feeds: false` rejects comment creation with 403
229+
`FEEDS_DISABLED`, `files` must be opted in before `sys_attachment` rows
230+
can be created (403 `FILES_DISABLED` otherwise), and `activities` /
231+
`trackHistory` gate the timeline and History tab. The compliance
232+
`sys_audit_log` row is always written regardless of flags.
233+
234+
## Data lifecycle (retention)
235+
236+
High-volume objects can declare a `lifecycle` block so the platform
237+
bounds their growth (ObjectStack 14.4, ADR-0057):
238+
239+
```ts
240+
ObjectSchema.create({
241+
name: 'my_event',
242+
lifecycle: {
243+
class: 'event', // 'record' | 'audit' | 'telemetry' | 'transient' | 'event'
244+
retention: '14d', // reaper deletes rows past the window
245+
storage: { rotation: 'weekly' }, // time-sharded tables, O(1) expiry
246+
},
247+
});
248+
```
249+
250+
The built-in LifecycleService (disable with `OS_LIFECYCLE_DISABLED=1`)
251+
reaps expired rows, rotates time-sharded tables, and archives
252+
audit-class objects. Platform objects such as `sys_activity` (14 days)
253+
and `sys_audit_log` (90 days hot, then archive) ship with lifecycle
254+
declarations you can tune per environment via the
255+
`lifecycle.retention_overrides` setting.
256+
224257
## System objects (free with every project)
225258

226259
You don't have to declare these — they're always there:
@@ -230,7 +263,7 @@ You don't have to declare these — they're always there:
230263
| `sys_user` | User accounts |
231264
| `sys_org` | Organizations / tenants |
232265
| `sys_member` | Org membership |
233-
| `sys_role`, `sys_permission_set` | RBAC primitives |
266+
| `sys_position`, `sys_permission_set` | RBAC primitives |
234267
| `sys_audit_log` | Audit trail (when audit capability loaded) |
235268
| `sys_file`, `sys_attachment` | File metadata (when storage loaded) |
236269
| `sys_comment`, `sys_activity` | Feed / chatter (when feed loaded) |

content/docs/build/data-model.zh-Hans.mdx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,21 +197,50 @@ ObjectSchema.create({
197197
});
198198
```
199199

200-
## 生命周期与所有权
200+
## 能力开关与所有权
201201

202202
```ts
203203
ObjectSchema.create({
204204
name: 'task',
205205
ownership: 'own', // 'own' | 'shared' | 'system'
206+
sharingModel: 'private', // OWD——自定义对象默认私有(v13)
206207
enable: {
207208
apiEnabled: true, // 生成 REST 端点
208-
trackHistory: true, // 字段变更审计日志
209-
feeds: true, // sys_comment / sys_activity / @提及
209+
trackHistory: true, // History 选项卡 + 字段级差异(默认 true)
210+
feeds: true, // sys_comment / @提及(默认 true)
211+
activities: true, // CRUD 镜像到 sys_activity 时间线(默认 true)
212+
files: true, // 附件面板(需显式开启,默认 false)
210213
softDelete: true, // 软删除而非硬删除
211214
},
212215
});
213216
```
214217

218+
自 ObjectStack 14 起,`enable.*` 开关是**强制执行**的,而不再只是声明:
219+
`feeds: false` 会以 403 `FEEDS_DISABLED` 拒绝评论创建;`files` 必须显式开启
220+
后才能创建 `sys_attachment` 行(否则返回 403 `FILES_DISABLED`);
221+
`activities` / `trackHistory` 控制时间线和 History 选项卡。无论开关如何,
222+
合规用途的 `sys_audit_log` 行始终会写入。
223+
224+
## 数据生命周期(保留策略)
225+
226+
大数据量对象可以声明 `lifecycle` 块,让平台约束其增长(ObjectStack 14.4,ADR-0057):
227+
228+
```ts
229+
ObjectSchema.create({
230+
name: 'my_event',
231+
lifecycle: {
232+
class: 'event', // 'record' | 'audit' | 'telemetry' | 'transient' | 'event'
233+
retention: '14d', // 回收器删除超出窗口的行
234+
storage: { rotation: 'weekly' }, // 按时间分片表,O(1) 过期
235+
},
236+
});
237+
```
238+
239+
内置的 LifecycleService(可用 `OS_LIFECYCLE_DISABLED=1` 关闭)负责回收过期行、
240+
轮换分片表,并归档 audit 类对象。`sys_activity`(14 天)、`sys_audit_log`
241+
(热存 90 天后归档)等平台对象自带生命周期声明,可通过
242+
`lifecycle.retention_overrides` 设置按环境调整。
243+
215244
## 系统对象(每个项目免费自带)
216245

217246
这些你不必声明 —— 它们一直都在:
@@ -221,7 +250,7 @@ ObjectSchema.create({
221250
| `sys_user` | 用户账户 |
222251
| `sys_org` | 组织 / 租户 |
223252
| `sys_member` | 组织成员关系 |
224-
| `sys_role``sys_permission_set` | RBAC 原语 |
253+
| `sys_position``sys_permission_set` | RBAC 原语 |
225254
| `sys_audit_log` | 审计轨迹(加载审计能力时) |
226255
| `sys_file``sys_attachment` | 文件元数据(加载存储能力时) |
227256
| `sys_comment``sys_activity` | Feed / chatter(加载 feed 能力时) |

content/docs/configure/api-access.mdx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,14 @@ Both are enforced at the REST layer — see
4545

4646
## Authentication options
4747

48-
Callers can authenticate in three ways:
48+
Callers can authenticate in four ways:
4949

5050
| Method | Best for | How |
5151
|---|---|---|
5252
| Session cookie | Browser/UI traffic | Sign in through `/api/v1/auth/*`; cookies are scoped to the project hostname |
5353
| Bearer access token | Mobile, SPA, short-lived server jobs | Exchange credentials at `/api/v1/auth/sign-in/email` and pass `Authorization: Bearer <token>` |
5454
| API key | Server-to-server, ETL, long-lived integrations | Create a `sys_api_key`, pass it as a bearer token |
55+
| OAuth 2.1 (MCP) | AI agents / MCP clients acting as a signed-in user | Self-serve authorization-code + PKCE flow against the deployment itself |
5556

5657
All three pass through the same `AuthPlugin` and resolve to a `sys_user`
5758
context that the `SecurityPlugin` evaluates against permissions and
@@ -95,6 +96,28 @@ To revoke a key, run the `revoke_api_key` action on the corresponding
9596
`sys_api_key` record (also available in the Console UI). Revocation takes
9697
effect immediately on the next request.
9798

99+
## MCP clients & OAuth 2.1 (ObjectStack 13+)
100+
101+
Any OAuth-capable MCP client — Claude.ai custom connectors, Claude
102+
Desktop, Claude Code — can connect **self-serve**, without an admin
103+
minting API keys:
104+
105+
- Each deployment acts as its own authorization server (backed by the
106+
embedded auth instance), with RFC 8414 / RFC 9728 discovery, dynamic
107+
client registration (RFC 7591), authorization-code + PKCE, and
108+
resource binding to `<origin>/api/v1/mcp`. TLS is required
109+
(localhost exempt).
110+
- Users sign in as themselves; tool calls run under their own
111+
permissions and row-level security.
112+
- OAuth scopes establish a hard permission ceiling
113+
(ObjectStack 14.5): `effective_permission = scope_ceiling ∩
114+
user_grants`. `data:read` grants read-only data access, `data:write`
115+
full CRUD, and `actions:execute` is required for capability-gated
116+
business actions. Tokens missing a scope fail closed.
117+
118+
API keys remain a parallel track for CI and headless agents — `x-api-key`
119+
and `Authorization: Bearer osk_…` continue to work unchanged.
120+
98121
## Pagination, filtering, and sorting
99122

100123
Generated list endpoints accept the standard ObjectStack query

content/docs/configure/api-access.zh-Hans.mdx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ API 暴露在 artifact 中按对象逐个治理,而不是在网关层:
4040

4141
## 身份验证方式
4242

43-
调用方可以通过三种方式进行身份验证
43+
调用方可以通过四种方式进行身份验证
4444

4545
| 方式 | 适用场景 | 做法 |
4646
|---|---|---|
4747
| Session cookie | 浏览器/UI 流量 | 通过 `/api/v1/auth/*` 登录;cookie 的作用域限定在项目主机名 |
4848
| Bearer 访问令牌 | 移动端、SPA、短时服务端任务 |`/api/v1/auth/sign-in/email` 用凭据换取令牌,并以 `Authorization: Bearer <token>` 传递 |
4949
| API 密钥 | 服务器到服务器、ETL、长期存续的集成 | 创建一条 `sys_api_key` 记录,作为 bearer 令牌使用 |
50+
| OAuth 2.1(MCP) | 以登录用户身份行事的 AI 代理 / MCP 客户端 | 直接对部署本身执行自助授权码 + PKCE 流程 |
5051

51-
这三种方式都会经过同一个 `AuthPlugin`,并最终解析为 `sys_user` 上下文,由 `SecurityPlugin` 据此评估权限和记录访问。
52+
这些方式都会经过同一个 `AuthPlugin`,并最终解析为 `sys_user` 上下文,由 `SecurityPlugin` 据此评估权限和记录访问。
5253

5354
## API 密钥
5455

@@ -80,6 +81,16 @@ curl https://app.example.com/api/v1/data/account \
8081

8182
要撤销某个密钥,请在对应的 `sys_api_key` 记录上运行 `revoke_api_key` action(Console UI 中也提供)。撤销会在下一次请求时立即生效。
8283

84+
## MCP 客户端与 OAuth 2.1(ObjectStack 13+)
85+
86+
任何支持 OAuth 的 MCP 客户端——Claude.ai 自定义连接器、Claude Desktop、Claude Code——都可以**自助**接入,无需管理员签发 API 密钥:
87+
88+
- 每个部署都充当自己的授权服务器(由内嵌认证实例支撑),支持 RFC 8414 / RFC 9728 发现、动态客户端注册(RFC 7591)、授权码 + PKCE,以及绑定到 `<origin>/api/v1/mcp` 的资源约束。要求 TLS(localhost 豁免)。
89+
- 用户以自己的身份登录;工具调用在其本人的权限和行级安全下运行。
90+
- OAuth scope 构成硬性权限上限(ObjectStack 14.5):`effective_permission = scope_ceiling ∩ user_grants``data:read` 授予只读数据访问,`data:write` 授予完整 CRUD,能力门控的业务动作需要 `actions:execute`。缺少 scope 的令牌将失败关闭。
91+
92+
API 密钥仍作为 CI 与无头代理的并行通道——`x-api-key``Authorization: Bearer osk_…` 继续原样工作。
93+
8394
## 分页、过滤与排序
8495

8596
自动生成的列表端点接受标准的 ObjectStack 查询参数:

content/docs/configure/authentication.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,38 @@ support:
2222
- two-factor authentication;
2323
- passkeys/WebAuthn;
2424
- magic links;
25+
- phone number sign-in with SMS OTP (opt-in);
2526
- CLI/browser device flow.
2627

28+
## Phone sign-in & SMS (ObjectStack 14.3+)
29+
30+
Enable phone-number authentication via the `auth.plugins.phoneNumber`
31+
setting. Once on:
32+
33+
- `POST /sign-in/phone-number` accepts phone + password;
34+
- SMS OTP covers sign-in verification and self-service password reset,
35+
with per-number cooldowns, rolling-hour caps, and per-IP rate limits;
36+
- `sys_user` gains unique `phone_number` and `phone_number_verified`
37+
columns; phone-only accounts get a placeholder email.
38+
39+
SMS delivery is provided by `@objectstack/plugin-sms` with Aliyun SMS,
40+
Twilio, or a dev log fallback, configured through the `sms` settings
41+
namespace. Message bodies containing OTP codes are never persisted or
42+
logged. Notifications can also target the `sms` channel via
43+
`notify(channels: ['sms'])`.
44+
45+
## Admin user management (ObjectStack 14.3+)
46+
47+
Platform admins can provision accounts without the email invite flow:
48+
49+
- `POST /api/v1/auth/admin/create-user` creates a user directly, with an
50+
optional one-time password (returned once, never persisted). The
51+
`must_change_password` flag forces rotation at first sign-in (403
52+
`PASSWORD_EXPIRED` until changed).
53+
- `POST /api/v1/auth/admin/import-users` bulk-imports rows / CSV / XLSX
54+
(max 500 rows per request) with dry-run and upsert-by-email-or-phone
55+
modes; existing users never get their passwords reset.
56+
2757
## Required secret
2858

2959
Set:

content/docs/configure/authentication.zh-Hans.mdx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,26 @@ ObjectOS 使用由 Better Auth 驱动的 ObjectStack 认证插件。认证是项
1919
- 双因素认证;
2020
- Passkey/WebAuthn;
2121
- 魔法链接;
22+
- 手机号登录与短信 OTP(需显式开启);
2223
- CLI/浏览器设备流程。
2324

25+
## 手机号登录与短信(ObjectStack 14.3+)
26+
27+
通过 `auth.plugins.phoneNumber` 设置开启手机号认证。开启后:
28+
29+
- `POST /sign-in/phone-number` 接受手机号 + 密码登录;
30+
- 短信 OTP 覆盖登录验证和自助密码重置,并自带按号码冷却、滚动小时上限和按 IP 限流;
31+
- `sys_user` 增加唯一的 `phone_number``phone_number_verified` 列;仅手机号账户会获得占位邮箱。
32+
33+
短信发送由 `@objectstack/plugin-sms` 提供,支持阿里云短信、Twilio 或开发环境日志回退,通过 `sms` 设置命名空间配置。含 OTP 验证码的消息体永不持久化或写入日志。通知也可以通过 `notify(channels: ['sms'])``sms` 通道。
34+
35+
## 管理员用户管理(ObjectStack 14.3+)
36+
37+
平台管理员可以不经邮件邀请流程直接开通账户:
38+
39+
- `POST /api/v1/auth/admin/create-user` 直接创建用户,可选生成一次性密码(仅返回一次,不持久化)。`must_change_password` 标志强制首次登录时修改密码(未修改前返回 403 `PASSWORD_EXPIRED`)。
40+
- `POST /api/v1/auth/admin/import-users` 批量导入行 / CSV / XLSX(每次请求最多 500 行),支持 dry-run 和按邮箱或手机号 upsert;已存在用户的密码永不重置。
41+
2442
## 必需的 Secret
2543

2644
设置:

0 commit comments

Comments
 (0)