Keep one record per client site with the CMS version, theme, plugins, package manager dependencies, PHP version, host and a named owner, and refresh it whenever you ship. When an advisory lands, that record is how you answer "which clients are affected?" in minutes instead of days.
An agency with thirty sites and no inventory is a team that learns about a vulnerable plugin from a client.
The columns that earn their place
| Column | Example content | Used for |
|---|---|---|
| Site and owner | Name, client contact, internal owner | Who to tell, who fixes |
| Host and PHP version | Provider, PHP branch | Spotting unsupported runtimes |
| CMS and version | WordPress and release | Core advisories |
| Theme and parent theme | Name, version, source | Theme advisories |
| Plugins | Name, version, source, licence holder | Plugin advisories |
| Packages | Composer and npm top level and locked versions | Library advisories |
| Last updated | Date | Spotting neglected sites |
| Backup and last restore test | Dates | Recovery confidence |
Where the data comes from
For the CMS layer, the plugin list in the dashboard or a command line tool gives you names and versions. For the code layer, lockfiles are the better source, because they record exact versions. Composer's documentation says to commit composer.lock so that everyone, including CI and production, runs the same versions. npm's documentation describes npm ci as an install that requires an existing lockfile and fails if it does not match package.json, which makes the lockfile the truth about what ships.
If a project does not commit lockfiles, fix that first. Without them, the inventory describes what you hoped was installed.
Know the source of every plugin
Record where each plugin came from. The WordPress handbook advises restricting yourself to the WordPress.org repository or well known companies, because plugins and themes from untrusted sources may lead to problems. A "source" column makes exceptions visible.
Keep the process light
An inventory that takes an afternoon to update will be stale by Friday. Aim for something you can regenerate from a script or a scanner, then store the output. Review it monthly, and compare against the PHP support calendar: the PHP project says each branch gets two years of active support and two more of security fixes only, then reaches end of life.
Use it when an advisory lands
The workflow is short. Search the inventory for the affected name and version range, list the sites, check which ones actually load the vulnerable code, patch those first and tell clients in plain words. If you have no way to check reachability, patch everything that matches.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how packages, versions and sources are listed together; that is the shape your sheet should take.
Safeguard produces an SBOM and scans dependencies for projects with manifests in a repository, and the free scan can seed your first inventory.
Quick check
Is a spreadsheet good enough?
For a handful of sites, yes. Past that, generate the data from lockfiles and scans so it does not rely on memory.
Should the inventory include inactive plugins?
Yes. Inactive plugins still sit on disk and can still hold vulnerable code, so list them and remove the ones you do not need.
Sources
Last reviewed: 19 October 2026.