How to create n8n workflows and run them on behalf of 100s of customers

Description of the problem

I have built an n8n workflow where I manually set up my Google Calendar credentials and use a scheduler to fetch my events daily. The workflow then sends the events to an AI assistant, which generates a voice message summarizing them and delivers it to me via Telegram.

Now, I want to offer this workflow to multiple users via a user interface (outside n8n) where they can connect their Google Calendar and receive personalized voice messages, all without accessing n8n directly.

Here’s the flow I am thinking of:

  1. User authentication: On the client-side, users log in via Google OAuth, which I can handle separately.
  2. Service activation: When a user clicks “Connect Service,” I collect additional required data (e.g., where to send the voice message) and store it in Supabase.
  3. Credential creation: I know that n8n has an API for generating credentials. After a user connects their Google Calendar, I might be able to programmatically create credentials for them, but I’m unsure how this works.
  4. Subscription management: I save user credentials and settings in a subscriptions table in my database.
  5. Workflow execution: When the scheduler triggers, I fetch all subscribed users from my database, dynamically insert their credentials into the Google Calendar node, and continue the workflow—sending messages via Telegram based on user-specific preferences.

Main questions:

  1. Can I provide a “Sign in with Google” window on my client UI that works like an n8n form trigger to create credentials?
  2. If I programmatically create credentials for each customer, will n8n automatically handle access token refreshing?
  3. How should I structure this system to support hundreds of users without manual intervention?
  4. Is it possible to dynamically inject different users’ credentials into the Google Calendar node when executing the workflow?

I would love any insights or best practices from the community on this approach! Thanks in advance.

Information on your n8n setup

  • **n8n version:1.78.1
  • **Database (default: SQLite):SQLite
  • **Running n8n via (Docker, npm, n8n cloud, desktop app):n8n cloud

This sounds like you would need an embed license. The documentation about embed workflow management might give you some insight into how you’d have to manage the authorization and refresh tokens for multiple users too.

1 Like

Thank you for your response, @hubschrauber

At the moment, I’m still exploring n8n primarily for learning purposes and to better understand its capabilities. Before considering an embed license, I’d like to first explore more cost-effective options to see what’s possible within n8n’s existing features.

I came across this section in the documentation:
Expressions in Credentials

It suggests that expressions can be used inside credential fields. However, when I tested the example provided, it seemed like this only allows me to manually enter credentials rather than dynamically injecting them at runtime.

Do you know if there’s a way to fully automate credential assignment per user when executing a workflow?

I think if that gets added as a feature of n8n, it would fall under this feature request, so you might want to use one of your votes on that.

1 Like

BTW, that Expressions in Credentials part of the documentation is a bit confusing because the preview of nodes, in the example workflow, doesn’t show the credential part of the NASA Picture of the Day node at all, and the sticky-note comment only describes part of the actual expression you would need. So, if you try to use that feature, there are a few things to be aware of.

  1. It only works for credentials where all of the values could be typed-in strings (i.e. It does not work with an oauth2 credential that requires a connected user).
  2. The “secret” part of the credential would be exposed in the workflow execution data, which is not friendly or secure for users (and would likely NEVER pass a legitimate security audit).
  3. It does not allow you to dynamically select the Credential item itself.
  4. If you don’t enter an expression just right - e.g. {{ $('API Key Input Source Node').first().json.theApiKeyFieldName }}, things can get frustrating and confusing.
    • For instance, if you accidentally omitted the {{ }} braces, n8n interprets the expression once, stores a string value like __n8n_BLANK_VALUE_e536-... instead of the expression, and switches the field back to Static.
1 Like

Thanks for the clarification!
I understand that passing credentials as plain text fields is not a good idea, especially considering security risks.

However, in my case, I can’t ask the user—who just wants to connect a service—to log in directly through n8n. The best approach would be to create a secure chain, similar to a Form Trigger, but with the ability for the user to authenticate via Google directly within that flow. This way, n8n could generate credentials for the user without them ever accessing the n8n interface.

Even if I manage to authenticate the user on the client side and obtain their access token, which I could later use in an HTTP Request node to call the Google API, it wouldn’t be a great solution. The problem is that I would then need to manually handle token refreshes, and tokens are more likely to expire, causing service failures.

On the other hand, I assume that when using built-in n8n nodes, the connection is maintained automatically, ensuring that credentials don’t expire—at least that’s how I imagine it should work.

So, if I only needed API keys from the user, I could securely pass them to the n8n backend and use the API to create credentials. I would then store only the credential IDs in a database table linked to users who have connected (or subscribed to) a service. This would allow me to dynamically fetch all users who have subscribed to a specific service or workflow and automatically inject their credentials when executing workflows. However, this is currently not possible in n8n.

That all sounds about right according to how I understand the current state of things.

For oauth2 credentials with a “connected” user (done through the n8n ui), n8n seems to do a fairly good job dealing with refresh tokens and renewing the access token when needed.

There are some circumstances (maybe some specific nodes) where it seems like the discovery of an expired token happens too late and the workflow has to be re-run, or the API call has to be retried. I don’t know specific conditions where this happens, but there are some forum posts that would lead me to believe it isn’t always handled in a 100% bulletproof way. However, I sorta doubt there is any oauth2 client out there which handles everything perfectly all the time.

I have been meaning to check out oauth2-proxy to see how it might fit in situations like this. With what I know about it so far, it seems like it could sit between a web-app in an end-user’s browser and one or more API services that it “preflights” to be sure the tokens are all good, and any re-authentication is done. Then, if there were a way to pass just the user-context to an n8n workflow, maybe the same API service(s) could be accessed from n8n, on behalf of that user (without credentials), via the reverse-proxy part of oauth2-proxy (using it more like a forward proxy). I don’t know if any of this would work, but one of these days I’ll probably try it anyway.

1 Like