--- title: "1.25.0 — Date of birth is immutable after signup; consumer roles for brand metrics" description: "Two framework changes. `account.User.dob` can no longer be changed by the account holder once a value is stored — on an age-gated deployment that field is the eligibility record, and it was editable at any time after signup. That is breaking for any consumer offering a self-service date-of-birth edi…" date: "2026-09-11" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-25-0/" --- Two framework changes. `account.User.dob` can no longer be changed by the account holder once a value is stored — on an age-gated deployment that field is the eligibility record, and it was editable at any time after signup. That is breaking for any consumer offering a self-service date-of-birth edit, which is why this is a minor. Separately, a deployment whose permission vocabulary has no `view_metrics` can now nominate its own keys as satisfying its own `group-` metrics accounts, without widening the global feed; those settings default to empty, so a deployment that declares nothing sees no change there. ### Breaking - `User.dob` is no longer writable by the account holder once a value is stored. Change, clear (`null` / `""`) and re-set all return `403` on both `POST /api/user/me` and `POST /api/user/`. The admin tier (`users` / `manage_users` / superuser) still corrects it, and setting a date for the first time on a row that has none is unchanged. ### Security - Closes an age-gate bypass: on a deployment that uses `dob` for an age or eligibility decision, the account holder could rewrite it at any point after registration — including after the value had already been asserted to a downstream identity provider. ### Added - `METRICS_GROUP_VIEW_ROLES` and `METRICS_GROUP_WRITE_ROLES` — a deployment may nominate its own permission keys as satisfying reads/writes of its own `group-` metrics accounts. Both default to empty. `global`, `user-`, `public` and custom accounts are untouched, and the always-true membership tokens (`all`, `authenticated`, `member`, `full_member`) and any `sys.`-prefixed key are refused rather than honored. ### Changed - A `dob` write is normalized to a date before the change is recorded, so re-posting the unchanged value is a `200` no-op and no longer resets `is_dob_verified`. - An unparseable or future `dob` is now a `400`. A datetime-shaped string such as `1990-01-01T00:00:00Z` is rejected where the generic date path previously accepted it. - An admin correction of `dob` is logged as `dob:changed` with the before and after values. ### Upgrade notes - If your application offers a self-service date-of-birth edit after signup, that form now fails for non-admin users — move it behind an admin or support flow before upgrading. A client that round-trips the whole user object is unaffected: an unchanged `dob` is still a `200`. - Nothing to configure for metrics. Leave both new settings unset and the permission gates behave exactly as they did in 1.24.27.