[GH-ISSUE #4251] updated_at field in OpenID JWT should be a number #9873

Closed
opened 2026-04-13 05:40:11 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @conradev on GitHub (Aug 27, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4251

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Right now, the updated_at field in a better-auth JWT is an ISO date string: eca7fc5ec7/packages/better-auth/src/plugins/oidc-provider/index.ts (L789)

This doesn't match the OpenID spec, which calls for it to be a JSON number. The name updated_at is reserved for OpenID.

I noticed this issue because it caused an error in my JWT client implementation, which I worked around.

Current vs. Expected behavior

I expected the updated_at field to be a number, but it is a string.

What version of Better Auth are you using?

1.3.7

System info

N/A

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)


Additional context

No response

Originally created by @conradev on GitHub (Aug 27, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4251 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Right now, the `updated_at` field in a better-auth JWT is an ISO date string: https://github.com/better-auth/better-auth/blob/eca7fc5ec7f41013c167fa8c79909d27316e5bcc/packages/better-auth/src/plugins/oidc-provider/index.ts#L789 This doesn't match the OpenID spec, which calls for it to be [a JSON number](https://openid.net/specs/openid-connect-core-1_0-final.html#:~:text=updated.-,Its%20value%20is%20a%20JSON%20number%20representing%20the%20number%20of%20seconds%20from%201970%2D01%2D01T0:0:0Z%20as%20measured%20in%20UTC%20until%20the%20date/time.). The name [`updated_at`](https://www.iana.org/assignments/jwt/jwt.xhtml#:~:text=1.0%2C%20Section%205.1]-,updated_at,-Time%20the%20information) is reserved for OpenID. I noticed this issue because it caused an error in my JWT client implementation, which I worked around. ### Current vs. Expected behavior I expected the `updated_at` field to be a number, but it is a string. ### What version of Better Auth are you using? 1.3.7 ### System info ```bash N/A ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript ``` ### Additional context _No response_
GiteaMirror added the lockedbug labels 2026-04-13 05:40:11 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Aug 27, 2025):

Hi @conradev! I'm Dosu and I’m helping the better-auth team.

The OpenID spec requires the updated_at field in JWTs to be a JSON number (seconds since epoch), but Better Auth currently sets it as an ISO date string in the OIDC provider plugin. To fix this, update the code in packages/better-auth/src/plugins/oidc-provider/index.ts from:

updated_at: new Date(user.updatedAt).toISOString(),

to:

updated_at: Math.floor(new Date(user.updatedAt).getTime() / 1000),

This change will make updated_at a numeric Unix timestamp, ensuring OpenID compliance and resolving client errors caused by the string format source.

There are no internal consumers in the codebase that depend on the ISO string format, so this update should not break anything inside Better Auth. After making the change, test your JWTs with your client implementation and any OpenID Connect validation tools to confirm the field is now a number and accepted by compliant clients. If you have integrations or downstream consumers outside Better Auth that expect the old format, you may need to update them to handle the new numeric value.

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

<!-- gh-comment-id:3226721673 --> @dosubot[bot] commented on GitHub (Aug 27, 2025): <!-- Greeting --> Hi @conradev! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> The OpenID spec requires the `updated_at` field in JWTs to be a JSON number (seconds since epoch), but Better Auth currently sets it as an ISO date string in the OIDC provider plugin. To fix this, update the code in `packages/better-auth/src/plugins/oidc-provider/index.ts` from: ```typescript updated_at: new Date(user.updatedAt).toISOString(), ``` to: ```typescript updated_at: Math.floor(new Date(user.updatedAt).getTime() / 1000), ``` This change will make `updated_at` a numeric Unix timestamp, ensuring OpenID compliance and resolving client errors caused by the string format [source](https://github.com/better-auth/better-auth/blob/f978fe9a983c336356364e2392ffcdd99e551b2b/packages/better-auth/src/plugins/oidc-provider/index.ts). There are no internal consumers in the codebase that depend on the ISO string format, so this update should not break anything inside Better Auth. After making the change, test your JWTs with your client implementation and any OpenID Connect validation tools to confirm the field is now a number and accepted by compliant clients. If you have integrations or downstream consumers outside Better Auth that expect the old format, you may need to update them to handle the new numeric value. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/353775f3-94f7-4dc0-9a5b-dfc17199c7c4?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4251)
Author
Owner

@dvanmali commented on GitHub (Aug 29, 2025):

The id_token should not even have an updated_at field in the payload. #4163 has proper fields in ISO sec number format.

<!-- gh-comment-id:3237570719 --> @dvanmali commented on GitHub (Aug 29, 2025): The `id_token` should not even have an `updated_at` field in the payload. #4163 has proper fields in ISO sec number format.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9873