Skip to content

[RBAC PR 2 follow-up] Verify break-glass readiness#2340

Open
philipfweiss wants to merge 1 commit into
DataJunction:mainfrom
philipfweiss:rbac-breakglass-readiness
Open

[RBAC PR 2 follow-up] Verify break-glass readiness#2340
philipfweiss wants to merge 1 commit into
DataJunction:mainfrom
philipfweiss:rbac-breakglass-readiness

Conversation

@philipfweiss

@philipfweiss philipfweiss commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Tracking: #2234 (step 2 follow-up in the RBAC enablement sequence).

Restrictive RBAC depends on an admin recovery path, but the server can start while the configured user has is_admin=false. That can lock every operator out, while bypass use is difficult to identify in ordinary authorization logs.

Why this was missed initially: #2232 manually promoted dj before testing the bypass, so it proved recovery only after a valid admin already existed. It did not exercise cold startup with a missing or invalid admin, or check for a machine-distinct audit event.

This PR makes the recovery path an activation prerequisite:

  • Startup verification: restrictive RBAC, or RBAC_REQUIRE_ADMIN=true, requires every configured RBAC_ADMIN_USERS entry to exist as a human user with is_admin=true.
  • Local admin seed: the Compose path seeds dj as an admin, updates existing local rows idempotently, and waits for db-seed before starting the server.
  • Distinct audit event: admin bypasses emit one bounded WARNING event on datajunction.audit.rbac with event=rbac_admin_bypass, actor fields, request count, and reason=admin_bypass.

Permissive deployments remain unchanged when admin readiness is disabled. Restrictive deployments fail before serving requests when the configured admin set is missing or invalid. Admin promotion remains an operations and seed concern; this adds no public promotion API.


Verification:

  1. Started this branch from a fresh slot 2 database. Compose ran db-seed before the server, the seeded dj row was an admin, and startup verified the configured admin.
./dev.sh up -d
SELECT username, is_admin FROM users WHERE username='dj';
-> dj | t

server log:
rbac_admin_readiness_verified admins=dj

GET http://localhost:8200/health/
-> [{"name":"database","status":"ok"}] HTTP_STATUS:200
POST /basic/login/ username=dj password=dj
-> HTTP_STATUS:200
GET /whoami/
-> {"username":"dj","is_admin":true,...} HTTP_STATUS:200
  1. Created a namespace and source node through the admin bypass, then checked the dedicated audit event.
POST /namespaces/manual_admin_bypass
-> HTTP_STATUS:201

POST /nodes/source/ {name:"manual_admin_bypass.orders_admin", catalog:"default", schema_:"public", table:"orders_admin", columns:[{name:"id",type:"int"}]}
-> HTTP_STATUS:200

server log:
WARNING datajunction.audit.rbac:
event=rbac_admin_bypass reason=admin_bypass actor=dj actor_id=1 request_count=1 requests=write:namespace/manual_admin_bypass truncated=False
  1. Removed the configured user's admin flag and restarted only the server. The application refused to start and the health request could not connect.
UPDATE users SET is_admin=false WHERE username='dj';
docker restart dj-s2
GET http://localhost:8200/health/
-> connection reset, HTTP_STATUS:000

server log:
RuntimeError: RBAC break-glass admin verification failed: users without is_admin: dj
ERROR: Application startup failed. Exiting.
  1. Restored the admin flag and restarted the server. Readiness passed and traffic resumed.
UPDATE users SET is_admin=true WHERE username='dj';
docker restart dj-s2
GET http://localhost:8200/health/
-> [{"name":"database","status":"ok"}] HTTP_STATUS:200

@netlify

netlify Bot commented Jul 17, 2026

Copy link
Copy Markdown

Deploy Preview for thriving-cassata-78ae72 canceled.

Name Link
🔨 Latest commit 42dac97
🔍 Latest deploy log https://app.netlify.com/projects/thriving-cassata-78ae72/deploys/6a5accc020ba9000085f29e0

Fail startup when restrictive RBAC lacks its configured admins, seed the local recovery account, and emit distinct bounded bypass audit events.
@philipfweiss
philipfweiss force-pushed the rbac-breakglass-readiness branch from 0fb2a07 to 42dac97 Compare July 18, 2026 00:45
@philipfweiss philipfweiss changed the title [RBAC follow-up] Verify break-glass readiness [RBAC PR 2 follow-up] Verify break-glass readiness Jul 18, 2026
@philipfweiss
philipfweiss marked this pull request as ready for review July 18, 2026 01:16
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