Skip to content
Insights · Engineering

Name the role that account holds

Name the role on that account, show a forbidden action refused, and show a different role still allowed. A job title is not the binding.

Scroll
EngineeringOct 20, 202612 min readBy Salman Naqvi, Founder & CEO
Name the role that account holds

Someone has an account. Tonight, in a console you administer, three things. Name the role, or the set of privileges, bound to that account, as the product stores it, not as a job title in a slide. Show one action that role is not allowed to take, and show the product refuse it. Show a different account, bound to a different role, still succeed at an action that second role is allowed to take. If the name, the refusal, or the success requires the person who built the login, you have not named a role. You have a list of people and a hope that everyone is allowed the same things.

This is the binding between an account and what it may do. It is not the question of whether that person is still signed in. End the session they still hold ends a secret. A session you have ended does not tell you what the account was allowed to do while the secret was still good, and a session that is still valid does not grant a role you have not attached. It is not a quota. Cap one account and leave the rest up is how much one account may consume. A cap can be hit by an account whose role is narrow, and a role can be broad on an account that has not hit a cap. It is not the record of a permission they were shown and accepted. Show the consent they gave is that record. Consent to a policy is not the role the console will enforce on the next click. And it is not a cross-tenant leak. If one customer can already read another customer's rows, the first hour is that boundary. Renaming a role will not close it.

None of what follows is a finding that your product's roles are wrong, and none of it is legal advice. A category rate is not the share of your accounts that are administrators. A control statement is not a lawsuit, and it is not a questionnaire you can paste into a security form and call done. The work on this page is three proofs in a console you hold. If you wanted a lawyer to say whether a regulation names you, hire the lawyer.

The category that contains a missing check is wider than the role on one account, and the rates are the category's. OWASP Top 10:2025 A01, Broken Access Control, keeps the first place. The background says "100% of the applications tested were found to have some form of broken access control." The score table on the same page prints 40 CWEs mapped, maximum incidence 20.15%, average incidence 3.74%, maximum coverage 100.00%, average coverage 42.93%, average weighted exploit 7.04, average weighted impact 3.84, 1,839,701 occurrences, and 32,654 CVEs. The category "has the highest number of occurrences in the contributed data, and second highest number of related CVEs." Highest occurrences is not second-highest CVEs. 1,839,701 is not 32,654. The introduction, a different page, says "on average, 3.73% of applications tested had one or more of the 40 Common Weakness Enumerations (CWEs) in this category." 3.73 is not 3.74. The background's 100% is not the introduction's 3.73, and neither is the table's 3.74. Maximum coverage of 100.00% is how widely a weakness was tested, not the background's claim that every tested application had some form of the weakness. Average coverage 42.93% is not an incidence. 7.04 and 3.84 are weighted exploit and impact scores, not percentages of applications, and 7.04 is not 3.84. Do not hang any of those figures on the one account in front of you (OWASP, A01:2025 Broken Access Control, and the introduction).

The same introduction prints a different average for other categories, so 3.73 is not a sitewide rate. Security misconfiguration is 3.00% of applications tested, for 16 CWEs. Cryptographic failures are 3.80%, for 32 CWEs. 3.00 is not 3.73 is not 3.80. The method ignores how often a weakness repeats inside one application: four instances and 4,000 instances are the same for this ranking. They analyzed 589 CWEs, up from almost 400 in 2021 and about 30 in 2017. 248 of those sit inside the ten categories. The MITRE dictionary they name had 968 CWEs at release. 589 is not 248 is not 968. They capped a category at 40 CWEs, and A01 is at that cap. The cap is their decision. It is not a count of roles in your product. Eight of the ten categories come from the testing data. Two come from the community survey. A01 has a score table, so it is one of the eight, not a survey-only line. The contributors note says data was donated for "over 2.8 millions applications." That phrase is the contributors note, plural and all. It is not 1,839,701, and it is not your user table. On the CVE side of the method they used about 175k records of CVEs mapped to CWEs, up from 125k in 2021, extracted from nearly 220k CVEs. Of those, 160k had a CVSS v2 score, 156k a v3 score, and 6k a v4 score. Those three overlap, which is why they can total more than 220k. 643 unique CWEs were mapped, up from 241. 175k is not 220k is not 643. In CVSS v2, exploit and impact could each reach 10.0, then the formula kept 60% for exploit and 40% for impact. In v3 the theoretical maximums are 6.0 and 4.0. They say impact shifted almost a point and a half higher on average in v3, and exploitability nearly half a point lower. Almost a point and a half is not 7.04, and nearly half a point is not 3.84. None of this is the role bound to the account you can open.

What the category says to do is narrower than the table. "Access control enforces policy such that users cannot act outside of their intended permissions." The first common failure they name is "violation of the principle of least privilege, commonly known as deny by default, where access should only be granted for particular capabilities, roles, or users, but is available to anyone." Deny by default is a design. 3.74% is not that design, and 100% is not a reason to make every account an administrator so that nobody is "broken." Prevention that belongs on this page: except for public resources, deny by default; enforce record ownership rather than letting a user create, read, update, or delete any record; log access-control failures. Two neighboring lines are not this proof. Invalidating a session identifier on the server after logout is the session article. Rate limits on a controller are the cap article. A product can log a refusal and still not be able to name the role that was refused. The examples are a parameter that selects someone else's account, a privileged URL a normal user can open, and a check that exists only in the browser. Those are missing checks. They are not a substitute for the row that says which role this account holds.

A control catalog asks you to write the binding down, and it does not publish a rate. NIST Special Publication 800-53 Revision 5, September 2020, with updates as of 10 December 2020, is the catalog. A minor release on 27 August 2025, Release 5.2.0, lists new and revised controls. That change list does not include AC-6, so the least-privilege statement here is the Rev. 5 statement. AC-3, Access Enforcement, is one sentence: "Enforce approved authorizations for logical access to information and system resources in accordance with applicable access control policies." Enforcement is not the list of authorizations. AC-2, Account Management, is the list. It tells you to define the types of accounts that are allowed and the types that are prohibited, to require whatever the organization defines for group and role membership, and to specify, for each account, the authorized users, the group and role membership, and the access authorizations, meaning the privileges. The blanks are organization-defined parameters. An unfilled blank is not a role named "member," and it is not evidence that a default of administrator satisfies the control. AC-6, Least Privilege: "Employ the principle of least privilege, allowing only authorized accesses for users (or processes acting on behalf of users) that are necessary to accomplish assigned organizational tasks." The guidance says organizations consider creating additional processes, roles, and accounts in order to get there. "Consider" is not "you already have three roles." AC-6(9) says log the execution of privileged functions. AC-6(10) says prevent non-privileged users from executing privileged functions. A log of a privileged function is not the membership record, and a prevention you have not tested is not the refusal in the second proof. Least privilege is a principle in a catalog. It is not 3.74%, it is not 20.15%, and it is not a finding that your product is in scope for the catalog (NIST, SP 800-53 Rev. 5).

Do the three proofs on one account you can name, then stop generalizing. Open the account. Read the role or the privilege set the product actually stores. If the screen says "admin" because every account was created as admin, write that down. That is a finding about the binding. It is not the OWASP background, and it is not AC-6 satisfied. Pick an action that role must not take: deleting another account, exporting every row, changing a price, inviting a member. Perform it as that account. The product must refuse, in a way you can show, not in a menu that is merely hidden. Then take a second account whose role should allow a different action, or should allow the same action the first role must not, and show that action succeed. The second success is what stops the refusal from being a broken product. A refusal that also blocks the owner is not least privilege. It is an outage. If you cannot find a second role because the product has only one, the first proof is the sentence "there is one role, and every account holds it." That sentence is allowed. A slide that draws three boxes is not.

A job title is the trap. "She is the founder" is not a role in the database. "He is in finance" is not a privilege set. The console either has a membership you can read or it does not. AC-2's phrase is role membership and access authorizations for each account. If the only place the role appears is the signature block of an email, you have not done the first proof. Do not ask a model to infer the role from the person's title. The model was not there when the account was created, and a guessed role that you then enforce is how a stranger becomes an administrator.

What the three proofs look like, when a product already has more than one kind of account, is ordinary and visible. Gigbase is a multi-tenant workspace with subscription plans and role-based access for agencies, admins, and team members. Nothing in that description is a headcount, a duration, or a result figure. The shape is the point: three kinds of account are named, so a founder can point at one person, read which kind they hold, refuse an action that kind must not take, and show a person of a different kind still working. That case is not a role ledger, and it is not a finding that any of those kinds is least privilege. A product whose only account type is "user," with every user able to export every tenant, cannot borrow the shape. It has to grow a second binding, or it has to say, in writing, that one binding is the whole product.

There is a version of this afternoon where hiring the path is the wrong purchase. Nobody has an account, because the product does not have accounts yet. You have no product. You are still choosing who will build, and the document in front of you is a term sheet. The criteria for that choice sit on the page written for a top saas development company. That page is criteria. It does not rank anyone, including us. The only fact in the email is a job title, and the product does not store a role. A title is not a build. A customer has already seen another customer's data. Naming a role does not close a leak. Or you wanted a lawyer to say whether a catalog applies. Hire the lawyer. A console does not answer that, and neither does this page.

When the account is real and the console cannot name a role, the missing object is specific. A membership you can read without the person who wrote the signup, a refusal that account receives, and a different account that still completes a different action. A startup software development company that expects this will have put the membership next to the rest of account admin, before the first customer is the way you discover every user is an owner. One that needs a call in order for you to read a role is telling you who holds the binding. If the first slice is a fixed capability, an AI integration sprint is the shape where the acceptance sentence can include the three proofs. If you do not yet know which system stores accounts for the product you have, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a rate, and they are not a role.

The same afternoon can fail in a neighboring place, and the repair is not this one. A workflow that fetches someone else's code is name the action the workflow runs. A model that called a function you cannot name is name the tool the model called. Neither of those is a role, and a role you finally write down does not pin an action or record a tool call. Do not collapse the three into one screenshot.

Before you tell a customer that only the right people can do the dangerous thing, do the three proofs and write the time. Name the role the account holds. Show the forbidden action refused. Show a different role still allowed through. Do not quote a category percentage as if it were your user table, and do not ask a model to invent the membership. The row in the console is the page you can defend.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→