How I Audit Access Control Flaws

August 10, 2026 Melalew Mengistu

I first ran into access control while watching a SOC analyst course on YouTube. The instructor mentioned IAM — Identity and Access Management — in passing, and I realized I had never actually thought about who gets to do what in the systems I build. I knew how to log someone in. I knew how to check if a user was an "admin" before showing a dashboard. But I had never stepped back and asked whether the entire flow of permissions across my application made sense.

So I searched Google for how to audit access control and found a formal seven-step process: define objectives, review policies, assess permissions, test authentication, identify vulnerabilities, document findings, and monitor continuously. It sounded thorough, but reading it and doing it are different things. When I tried to apply it to my own projects, I got stuck on the first step. I couldn't even list every resource that needed protection. I didn't know all the API endpoints I had exposed, I had forgotten about old service accounts, and I had users with roles that didn't match their actual jobs. That's when I realized access control isn't a policy document. It's a living map of every door in your system and who has a key to each one.

What This Guide Actually Covers

This isn't a compliance checklist. I'm walking through exactly how I audit access control in practice — how I map the full scope of resources and roles, verify that permissions match real job duties, test whether least privilege is actually enforced, attempt privilege escalation to find gaps, and read access logs for the story they tell. I'll also touch on whether this can be automated, and what AI actually brings to the table versus what still requires human judgment.

What Access Control Actually Is

At its core, access control is the set of rules that decides who can touch what. It's not just login and logout. It's the entire flow from authentication — proving who you are — through authorization — deciding what you're allowed to do — to enforcement — actually blocking the actions you aren't allowed to take. A resource is anything worth protecting: a database table, an API endpoint, a file, a dashboard, a configuration setting. A role is a collection of permissions grouped by job function. A permission is a specific allowed action on a specific resource, like "read users" or "delete orders."

When access control breaks, it usually breaks in one of three ways. First, excessive permissions — someone has more access than they need. Second, stale access — someone still has permissions after their role changed or they left. Third, missing enforcement — the rules exist on paper but the application doesn't actually check them at the critical boundary. My audit process is designed to catch all three.

How I Audit It

I distilled the formal seven-step process into five practical actions I can actually execute on a real codebase. Here's what I do.

Step 1: Map the Scope

Before I check a single permission, I inventory everything that needs protection. I list all API endpoints, database tables, admin panels, file storage buckets, background job queues, and third-party integrations. I also list every user role, service account, and integration token. If I don't know a resource exists, I can't protect it. This step is tedious and often reveals forgotten endpoints, old test accounts, and services running with credentials no one remembers creating.

Step 2: Review Role-Based Access

I compare every user's assigned role against their actual job duties. A developer who moved to a different team six months ago might still have production database access. An intern's test account might still be active. I look for role explosion — when an organization creates too many custom roles that overlap and become impossible to reason about. I also check for the opposite: too few roles, where everyone is either "user" or "admin" and there's no middle ground. A service account is a non-human account used by applications or scripts to authenticate with other services.

SQL: Finding Stale Admin Accounts
SELECT u.id, u.email, u.role, u.last_login, u.created_at
FROM users u
WHERE u.role = 'admin'
  AND u.last_login < NOW() - INTERVAL '90 days'
ORDER BY u.last_login;

Step 3: Test Least Privilege

The principle of least privilege means every user and service should hold only the minimum permissions needed for their specific tasks. I verify this by picking representative accounts from each role and tracing every action they can perform. If a "support" user can export the entire user database, that's not least privilege. If a microservice token can delete tables when it only needs to read them, that's a problem. I document every over-permissioned account and queue it for remediation.

Step 4: Attempt Privilege Escalation

This is the most revealing step. I put on an attacker's hat and try to climb from a low-privilege account to a high-privilege one. I test whether a standard user can access administrative pages by guessing URLs, manipulating request parameters, or replaying tokens. I check if role checks happen on the client side but not the server. I look for IDOR vulnerabilities — Insecure Direct Object Reference — where changing a numeric ID in a URL lets me access another user's data. If I can escalate privileges without exploiting a complex bug, the access control flow is broken.

Client-side role checks are decorative. If your React component hides an admin button but your API doesn't verify the role server-side, the access control doesn't exist. I always test the API directly with a low-privilege token.

Step 5: Analyze Access Logs

Logs are where the truth lives. I check login histories for unusual patterns — logins from new countries, off-hours access, or rapid successive failures followed by a success. I look for permission changes: who granted admin rights, when, and from where. I correlate failed access attempts with the resources they targeted. A spike in 403 errors from a single account might mean someone is probing for gaps. A single successful admin action from a regular user account might mean escalation already happened.

Can AI Automate This?

After running this process manually a few times, I started wondering whether AI could speed it up. The answer is: partially. AI and multi-agent systems are already good at specific pieces of the puzzle.

Log analysis is the strongest fit. Machine learning models can baseline normal access patterns and flag anomalies — unusual login times, impossible travel, or sudden spikes in data access — faster than any human scrolling through rows. Permission review can be partially automated by comparing role assignments against HR data or ticketing systems to detect stale access. Vulnerability scanning tools can already test for IDOR and missing authorization checks at scale.

But the parts that matter most — understanding business context, judging whether a permission is excessive for a specific person's duties, and interpreting the intent behind a suspicious log pattern — still need human judgment. AI can tell me that an account accessed 10,000 user records at 3 AM. It can't tell me whether that was a legitimate data migration or a breach without asking the team. I treat AI as a force multiplier for the tedious steps, not a replacement for the audit itself.

Automation finds patterns; humans find meaning. Use tools to surface anomalies, but always validate them against business context before calling something a vulnerability.

Production Checklist

Access control auditing isn't a one-time project. These are the four rules I hold every system to:

  • Inventory every resource, API, and account before checking permissions — you can't audit what you don't know exists
  • Verify least privilege by tracing what each role can actually do, not just what the policy document says
  • Always test privilege escalation from the attacker's perspective; client-side checks alone mean nothing
  • Correlate access logs with business context — automation surfaces anomalies, but humans determine intent

None of this makes a system unhackable, and I don't treat it that way. Access control was just another layer I learned to inspect properly. XSS, SQL injection, insecure deserialization, and supply chain attacks are all still sitting on the same list. Security is a process I keep working through, not a milestone I hit once and move past.

Melalew Mengistu

Melalew Mengistu

Web engineer and web security specialist. Helps teams build and ship secure applications.