S
Supabase•2mo ago
Faiz Khatri

Getting 403 even if policy allow read access to all users

I have created a profiles table that stores details of authenticated users. I have got this Idea from the documentation. I'm using supabase for the first time. I have setup the policy of this table to "allow access to all users to read profiles." Still when I'm trying to make a query to the database, it returns the following error:
{
error: {
code: '42501',
details: null,
hint: null,
message: 'permission denied for table profiles'
},
data: null,
count: null,
status: 403,
statusText: 'Forbidden'
}
{
error: {
code: '42501',
details: null,
hint: null,
message: 'permission denied for table profiles'
},
data: null,
count: null,
status: 403,
statusText: 'Forbidden'
}
I'm using Next js with supabase. I don't have clue of what is wrong here. Here's the log of API request if it helps:
19 Replies
garyaustin
garyaustin•2mo ago
What call are you making that gets this? If this is an auth trigger function getting the error you likely did not make the function security definer so it does not have access to public tables.
Faiz Khatri
Faiz KhatriOP•2mo ago
Here's the code:
import { redirect } from "next/navigation";
import { createClient } from "@/lib/supabase/server";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";

export default async function ProtectedPage() {
const supabase = await createClient();

const { data, error } = await supabase.auth.getClaims();
if (error || !data?.claims) {
redirect("/auth/login");
}

const totalUsers = await supabase.from("profiles").select("*");
console.log(totalUsers);

return (
<div className="grid grid-cols-4 p-5">
<Card className="@container/card">
<CardHeader>
<CardTitle>Total Users</CardTitle>
<CardDescription>
This is the number of users Active on the platform
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-5xl font-bold">100</p>
</CardContent>
</Card>
</div>
);
}
import { redirect } from "next/navigation";
import { createClient } from "@/lib/supabase/server";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";

export default async function ProtectedPage() {
const supabase = await createClient();

const { data, error } = await supabase.auth.getClaims();
if (error || !data?.claims) {
redirect("/auth/login");
}

const totalUsers = await supabase.from("profiles").select("*");
console.log(totalUsers);

return (
<div className="grid grid-cols-4 p-5">
<Card className="@container/card">
<CardHeader>
<CardTitle>Total Users</CardTitle>
<CardDescription>
This is the number of users Active on the platform
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-5xl font-bold">100</p>
</CardContent>
</Card>
</div>
);
}
It's a server component in Next JS. The user is authenticated and I'm able to access the claims on the server side. I have the following policies setup on the profiles table:
Faiz Khatri
Faiz KhatriOP•2mo ago
No description
Faiz Khatri
Faiz KhatriOP•2mo ago
No description
garyaustin
garyaustin•2mo ago
Did you by any chance remove grants to authenticated as part of setting up an auth hook? Is that why you have supabase_auth_admin having access?
Faiz Khatri
Faiz KhatriOP•2mo ago
I'm not sure. How can i check? I have followed documentation to do all this. I'm able to understand something and somthings are bouncing from above my head 😅 . trying to make it woek
garyaustin
garyaustin•2mo ago
Your error is not RLS. IF you are getting that error on the select you show. RLS is silent and just returns no data. Your error is you don't have grants on the table. Do you set your own claims in the JWT?
Faiz Khatri
Faiz KhatriOP•2mo ago
yes I did I have setup user_roles claim in JWT using custom jwt hook
garyaustin
garyaustin•2mo ago
And it is coming from profiles?
Faiz Khatri
Faiz KhatriOP•2mo ago
yes
garyaustin
garyaustin•2mo ago
So if you look thru that code it assumes anon/authenticated should NOT access the table they are using. But they don't have it with normal profile data. In your case you can't change the grant to remove authenticated or then you can't access from the API.
garyaustin
garyaustin•2mo ago
No description
garyaustin
garyaustin•2mo ago
So you would need to grant all back to authenticated if you want to share the profile table with the RBAC code. BUT you don't want authenticated to be able to write or update it as they could then change their own role. That could be handled with RLS. I recommend you have a separate role table from your profile table.
Faiz Khatri
Faiz KhatriOP•2mo ago
hmm. It makes sense. Thank you for the explaination. How do I change the grant permission? SQL Editor will work?
garyaustin
garyaustin•2mo ago
You change the grant all in the code above so it is to authenticated and make sure you use table profiles Yes SQL editor.
Faiz Khatri
Faiz KhatriOP•2mo ago
Okay. Thanks for the help. I will try it.
garyaustin
garyaustin•2mo ago
I'm out for the night. Good luck.
Faiz Khatri
Faiz KhatriOP•2mo ago
It worked 🎊 Thank you @garyaustin 🙌

Did you find this page helpful?