Skip to content

docs(adr): ADR-0073 — automation execution identity (non-human principal for user-less runs) - #2318

Merged
os-zhuang merged 3 commits into
mainfrom
adr/automation-execution-identity
Jun 25, 2026
Merged

os-zhuang merged 3 commits into
mainfrom
adr/automation-execution-identity

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Status: Proposed — opened for discussion (not for immediate merge).

Follow-up to #1888 / #2308. #2308 made the schedule/user-less runAs:'user' fail-open audible but deliberately left the runtime identity unchanged, because the real fix is a platform-identity decision. This ADR records it.

The decision in one breath

ObjectStack conflates two axes into "is userId present?": authorization (what may the run do) and attribution (who did it). That's why a user-less scheduled run both skips into god-mode and writes created_by = NULL. ADR-0073 separates them, in the ADR-0068 idiom:

  1. Automation is a first-class non-human identity, expressed as built-in roles — automation (org-scoped) and platform_automation (unscoped, platform-only). No anonymous run.
  2. runAs becomes an authorization posture: user / automation (RLS-enforced — the Salesforce "with sharing" middle, new default for user-less triggers) / system (god-mode, unchanged for back-compat).
  3. Attribution always concrete (audit actor), decoupled from ownership so automation never silently owns the rows it writes (owner-RLS would hide them from humans — Salesforce models this the same way).
  4. User-less runAs:'user' is a config error.

Why this shape

Grounded in how Salesforce (Automated Process user + system-with/without-sharing), ServiceNow (Run-as service account), AWS IAM (execution roles, least-privilege), Kubernetes (ServiceAccount), iPaaS (connection owner), and GitHub Actions (least-privilege token) all converge on four invariants: automation runs as a concrete non-human principal; authorization ≠ attribution; safe explicit defaults; elevation is explicit + audited.

It's a platform primitive, not a flow feature — plugin-reports (already hand-rolling SYSTEM_CTX), audit, ADR-0057 lifecycle jobs, webhooks, and AI agents are all consumers.

Staging (per ADR-0049)

  • v1 (non-breaking, foundational): the contract + seeded roles + lint completeness (extend the fix(security): surface schedule/user-less flow runAs fail-open (#1888 follow-up) #2308 lint to all user-less triggers; user-less runAs:'user' → validation error). Runtime behavior unchanged.
  • M2 (roadmapped enforcement): attribution wiring (non-breaking) → then automation-default RLS-enforced authorization + scopable grants (default-broad → tighten).
  • runAs:'system' unchanged throughout.

Open questions called out in the ADR's "Alternatives" + costs. Builds on ADR-0049 / 0057 / 0066 / 0068.

🤖 Generated with Claude Code

…pal for user-less runs)

Completes the identity model (ADR-0068 unified the human surface) by adding the
non-human / automation identity that user-less runs need:

- Automation is a first-class identity expressed as built-in roles (`automation`
  org-scoped, `platform_automation` unscoped) — the ADR-0068 idiom; no anonymous run.
- `runAs` becomes an authorization POSTURE (user / automation-with-RLS / system),
  decoupling authorization from attribution; `automation` (RLS-enforced) is the new
  safe default for user-less triggers, `system` (god-mode) unchanged for back-compat.
- Attribution always concrete (audit actor), decoupled from record ownership so
  automation never silently owns the rows it writes (owner-RLS would hide them).
- User-less `runAs:'user'` is a configuration error.

Staged per ADR-0049: contract + seeded roles + lint completeness now (non-breaking,
mirrors ADR-0068 v1); runtime wiring (attribution then RLS-enforced authorization +
scopable grants) deferred to M2. Grounds the decision in how Salesforce / ServiceNow
/ AWS IAM / K8s / iPaaS / GitHub Actions handle automation identity.

Status: Proposed — for discussion. Refs #1888, #2308; builds on ADR-0049/0057/0066/0068.

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

vercel Bot commented Jun 25, 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 25, 2026 6:12am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation size/m labels Jun 25, 2026
…, defer runtime to M2 (gated on first consumer)
…se (ADR-0002); automation principal is per-env Data-Plane, cross-env is Control-Plane
@os-zhuang
os-zhuang merged commit 60d48a0 into main Jun 25, 2026
15 checks passed
@os-zhuang
os-zhuang deleted the adr/automation-execution-identity branch June 25, 2026 06:15

This branch was successfully deployed

1 active deployment
Preview — 77484ecf Deployed Jun 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant