Platform 4.0
Platform 4.0 adds the access module to the backend service and carries a round of security fixes across the service, the modules and the CMS. The versions are in Versions below.
Highlights
Section titled “Highlights”- Access module.
entirius-django-accessjoins the service. Staff get roles: the built-in Administrator, Manager, Editor and Viewer, and custom roles made of read and write permissions per module area. A gate in front of the admin API answers a request without the needed permission with 403; it runs inenforceby default and has anobservemode that only logs. Machine clients get application tokens with scopes, an optional channel pin, rotation and an optional expiry, and every change is written to an audit log. The CMS has an Access panel for roles, staff, groups, applications and the audit log, hides the panels a user cannot read and shows a page the user may only read without its writing actions. How it fits together: Access and API Tokens. - One key system. With the access module installed, the storefront, erase, contact form, returns, reviews and vault keys are verified as access tokens. The keys an installation already has are imported as tokens with the same secret, so callers keep working.
- AI toolbox switch.
AI_TOOLBOX_ENABLED = Falseswitches the AI toolbox off on purpose. Nothing fails and nothing alerts: the health check passes with the statedisabled, AI drafts, rewrites and translations answer 503AI_TOOLBOX_DISABLEDbefore anything is written, and the CMS turns its AI actions off with one hint. What runs without the toolbox: AI Toolbox. - Modules without their siblings. No module in the registry of the service (
modules.yaml) forces another one any more. Matrix, QMS, FAQ, delivery points and the shared utilities no longer crash when an optional sibling app is installed but not enabled. - API document. The OpenAPI document and its Swagger and ReDoc pages are served to staff only, unless the
installation sets
API_SCHEMA_PUBLIC = True. Operations that fell back to the default tag carry a named one, paginated lists are generated as list operations, and URL examples useapi.example.com. - Public documentation. This portal is public at
docs.entirius.comfrom this release. It describes the platform version shown in the header, and every later release gets an entry on Release Notes.
Security
Section titled “Security”Backend Service
Section titled “Backend Service”api/token/counts failed logins per username and address, per address and per username. At a limit it answers 429 withRetry-After, also for a correct password.- The Django admin login form counts on the same counters. It accepted unlimited guesses before, also while
api/token/was blocked. - The default authentication of the REST framework is JWT only. It was unset, so a public route that declares no
classes answered differently for a right and a wrong password sent as
Authorization: Basic. The deployment checkvolkanos.E002fails when Basic or session authentication is back in the defaults.
Access Module
Section titled “Access Module”- Setting an expiry on a token that is already expired is refused with 409. A new date used to make it valid again.
- A per-process default cache is the error
django_access.E012undercheck --deploy: with such a cache a revoked grant keeps working in the other workers and the login limits multiply by the worker count. - Creating a staff account answers a taken username and a taken e-mail address with one 409 message that names neither the field nor the account.
Accounts
Section titled “Accounts”- The CMS staff login
customer/tokens/runs the failed-login guard of the access module when it is installed: 429 withRetry-Afterbefore the password is checked. - The signup response no longer echoes the password that was sent. It returned the whole request body.
PATCH customer/<uid>/profile/saves the first name, last name and sex. It answered 200 and stored nothing.customer/tokens/answers 403user_not_customerfor a valid login without a customer profile. It answered 500.
Agreements
Section titled “Agreements”- The public order-agreement write is throttled per address. It had no throttle.
- Where checkout is enabled, the same write needs an order of the URL’s channel whose billing or shipping e-mail is the one sent, and answers 404 otherwise. Any order id and any address were accepted before.
- A second write for the same order records nothing twice. It used to fail with HTTP 500.
- Legal text taken from stored page content is sanitised before it is returned. It was returned as stored, scripts and event handlers included.
- Links in sanitised agreement HTML keep an
hrefonly without a scheme or withhttp,httpsormailto. - The public order-agreement write refuses a
cookiesdefinition with HTTP 400.
Checkout
Section titled “Checkout”- The payment and pay-code throttles count the client, not the reverse proxy, once the number of trusted proxies is set. Behind a proxy the whole shop shared one allowance.
- A PayU method without
second_keyis reported by the system checkdjango_checkout.W001, and a notification refused for that reason is logged once per method.
ContentDB
Section titled “ContentDB”- The router roots of the v1 public and admin APIs ignore credentials. Under the framework defaults they answered
differently for a right and a wrong password sent as
Authorization: Basic. - Page HTML is sanitised on write: creating, updating and publishing a draft keep only the markup the CMS editor writes. Content stored earlier is sanitised the next time it is saved or published.
Delivery Points
Section titled “Delivery Points”point_service.update_pointapplies only the listed point fields and refuses any other keyword. The admin API is unchanged.
Matrix
Section titled “Matrix”- The public v2 views ignore credentials. They evaluated
Authorization: Basicoutside any login throttle in a service that left the framework defaults.
POST /api/munin/v2/health/check/runs live probes and needs the write level ofmunin.config. It was mapped to read. The cachedGET /api/munin/v2/health/stays readable.
Returns
Section titled “Returns”- The return views read the customer’s orders and returns of the URL’s channel only. A token pinned to one channel could read the same customer’s data of another one.
- The returns listing sorts by
created_at,modified_atorstatusonly. The client’s field went to the query unchecked.
Suppliers
Section titled “Suppliers”- Testing a supplier feed needs the write level of
suppliers.sources, and itslimitis capped. A read-only role could fetch a feed with the stored credentials.
verify_captchalogs a warning for each decorated view when the captcha package is installed but not enabled, so an app dropped by mistake is visible.
Admin CMS
Section titled “Admin CMS”- Stored HTML is cleaned where it is rendered: the rich-text previews of the page builder and the legal texts of the Agreements panel.
- The session cookies are set with
SameSite=Strict, and withSecurewhen the CMS is served over https. - A URL from the server reaches a link only as http, https or mailto, and every link that opens a new tab carries
rel="noopener noreferrer". - A production build ships no source maps and fails when
VUE_APP_USERNAMEorVUE_APP_PASSWORDis set. - In debug mode the login call and every access token call are logged as
[redacted]. - The visual and docs capture projects refuse a CMS or API address that is not a loopback host unless
CMS_ALLOW_REMOTE=1is set.
Upgrade
Section titled “Upgrade”This is a major release for three reasons: the keys of the modules are replaced by access tokens, so an integrator creates and manages keys in a new place; the service accepts only JWT by default, no Basic or session login on the API; and the access module is a required dependency of the service. The steps below take a service from 3.x to this release. The general procedure: Versioning and Upgrades.
- Trusted proxies. Set
DRF_NUM_PROXIESin the local settings before upgrading:0without a proxy, otherwise the number of trusted proxies in front of the service. Unset,check --deployfails withvolkanos.E001, and the throttles see the proxy as the one client of the whole shop. Notes: service changelog. - REST framework settings. An environment that replaces
REST_FRAMEWORKas a whole in its local settings keeps theDEFAULT_AUTHENTICATION_CLASSESkey, orcheck --deployfails withvolkanos.E002. - Shared cache. A deploy whose default cache is per-process fails
check --deploywithdjango_access.E012. Set a shared cache. - Access preflight. The access module needs PostgreSQL 15 or later. Before the first deploy, list the admin
routes without an access area (
manage.py access_routes --unmapped); an installation with its own Django apps deploys the first time withACCESS_GATE_MODE = "observe"and switches toenforceonce the log is clean. On first adoption every active staff user who is not a superuser gets the Manager role; access management stays with superusers until someone is granted Administrator, and the Django admin is open to superusers only. Notes: access upgrade notes. - Legacy API keys.
migrateimports the keys of the module key tables andAGREEMENTS_API_KEYas access tokens with the same secret. Check that every key arrived:manage.py access_import_legacy_keys --checkexits 1 while one is missing. The per-module key commands refuse from now on and nameaccess_token create. An imported erase key is pinned to its channel: it erases customers, orders and carts of that channel only. Notes: accounts changelog, checkout changelog. - PayU
second_key. Every PayU payment method (payu,payu_card,payu_blik) needssecond_key, the second key of the POS in the PayU merchant panel, in itsadditional_data. A notification that cannot be verified is answered 403, so a method without the key confirms no payment.manage.py check --database defaultlists the methods that lack it asdjango_checkout.W001. Notes: checkout changelog, section Upgrade notes. - Scripts and roles. A script that sends wrong passwords to
api/token/is answered 429 at the limit. A role with read only loses the supplier feed test and the live configuration-health check, which need the write level. The OpenAPI document needs a staff login unlessAPI_SCHEMA_PUBLIC = True. - CMS build. Remove
VUE_APP_USERNAMEandVUE_APP_PASSWORDfrom the production build environment and keep them in.env.development.local. Serve the CMS over https, or the session cookies are notSecure. Notes: CMS changelog.
Versions
Section titled “Versions”Patch of 2026-10-13. The service pins entirius-django-matrix 4.4.1: products no longer go missing from the
storefront API after a seed or a large import. Two fills of the read model that overlapped on one channel deleted
each other’s rows. An installation that ran the first service version of this release and lists fewer products than
its catalog rebuilds the read model once: Troubleshooting.
| Component | Version | Releases |
|---|---|---|
| Platform | 4.0.1 | entirius-service-volkanos |
| Backend service | 4.0.1 | entirius-service-volkanos |
| Admin CMS | 3.2.0 | entirius-pwa-cms |
| Access module | 1.0.0 | entirius-django-access |
Every other module has the version the lock of the service pins: Module Catalog.