Ghost-CLI
Ghost-CLI copied to clipboard
The `ghost backup` command no longer works
Issue Summary
Impossible to BACKUP (ghost backup) due to 2FA
Steps to Reproduce
ghost backup
Ghost Version
5.118.0
Node.js Version
20.19.0
How did you install Ghost?
self hosting/ Ubuntu 22.xxx
Database type
MySQL 8
Browser & OS version
No response
Relevant log / error output
Response code 403 (Forbidden)
Code of Conduct
- [x] I agree to be friendly and polite to people in this repository
Hmm we’re going to need a solution for this. Thanks for reporting 🙏
Hi team,
I wanted to follow up on the backup issue I reported about 7 days ago. As of now, I haven’t seen any updates or fixes rolled out, and I just want to stress how critical this functionality is.
Backups aren’t just a feature — they’re a safeguard. Without reliable backup support, any unexpected failure, misconfiguration, or even an update gone wrong can result in significant data loss. For those of us running production sites, this poses a serious risk.
I understand things take time, but I’d really appreciate an update on where this stands — even if it’s just acknowledgment or an ETA.
Thanks for your work on Ghost — just hoping this can get the attention it deserves.
Best regards,
Hi team, same here - the validation code shows up in my email and I get the 'Response Code 403 (Forbidden)' message as well. What's worse is after disabling "Require email 2FA codes to be used on all staff logins" and restarting Ghost, I'm still getting the 2FA code in my email when trying to run the backup.
I'm with @yannickcof above - love Ghost and definitely love 2FA.
Thank you all in advance for working on this issue!
I've updated the issue title and moved it to Ghost-CLI, because this problem is specific to the CLI tool. Although there ar related issues to resolve with the API in Ghost itself - the basic problem with ghost-backup mostly needs to be resolved her in Ghost-CLI
There are 2 authentication methods for Ghost's Admin API: session-based user authentication with a username and password, or JWT based auth using either integration tokens or staff tokens.
The ghost backup command is currently using User authentication, taking a username and password, which assumes the user is present. It currently doesn't have a prompt for the auth code, and anyway I'm assuming that the usecase for ghost-backup is something automated, or "off session" as it were, in which case user authentication isn't the right approach.
Essentially, I think the ghost backup command needs updating to use token auth here in Ghost CLI.
However, there is some gotchas to using token auth.
-
Right now, staff tokens don't have enough permissions to do a DB export, and nor do standard integration tokens. However, there is a special internal Ghost Backup integration that does have the right permission to do the DB backup...
-
The special Ghost Backup Integration does have permission to export the DB, but not members, which the
ghost-backupcommand also does.
Getting to a solution:
The main body of the work needed is to update the ghost-backup command to be able to take a token and use that token correctly. Ghost-CLI is usually maintained by the community, so I'd welcome help to resolve this part.
Meanwhile, I will be updating the backup integration to have enough perms, as well as revisiting permissions for staff tokens.
A potential workaround
If all you need right now is a backup of your data, that can be achieved via the API directly, without using the ghost-backup command. I've written a quick version of a script that will trigger a content backup, the same way ghost-backup does:
https://gist.github.com/ErisDS/1cc4d1a55a2f12fe31d86bb6c5d71961
Note: you need to run a query on your DB to get the id and secret from the Ghost Backup Integration.
@ErisDS I don't have context on the initial design decisions when ghost backup was added - is there a reason that credentials are requested [every time]? e.g. why can't the CLI use the backup integration directly, or save credentials?
From my recollection, the Ghost (core) mini-cli, was added after ghost backup. Does it make sense to add a "backup" or "get_backup_token" to the mini-cli, and have ghost backup call out to it for the Ghost versions that implement it?
FYI, there's a hidden config option to disable 2FA for staff; I put the following in my config.*.json:
"security": {
"staffDeviceVerification": false
},
Probably not recommended, but helpful for doing backups until this gets fixed.
Hi team,
I’m writing again to follow up on the Ghost backup issue I originally reported over two weeks ago, and again a week later. Unfortunately, the issue remains unresolved, and there’s been no official update or timeline shared with the community.
Others have echoed the same concerns — receiving 2FA codes even when 2FA is disabled, and being blocked by 403 errors when attempting to back up via the CLI. Community members have also identified the root of the problem: the current ghost backup implementation uses session-based user authentication, which is unsuitable for automated or off-session tasks, and lacks support for token-based authentication that could make this viable. The CLI doesn’t currently prompt for 2FA codes, and the Backup Integration is limited in scope, making it unusable for full exports. I understand priorities exist, but this functionality is foundational and deserves urgent attention.
Thanks again for your hard work — I’m hopeful we’ll see progress on this soon.
Best regards,
Hey @vikaspotluri123 I'm not sure on the original decision either.
I was also thinking it would make sense to have the cli tooling get the ghost backup token directly.
I'm not entirely sure what you mean by the mini-cli? I do agree though, the backup functionality is fairly core. It would make sense to have some way to do this in Ghost itself and then have the CLI use it - this would give those installing via docker a way to do backups as well.
I'm making slow but steady progress on getting the tokens themselves into a better state. Hopefully have that all completed shortly.
@yannickcof there are multiple responses on this thread - kindly read them before posting again. Thanks.
Hi, just wanted to add myself to the list of those waiting for a resolution as I just noticed this bug yesterday and spent time troubleshooting before landing here.
I agree backups are a critical function so hoping for a quick resolution.
Thanks for all your hard work on investigating and working to get this patched. :)
@ErisDS I have read the thread in full — including all current responses — before posting. My intention wasn’t to restate what’s already known, but to emphasize that the issue remains unresolved and continues to affect many users. If there’s been an official fix or definitive update that I’ve missed, I’d genuinely appreciate being pointed in the right direction.
That said, I’m raising this not just on my own behalf, but because a number of community members have reported the same concerns — 2FA prompts when disabled, 403 errors via CLI, and the broader limitations of the current backup system. This impacts automation, production backups, and overall reliability. It’s entirely reasonable to seek clarity on whether a solution is being worked on or planned.
Thanks again to everyone contributing — I hope we can work toward a fix together.
I'm not entirely sure what you mean by the mini-cli?
I'm referring to the different "boot modes" in the entrypoint
In the same vein, is it reasonable for the core to handle making the backup, and having the CLI just ask the core to do it? I remember we discussed this in the 1.0 times and held off since it would be too much coupling. Now that we have the boot mode switch, it feels less coupled 🤔
I've made the necessary changes to Ghost itself, such that the DB Backup Integration is able to do both content and member exports. Administrator level staff tokens can also do the same.
This will be released in Ghost v5.121 tomorrow
Now getting this fixed is a matter of switching the auth modes here in Ghost-CLI. Would love a PR for that.
@vikaspotluri123 I agree that there should be an internal tool in Ghost for reading the token and performing the backups. I'd definitely be happy to work on PRs for that, but I don't think that's necessary to close this issue. This just needs the prompt changing to get a different kind of auth.
Then we can improve it more after if needed.
@ErisDS I've got a draft PR (#1958) but I'm getting a permission error with an Owner access token. I also see the E2E test fail* if it uses an Owner access token (btw, very nice DX on that):
diff --git a/ghost/core/test/e2e-api/admin/backup.test.js b/ghost/core/test/e2e-api/admin/backup.test.js
index 982b4c2d61..a467e3a413 100644
--- a/ghost/core/test/e2e-api/admin/backup.test.js
+++ b/ghost/core/test/e2e-api/admin/backup.test.js
@@ -23,10 +23,10 @@ describe('Backup Integration', function () {
describe('Backup API', function () {
describe('Backup Integration', function () {
before(async function () {
- await agent.useBackupAdminAPIKey();
+ await agent.useStaffTokenForOwner();
});
- it('Can create a DB backup', async function () {
+ it.only('Can create a DB backup', async function () {
await agent
.post('db/backup?filename=test')
.expectStatus(200)
*The CLI uses /db/ which needs db.exportContent while the test uses db.backupContent. I added a breakpoint in can-this, and it looks like apiKeyPermissions don't have any db object_type permissions
FYI, there's a hidden config option to disable 2FA for staff; I put the following in my config.*.json:
"security": { "staffDeviceVerification": false },Probably not recommended, but helpful for doing backups until this gets fixed.
Thank you 😄
Hey @vikaspotluri123 I found the problems with auth and am working on fixing them 😬
Ok as of TryGhost/Ghost#24180, Staff Tokens really should actually have the right permissions 🙈
And as of TryGhost/Ghost#24208, the backup integration will have export as well as backup capabilities.
Both should be in the next release of Ghost
Just curious if there's any timeline on when this might be implemented? Ghost has had a couple of minor updates since this issue was opened, but backup is still broken unless MFA is disabled.
I'm hoping to re-do my smoke tests soon, but no promises 😉
@acburdine This is not fixed for me. Updated and still getting the 403 Forbidden error.
@PXAbstraction this was auto-closed when I merged in the code change that fixes the issue. I haven't actually shipped a new CLI version out yet with the fix in place. Aiming to do that here shortly assuming no other issues arise.
Ahh OK, misread that. Fair enough, thanks. :)
On Mon, Jul 21, 2025 at 12:02 PM Austin Burdine @.***> wrote:
acburdine left a comment (TryGhost/Ghost-CLI#1952) https://github.com/TryGhost/Ghost-CLI/issues/1952#issuecomment-3097355992
@PXAbstraction https://github.com/PXAbstraction this was auto-closed when I merged in the code change that fixes the issue. I haven't actually shipped a new CLI version out yet with the fix in place. Aiming to do that here shortly assuming no other issues arise.
— Reply to this email directly, view it on GitHub https://github.com/TryGhost/Ghost-CLI/issues/1952#issuecomment-3097355992, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE5NORL4NB5KSRMRIE777J33JUFJTAVCNFSM6AAAAAB4HZPIMWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTAOJXGM2TKOJZGI . You are receiving this because you were mentioned.Message ID: @.***>
-- Gerry Corcoran/Parallax Abstraction Ottawa, Ontario, Canada Owner/Tech Ninja of Capital Tech Support http://capitaltechsupport.ca Twitch https://twitch.tv/PXAbstraction | YouTube https://youtube.com/PXAbstraction | Bluesky https://bsky.app/profile/pxa.ca | Discord http://discord.pxa.ca/
Hey everyone, apologies for the delayed fix here. We just shipped Ghost-CLI 1.28.0 that has a fixed ghost backup command when 2FA is enabled.
Assuming you're running Ghost v5.129.0 or later, you should now be able to run ghost backup supplying a staff auth token instead of a username/password combination. In addition, you can specify the auth token via the GHOST_CLI_STAFF_AUTH_TOKEN environment variable to run backups in a non-interactive fashion.
Please let us know if you continue to have issues with ghost backup 😄
@acburdine I still have the same problem! I have upgraded from Ghost Version: 5.101.6 and an older CLI, to the following:
Debug Information:
OS: Ubuntu, v24.04.1 LTS
Node Version: v22.18.0
Ghost Version: 6.0.5
Ghost-CLI Version: 1.28.3
Environment: production
Command: 'ghost backup'
And now ghost backup fails, with ghost log showing the following error
NoPermissionError: You do not have permission to exportContent db
at /var/www/ghost/versions/6.0.5/core/server/services/permissions/can-this.js:107:43
at async nonePublicAuth (/var/www/ghost/versions/6.0.5/core/server/api/endpoints/utils/permissions.js:44:24)
at async sequence (/var/www/ghost/versions/6.0.5/node_modules/@tryghost/promise/lib/sequence.js:16:22)
at async getResponse (/var/www/ghost/versions/6.0.5/node_modules/@tryghost/api-framework/lib/pipeline.js:258:17)
at async ImplWrapper (/var/www/ghost/versions/6.0.5/node_modules/@tryghost/api-framework/lib/pipeline.js:264:30)
at async Http (/var/www/ghost/versions/6.0.5/node_modules/@tryghost/api-framework/lib/http.js:70:28)
[2025-08-25 21:54:11] INFO Worker for job "mentions-email-report" online
[2025-08-25 21:54:11] INFO Worker for job mentions-email-report sent a message: done
[2025-08-25 21:54:14] INFO "GET /rss/" 200 491ms
[2025-08-25 21:54:23] INFO "GET /ghost/api/admin/authentication/setup/" 200 14ms
[2025-08-25 21:54:29] ERROR "GET /ghost/api/admin/db/" 403 41ms
NAME: NoPermissionError
MESSAGE: You do not have permission to exportContent db
It seems the issue persists for some user unless there is some new configuration that I am missing
@acburdine I may be missing something. Here is my command:
# In /var/www/ghost
$ GHOST_CLI_STAFF_AUTH_TOKEN=[the token I obtained in the admin pannel] ghost backup
Message: 'Response code 403 (Forbidden)'
Debug Information:
OS: Ubuntu, v22.04.5 LTS
Node Version: v22.19.0
Ghost Version: 6.0.5
Ghost-CLI Version: 1.28.3
Environment: production
Command: 'ghost backup'
Am I missing anything? This makes future updates quite risky for me.
Hi @ErisDS the issue has been closed but we're still encountering issues :/
It seems that this issue should not be closed.
The proper token needed is not the one obtained by the admin backoffice. It's the one already created in the database. I am not aware how this token was created and from whom. But it was there.
Get the token by performing a query in the database like this:
select * from api_keys
where integration_id in (
select id from integrations where integrations.slug like 'ghost-backup'
);
You can use this token in your ghost backup command and it should work. Of course this should be covered by the CLI, without having to resort to things like this, but at least there's a workaround.
Please note that the following ghost backup may be triggered by a proxy configuration that blocks traffic from your server:
✖ Backing up site
An error occurred.
Message: 'Response code 403 (Forbidden)'
Debug Information:
OS: Ubuntu, v22.04.5 LTS
Node Version: v22.21.1
Ghost Version: 6.1.0
Ghost-CLI Version: 1.28.3
Environment: production
Command: 'ghost backup'
You can check from your ghost server whether this request works or not: curl https://[your-site-url]/ghost/api/admin/authentication/setup should return valid JSON such as {"setup":[{"status":true}]}.
If it does not, you may have a proxy problem, as the ghost installation queries the ghost server from a public internal URL and not an internal one (which is a design problem IMO).
On Cloudflare, you can create a custom security rule set to ignore all WAF rules.
After this change, running GHOST_CLI_S TAFF_AUTH_TOKEN=[TOKEN PROVIDED BY THE USER ADMIN BACKEND UI] ghost backup worked like a charm!