SellubDevelopersRBAC internals

RBAC internals

Engineering view of the role + admin sync system. For the operational view see Platform Admin → Roles & permissions.

Source of truth

apps/sellub/sellub-server/admin-config/admins.json

{
  "roles": [
    {
      "code": "platform-support",
      "description": "Tier 1 support — read-mostly",
      "permissions": ["ReadOrder", "ReadCustomer", "ReadAdministrator"],
      "channels": ["*"]
    }
  ],
  "admins": [
    {
      "emailAddress": "alice@sellub.com",
      "firstName": "Alice",
      "lastName": "Mensah",
      "roleCodes": ["platform-support"],
      "disabled": false
    }
  ],
  "_unmanaged_accounts": [
    "legacy@partner.com"
  ]
}

The sync script

apps/sellub/sellub-server/scripts/sync-admins.ts

Idempotent. Steps:

  1. Load admins.json for the target env.
  2. Validate every roleCodes[] references a role in roles[].
  3. Validate every permission name exists in Vendure’s Permission enum.
  4. For each role:
    • Upsert the Role record by code.
    • Replace the role’s permissions and channels to match JSON.
  5. For each admin in admins[]:
    • Find or create the Administrator by emailAddress.
    • If creating, generate a temp password and print it once.
    • Replace the admin’s role assignments to match roleCodes.
    • Set disabled flag.
  6. For every existing Administrator not in admins[] and not in _unmanaged_accounts:
    • Set disabled = true (do not delete — preserves audit trail).
  7. Print a diff summary: created / updated / disabled.

SuperAdmin recovery

Script: apps/sellub/sellub-server/scripts/recover-superadmin.ts.

Requires shell access to the prod server.

docker compose exec sellub-server node dist/scripts/recover-superadmin.js

What it does:

  1. Finds the SuperAdmin with the lowest ID (the bootstrap account).
  2. Generates a 15-minute one-time password.
  3. Stores its hash + expiry on the account.
  4. Prints the password to stdout.
  5. Logs the recovery to the audit log table.

The recovered admin must change password on first sign-in.

Permission enum reference

Vendure’s full Permission enum: https://docs.vendure.io/reference/typescript-api/common/permission/.

Custom permissions added by Sellub plugins:

PermissionGranted byWhat it gates
ApproveSellerApplicationOnboarding+Seller approval workflow
AdjustSellerWalletSuperAdmin, FinanceWallet adjustments
ManageDomainVerificationPlatform AdminCustom-domain DNS / cert
IssueApiKeySuperAdmin, IntegrationsAPI key issuance

These are registered in sellub-server/src/plugins/<plugin>/permissions.ts.

CI validation

.github/workflows/validate-admins.yml runs on every PR touching admins.json:

  • JSON schema check.
  • pnpm sync-admins --dry-run against an in-memory DB.
  • Diff comment on the PR showing what would change in production.