Short answer. An application’s access is not a login screen: it is five layers. One identity per person, no shared account, which gives every action a name. Roles, manager, sales rep, storekeeper, accountant, contractor, AI agent, each written from one sentence by the manager. Row rules: their customers, their depot, their branch, their discount limit; denied by default, allowed by rule, and enforced by the database and the server, not only the interface. Approvals: what exceeds a limit goes to the phone of whoever can say yes. And an append-only log, which keeps who, when, from where, the value before and the value after, refusals and sensitive reads. “Hidden” data is not hidden on screen: it is not sent. And an employee leaving is an action, not an oversight. Six weeks, built with the application and not after.
This guide is for the manager in Algeria who lent their password to three people, the founder settled in France running a team they do not see, and anyone comparing quotes where “user management” is one line. It does not repeat how a customer logs in, described in the OTP guide, nor how two companies are isolated in a SaaS, described in the multi-tenant guide; it describes what happens inside one company, between its own employees.
What the figures say
Access control is the first weakness of applications, by far. The 2025 ranking of the OWASP top ten risks, the open reference for application security, keeps broken access control in first place: some form of it was found in 100 % of the applications tested, with an average incidence rate of 3.74 % and more than 1.8 million occurrences recorded. Its list of forms reads like an inventory of what we take over: access granted to anyone instead of denied by default, bypass by altering the address, viewing someone else’s account by changing its identifier, modifying actions with no check. What this imposes: the question is not “are we concerned” but “where”.
The remedies are written, and simple to state. The same OWASP page starts with: “except for public resources, deny by default”; then build access control once and reuse it everywhere, enforce that every record has an owner, log access control failures and alert, and invalidate sessions at logout. The PostgreSQL documentation describes the tool that makes them enforceable: row security policies, which restrict, per user, the rows a query can read or modify; when enabled with no policy, “a default-deny policy is used”, and they can differ for select, insert, update and delete. What this imposes: the rule “their customers only” lives in the database, not in a screen.
What is written nowhere: your roles. No standard says whether your storekeeper should see selling prices or from what amount a discount needs your approval; that is decided with you, one sentence per role. What we did not find: a public measure of internal leaks in Algerian companies; what we see on the apps we take over is that the six leaks described below are habits, not attacks, and they are found in almost all of them.
The same data, five roles
Access is not understood on a diagram but on a grid: the same six pieces of data, seen by five roles.
The manager changes almost everything, across the company, and their exports are logged like everyone else’s. The sales rep sees selling prices and their own customers’ balance, not the others’; grants a discount up to their limit; purchase price and margin are not hidden on their screen, they are not sent to their phone, which is the only way they are not there. The storekeeper changes the stock of their depot, sees selling prices, and sees neither purchase prices nor balances. The accountant sees everything, read-only, and may export; they delete nothing.
The AI agent is the column people forget: the one answering customers on WhatsApp, described in the dedicated guide, is a role like the others, with fewer rights than the person it assists. It reads what it needs to answer, proposes a discount without granting it, never sees the margin and exports nothing; its actions carry its name in the log. The grid is written in the first week, with you, and it serves three times: it tells developers what to build, it is the acceptance scenario, and it is the document reread when someone asks for one more right.
An application’s access, in five layers
Behind the grid, five layers, and the middle one is the one most often missing.
Identity: one person, one account, logged in by phone number with a code or a passkey, on known devices, with a session that expires; there is no password to lend, hence no shared account. Roles say what each function sees and does, per screen and per action; a person can hold two, and a role is not bent to suit someone. Row rules say *which ones*: their customers, their depot, their branch, with limits, a discount limit, a maximum amount; they are enforced by the database and the server on every request, because a rule that exists only in the interface is bypassed by changing a number in the address.
Approvals keep the limit from blocking work: a discount above the limit, an invoice cancellation, an export, a deletion go to whoever can say yes, on their phone, through the notification described in the notifications guide, and the answer comes back with one key. The log writes who, when, from where, the value before and the value after, the reason and the approver, but also refusals and reads of sensitive data; it is append-only, out of reach of business roles, backed up separately as the hosting guide provides, and it is read: a weekly review and alerts on the unusual.
«Hidden data is not hidden on screen: it is not sent, and that is the only way it is not there.»
“Who changed this price?”
The log is not for watching people: it is for answering one precise question, in one minute, six months later.
14:02, Karim, sales rep, attempts a 10 % discount on order 1042 from his phone: refused, his limit is 5 %. The attempt is written; it is the most useful line of the log, because it says where a limit is badly placed or who is testing it. 14:02, the approval request goes to the manager with the order, the customer and the reason entered. 14:05, the manager approves with one key; their name and the time are attached to the decision. 14:05, the price goes from 4,800 to 4,320 dinars; the old value is kept, nothing is overwritten.
14:06, the AI agent reads the new price to answer the customer on WhatsApp: reading sensitive data is an action, and it has a line. Six months later, the question “who changed this price” has an answer in five lines, with two names, two times, a reason and both values. What the log keeps for each line: the person and not an account, the time and device, before and after, the why, what was refused, what was read. And one rule with no exception: lines are added, none is changed and none deleted, manager included.
Six access requests, and the rule that gets written
Six requests we hear from managers, and the rule each becomes.
The sales rep, “they should only see their customers, not my margins”: rows filtered on their portfolio by the database, purchase price and margin never sent, discount up to their limit and approval beyond; it is the role of the pre-seller in the field app. The storekeeper, “they manage stock without seeing prices”: their depot’s stock writable, selling price readable, purchase price hidden, stock count validated by a second person. The external accountant, “they see everything but touch nothing”: read-only, export allowed and logged, no deletion, access reviewed every year.
The branch manager, “they run their branch, not the others”: everything on theirs, nothing on the others, their totals visible to head office in the dashboard and not the reverse. The contractor, “they fix things without keeping access”: named access, limited in time and scope, cut automatically at the date. The AI agent, “it answers customers without knowing everything”: its own role, reading what is needed, actions under a limit, never the margin or the export. Every row starts with a sentence from the manager; if a request cannot be written in one sentence, the role is badly cut.
«The most useful line of the log is a refused attempt: it says where a limit is badly placed, or who is testing it.»
Six access leaks
Six leaks we find on the apps we take over; none is an attack, all are habits.
The employee who left: they left three months ago and their account still works on their phone; leaving is a single action, sessions cut, devices removed, customers reassigned, and a monthly review lists inactive accounts. The shared account: three people use the manager’s account and the log says “manager” everywhere; one account per person, login by phone, and a written delegation rather than sharing. The number changed in the address: the sales rep replaces 1042 with 1043 and sees someone else’s order; the row rule is checked server-side and in the database on every request, and the refusal is logged.
The export of the whole base: the customer list leaves in a file, then to a competitor; export is reserved, limited, logged, with an alert, and the interface shows without handing everything over. Everyone an administrator: to move fast, everyone got all rights “for now”; roles are written in week one, rights added on request, and reviewed every quarter. The editable log: whoever changed the price can delete the line; the log is append-only, out of reach of business roles, backed up separately. The first three show in the log if someone reads it; the last three are decided in week one.
Seen elsewhere: OWASP, PostgreSQL, and what transposes
Two sources say the essentials. The OWASP ranking says broken access control is the first risk and was found in one form or another in every application tested; what transposes is its first recommendation, deny by default, and its least followed, log refusals. The PostgreSQL documentation says the database can restrict rows per user and per operation type, and denies everything when no policy exists; what transposes is that a rule written in the database protects every screen, including those added in two years and the AI agent plugged onto it.
What these sources do not say: your roles, your limits, and who approves what; the project’s first week answers that, with one sentence per role and the grid in front of you.
The rules of access that holds
Six rules, written in the first week. One person, one account; no shared account, no exception for the manager. Denied by default: a right exists because a rule grants it. The rule lives in the database and the server, not in the interface. Hidden means not sent. What exceeds a limit asks for an approval, not a workaround. The log is append-only and it is read: before, after, refusals, sensitive reads, weekly review.
A seventh rule concerns the quote: “user and role management” is not a requirement, it is a line; the requirement reads “validated role grid; one account per person; row rules for portfolio, depot and branch enforced in the database; limits and approvals listed; hidden data not sent; append-only log with values before and after, refusals included; leaving in one action; acceptance where each role attempts what it is not allowed to do”, and it is checked as the specification guide recommends. A quote that prices “an admin screen” has priced a screen, not a control.
Six companies, and the rule written first
Six companies we often equip, and for each the first rule chosen.
- The distributor and its portal, described in the dedicated guide. Each sales rep sees their portfolio, the purchase price is sent to nobody in the field, the discount has a limit per role.
- The branch network. Each branch sees its own; head office sees the totals of all; one branch manager does not see the other’s cash.
- The clinic and the practice, described in the practice guide. The practitioner sees their patients, reception sees appointments without the record, and every opening of a record is logged.
- The private school. The teacher sees their classes, the office sees payments, the parent sees their child; no pupil list is exported without a trace.
- The company run from France. The founder does not see their team: the log and approvals on their phone give them control, without calling every evening.
- The SaaS vendor, described in the multi-tenant guide. Isolation between customers first, then roles per customer that each customer configures, and the vendor’s support access limited in time and logged.
The 2027 calendar
The calendar is that of complete access control in six weeks, built with the application.
Week 0 to 1 writes the roles: one sentence from the manager per role, the grid of who sees and changes what, the limits and who approves; signed. Week 1 to 2 builds identity and sessions: one account per person, login by phone, known devices, expiry, and leaving in one action. Weeks 2 to 4 build the row rules, portfolio, depot, branch, limits, in the database and server-side, with automated cross-access tests: each role tries to read and modify what belongs to another.
Week 4 to 5 builds approvals and the log: the request reaching the approver’s phone, the append-only log with values before and after. Week 5 to 6 is acceptance and review: each role attempts what it is not allowed to do, in front of you, and the access review screen is delivered with its alerts. These tests join those run at every delivery, per the delivery guide; and when data comes from an old system, accounts are created during the migration described in the data migration guide.
What makes access control fail
The access controls we take over almost always failed for one of these reasons.
- Roles with no row rules. The sales rep has the right role, and sees everyone’s customers.
- The rule in the interface only. The button is hidden; the address works.
- Data hidden but sent. The margin is in the server’s response; you only have to look.
- The manager’s account lent. The log exists, and no longer says anything.
- Limits with no approval. Blocked, employees ask for someone else’s password.
- The log nobody reads. Everything is written there; nobody has looked for a year.
- The forgotten departure. No procedure; the account lives months after the person.
Frequently asked questions
The questions we receive from managers, founders and teams comparing quotes.
- How do we stop a sales rep seeing other reps’ customers and my margins?
- By a row rule enforced in the database: their queries only return the customers in their portfolio, however they ask. And by the fact that purchase price and margin are not sent to their phone; data hidden only on screen is found by looking at what the server answers.
- How do we know who changed a price or cancelled an invoice?
- By an append-only log that writes, for every change, the person, the time, the device, the value before, the value after, the reason and the approver. That requires one account per person: with a shared account, the log exists and says nothing. Refused attempts are in it too.
- What happens when an employee leaves the company?
- One action: their sessions are cut on all their devices, their account is disabled, their customers and files are reassigned, and everything they did stays in the log under their name. A monthly review lists inactive accounts, in case the departure was not reported.
- Does the AI agent have access to all our data?
- No: it is a role like the others, with fewer rights than the person it assists. It reads what it needs to answer, acts under a limit, never sees the margin and exports nothing; its actions and its reads of sensitive data are in the log under its name. The same row rules apply to it.
- Won’t the limits block the work?
- Not if they have a way out: what exceeds a limit, a discount above the limit, a cancellation, an export, goes as an approval request to the phone of whoever can say yes, and the answer comes back with one key. A limit with no approval pushes employees to borrow someone else’s account.
- How long to build roles and the log?
- Six weeks, at the same time as the application: one to write the roles and the grid, one for identity and sessions, two for row rules in the database, one for approvals and the log, one of acceptance where each role attempts what it is not allowed to do. Adding them afterwards means reopening every screen.