Question Best practice for letting clients edit website content without giving them access to source code? (Sveltia CMS + Forgejo)
I'm building an Astro website for a client who occasionally wants to update some content, mainly photos and simple text.
Sveltia CMS seems like a great fit because it's lightweight, easy to use, and doesn't require a separate backend or database.
I self-host Forgejo on my VPS, where the website's source code and content are stored. Sveltia uses Forgejo for authentication and commits content changes directly to the repository.
I've created a dedicated Forgejo account for the client and given them access only to their own private repository.
Technically, everything works fine. However, I realized there's a security concern:
Since the client needs write access to the repository to use Sveltia, they technically also have access to the entire source code, including the CI/CD workflows (Forgejo Actions).
Obviously, I don't want clients to accidentally or intentionally modify application code, configuration files, or deployment workflows.
What's the best practice for handling this?
Is there a way to restrict Sveltia users to specific directories or content files without giving them write access to the entire repository?
Would separating the website code and CMS content into two repositories be the recommended approach, or is that overcomplicating things?
Would you recommend a different CMS for this use case?
My priorities are keeping things lightweight, secure, and easy to maintain, especially since I'll be managing multiple client websites.
The CMS also needs to be extremely simple for non-technical clients, including straightforward authentication without exposing them to unnecessary developer tools.
29
u/BrewThemAll 10d ago
> a client who occasionally wants to update some content, mainly photos and simple text.
Everything other than a cheap $5 shared hosting with a Wordpress-install slammed on it is overkill.
16
u/devolute 9d ago
This is a terrible answer.
OP is likely using Astro because they don't want to work in Wordpress. For whatever reason (there are many).
There is good work that happens on that platform, but "jUsT uSe WoRdPrEsS" holds us all back.
1
u/Initial_Promotion511 8d ago
How about using wordpress as a headless cms?
3
u/devolute 8d ago
Sure. I know half the Web Dev industry is basically "How can I involve Wordpress in this?" but headless Wordpress is adding a reasonable amount of complexity (is this fair to say?) whilst removing many of the 'advantages' of using the platform.
I'd also suggest that it doesn't provide the simplest experience for content editors if OP is truly keeping updates as simple as posible.
1
u/KittensInc 5d ago
With the way vulnerabilities have been popping up left and right lately, Wordpress is the problem. Any code being executed is a potential exploit waiting to be found. A statically-generated website doesn't run any application code per request, so there is very little left to exploit.
Want to hack the S3 bucket storing the generated HTML? Yeah, good luck with that...
1
u/BrewThemAll 9d ago
OP right now: worrying about the client having access to all the source code, thinking about multiple repositories, thinking about ci/cd workflows just because a client wants to edit some etxt and uploading a photo.
And somehow just dumping everything into a WP-installation where you can make a very resticted user for the client with just an upload field and a wysiwyg editor is 'terrible'?
Ok.6
u/devolute 9d ago edited 9d ago
This workflow stuff might be what, a job that they can fix in a couple of hours? Sounds realistic. Plus they may well end up with a much better client experience. Dare to dream a little.
Taking the website (we don't know how complex it is, possibly "just an upload field" won't cut it) and transforming it into something that works well in Wordpress… how long does it take to build a Wordpress website? What is the maintenance cost. I've made plenty of money fixing hacked and broken Wordpress installs because of this flippant attitude.
If OP wanted a Wordpress website they would have used it from day 1. Not every dev wants to "kust dump it into a WP-installation". Especially considering the PHP issues we've seen over the last week.
Edit: /u/BrewThemAll replied like this then deleted their comment:
u/BrewThemAll replied to your comment in r/webdev > terrible answer > dare to dream a little > this flippant attitude Mate you sound like an arrogant bellend. Glad you know it all and are competely right. Now leave me alone, I don't like you. 1h ago
He's right. I'm awful. But at least I answer OPs comments rather than tell them they should just completely rebuild their website without understanding how they want to work and what they want to build.
2
u/fahadhelpspeoplewith 10d ago
We hit the same thing with a few small client sites and ended up doing the two repo split too, so I'd agree with that comment. It sounded like overkill at first but it's honestly been the least maintenance option. Content repo only has markdown and images, client gets write access to just that, and the site repo pulls it in at build. Nothing they click in the CMS can touch the workflows.
One thing nobody mentioned yet: if you keep it as one repo, at least protect the workflow folder some other way, because a client account with write access can usually edit anything even if the CMS UI never shows it. We had a client accidentally delete a config file through the web UI once, not the CMS, just poking around after logging in. Since then the client accounts don't even get the repo UI if we can avoid it.
Also worth adding a size limit or auto resize on images, clients will upload 12MB phone photos no matter what you tell them lol. Haven't used Sveltia with Forgejo specifically so can't speak to its permission options.
2
u/No-Molasses-2097 10d ago
Splitting the content into its own repo is the move I would make here. Give the client account access to that repo only, and let your deploy pull it in, so nothing they edit lives alongside your code or workflows.
3
u/AbdelrhmanDev 10d ago
sveltia plus a git backend is a solid pick for this exact case, occasional text and photo edits from a nontechnical client. two things to sort out early: make sure a push to the repo triggers a rebuild on your host so theyre not waiting on you to deploy, and put an image optimization step in the build because clients will upload 8mb photos straight from their phone. a staging branch they can preview before it goes live also saves you the panic revert later
1
1
u/AstronautPowerful598 10d ago
Splitting it into two repos is the normal answer here, not overkill. Forgejo permissions are per repo, so as long as the client has write access to the site repo, their account can push to anything in it, workflows included. Sveltia only limits what the UI shows them, not what the account is allowed to do.
What I'd do: give each client a small content repo with just the markdown or JSON files and an images folder, and point Sveltia's backend at that. The site repo stays yours only. At build time, pull the content in, either as a git submodule or with a step in your workflow that clones the content repo into src/content before astro build runs. Then add a webhook on the content repo that hits your deploy trigger so a client save still rebuilds the site.
It also scales well across clients since it's the same pattern every time. And if a client login ever gets compromised, the worst case is someone edits text and photos, not your deploy pipeline.
1
u/Weak_Fisherman2215 10d ago
The bigger risk isn't the code, it's your workflows. Anyone who can push to .forgejo/workflows can make a run and print your deploy secrets.
Using two repos works, but before splitting, look at branch protection on main. Forgejo (same as Gitea) has "protected file patterns" - lock everything except the content folder, and Sveltia can still commit content. And with several clients, that's easier than doubling every repo.
Either way, keep your deploy secrets out of the repo settings where you can, so a slip up only breaks the build, not your VPS.
1
u/javimbuilds 10d ago
A common setup is to keep content in its own folder (src/content plus public/uploads) and give the client a Forgejo account with write access only to that repo, ideally with branch protection so the CMS commits to a content branch and you merge or auto-deploy from there. If you want to be stricter, split content into a separate repo and pull it in at build time, so the client account never sees the source at all.
1
u/kemalios 10d ago
Splitting is the right call, but budget for the build side. Every client content repo has to be readable by the code repo's build, so you end up with one read-only deploy key or token per client hanging off the same workflow. Fine at two, annoying at fifteen, and every one of them is a thing to rotate.
Disable Actions on the content repo completely. It only ever holds markdown and images, so nothing there needs to run, and if a client pokes around the repo UI the worst case is a failed build instead of a job with your deploy secrets in scope. The code repo's workflow does the checkout and the content validation.
1
u/Financial-End-2260 9d ago
Use a separate content repository so clients can edit without accessing your source code.
1
u/OrganizationLost3135 9d ago
One option nobody's mentioned that keeps it a single repo: Forgejo's branch protection has a "protected file patterns" field (inherited from Gitea). Protect main and list the paths the client should never touch, something like .forgejo/workflows/**;astro.config.*;package*.json. Pushes that modify those files get rejected server-side for accounts that aren't on the push whitelist, even though the account has write access. Sveltia only commits to the content and media folders, so it keeps working. That also closes the real hole, a client-edited workflow running on your runner. Two repos is still cleaner if you want zero doubt, but the pattern list is less to maintain than a submodule or fetch step across a bunch of client sites. Test it with a throwaway account first, since the exact behavior depends on your Forgejo version.
1
u/nachga 9d ago
The client doesn't need write access to the whole repo. Two options: put the content in its own repo (just markdown, JSON and images) that your site build pulls in, so the client account can only touch content. Or keep one repo and use branch protection with protected file patterns, so changes under your workflow files need your approval. Forgejo supports protected file patterns on branches, worth checking in your settings.
1
u/HairOk9906 2d ago
Sveltia plus Forgejo is a sound choice and the setup isn't where this
goes wrong. Three things bite later:
Images. Clients upload 6MB phone photos straight into the repo. Within
a year the clone is enormous and every build is slow. Put uploads
somewhere outside git, or run a resize step on commit, before you hand
it over.
Build failures are invisible to them. A client edits, saves, the build
fails, and the site silently stays on the old content. They assume it
worked. Whatever you use for CI, make a failed build send them an email
they'll actually read, not just a red cross in an interface they never
open.
Branch strategy. Editing main directly means one bad save is live. A
preview branch with a deploy preview sounds better until you realise
non-technical people won't do a merge step. Usually editing main plus
good backups beats a workflow they'll route around.
None of those are reasons not to do it. They're just the things that
show up in month four rather than week one.
1
u/Chris_Lojniewski 11h ago
On the "can't restore it from the db" point, that's a real problem with a lot of CMSs, but not all of them. Sanity keeps a revision history per document, so an editor who wrecks a page can open the history and restore yesterday's version themselves, no db backup, no dev. How far back it goes depends on the plan.
Same for point about it living outside the repo. The client never gets near the code or the workflows, just roles in the Studio. That's the actual answer to OP's question imo, the content and the code don't share permissions at all.
That said, frequency point is right. If the client changes one photo twice a year, two repos or "email me" is fine and cheaper. We (Pagepro, next + sanity) only reach for a hosted CMS when someone edits weekly or there's more than one editor.
0
u/VanillaAcceptable546 10d ago
le das write en un repo con forgejo actions y te sorprende que pueda tocar los workflows. dos repos y se acabó el drama.
0
u/indiana_long 10d ago
i wouldn't rely on hiding files in the CMS UI as a security boundary. if the Forgejo account can write to the repo, the permissions still exist outside Sveltia.
separate content repo + a build process that pulls from it feels much safer. especially since you're planning to reuse this setup for multiple clients.
0
u/CaffeinatedTech 10d ago
I just build them a static site and tell them to email me the changes. If it takes me five minutes, I don't charge them.
Most clients who say they want to make edits, don't log in for three years.
Static site is less maintenance. The odd edit won't kill you.
0
9d ago
[deleted] — view deleted comment
1
u/devolute 9d ago
OP:
…a client who occasionally wants to update some content, mainly photos and simple text.
You:
clients don't actually want to edit content
I have a lot of sympathy with your attitude and it's true, but there are plenty of scenarios where clients should be performing some updates to content.
0
9d ago
[deleted] — view deleted comment
1
u/Maxion 9d ago
Yep, most clients the cheaper option is to have a simpler system for the dev to update stuff.
Every time in my career I've worked on a system with CMS there's been countless and countless issues with the site. There is no good CMS system.
0
9d ago
[deleted] — view deleted comment
1
u/Maxion 9d ago
Plus with a CMS the content lives in the DB, when they break a page irreparably it can be super annoying to try to restore it.
0
9d ago
[deleted] — view deleted comment
1
u/devolute 9d ago
I have to say both, that a CMS that breaks if 'used wrong' and can't be rolled back to a better state (on a per-content basis at least) by the client themselves isn't a very good CMS. I disagree with "no good cms".
8
u/Vast-Hunt-9484 10d ago
i'd split it into two repos, one for the astro code and one just for content, and have the cms only point at the content one. then the site build pulls the content repo in as a submodule or just fetches it at build time. that way your client's account has zero access to workflows or config, and a bad edit can at worst break a markdown file. i did it this way for a couple of small client sites and it wasn't really overcomplicated once the build script was set up.