Give Record Recovery Its Own Permission

One line in an authorization test needed changing after I added record management to AdzByte App. The expected list of custom permissions didn’t yet include Manage:DataRecords. Updating that list was small, but the surrounding rule deserved a closer look: who should gain the new power?
The test correction followed the implementation in the record-management change. It preserved an important assertion: the ordinary administrator role starts with no default permission grants. Adding a capability to the application didn’t silently assign it to that role.
Name the actual power being granted
The new permission covers reading the supported business records and managing their deletion and restoration. It’s broader than a Restore button. A reviewer needs to understand that breadth before deciding who should receive it.
The management page can inspect records from a closed registry, including history and internal support notes. The registry excludes credential and session internals and limits displayed fields, but the feature is still a powerful administrative view.
Calling this permission something vague like “admin access” would hide the decision. Its specific name makes the configuration and tests easier to discuss. Someone may need to manage a customer’s projects without receiving a cross-record inspection and recovery tool.
For another application, I’d describe the accessible data and permitted state changes next to the permission definition. A short action label rarely communicates everything the role is gaining.
Create the permission without granting it by accident
The seeder creates the permission so the application can refer to it consistently. It doesn’t attach the permission to the ordinary administrator role. Those are separate operations, even when a setup script happens to perform both elsewhere.
The exact-list test catches a missing or unexpected custom capability. The no-default-grants assertion checks a different property: which role receives permissions automatically. Keeping both assertions matters because either can change while the other still passes.
The recorded qualification explains the initial failure as an outdated expected list. It doesn’t describe the follow-up commit as a new authorization implementation, because it wasn’t one. The functional rule had already been added in the preceding change.
That’s a useful way to handle tests that fail after a permission addition. Read what the assertion protects before refreshing the expected value. Sometimes the expected list is stale; sometimes the implementation has unintentionally widened access.
Check the actor when the action runs
The record-visibility service requires a verified, nondeleted user with an administrator or super-administrator role. An ordinary administrator also needs the explicit management permission. The super-administrator path is an intentional special case.
The management page uses that rule for access, but the state-changing service checks it again against a fresh actor inside the transaction. A previously rendered button shouldn’t be the final source of authority.
This matters when permissions or account state change while a page remains open. The page can still contain an action that was valid earlier. The server needs to decide whether the current actor may perform it now.
The tests include direct access to the management page by a customer and an ordinary administrator without the permission. Both are denied. After an explicit grant, the administrator can perform the supported visibility operation. That connects the permission to observable behavior.
Preserve the permissions of linked workflows
A generic management screen can become an accidental shortcut into every edit page. AdzByte App avoids treating its inspection permission as permission to create or edit each kind of record.
Create and edit destinations check the relevant resource or domain capability. A minimal record manager can open the management page while create and edit actions remain hidden when those separate permissions are missing.
That test is useful because navigation itself can imply a capability the user doesn’t have. Showing a link that always ends in a denial is confusing. Allowing it to succeed by trusting the management permission would be a more serious mistake.
The destination still needs its own server checks. Hiding a link makes the interface accurate; it doesn’t protect a route someone calls directly. When adding similar cross-feature links, I review both the link’s visibility and the action it reaches.
Protect higher-privilege identities during recovery
Restoring an account isn’t just a display change when that account has greater privileges than the actor. The service prevents an ordinary administrator from restoring a super-administrator account, even if the actor has record-management permission.
A regression test creates that situation and expects a denial. The same test then lets the administrator delete an ordinary work record, showing that the permission is useful without authorizing the higher-privilege operation.
The wider change also protects self-deletion and the final active super-administrator. Independent-process tests cover deletion racing with demotion and role deletion racing with assignment. These checks address the state that survives, not just the order of clicks in one browser.
I wouldn’t assume every application needs exactly these roles. The general review question is which administrative operation could remove the last valid recovery path or reactivate an identity beyond the actor’s authority.
The follow-up commit changed one assertion, while the preceding implementation supplied the capability, query rules, and actions. Keeping that history straight helps explain what was fixed and what was merely brought into the test’s expected list.
The practical result is an explicit grant model: record management is available to eligible actors, ordinary editing retains its own checks, and higher-privilege recovery stays restricted. When the next admin tool arrives, the same questions are worth asking before anyone adds it to a role’s default permissions.
Written by
Adrian Saycon
A developer with a passion for emerging technologies, Adrian Saycon focuses on transforming the latest tech trends into great, functional products.



