If you deployed this boilerplate before today, please read the first section. Two of the defaults in this repository were published values, and a fork or an existing deployment does not pick up a fix on its own.
Neither is a new disclosure: both were readable by anyone who opened the source, for as long as they existed. What was missing was the notice telling the people already running them what to do.
Do these three things
1. Rotate your SECRET_KEY. core/settings.py fell back to a key committed to this repository. If you deployed without setting the environment variable, your site is running with a key anyone can read, and with it forge session cookies and password-reset tokens.
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"2. Change the seeded admin password. manage.py seed_data created a superuser whose password was printed in the README, and the deployment section told you to run the command on Heroku.
python manage.py changepassword <the seeded admin email>3. Check DEBUG. It used to default to True. If your environment does not set it explicitly, an older deployment is serving debug pages, which expose settings, environment variables and stack traces to anyone who triggers an error.
See SECURITY.md for the full detail.
Also fixed
The Stripe checkout could not complete. It expanded latest_invoice.payment_intent, a field removed from current API versions, and requirements.txt pinned nothing, so a fresh install brought the SDK that removed it. Three more defects lived in the same path: the view read a legacy stripeToken while the template posted a payment_method_id, stripe.error.SignatureVerificationError does not exist in v15 so a bad webhook signature answered 500 instead of 400, and the renewal date rendered blank.
Paying did not grant access. StripeCustomer.subscription_status was written by the payment flow and read by nothing; every permission check read UserSettings, which that flow never touched. A customer could pay, have Stripe report the subscription active, and stay locked out of what they had just bought. Cancelling had the mirror problem: it flipped a local flag and never called Stripe, so the card kept being charged.
A route granted paid plans for free. A POST to /dashboard/subscription/plans/<slug>/subscribe/ activated any plan with no payment. Free plans only now. The trial was also restartable indefinitely.
Nobody got as far as those bugs. make install created a virtualenv and every other target called a bare python, so five of nine documented commands died on a fresh clone. The README never mentioned python3-venv either, without which make install itself fails on Debian and Ubuntu.
The CSP silently blocked payments. js.stripe.com and hooks.stripe.com were missing, which kills any 3-D Secure challenge with nothing but a console message. In Europe that is most cards. A nonce with no unsafe-inline also meant inline onclick handlers never ran, so "Generate API key" answered 405 and the dismiss buttons did nothing.
Everything is pinned to tested ranges now. 29 → 46 tests.
Upgrading a fork
git remote add upstream https://github.com/eriktaveras/django-saas-boilerplate.git
git fetch upstream
git merge upstream/mainWhat this still does not do
No teams, no per-plan entitlements or usage quotas, no REST API, no Docker or CI. Those are named honestly in the README rather than implied. This is a small, finished starter for a project that does not have customers yet.