Releases: objectstack-ai/objectstack
Release list
@objectstack/service-datasource@16.1.0
@objectstack/service-cluster@16.1.0
@objectstack/service-cluster-redis@16.1.0
Patch Changes
- Updated dependencies [9e45b63]
- @objectstack/spec@16.1.0
- @objectstack/service-cluster@16.1.0
@objectstack/service-cache@16.1.0
@objectstack/service-automation@16.1.0
Minor Changes
-
b20201f: fix(service-automation):
runAs:'user'runs data ops with the triggering user's
real permission sets + positions, not a bare member fallback (#3356, follow-up to
#1888)Since #1888 the automation engine honours
flow.runAs(systemelevates), but
therunAs:'user'credential propagation was hollow. A record-change-triggered
runAs:'user'flow ran its data nodes (update_record, …) with a zero-grant
principal — only themember/everyonebaseline — even when the triggering user
was fully authorized. Two faces by object config: aprivateobject 403'd the
in-flow write (not permitted for positions [org_member, everyone]— the user's
permission sets were invisible); apublic_read_writeobject let the write
through but silently stripped readonly/FLS-gated fields. The root cause: the
ObjectQL record-change hook session carries only auserId— never the writer's
positions/permission sets — and nothing in between resolved them, so the comment
promising "enforces RLS exactly as the user who made the change" never held.The fix resolves the triggering user's actual authorization at run setup, from
the same tables a direct REST request resolves through:@objectstack/corefactors the userId-driven core ofresolveAuthzContext
into a new exportedresolveUserAuthzGrants(ql, userId, opts)— the single place
that readssys_member/sys_user_position/sys_*_permission_setand
derives positions, permission-set names,platform_admin, and posture. The
HTTP resolver now delegates to it (behaviour byte-identical; the full contract
suite still passes), so a non-HTTP surface that already knows the user id builds
the SAME envelope instead of re-implementing the reads.@objectstack/service-automationgainsAutomationEngine.setUserGrantsResolver,
wired by the plugin toresolveUserAuthzGrantsover the objectql/data engine.
For arunAs:'user'run whose trigger left the authz envelope unresolved (no
permissions), the engine now resolves the user's positions + permission sets
once at run setup and threads them into every data node's ObjectQL context —
so the run enforces RLS/FLS exactly as that user. Contexts that already carry
permissionsare left untouched (a REST trigger, and notably an ADR-0090 agent
ceiling acting on-behalf-of a user — always non-empty — so a deliberately
narrowed identity is never re-broadened).runAs:'system'is unchanged, and a
resolver error fails safe (warns, keeps the bare user — never elevates).@objectstack/trigger-record-changestops forwarding the misleading
half-populatedpositions(empty in practice, and neverpermissions) from the
hook session; it forwardsuserId+ tenant only and lets the engine resolve the
full grants authoritatively.
When no ObjectQL engine is present (bare engine / tests) the resolver is unwired
and run identity is unchanged from before.
Patch Changes
@objectstack/service-analytics@16.1.0
@objectstack/sdui-parser@16.1.0
@objectstack/sdui-parser@16.1.0
@objectstack/runtime@16.1.0
Patch Changes
-
818e6a3: fix(server-timing): emit the per-request, admin-gated
Server-Timingheader on the standard server (os serve/dev) (#3361)The per-request
Server-Timingpath (#2408) — where an admin sends
X-OS-Debug-Timing: 1(orjson) and gets phase timings while an ordinary user
gets nothing — never emitted on the shipped Hono server. The disclosure gate the
Hono middleware opens is only ever flipped by the runtime dispatcher's
timedResolveExecutionContext, but the data (/api/v1/data/*) and metadata
(/api/v1/meta/*) routes onos serve/devare served by@objectstack/rest's
RestServer(which shadows the Hono plugin's own CRUD), and its identity
resolver never opened the gate. Only global mode (OS_SERVER_TIMING=true) — which
discloses to every caller, not just admins — worked.- observability: the disclosure predicate
isPerfDisclosurePrincipal(ec)now
lives here (the home of the gate), the single definition of "who may pull
per-request timings" shared by every HTTP entry point.@objectstack/runtime
re-exports it for back-compat. - rest:
RestServer.resolveExecCtxopens the gate for an admin/service
principal (via the carriedposturerung), the REST-server analog of the
dispatcher — this is the fix that makesos serve/devemit. - plugin-hono-server: the standalone CRUD surface's self-contained
resolveCtxopens the gate too (deriving the rung for the gate decision only,
never writing it onto the enforcement context). Adds an e2e test that boots the
Hono app and asserts an admin getsServer-Timingwhile a member/anon does not.
- observability: the disclosure predicate
-
Updated dependencies [9e45b63]
-
Updated dependencies [b20201f]
-
Updated dependencies [818e6a3]
- @objectstack/spec@16.1.0
- @objectstack/core@16.1.0
- @objectstack/observability@16.1.0
- @objectstack/rest@16.1.0
- @objectstack/metadata@16.1.0
- @objectstack/plugin-auth@16.1.0
- @objectstack/plugin-security@16.1.0
- @objectstack/formula@16.1.0
- @objectstack/metadata-core@16.1.0
- @objectstack/objectql@16.1.0
- @objectstack/driver-memory@16.1.0
- @objectstack/driver-sql@16.1.0
- @objectstack/driver-sqlite-wasm@16.1.0
- @objectstack/service-cluster@16.1.0
- @objectstack/service-datasource@16.1.0
- @objectstack/service-i18n@16.1.0
- @objectstack/types@16.1.0
@objectstack/rest@16.1.0
Patch Changes
-
818e6a3: fix(server-timing): emit the per-request, admin-gated
Server-Timingheader on the standard server (os serve/dev) (#3361)The per-request
Server-Timingpath (#2408) — where an admin sends
X-OS-Debug-Timing: 1(orjson) and gets phase timings while an ordinary user
gets nothing — never emitted on the shipped Hono server. The disclosure gate the
Hono middleware opens is only ever flipped by the runtime dispatcher's
timedResolveExecutionContext, but the data (/api/v1/data/*) and metadata
(/api/v1/meta/*) routes onos serve/devare served by@objectstack/rest's
RestServer(which shadows the Hono plugin's own CRUD), and its identity
resolver never opened the gate. Only global mode (OS_SERVER_TIMING=true) — which
discloses to every caller, not just admins — worked.- observability: the disclosure predicate
isPerfDisclosurePrincipal(ec)now
lives here (the home of the gate), the single definition of "who may pull
per-request timings" shared by every HTTP entry point.@objectstack/runtime
re-exports it for back-compat. - rest:
RestServer.resolveExecCtxopens the gate for an admin/service
principal (via the carriedposturerung), the REST-server analog of the
dispatcher — this is the fix that makesos serve/devemit. - plugin-hono-server: the standalone CRUD surface's self-contained
resolveCtxopens the gate too (deriving the rung for the gate decision only,
never writing it onto the enforcement context). Adds an e2e test that boots the
Hono app and asserts an admin getsServer-Timingwhile a member/anon does not.
- observability: the disclosure predicate
-
Updated dependencies [212b66a]
-
Updated dependencies [d10c4dc]
-
Updated dependencies [9e45b63]
-
Updated dependencies [b20201f]
-
Updated dependencies [818e6a3]
- @objectstack/platform-objects@16.1.0
- @objectstack/spec@16.1.0
- @objectstack/core@16.1.0
- @objectstack/observability@16.1.0
- @objectstack/service-package@16.1.0
- @objectstack/types@16.1.0