Lifetime updates included on every script: buy once, keep it running through framework bumps. Browse scripts →

ESX Job Permissions After a Promotion, Demotion or Job Change

ESX Job Permissions After a Promotion, Demotion or Job Change

Consider this test: a player opens a boss menu and then loses their management grade. A fresh menu correctly hides the withdrawal button, but the request from the previously opened panel still succeeds. The demotion system worked. The permission check happened at the wrong time.

ESX job permissions need to follow the player's current role through promotions, demotions, duty changes and job switches. Setting up a job once is only the beginning. This guide focuses on the transitions that expose stale access, with a practical way to trace and test them.

Write down the action being protected

Start with one action, such as withdrawing society funds, issuing an invoice or opening a restricted storage area. “Police access” is too broad to test. A recruit might enter the station but have no authority to manage staff. A supervisor might manage staff while being unable to withdraw business money.

For each action, describe the rule in ordinary language. For example: the character must currently hold the mechanic job, have one of the approved management grades, and be on duty if your server requires that. Add location or interaction requirements separately.

This exposes assumptions hidden inside a comparison such as “grade greater than two.” Does every higher grade really inherit this action? Does the number mean the same thing in another job? If the answer is uncertain, use an explicit role policy in your resource rather than depending on the numbering accidentally working out.

The ESX custom job guide covers the underlying grades and society setup. Permission transitions are a useful follow-up once those basics work.

Check the live player object before the database

An online player's framework state and a row viewed through a database client can disagree during troubleshooting. Record both, but first inspect the job data that the resource actually reads when deciding access.

The documented xPlayer interface exposes getJob() and setJob(). ESX distinguishes the internal job name, numeric grade, grade name and display labels. Use the field your rule intends: a translated label is a poor substitute for a stable job key. Check the xPlayer reference against the installed framework version before changing an integration.

For an illustrative mechanic role, “Workshop Manager” might be the displayed grade label while the configured grade name is boss. Another server may choose different names. A resource that compares the label with boss can look beautifully configured while refusing every manager.

Normalize values at the boundary where your resource reads them. If one adapter gives you a numeric grade and another gives you text, decide how conversion works and reject malformed values. Avoid fixing a mismatch by accepting every value that is not explicitly false.

A job change is an event, not a universal cleanup service

In the current ESX core source, setJob checks that the job and grade exist, constructs the new job data and emits job change events. The server event and client event have different argument lists. Current source also includes duty information, which older versions and custom duty systems may handle differently. Inspect your installed release alongside the official player implementation.

That framework update does not automatically empty every cache in every resource. A door script may remember an earlier result. A boss menu may keep its last list of options. A custom terminal may save an authorization flag when the player first logs in.

Treat the job change notification as a prompt to refresh those views and invalidate derived access. Close a management panel if its owner no longer qualifies. Clear cached permission decisions. Rebuild interaction options where the resource expects you to do so.

Also initialize correctly when your resource starts while players are already online. Listening only for future changes leaves a gap: nothing changed after startup, so your cache never learned the existing role. Test normal joining and resource startup as separate paths.

Recheck where the action changes something

A menu being visible proves only that the client decided to show it. The server should independently check the current player, job and action requirements when the request arrives. Cfx.re's event security guidance specifically recommends server checks for values such as permissions, roles, inventory and position rather than accepting client claims.

Apply that rule to each privileged operation. If a manager opens a staff list and is demoted before pressing “promote,” the eventual request must use their role at execution time. The role from when the menu opened is historical information.

Longer operations need another decision. Suppose approval starts a database lookup and that lookup yields before the final change. Decide whether authorization must still be valid at the final commit, and arrange the operation accordingly. A successful check several seconds earlier is not a permanent licence.

Keep a legitimate denial understandable. “Your role changed; reopen this menu” is much more useful than a silent button. It also stops staff mistaking a correct permission denial for a broken society account.

Keep employment, duty and staff powers separate

Some servers represent off duty as another job. Others retain the job and store a duty flag. These designs create different transitions, so do not copy an off-duty comparison from a resource using a different arrangement.

Decide which actions actually require duty. A former employee should lose access to restricted stock. A current employee checking their own information may reasonably retain access outside a shift. Those are server design decisions, not a property implied by the word “job.”

Server moderation powers belong to a separate policy too. A game master temporarily taking the medic job should not gain or lose administrative authority because a business grade changed. When testing, use an ordinary account as well as your administrator account. Bypass permissions can hide a broken employment check all evening.

Test the transition while the screen is still open

Use a staging account and one harmless test action. Write the expected result before you click anything. A compact transition check should include:

Test both the interface and the resulting server state. A closed menu with an accepted background request is still a failure. A visible button with a rejected request is safer, but still confusing and worth fixing.

Record only the information needed to follow the decision: test character, action, job key, grade, duty state if applicable, and allow or deny reason. Avoid filling routine logs with whole player objects. A short explanation of the failed condition makes these bugs much easier to reproduce.

Make the fix survive the next job edit

Keep one permission function or adapter for each coherent policy rather than copying grade comparisons into five menus. Then a renamed grade or revised duty rule has one deliberate place to change.

Before releasing the fix, repeat the demotion and job-switch cases with the same panel left open. Those transitions are the strongest evidence that you removed the stale decision, instead of merely hiding its symptom. A promotion should grant the intended action promptly, and a demotion should revoke it just as reliably.

Related posts

ESX Custom Jobs: Building a Job From Scratch With Grades, Payslips and Society Accounts
Guide
ESX Custom Jobs: Building a Job From Scratch With Grades, Payslips and Society Accounts
How to Install ESX in 2026: ESX Legacy Setup From Zero to First Job
Guide
How to Install ESX in 2026: ESX Legacy Setup From Zero to First Job
Which ESX Version Am I Running, and Why Does Every Tutorial Disagree?
Guide
Which ESX Version Am I Running, and Why Does Every Tutorial Disagree?
Published · Sep 21, 2026 Read more posts →