Instance owner/operator role (env-declared via OWNER_EMAIL) #240
Reference in New Issue
Block a user
Delete Branch "instance-owner"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Gives a self-hosted Provenance instance a real owner/operator, which it previously lacked — ownership was only per-tree, so no account could administer the instance.
Model
OWNER_EMAIL(comma-separated) names the instance owner(s). Derived at request time — no DB column, no migration, cannot drift from the env, survives DB resets.REQUIRE_EMAIL_VERIFICATION). Registration is open, so without this someone could seize the role by registering the owner address first; verification ties it to inbox control.GET /api/v1/admin/instance(owner-only): version, env, user/tree counts, configured AI providers. No tree data or PII — instance ownership is an operator role, not a privacy-engine bypass (documented invariant)./users/mereportsis_instance_owner; frontend adds an owner-only/adminpage + conditional sidebar link (server-enforced via theInstanceOwnerdependency, not just client-hidden).Security review (ran before merge)
A 3-lens adversarial review (privacy-bypass / authz-edgecases / surface) with per-finding verification surfaced 8 findings; 2 confirmed and fixed in this PR:
is_instance_ownermatched on email without checking verification → fixed by requiringemail_verified_at, plus a regression test.The other 6 were rejected as false alarms (e.g. the
/admin/instanceaggregates were confirmed PII-free).Tests
tests/test_instance_owner.py: owner matching (case-insensitive), the verified-email land-grab guard,/users/me, owner-only/admin. Suite 96 passing.No migration. Activating it on a deployment is just
OWNER_EMAIL=<you>in.env+ a restart (and a verified account).🤖 Generated with Claude Code