JWT token support for added security

I’m using n8n on Render (free tier) with Supabase for a persistent Postgres Back-end.
I got dozens of security warnings from Supabase that all calls n8n Render were not safe (as RLS was not defined with some form of Authentication (e.g. JWT…).

I believe the easiest would be to use JWT indeed (so that Supabase gives a JWT token to n8n as its first connect, to then use the token in all subsequent calls)

→ How can n8n be configured for this?
IMO the best place would to add this

  • either under every credential ,
  • or (even better) as a global setting.

But I did not see it there, nor at the Nodes itself.

Information on your n8n setup

  • n8n version: → latest
  • Database (default: SQLite): → Postgres on Supabase.
  • Running n8n via (Docker, npm, n8n cloud, desktop app): → Running N8N with Docker on Render.
  • Operating system: → Web based (but running it from a OSX browser)

Can you share some screenshots?

I’ve never seen those warnings and I use Supabase credentials and Postgres credentials with n8n.

Sure - her’s both: the security warning mail I got from Supabase, and a screenshot of a fraction of the 36 warnings (same issue)


I can enable RLS on supabase but that means shutting out n8n unless some Auth is set up. So that’s the essence of my question: what is the best (safest) practice here?

To add some more thinking to this topic:

  • I believe (correct me if I’m wrong) n8n keeps the encryption key local (under .n8n/config) and does NOT store this to the DB ?
  • this key is used to encrypt all credentials & WFs in the DB so without the key it should be safe. Also, the comm between n8n and Postgress (Supabase) is over HTTPS, which avoids man in the middle attacks.

So it’s not totally unsafe.
YET I believe Supabase’s concern is valid as the BE as such remains ‘open’ even if it is encrypted.
To avoid that, RLS can only be added to protect the BE, but that would block n8n out.
It’s why I posted it here: without support from n8n for such vulnerability, this security concern cannot be addressed, I think.

Hey @Wicked_AI_Ware,

RLS (row level security) works like this:

  • For each row in your table you can allow or block certain actions from certain people

Let’s say you put your database into a web project and now hundreds of users can interact with it.

Without RLS the users would be able to make changes to other users’ data.

For example:

  • User A would be able to delete content from User B

To prevent that you enable RLS with certain rules.

But if your database is only required for internal use, sometimes you don’t need RLS at all and can leave it disabled. It’s not recommended for most cases, but it is also not necessary for every situation.

It adds more complexity and sometimes you don’t need it.

So yes, the credentials are safe if you don’t share them. You can keep using your database without RLS if it’s not a public database.

:point_right: Does my reply answer your question? If yes, them please mark it as the solution.

Hi gmsalomao2 (tried to pronounce it… failed miserably!).

The reason this is not a solution is that the essential security threat is missed in this reasoning:

I am NOT afraid “app logic” (your example) would jeopardize data integrity (and if it does through “my app”, that is… on me, obviously!)

The real security threat is this: BECAUSE I cannot set RLS (otherwise I block n8n access), ALSO 3RD PARTIES have access.
So my worry is data compromisation through extra-app access.

Note that, to compromise data integrity, it would suffice for a 3rd party to just scramble the data a bit - not even the requirement to decrypt it. As scrambling would already paralyze my creds & n8n WFs.
(thanks for thinking about it though!)

Enable RLS and use service level API key

I didn’t know you had that complexity going on.

If you are using Service Key in n8n (which is the default) you can still do everything in your database through n8n. Even if RLS is enabled.

Try enabling RLS in one of the tables and see if you can still access the data using n8n (you should be able to).

After testing, enable in every other table.

Let me know if that solves your problem

Hi Daniel/gmsalomao2 - could you drop a few more words on the steps / process to implement this? (the enable RLS part on Supa is clear), but the key part not.

Is what you mean with “Service Level key” have a n8n “API key” generated (n8n Settings / API Key) and then (somewhere @Supa) enter that? (where?)

I saw something under Supa’s Authentication Settings called “Auth Hooks”.
I see an entry there called “Add hook > Customize Access Token (JWT) Claims hook” . Is that what you mean?

I figured out a few things, per your directions, but I’m still left with 2 questions.
I wrote something out for ppl that come after me and have the same issue:
__

Security aspect

Problem:

  • The line between n8n (on e.g. Render) and Supabase is protected (https), and also the data itself (WF & Creds) on Supabase is.
    Yet, without RLS (Row Level Security) enabled on Supabase, the data (WF & creds) integrity can still be damaged by any 3rd party, without even the need to have the encryption key; e.g. by deleting or scrambling data. As it is part of Supa’s public schema.

  • Adding RLS on Supa (protecting the data at its source) would shut n8n out unless also a security key is set to allow n8n access.

How to set this up?

1/ In Supa: under Project —> Settings —> Data API —> copy the API key of the Service role. This role bypasses RLS; Supabase provides two default keys when you create a project: an anon key, and a service_role key. You can find both keys in the API Settings. These 2 keys both map to those Postgres roles.

2/ In the N8N Envir settings: add the service key to the environment variables

—> what is the variable name to use? (could not find it under Database environment variables | n8n Docs)

3/ Enable RLS on all Supa’s tables of the project

For 1 table: > alter table <schema_name>.<table_name> enable row level security;

—> I was wondering, to avoid having to do that for all tables manually: does PostGres (or SQL) accept regex like e.g. > alter table public.x enable row level security; ?

** Test:**
Try to refresh one of the WFs after setting it up and so if that goes fine.

Someone has an idea on the 2 remaining questions?

No one? One of the n8n engineers maybe?
(Have so people ran into a 3rd party attack so far then? )

Has anyone an idea how to solve this issue?
(thanks for the think work below but… I’m still not sure how to do it - cf the questions)