It also depends on how far you want to go.
In the wider world Google's Zansibar has become quite popular, which is a general authorization framework. There's also AWS's verified permissions where you can centralize rules about who can "verb" which "noun". Zanzibar has open source implementations, and all the good docs come from Auth0, but it's certainly worth a look.
With regards to authentication I find myself implementing OAuth2 and OIDC on every new project. I just assume that users are coming in with a UUID identifier, and a signed token. I don't care where that token comes from as long as my app has the relevant public/private key to authenticate it.
That means when I'm starting out a new project I can just make broad assumptions that a user will have a JWT/cookie and a UUID, and _how_ the user gets that token down the line is easy for me to handle later. Then you practically get SSO for free. It also makes testing easier, as your app can just assume that any valid token with a "sub" claim (subscriber ID) is a valid user (who likely has no email/profile/given name, etc) so you avoid a lot of boostrapping and factories in tests.
It also means that when I setup a new project I make a `/login` page which just has a list of 3/4 example users and with a click it sets a cookie/jwt and that lets me hope between demo users nice and easily.
I know that's pretty left of field for Rails apps where there's often a "batteries included" way of doing things, but in my experience it all pays off quite quickly.
(this idea was honed over a few years coaching startups in Google's accelerator, we needed to get product demos up and running ASAP and people would always spend a day working on login and lose 20% of the on-site tutoring time during the on-site weeks. This approach gave the folks more time to work on differentiating features, and also created an easy "demo" mode they could show to prospective customers when we sent them out doing user interviews)