Skip to content

Enable secret manager integrations. #13128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jamestalmage
Copy link

@jamestalmage jamestalmage commented Jul 24, 2025

This seperates the logic that scans the environment for secrets from the logic that applies those secrets to the config. This will allow frameworks / plugins to process any secrets found.

As an example, using Cloudflare Secrets Store, a framework implementor could use the collectEnvSecrets function to scan for secrets relevant to the provider (using the same naming convention used for string secrets), and then await the secret.get() callback before calling applyEnvSecrets.

The behavior used by the default implementation setEnvDefaults should be completely unchanged.

☕️ Reasoning

🧢 Checklist

  • Documentation
  • Tests
  • Ready to be merged

🎫 Affected issues

📌 Resources

This seperates the logic that scans the environment for secrets from the logic that applies those secrets to the config. This will allow frameworks / plugins to process any secrets found.

As an example, using [Cloudflare Secrets Store](https://developers.cloudflare.com/secrets-store/), a framework implementor could use the `collectEnvSecrets` function to scan for secrets relevant to the provider (using the same naming convention used for `string` secrets), and then `await` the `secret.get()` callback before calling `applyEnvSecrets`.

The behavior used by the default implementation `setEnvDefaults` should be completely unchanged.
@jamestalmage jamestalmage requested a review from ThangHuuVu as a code owner July 24, 2025 00:36
Copy link

vercel bot commented Jul 24, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
auth-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 24, 2025 0:40am
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
next-auth-docs ⬜️ Ignored (Inspect) Visit Preview Jul 24, 2025 0:40am

Copy link

vercel bot commented Jul 24, 2025

@jamestalmage is attempting to deploy a commit to the authjs Team on Vercel.

A member of the Team first needs to authorize it.

@jamestalmage
Copy link
Author

I think there is an opportunity for an entire new category of secret-manager plugins here.

One potential pitfall: API's like cloudflare's secret manager are async, and the current config initialization code is synchronous... So there would be some significant refactoring required to make it work (and do so without breaking 3rd party integrations expecting it to still be synchronous).

@jamestalmage
Copy link
Author

jamestalmage commented Jul 25, 2025

Copying my comment from the discussion on hono/auth-js where I was explaining intended improvements this will enable:

Auth.js collects a number of different environment variables (up to four per configured OAuth provider). You end up with a list like AUTH_SECRET, AUTH_GITHUB_ID, AUTH_GITHUB_SECRET, AUTH_GOOGLE_SECRET... etc. If you use the specified naming convention, you don't have to manually fetch those values from the environment and inject them into the provider (a nice feature, as it eliminates a bunch of boilerplate). However, when Auth.js finds a value, it simply assumes the value is a string, and injects it without inspecting it or processing it.

Cloudflare allows you to bind more than just strings to the environment. One of the options is secrets. Cloudflare secrets are objects with a secret.get() method that returns Promise<string>. Without a change, using the cloudflare secret store means giving up all of the convenience offered by the Auth.js naming conventions. You have to fetch all those values and inject them manually.

My PR in the Auth.js repo separates the steps of scanning for environment variables and for injecting them into the OAuth provider objects. This would allow implementers of secret-manager plugins to scan the environment easily: They don't have to determine the configured providers, or which variable names to lookup. They just provide the logic to convert the secrets to strings. For cloudflare the check would just be

forEachSecret(secret => {
   if (typeof secret === 'string') {
      return secret;
   }
   if (typeof secret?.get === 'function') {
      return secret.get()
   }
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Refers to `@auth/core`
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant