Skip to content

Conversation

Copy link

Copilot AI commented Jan 12, 2026

OAuth access_token and refresh_token values are now encrypted using AES-256-GCM before persisting to the Payload database Users collection. Decryption is automatic on retrieval.

Changes

  • crypto.ts: New module with encryptToken() and decryptToken() using AES-256-GCM

    • Derives 256-bit key from PAYLOAD_SECRET via SHA-256
    • Generates unique random IV per encryption
    • Returns format: iv:authTag:encryptedData (hex-encoded)
    • Backward compatible: returns unencrypted tokens as-is during migration with audit warning
  • configuration.ts: Encrypts tokens in upsertAccount() before database write

  • getAccessToken.ts: Decrypts tokens on read, re-encrypts refreshed tokens before write

  • docs/token-encryption.md: Documents encryption method, security considerations, and migration strategy

Example

Encryption/decryption is transparent to consumers:

// Storing tokens (automatic encryption)
await payloadAuthConfig.persistTokens(user.id, account, payloadConfig)

// Retrieving tokens (automatic decryption)
const token = await getAccessToken(payload, session.user.id)

Security

  • Authenticated encryption prevents tampering
  • Unique IVs prevent pattern analysis
  • Error logging omits sensitive data
  • Requires PAYLOAD_SECRET env var; changing it invalidates existing encrypted tokens
Original prompt

This section details on the original issue you should resolve

<issue_title>Encrypt access and refresh tokens before storing them in the database</issue_title>
<issue_description>in the auth package, we need to encrypt, with reversible encryption, the access and refresh tokens before we store them in the payload account table.
should we use the existing PAYLOAD_SECRET env var as the encryption key?</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits January 12, 2026 10:29
Co-authored-by: rob-at-cortex <50111225+rob-at-cortex@users.noreply.github.com>
…ssues

Co-authored-by: rob-at-cortex <50111225+rob-at-cortex@users.noreply.github.com>
Co-authored-by: rob-at-cortex <50111225+rob-at-cortex@users.noreply.github.com>
Copilot AI changed the title [WIP] Encrypt access and refresh tokens in database Encrypt OAuth tokens before storing in database Jan 12, 2026
Copilot AI requested a review from rob-at-cortex January 12, 2026 10:33
@rob-at-cortex
Copy link
Contributor

rob-at-cortex commented Jan 12, 2026

lets use the user id as part of the encryption key as well @copilot

@rob-at-cortex rob-at-cortex removed their assignment Jan 13, 2026
Copy link
Contributor

@rob-at-cortex rob-at-cortex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add the user id to part of the encryption key as well @copilot

Copy link
Author

Copilot AI commented Jan 13, 2026

@rob-at-cortex Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 03fbdc26-9ed6-47b1-9187-ab1074bb0b9c

Sorry for the inconvenience!

@rob-at-cortex
Copy link
Contributor

lets add the user id to part of the encryption key as well @copilot

Copy link
Author

Copilot AI commented Jan 13, 2026

@rob-at-cortex Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: b62fde91-d2e4-4ff2-a17e-4a155ae59986

Sorry for the inconvenience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Encrypt access and refresh tokens before storing them in the database

2 participants