Skip to content

Who has access to your system, and when did you last check

  • Home
  • Blog
  • Who has access to your system, and when did you last check
Who has access to your system, and when did you last check

A website access audit is the practice of listing every person, account, token and integration that can read or change your site, then removing anything that no longer needs to be there. Most compromises we investigate trace back to a login nobody reviewed for years.

Key Takeaways

  • A website access audit spans the CMS, hosting panel, database, registrar, DNS, email and code repository — not just admin logins.
  • Former employees and contractors are the most common source of stale, unused access.
  • Shared admin accounts destroy accountability; audit logs become useless.
  • Rotate passwords, SSH keys and API tokens the moment anyone with access leaves.
  • Run a lightweight audit quarterly, and a full one after any role change or suspected compromise.
  • Two-factor authentication is the cheapest meaningful hardening you can apply today.
How a website access audit runs from inventory to documentationOrdered stages of a website access audit, connected by arrows.How an access audit runs1Inventoryevery surface2List usersand tokens3Revokestale access4Rotateall secrets5Documentand review
The five stages of a website access audit, from listing every surface through removing stale access to writing down what you found.

What does a website access audit actually cover?

A website access audit covers every surface that can read, modify or publish to your site: the CMS, the hosting control panel, SSH or server logins, the database, the domain registrar, DNS records, business email and any connected CI/CD or repository. You also review API keys and third-party integrations, which people routinely forget.

The common mistake is treating this as a WordPress admin cleanup. It is not. A stale SSH key on the server or a personal access token in an old deploy script gives an attacker far more reach than an extra CMS login. On AWS-hosted workloads, that means reviewing IAM users and roles; on GitHub, it means checking deploy keys, personal access tokens and repository collaborators. The AWS IAM documentation and GitHub authentication docs both frame access as a standing inventory, not a one-time setup — that is the right mental model.

Ownership questions sit underneath all of this. If nobody can say who controls the domain registrar or the hosting account, you have an operational problem before you have a security one. Our guidance on who owns website code and credentials covers the handover side; the audit is where you discover the gaps.

Why does access drift, and why is it dangerous?

Access drift happens because permissions are granted for a specific task and never revisited. A contractor gets admin to install a plugin; a developer gets SSH to debug a cache issue. When the task ends, the access stays. The danger is that every stale login is a potential entry point with no human watching it.

Drift is not a failure of discipline so much as a failure of process. Nobody writes down why access was granted, so nobody feels safe revoking it later. Two years on, the site has five administrators, three of whom left the business, and nobody can explain why a marketing agency still has hosting panel access. In practice, we have been burned by exactly this: a site redirecting visitors to a pharmacy spam page, traced to a freelancer's admin account that was never removed after a one-week theme fix.

The danger is rarely the current employee. It is the departed contractor, the shared "admin" password written in a group chat, and the API token that still works long after the integration was retired. Each one is a silent door.

When do you need a full website access audit?

Run a full website access audit after any of these events: an employee or contractor leaves, a password is reused across services, a plugin or theme shows signs of compromise, or your site changes hands. You should also audit quarterly as routine hygiene, even when nothing feels wrong.

Triggers that justify an immediate audit include:

  • Someone with access resigns, is dismissed or finishes a contract.
  • You inherit a site from another agency or owner and cannot account for every login.
  • A plugin, theme or custom code shows unexpected behaviour, new admin users or strange outbound traffic.
  • You receive a password-reset email you did not request, or a login notification from an unknown location.
  • A quarterly review date passes, and the access register has not been touched.

What should you check first in a website access audit?

Start with the surfaces that carry the widest blast radius — the scope of damage a single compromised login can cause — not the ones you think about most. The hosting panel and domain registrar matter more than the CMS because they let an attacker bypass the site entirely. Check who can log into hosting, then who can transfer your domain, then the CMS.

A useful diagnostic order is: hosting panel and cloud console, domain registrar and DNS provider, CMS admin users, database credentials, SSH keys and server access, code repository and CI tokens, business email accounts, then third-party integrations and API keys. Each layer you skip is a layer that can undo the work below it.

Which access surface carries the most riskRows mapping each access surface to the risk it carries and what to check.Which surface carries the most riskHostingFull server control; one leaked login can take the whole site offlineRegistrarDomain transfer and DNS changes; often recoverable via an old emailCMS adminInstall plugins and edit code; the most commonly forgotten accountDatabaseRead or write every record; credentials often copied into config filesRepo / CIPush code to production; deploy keys and tokens outlive projects
How the common access surfaces map to the damage a single compromised credential can cause, and the specific check each one demands.

How do you run a website access audit step by step?

A website access audit has five mechanical stages: inventory, review, revoke, rotate and document. You list every surface, name every user and token attached to it, remove anything stale, change every credential a departing person might have seen, and write down what you found so the next audit starts faster.

Some of this is read-only work you can do yourself with command-line tools, though not every host exposes them. These commands simply list what exists; they change nothing:

# List WordPress administrator accounts (read-only)
wp user list --role=administrator

# List SSH keys that can reach the server (read-only)
cat ~/.ssh/authorized_keys

# List IAM users in the cloud account (read-only)
aws iam list-users --query 'Users[].UserName'

The ordered sequence:

  1. Inventory every access surface — hosting, registrar, DNS, CMS, database, email, repository and connected services.
  2. Pull the user and token list from each surface. Include personal logins, shared accounts, service accounts, SSH keys, deploy keys and API tokens.
  3. Mark each entry as keep, revoke or review. If you cannot name the human who owns it and the job it does, it is a revoke candidate.
  4. Revoke or disable everything marked. Where the platform allows, disable first for a short window, then delete once you are sure nothing broke.
  5. Rotate all credentials the departing person or project touched — passwords, keys and tokens — even if you think they were never shared.
  6. Record the outcome: what changed, why, and the next review date. Store the register somewhere the next person can find it.

Step four is the only destructive stage. Revoking a key or account can break an automated job that silently depends on it. Disable before you delete, and warn anyone whose workflow might be affected.

Access review decision treeA decision tree showing whether to keep, revoke or disable an account based on whether it still needs access.Access review decisionDoes this accountstill need access?Yes — keep itrecord justificationand review dateNo — revokeremove the accountand rotate secretsUnsure — disabletemporarily, thenverify with the owner
The decision each account faces during a website access audit: keep it with a written reason, revoke it now, or disable it while you confirm ownership.

Which access configuration matters most?

The configuration that matters most is the principle of least privilege: every account should hold only the permissions its owner currently needs. A content editor does not need theme-editing rights in WordPress; a marketing contractor does not need access to the hosting panel. Second is enforcing two-factor authentication on every externally reachable login.

SurfaceHighest-risk accessWhat to check
Hosting panelFull server controlNamed accounts, two-factor, last login dates
Domain registrarDomain transfer or DNS changesTransfer lock, who can approve changes
CMS adminInstall plugins, edit theme codeAdministrator count, two-factor enforcement
DatabaseRead or write every recordShared credentials stored in config files
Repository / CIPush code to productionDeploy keys and personal access tokens
EmailTrigger password resetsWho holds each mailbox login

Least privilege is not a one-off setting; it is a standing rule you reapply at every audit. When in doubt, start users at the lowest level and escalate only when a task actually fails for lack of permission.

How do you verify the audit worked?

Verification is simple but often skipped: attempt the things you revoked. Log out of the shared account and try to log back in. Ask a developer to pull a repository with a removed deploy key. Check that two-factor prompts appear on logins that previously skipped them. If the old path still works, the audit did not finish.

  • Try each revoked account from a clean browser or session.
  • Attempt an SSH connection with a removed key to confirm it is rejected.
  • Trigger a deploy or integration that used a rotated token and watch for the expected failure, then restore it with the new credential.
  • Confirm your own admin account still works, with two-factor enabled, before you close the audit.

What are the failure modes and how do you debug them?

The most common failure is an account that looks revoked but still has access through a second route — a shared password, an SSH key copied to another server, or a personal access token embedded in a deploy script. Debug by tracing every place a credential could be stored, not just the obvious login screens.

Specific failure modes we see repeatedly: an SSH key left in authorized_keys on a second server, a WordPress admin created with a different email address, a domain registrar account still tied to a former employee's personal inbox, and an API token committed into an old repository. Debug each by going to the source of truth — the key file, the user table, the registrar's contact list, the repository settings — and reading what is actually there, not what you assume was removed.

What does a website access audit cost in operational effort?

A full first audit for a small business site typically takes a few focused hours spread across a week, mostly waiting on people to confirm who still needs access. The ongoing cost drops sharply if you keep a simple access register and review it quarterly. The expensive version is skipping the audit and paying for a breach in downtime, lost customer trust and recovery work.

Larger estates with many servers, cloud accounts and team members cost more because the inventory itself is larger. The effort is driven by the number of surfaces and the number of people, not by the tooling. Most of the time goes into the awkward conversations — "who is this account?" — rather than the technical steps.

Security considerations beyond the basics

Two-factor authentication, unique passwords and access logging are the baseline. Beyond that, consider service accounts with narrowly scoped tokens instead of personal logins for automated jobs, and protect the access register itself — it is effectively a map of every way into your site.

  • Keep named accounts for people and separate service accounts for automations.
  • Store secrets in a password manager or secret store, never in a shared document.
  • Enable login alerts where the platform supports them, so new logins are visible.
  • Treat the staging environment with the same care as production; a leak there often reaches production credentials.

Common mistakes during access audits

Teams often audit only the CMS and ignore the hosting panel, or they revoke a user but forget to rotate the password that user once knew. Another common mistake is recording the decision but not the next review date, so the register goes stale and the audit has to start from scratch.

  • Auditing one surface and declaring victory.
  • Not rotating shared secrets after a departure.
  • Keeping a shared "admin" account for convenience.
  • Skipping third-party integrations and API tokens.
  • Writing decisions down with no named owner or review date.

A realistic scenario: the marketing site nobody questioned

A Kathmandu business runs a WordPress marketing site. Two years ago, a freelancer fixed a theme and received an administrator account. Six months later, a designer got hosting panel access to help with a migration. Neither was removed. The domain registrar account sits under a former employee's personal email. One morning the site redirects to a spam pharmacy page, and the logs show a login from an unrecognised location using an old admin account.

The audit finds three stale administrators, a shared hosting login, an SSH key nobody recognises, and a registrar recovery path that routes through an inbox the company no longer controls. Cleaning this up means rotating every credential, reclaiming the registrar, removing the stale accounts and writing down who owns what. That is exactly the kind of messy, cross-surface cleanup our team handles as part of website maintenance, and it is far cheaper to do before the redirect happens than after. A website handover checklist helps prevent this when a site changes hands; the audit is how you catch it when it was never handed over properly.

Alternatives compared: manual audit vs tooling vs ongoing review

A manual audit works well for small sites with a handful of surfaces. Dedicated identity and access tooling matters when you run many servers or a larger team, but it adds operational overhead of its own. Most businesses need the manual register first; automation helps later, once the register is trusted.

Tooling such as AWS IAM Access Analyzer or GitHub's access review features can flag unused keys and overly broad permissions, but they only see the surfaces they are connected to. A manual register still has to cover the registrar, the CMS and the email accounts. In practice, the right combination for most small businesses is a quarterly manual review plus platform-native alerts where the platform already provides them.

In short: a website access audit answers one uncomfortable question — who can still touch your site, and should they? List every surface, remove what looks stale, rotate what departing people saw, and repeat quarterly. It is boring work until the day it stops a breach.

People also search for

If your access register has not been touched in over a year, or you just found a login you cannot explain, our team can run the audit with you, remove what should not be there and hand back a clean, documented access list. Contact us and we will start with the highest-risk surfaces first, or see how ongoing website maintenance keeps the register current.

Frequently asked questions

  • A website access audit lists every account, API key, SSH key and third-party integration that can touch the site, server, domain registrar or code repository. You compare that list against current staff, contractors and services, then revoke anything stale. The output is a dated access register and removal tasks.

  • Quarterly is the practical minimum for a production site; run one immediately after an offboarding, a suspected compromise or a major role change. Higher-risk environments with frequent contractor turnover should also trigger an audit when a contract ends. Record the date so the last check is always answerable.

  • Cover at least six surfaces: WordPress or application admin users, hosting panel and SSH users, database users, DNS and domain registrar logins, code repository collaborators, and third-party services with OAuth or API access such as backup, analytics or payment plugins. Each surface has a separate list and removal procedure.

  • Run wp user list --fields=ID,user_login,user_email,roles --role=administrator from the site root. Add --format=table for readable output. This shows administrator-role users only; also run without --role to catch editors or shop managers whose permissions still allow content or order access. Back up the database before bulk changes.

  • Inspect /home/*/.ssh/authorized_keys and /root/.ssh/authorized_keys, then run getent group sudo or grep '^sudo' /etc/group to see privileged users. Check /etc/ssh/sshd_config for AllowUsers or AllowGroups restrictions. Before removing a key, copy the line to a dated backup file.

  • A former employee's WordPress account still active, an SSH public key tied to an old laptop, a contractor's IAM access key with last-used date months old, or a deactivated plugin still holding OAuth tokens. The common marker is a credential whose owner no longer needs access but whose entry was never removed.

  • Generate a credential report with aws iam generate-credential-report, fetch it with aws iam get-credential-report and decode Content. Look for access_key_1_last_used_date or access_key_2_last_used_date older than 90 days. For one user, run aws iam list-access-keys --user-name and aws iam get-access-key-last-used; deactivate before deleting.

  • Export a dated CSV or text list of every user, key, collaborator or token you plan to remove. In WordPress, reassign content with wp user delete --reassign= rather than deleting outright. In AWS, deactivate keys first and monitor for breakage. In Git hosts, record collaborator permissions before demotion.

  • Re-run the same commands after removal and confirm the revoked user, key or collaborator no longer appears. Test an old SSH key or revoked API token against the system and expect authentication failure. For WordPress, confirm the former user cannot log in and that content ownership moved to a current account.

  • Centralise logins with SSO and a directory such as Google Workspace or Entra ID, so offboarding revokes access in one place. Use groups in the hosting panel, repo and cloud provider instead of per-person grants. Scheduled credential reports and short-lived deploy tokens reduce the manual list-checking each quarter.

0 comments

Be the first to share your thoughts.

Leave a comment

Chat on WhatsApp