This is somewhat complicated but I have managed to configure this.
In your self reg page, edit the expire_after field and make it hidden and uncheck 'field required'.
Add [Time Source] as an authorization source into your service. We need to create a custom query for this as such.
SELECT
DATE_PART('day', (date_trunc('month', localtimestamp(0)+ interval '1 month') - (localtimestamp(0)::timestamp)::timestamp)) * 24 * 60 +
DATE_PART('hour', (date_trunc('month', localtimestamp(0)+ interval '1 month') - (localtimestamp(0)::timestamp)::timestamp)) * 60 +
DATE_PART('min', (date_trunc('month', localtimestamp(0)+ interval '1 month') - (localtimestamp(0)::timestamp)::timestamp)) AS mins_month
Then in the enforcement profile for Expire Post Login, change the value in there to be the value of that query.
When the user first logs in, that value will get updated for that account.
There may be a +- 1min either side of midnight due to rounding, but that shouldn't be an issue.