Skip to content

fix(flow): create the durable authority database owner-only before SQLite opens it - #1363

Merged
abrichr merged 1 commit into
mainfrom
fix/durable-authority-create-owner-only
Oct 19, 2026
Merged

abrichr merged 1 commit into
mainfrom
fix/durable-authority-create-owner-only

Conversation

@abrichr

@abrichr abrichr commented Oct 19, 2026

Copy link
Copy Markdown
Member

Bug

Two durable runs that start at the same moment in a fresh environment (for example --workers 2 --durable on a new machine, or two processes) race on first creation of the external durable authority database:

  1. Run A finds no database. sqlite3.connect creates it with the process umask (0644), and _connect tightens it to 0600 only after setting up the schema.
  2. Run B, in between, finds the file at 0644 and refuses: DurableAuthorityBusy: the external durable authority database permissions are too broad.

In a worklist pool that error stops every worker. I found it while building the compatibility matrix for the API-step stack (#1355 and the PRs stacked on it): two workers, each item a Regulated durable run, failed on the first item.

Fix

When the database doesn't exist, create it owner-only (O_CREAT | O_EXCL | O_NOFOLLOW, mode 0600) before SQLite opens it. A run that loses the O_EXCL race just opens the file the other run created, which is already 0600. The permission check itself is unchanged.

Tests

tests/test_durable_authority_create.py (new): one test checks that a fresh database is owner-only at the moment SQLite opens it; the other starts four durable runs together behind a barrier and checks that all four start. Both fail on main; the concurrent one reproduces the "too broad" refusal.

Locally: 99 passed across the durable authority and durable runtime suites. ruff passes.

🤖 Generated with Claude Code

…Lite opens it

SQLite created a missing authority database with the process umask, and
_connect tightened it to 0600 only after the schema was set up. A second
durable run starting at the same moment (two --workers, or two processes on
a fresh machine) saw a world-readable file and refused with "the external
durable authority database permissions are too broad", which stopped the
pool. The file is now created 0600 with O_EXCL (and O_NOFOLLOW) first. The
permission check is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@abrichr
abrichr merged commit 2a7c106 into main Oct 19, 2026
38 checks passed
@abrichr
abrichr deleted the fix/durable-authority-create-owner-only branch October 19, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant