02.04 Upgrading Extras
Each Extra has its own version-tracking, its own upgrade chain, and its own upgrade entry point — and Core upgrades don't bring Extras forward automatically. Here's the per-Extra upgrade workflow, the version-tracking pattern, and the catch about page-load-driven schema migration.
Why this matters
The Extras catalog (Vulnerability Management, Incident Management, Workflows, Notification, ComplianceForge SCF, AI, Authentication, Encryption, Import/Export, Customization, API, Advanced Search, Jira, Risk Assessments, Organizational Hierarchy, Team-Based Separation) is a sizable portion of the SimpleRisk surface, and each Extra has its own release cadence and its own schema-migration chain. The Core upgrade workflow (The Upgrade Process) walks the Core schema chain; it does NOT walk the Extras' schema chains. Extras have to be upgraded separately.
The honest scope to know: this still catches operators out. The pattern "Core just upgraded; everything's current" is only half-true. A one-click upgrade brings the Extras along: after it replaces the core's files and migrates the core database, it downloads the newer version of each installed Extra, upgrades the database of each of those that is enabled, and asks the queue workers to restart. The other upgrade paths do not: the manual /admin/upgrade.php page, the POST /api/v2/admin/upgrade/db endpoint and a container image replacement move the core only. After one of those, walk the activated Extras and verify each is at the version expected for the new Core release.
The other thing worth knowing: an Extra's schema upgrade also runs automatically the first time the Extra is used after its files change, whichever path brought the new files. That is why an Extra that missed the one-click step still catches up, and why you don't usually need to run an Extra upgrade explicitly. The exception is when a migration takes long enough that the page that triggers it times out, or when you want to see that it ran cleanly before letting users onto the application. The one-click upgrade does that for you and reports a failure instead of leaving it for the first user to hit; for deployments that don't use it, one call to POST /api/v2/admin/extras/upgrade-databases (below) does the same.
The third thing: each Extra tracks its version in your instance settings with key {name}_extra_version (e.g., notification_extra_version, vulnmgmt_extra_version, ai_extra_version). The version progression is a numeric index into the Extra's ${name}_updates array — not a date-based version like Core. The first time the Extra activates, the version is 0; each subsequent migration in the chain increments it.
Before you start
Have these in hand:
- A current SimpleRisk install with Core already upgraded to the target version (per The Upgrade Process, Upgrading via Docker, or Upgrading on Bare Metal). This one is not advice. SimpleRisk always ships the newest build of an Extra, and it will refuse to install a build your release does not support — so Core comes first, or the download stops with a message naming the Extra, the build it was offered, and your release, and telling you to upgrade first. Registration and Licensing shows the exact wording. The Upgrade Extra is exempt from that check by design, so it installs whatever your release — it has to, since it is what performs the upgrade. The one-click upgrade already handles the ordering for you; it is manual Extra installs that hit this.
- A list of activated Extras. Visible in the Settings Hub at
/admin/index.php(open it from the Settings cog in the page header, then click the Extras chip) — note which Extras show as Active. - The release notes for the new SimpleRisk version, especially any Extra-specific upgrade notes.
- A current database backup — see Database Backup and Restore. The Extra upgrades modify the database; backing up first gives you the rollback path.
- For network-dependent Extras (Vulnerability Management Extra with scanner credentials, AI Extra with provider API keys), confirmation that the credentials are still valid — sometimes Extra upgrades exercise the upstream connection during migration.
Step-by-step
1. Identify the activated Extras
Header: Settings cog → Settings Hub → Extras chip filters the catalog to per-Extra tiles. Each tile shows the Extra's current state. Make a list of the ones showing as Active; those are the ones that need an upgrade pass.
For programmatic identification:
SELECT name, value FROM settings WHERE name LIKE 'extra_%' AND value = 'true';
(Some Extras use the extra_{name} setting; some use {name} directly with a 'true' value — both patterns appear depending on Extra age.)
2. Run the per-Extra upgrade
For each activated Extra, the upgrade is invoked via the Extra-specific API endpoint or via the Extra's admin page.
API-based (the cleanest pattern): send a POST to the Extra's database-upgrade route, authenticated with an administrator's API key. These routes change data, so they accept POST only; a GET is answered 404.
curl -X POST -H "X-API-KEY: {your-api-key}" \
https://{your-simplerisk-host}/api/v2/{route}
- Advanced Search:
advanced_search/upgrade/db - API:
api/upgrade/db - Artificial Intelligence:
ai/upgrade/db - Risk Assessment:
assessments/upgrade/db - Custom Authentication:
authentication/upgrade/db - Customization:
customization/upgrade/db - Encrypted Database:
encryption/upgrade/db - Import-Export:
import-export/upgrade/db - Incident Management:
im/upgrade/db - Jira Integration:
jira/upgrade/db - Email Notification:
notification/upgrade/db - Organizational Hierarchy:
organizational_hierarchy/upgrade/db - Team-Based Separation:
separation/upgrade/db - Vulnerability Management:
vulnmgmt/upgrade/db - Workflows:
workflows/upgrade/db - Secure Controls Framework:
scf/upgrade
For example, to upgrade the Notification Extra's database:
curl -X POST -H "X-API-KEY: $KEY" https://simplerisk.example.com/api/v2/notification/upgrade/db
Each route applies whatever migrations the Extra has pending and answers 200 when it is done. The Secure Controls Framework route works differently: it queues the SCF install and upgrade as a background task and answers 200 as soon as the task is queued, so check the SCF status for the outcome.
To see which Extras are installed and enabled, and at what version, call GET /api/v2/admin/extras/status as an administrator. The one-click upgrade reads the same list to decide which Extras to upgrade.
Upgrade every Extra's database in one call. When the code was replaced without the one-click upgrade (a container image swap, or any scripted deployment), call POST /api/v2/admin/extras/upgrade-databases as an administrator once the core database upgrade has finished. It upgrades the database of every Extra that is installed and enabled, and answers with what it did to each one:
curl -X POST -H "X-API-KEY: $KEY" https://simplerisk.example.com/api/v2/admin/extras/upgrade-databases
{
"status": 200,
"status_message": "Extra databases are up to date.",
"data": {
"extras": [
{ "name": "assessments", "installed": true, "enabled": true, "version": "20261003-001",
"result": "upgraded", "database_version_before": "71", "database_version_after": "72", "error": null },
{ "name": "complianceforgescf", "installed": true, "enabled": true, "version": "20261003-001",
"result": "queued", "database_version_before": null, "database_version_after": null, "error": null }
],
"summary": { "upgraded": ["assessments"], "current": [], "queued": ["complianceforgescf"], "skipped": ["jira"], "failed": [] },
"workers_restart_requested": true
}
}
(The real response lists every Extra; the example is cut down.) Each Extra's result is one of:
upgraded: Its database version moved.database_version_beforeanddatabase_version_aftershow how far.current: It was already up to date.queued: The Secure Controls Framework queues its content import as a background task and has no database version to compare; check the SCF status for the outcome.not_enabled/not_installed: Left alone. A disabled Extra is never upgraded, because that would create tables the Extra's owner never turned on.no_database: The Extra has no database of its own to upgrade (the Upgrade Extra).failed: Its database could not be upgraded.errorholds a stable code and the detail is in the debug log.
One Extra failing does not stop the others. When any fails the response is 500 with the same body, so a deployment script can fail the deploy and still see which Extra to look at. If another upgrade is running the call answers 409 and changes nothing; call it again when that upgrade finishes. When something was upgraded or queued, the queue workers are asked to restart so they load the new Extra code. It is safe to call again: an Extra that is already current is reported as current.
The call can take as long as the slowest migration, so give the HTTP client a generous timeout.
Replace an Extra's files. The routes above upgrade an Extra's database. To download and install a newer build of the Extra itself, send a POST to the Extra's upgrade/app route (note /api/, not /api/v2/) as an administrator, with the Upgrade Extra installed and activated. It changes files, so it accepts POST only; a GET is answered 404.
curl -X POST -H "X-API-KEY: $KEY" https://simplerisk.example.com/api/notification/upgrade/app
The route name is the Extra's short name, as in the table below. Incident Management, Artificial Intelligence and the Secure Controls Framework also answer to im, ai and scf, the names their database-upgrade routes use.
- Advanced Search:
advanced_search/upgrade/app - API:
api/upgrade/app - Artificial Intelligence:
artificial_intelligence/upgrade/app(orai/upgrade/app) - Risk Assessment:
assessments/upgrade/app - Custom Authentication:
authentication/upgrade/app - Secure Controls Framework (ComplianceForge):
complianceforgescf/upgrade/app - Customization:
customization/upgrade/app - Encrypted Database:
encryption/upgrade/app - Import-Export:
import-export/upgrade/app - Incident Management:
incident_management/upgrade/app(orim/upgrade/app) - Jira Integration:
jira/upgrade/app - Email Notification:
notification/upgrade/app - Organizational Hierarchy:
organizational_hierarchy/upgrade/app - Team-Based Separation:
separation/upgrade/app - Upgrade:
upgrade/upgrade/app - Vulnerability Management:
vulnmgmt/upgrade/app - Workflows:
workflows/upgrade/app
Core has to be at the new release first, or the download is refused (see Before you start). Run the Extra's database upgrade afterward.
Browser-based: open the Extra's admin page (e.g., /admin/notification.php, /admin/vulnmgmt.php, /admin/incidentmanagement.php); the page typically shows the Extra's current version and offers an Upgrade action if migrations are pending.
Implicit (use-driven): an enabled Extra checks its own version when it loads and applies any pending migrations. Just navigating around SimpleRisk after a Core upgrade typically triggers the Extra upgrades implicitly. This works for most cases; explicit invocation is preferable for visibility into the migration progress and any errors.
3. Verify each Extra is at the expected version
SELECT name, value FROM settings WHERE name LIKE '%_extra_version';
Each row shows the current version (numeric index) for an Extra. Compare against the expected version for the SimpleRisk release you upgraded to. The expected versions for each Extra are documented in the SimpleRisk release notes and in the Extra's own admin page header.
4. Test each Extra's operational paths
After the upgrade, test the Extras end-to-end:
- Notification Extra: trigger a test event (submit a test risk) and verify the email arrives.
- Vulnerability Management Extra: open the triage queue and verify it renders; trigger a manual sync (
POST /api/v2/vulnmgmt/update/all) and verify it completes. Before that first sync, know that the import and auto-triage thresholds now compare each finding's newest CVSS score (v4.0, then v3.1, v3.0, v2.0) instead of its CVSS v2 score alone. Newer scores usually run higher for the same flaw, so many findings that used to fall below a threshold now pass. That includes findings with both a v2 and a v3 score, not only findings scored solely under v3. A few go the other way: a finding whose newest score is lower than its v2 score (or a Qualys finding whose CVSS score is lower than severity × 2) can now miss a threshold it used to meet. The first sync can therefore import and auto-triage many more findings than usual, and open a Jira issue for each new risk when the Jira Extra is configured. Review both thresholds first, and consider turning auto-triage off for that one sync. The details are in The Vulnerability Management Extra. - Incident Management Extra: open the Incidents page and verify the list renders; submit a test incident and verify the workflow works.
- AI Extra: open the chat sidebar and send a test message; verify the response.
- Workflows Extra: trigger an event that should fire a workflow and verify the workflow runs.
- Authentication Extra (SAML/OIDC/LDAP): log out and back in via the configured identity provider; verify the round-trip works.
- Other Extras: walk through the basic operations the Extra adds.
If a test fails, check the SimpleRisk debug log at simplerisk/logs/simplerisk.log (and the Extra's own log if it keeps one, as the Vulnerability Management Extra does for scanner syncs).
5. Handle migration failures
If an Extra's upgrade fails partway through its migration chain, the Extra's {name}_extra_version setting will be at some intermediate value, and subsequent page loads will keep retrying the failed migration (and failing).
Recovery:
- Check the SimpleRisk debug log for the specific error.
- Fix the underlying issue (often a database privilege issue, a constraint conflict, or a missing dependency).
- Re-run the Extra upgrade. It picks up from the
{name}_extra_versionand retries the failed migration.
For migrations that genuinely can't proceed (e.g., a constraint conflict that would lose data), the recovery may require restoring from the backup taken in the Before You Start section.
6. Update operational documentation
After successful upgrade, update any operational runbooks that reference Extra versions or capabilities. New Extras' versions may add features the runbooks should mention; deprecated features may need updating.
Common pitfalls
A handful of patterns recur with Extra upgrades.
-
Assuming Core upgrade upgrades the Extras. This is the single most common surprise. The Core upgrade brings the Extra's application code forward (the new Core release includes the new Extra code under
simplerisk/extras/{name}/), but the per-Extra schema migrations don't run until the Extra upgrade is invoked. After every Core upgrade, walk the activated Extras and run each one's upgrade. -
Letting page-load-driven upgrades happen on the user's first request. When the Extra upgrade runs implicitly on the first post-Core-upgrade page load, the user who happens to land that request waits for the migration to complete before getting their page. For migrations that take seconds, this is fine; for migrations that take minutes, it's a poor user experience. Run the explicit upgrade right after the Core upgrade so the migration completes during the maintenance window rather than during a user's request.
-
Forgetting an Extra exists. Long-running installations accumulate Extras over years; the operator running this quarter's upgrade may not remember every Extra that's active. Always start by listing activated Extras (
SELECT name, value FROM settings WHERE name LIKE 'extra_%' AND value = 'true') so the upgrade pass covers them all. -
Network-dependent Extras failing during upgrade. Some Extras' migrations make outbound API calls (the SCF Extra fetches new framework definitions during upgrade). Network blocks or expired credentials cause these migrations to fail. Verify network connectivity and credential validity before running these specific Extras' upgrades.
-
Skipping the backup before the Extra upgrade. The Core backup before the Core upgrade doesn't reset for the Extra upgrades. If the Core upgrade succeeded but a subsequent Extra upgrade fails badly, restoring from the pre-Core backup undoes the Core upgrade too. Take a fresh backup between the Core upgrade and the Extra upgrades if you want a separate rollback point.
-
Running multiple Extra upgrades concurrently. Each Extra's migration writes to the database. Running multiple Extra upgrades in parallel can produce lock contention or, worse, race conditions in the version-stamp updates. Run Extra upgrades sequentially.
-
Not verifying the new Extra version after the upgrade. A migration that errors silently (the function returned without raising an exception, but didn't actually do its work) leaves the version stamp incremented but the schema in an inconsistent state. Verify each Extra's version stamp matches what the release expected; if it doesn't, investigate the debug log.
-
Treating Extras as one-time installs. Some operators activate an Extra during initial setup and never upgrade it. Years later, the Extra is at the version it was activated at, while Core has moved forward many releases. This produces version-skew problems where the Extra's expected schema doesn't match what Core's queries assume. Upgrade Extras as part of every Core upgrade pass.
-
Activating new Extras in the new release without realizing they're new. Sometimes a SimpleRisk release introduces a new Extra. After upgrading Core, the new Extra appears in the catalog but isn't activated by default. Activating it has its own implications (resource usage, configuration overhead); review the release notes for new Extras and decide whether to activate.