Skip to content

feat(audit): record a service/non-user principal on sys_audit_log.actor (ADR-0014 D2, cloud#340)#2101

Merged
xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-0014-audit-service-actor
Jun 21, 2026
Merged

feat(audit): record a service/non-user principal on sys_audit_log.actor (ADR-0014 D2, cloud#340)#2101
xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-0014-audit-service-actor

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Why

A non-user-authenticated write — e.g. an OS_CLOUD_API_KEY service-token call — left sys_audit_log.user_id null and was therefore unattributable. That's exactly how the prod env-delete of os-790m7q went unaccountable (service-token, no user/IP/UA). user_id is a strict sys_user lookup, so a service principal can't be recorded there at all.

What — open the mechanism (the host wires the value)

  • spec ExecutionContext (execution-context.zod.ts): new optional actor field — a stable principal label for attribution when there's no userId (e.g. svc:<name>). Additive / backward-compatible; public API surface unchanged (the gate tracks export names, not zod field internals).
  • plugin-audit sys_audit_log: new first-class actor text field, independent of the user_id lookup. user_id stays user-only.
  • audit writer (audit-writers.ts): record actor = userId ?? session.actor ?? null. Conditionally stamped (same pattern as organization_id) so audit tables that predate the column keep inserting cleanly; the column auto-adds on the next schema sync.

This is the open half (ADR-0012 style): the framework defines + records the contract; the host sets ExecutionContext.actor. The cloud control plane will set svc:<name> in service-mode auth (cloud#340 cloud half) — no behavior change here until it does.

Tests

  • real user → actor = user id, user_id = user id
  • service token (no userId)actor = 'svc:cloud-control', user_id stays null (the os-790m7q class, now attributable)
  • neither → actor null

@objectstack/spec 6599/6599 + check:api-surface ✓; @objectstack/plugin-audit 21/21; spec build clean.

Pairs with cloud#340 (cloud sets the service-mode actor + names the token). Relates to cloud ADR-0014 D2.

🤖 Generated with Claude Code

…or (ADR-0014 D2, cloud#340)

A non-user-authenticated write (e.g. a service token) left
`sys_audit_log.user_id` = null and was therefore UNATTRIBUTABLE — exactly how
the prod env-delete of `os-790m7q` went unaccountable (a service-token call with
no user/IP). `user_id` is a strict `sys_user` lookup, so a service principal
can't be stuffed there.

This opens the mechanism (the host wires the value — see cloud#340 cloud half):

- `spec` ExecutionContext: add an optional `actor` field — a stable principal
  label for attribution when there's no `userId` (e.g. `svc:<name>`). Additive,
  backward-compatible; public API surface unchanged.
- `plugin-audit` sys_audit_log: add a first-class `actor` text field (the
  principal label), independent of the `user_id` lookup. `user_id` stays
  user-only.
- audit writer: record `actor = userId ?? session.actor ?? null`. Conditionally
  stamped (same pattern as organization_id) so audit tables that predate the
  column keep working.

No behavior change until a host sets `ExecutionContext.actor` (cloud control
plane will, in service mode). Tests: real user → actor=user id; service token
(no userId) → actor='svc:cloud-control', user_id stays null; neither → null.
spec 6599/6599 + api-surface ✓; plugin-audit 21/21.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 21, 2026 6:55am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-audit, @objectstack/spec.

90 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/cloud-artifact-api.mdx (via packages/spec)
  • content/docs/concepts/cluster-semantics.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/concepts/packages.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/concepts/setup-app.mdx (via @objectstack/spec)
  • content/docs/concepts/skills.mdx (via @objectstack/spec)
  • content/docs/concepts/webhook-delivery.mdx (via @objectstack/spec)
  • content/docs/getting-started/architecture.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/getting-started/core-concepts.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/guides/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/guides/ai-capabilities.mdx (via @objectstack/spec)
  • content/docs/guides/airtable-dashboard-analysis.mdx (via @objectstack/spec)
  • content/docs/guides/analytics-datasets.mdx (via @objectstack/spec)
  • content/docs/guides/api-reference.mdx (via @objectstack/spec)
  • content/docs/guides/business-logic.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/error-catalog.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-type-gallery.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-validation-rules.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/protocol-diagram.mdx (via packages/spec)
  • content/docs/guides/cheatsheets/query-cheat-sheet.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/quick-reference.mdx (via @objectstack/spec)
  • content/docs/guides/client-sdk.mdx (via @objectstack/spec)
  • content/docs/guides/common-patterns.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/auth-service.mdx (via packages/spec)
  • content/docs/guides/contracts/cache-service.mdx (via packages/spec)
  • content/docs/guides/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/index.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/guides/contracts/storage-service.mdx (via packages/spec)
  • content/docs/guides/data-modeling.mdx (via @objectstack/spec)
  • content/docs/guides/deployment-vercel.mdx (via @objectstack/spec)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/guides/formula.mdx (via @objectstack/spec)
  • content/docs/guides/hook-bodies.mdx (via packages/spec)
  • content/docs/guides/kernel-services.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/dashboard.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/field.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/flow.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/index.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/object.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/validation.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/workflow.mdx (via @objectstack/spec)
  • content/docs/guides/packages.mdx (via @objectstack/plugin-audit, @objectstack/spec)
  • content/docs/guides/plugin-development.mdx (via @objectstack/spec)
  • content/docs/guides/plugins.mdx (via @objectstack/spec)
  • content/docs/guides/production-readiness.mdx (via @objectstack/plugin-audit)
  • content/docs/guides/project-scoping.mdx (via @objectstack/spec)
  • content/docs/guides/public-forms.mdx (via @objectstack/spec)
  • content/docs/guides/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/index.mdx (via packages/spec)
  • content/docs/guides/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/guides/security.mdx (via @objectstack/spec)
  • content/docs/guides/seed-data.mdx (via @objectstack/spec)
  • content/docs/guides/skills.mdx (via @objectstack/spec)
  • content/docs/guides/standards.mdx (via @objectstack/spec)
  • content/docs/guides/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@xuyushun441-sys
xuyushun441-sys merged commit 7fe7e85 into main Jun 21, 2026
17 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the feat/adr-0014-audit-service-actor branch June 21, 2026 07:06
os-zhuang added a commit that referenced this pull request Jun 29, 2026
chore(chatbot): upgrade to Vercel AI SDK v7 / @ai-sdk/react v4 (#2101)

objectui@8d351f100c149316b41528950fdc423a41f0f7ae
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants