Imagine a furniture manufacturer. Sales prepares quotes, the warehouse ships orders, accounting follows payments, and dealers enter their own orders. They all use the same web application. Throughout the project, screens, reports and integrations were discussed; the question "who sees what" came up one week before handover, when someone noticed that a sales rep could see product costs and the other reps' customer lists.
What happens at that point is usually the same: some menus are hidden, some buttons are removed, a few users are called "admin". The system appears to work. A few months later it turns out that the account of an employee who left is still active, that nobody knows who approved a discount, or that a hidden screen opens when its address is typed into the browser.
In the first version of a new product, keeping the number of roles small is often the right call. The subject here is different: business software that several departments use every day. In a system like that, permissions are not a layer added on top of the screens later; they are part of the data model. The seven decisions below take a few meetings when discussed before screen design begins; added to a live system later, they mean touching almost every screen.
1. Derive roles from the work people do, not from job titles
Titles such as "sales manager", "regional lead" or "specialist" change from company to company, and even from year to year. If you build the roles in the software around them, you will reopen the permission structure with every reorganisation.
Instead, list the tasks first: prepares a quote, gives a discount, approves a discount, ships an order, accepts a return, changes the price list. Then mark in a table which of these tasks each role performs. When a title changes, the table stays the same; only the person's role changes.
This table also lets the software team and the business side speak the same language. "Should the regional lead be able to do this?" stays abstract; everyone can answer "should they be able to approve a discount?"
2. Seeing, changing and approving are separate permissions
In most systems, permission is reduced to a single question: can this person open this screen? Yet different people do different things with the same record. Accounting should see an order but not change it. A sales rep should be able to change a quote but should not approve a discount above a certain rate themselves.
For each important record type, answer at least four questions separately: who can see it, who can create it, who can change it, who approves or deletes it. For tasks that need approval, set a threshold (for example above a certain amount or rate), and write down who may change the threshold itself.
3. Decide which records each person sees, too
"Can see the customers screen" is not enough; which customers? A sales rep sees only their own customers, a regional lead their own region, the general manager all of them. A dealer should see only their own orders and the prices assigned to them.
This record-level separation requires the data model to store who or which region each record belongs to. Planned from the start, it amounts to adding a filter to each query. Added later, you first have to find out who owns thousands of existing records, and then go through every report and export one by one. Don't forget the reports: data hidden on screen is not hidden if it appears in the report exported to Excel.
4. Check on the server, not on the screen
Hiding a menu or a button is good for the user experience, but it is not security. If the application sends requests to a server in the background, someone who can send that request directly does not need the hidden button. Typing a record number into the address bar or opening the browser's developer tools may be enough.
So on every request the server should check two things: does this person have permission for this task, and is this record one of the records they may see? If different interfaces such as a mobile app and a dealer portal use the same server, the rule lives in one place and is not written again for each interface.
Try a simple test at handover: sign in as a user with low permissions and paste the address of a record opened by a user with higher permissions. The record should not open.
5. Some fields are more sensitive than the rest of the screen
On the same product card, the product name can be open to everyone while cost and margin should be open to only a few people. On the same staff record, the name and internal phone number concern everyone, while the national ID number, salary and health information concern only the relevant department.
Mark these fields from the start and tie them to a separate permission. Where personal data is involved this is not only good practice but also what data protection laws such as KVKK and GDPR expect: personal data should be accessible only to those who need it for their work. Check that sensitive fields do not appear in exports and notification emails either.
6. Record who changed what, and when
When a price is entered wrongly or an order is cancelled, the first question is "who did it?" If the system doesn't know, the answer is left to guesswork and mutual blame.
Keep a change history on important records: who changed which field, when, and from what to what. For approvals, store who approved and against which threshold. This record itself should be impossible to change; a history that even an administrator cannot delete ends arguments in a few minutes.
You do not need to record everything. Prices, discounts, customer account details, payments, stock adjustments and permission changes are usually a sufficient start.
7. Plan for people joining, leaving and going on leave
The moments when a permission structure breaks down most are not when the system changes, but when people do. A new employee is given admin rights "for now", and they are never taken back. The account of someone who left stays open. A manager goes on leave and approvals pile up, or their password is handed to someone else.
Settle three things for these from the start. Whose job is it to open and close accounts, and how is that tied to the HR process? During leave, how is approval authority handed to someone else for a limited time without sharing a password? And once or twice a year, who reviews who is in each role? This review often takes half an hour and turns up a few forgotten accounts.
In short
- Derive roles from the work people do, not from job titles, and show them in a table.
- Decide separately on seeing, creating, changing and approving; put thresholds on approvals.
- Decide which records each person sees; include reports and exports.
- Check permissions on the server for every request; hiding a button is not enough.
- Tie sensitive fields such as cost, margin and personal data to a separate permission.
- Keep a history of important changes that cannot be deleted.
- Plan account opening, closing, delegation and periodic review from the start.
In custom software and internal tool projects, we work out the role and permission structure as a table with the business side before screen design, and build the checks on the server side.
Our work on this: Custom Software Development
Planning a project like this?
Plan it in 10 steps