Logo

dev-resources.site

for different kinds of informations.

Auth in Supabase storage

Published at
1/14/2025
Categories
webdev
javascript
supabase
Author
ajitsinghkaler
Categories
3 categories in total
webdev
open
javascript
open
supabase
open
Author
14 person written this
ajitsinghkaler
open
Auth in Supabase storage

Authentication and Authorization

Now we will go through the authentication and authorization lifecycle. How authorization and authentication work in the storage repository. We will understand the various parts involved in authentication and authorization and how they work together.

Authentication and Authorization Components

The Supabase storage repository employs a combination of JWTs (JSON Web Tokens) and row-level security (RLS) policies to ensure that only authorized users and services can access resources. It uses JWT for authentication and RLS for authorization. Here's a step-by-step breakdown:

  1. Authentication:
  • JWT Acquisition: Clients obtain JWTs through the Supabase Auth service or through the storage service for a signed upload. These JWTs contain claims that specify the user's identity, roles, and permissions. With these JWTs, the client can access the storage service. Sometimes, when signed URLs are generated by the storage service, the JWT also contains the resource to which it has access.
  • Request Headers: Clients making requests to the Storage API include the JWT in the Authorization header, typically using the Bearer <token> format (or via query params for upload signed URLs).
  • JWT Extraction (HTTP Layer):
    * The auth-jwt plugin extracts the JWT from the request's Authorization header or query param.
    * It removes the Bearer prefix if present.
    * The extracted JWT is stored in request.jwt.

    • JWT Verification (Internal Layer):
      • The verifyJWT function from src/internal/auth/jwt.ts is called.
      • It uses the server's JWT secret or JWKS to verify the signature and validity of the JWT.
      • If signature validation fails, a 401 error is returned.
    • Retrieving the Key for Signature Verification:
      • The function getJWTVerificationKey determines which key to use for verification based on the kid on the token or the static secret.
      • If the alg header from the token is using RSA or ECC, the key will be determined using kty and kid, or the static secret will be returned.
      • If there is an issue while extracting the public key from JWKS, the system will fall back to use the configured static key if the algorithm is HS256 or fail.
    • JWT Payload Parsing: If the JWT is valid, the payload is parsed and saved in request.jwtPayload. The role key is assigned to request.jwtPayload.role if available.
    • Request Decoration: If the JWT is valid, the system also sets request.isAuthenticated to true.
      • If an invalid or no JWT is provided but the route has the allowInvalidJwt option, request.jwtPayload and request.isAuthenticated are set to anon and false, respectively.
    • Authorization Through RLS: The RLS will check the authorization on specific database queries as explained in the next section.
  1. Authorization and Row Level Security (RLS):
  • Database Queries: When performing database operations (reading, creating, updating, deleting records), queries go through RLS policies.
    • RLS Policies:
      • RLS policies are defined in the database using PostgreSQL's row-level security mechanism. These policies are configured by using the storage.install_roles flag; the roles that you set when running the migrations are set on the database as well.
      • RLS policies define rules for which users can access which rows of the database. These policies are based on the context of the request, such as auth.uid() (user ID) and auth.role() (user role) claims inside a JWT.
      • For example, a simple policy can be written as USING(owner = auth.uid()), which means only the objects with the same owner can be viewed, modified, or deleted.
    • Dynamic RLS: The system will extract the current authenticated user information from the JWT token and add it to the current database context. The RLS policy will then use these values to validate the user permissions against the database.
    • Enforcement: The database automatically applies the RLS policies on queries and operations to restrict data access.
    • Error Handling: If an RLS policy violation occurs, PostgreSQL returns an error. The application catches this error using the DatabaseError error handler and returns a 403 (Unauthorized) response.
    • Bypass with Service Key: For server operations, the system uses the service key that is generated and passed on the JWT token; this can be used to bypass any RLS rules in the database.
    • Scope Setting: Before each database query, using the TenantConnection.setScope, the system sets the required options to the current_setting, allowing RLS to extract the required information from it.
    • Tracing: If tracing is enabled, a span named knex.query is created using the @opentelemetry/instrumentation-knex, which shows the database query that was performed.
  1. Presigned S3 URLs

    • The presigned S3 URL follows the same flow as a normal GET object request.
    • The URL is signed on the server side to allow access to the protected resources; it is used when uploading files or accessing private files using the S3 protocol.
      • signJWT is used to sign the URL using the server secrets.
    • The authentication process happens using the x-signature header, which has the value of the signed JWT.
      • The verifyObjectSignature will verify if the provided token is valid using the verifyJWT function, and the function will check if the URL on the JWT matches the route.
  2. Admin API Key:

    • Any request to the /admin routes needs to send an apikey in the header to pass the validation; if this header is missing or invalid, the request will be refused.

Role of Schemas in Validation

JSON Schemas are used here to validate the request and response data.

  1. Request Validation:
  • Definition: JSON Schema is used to define the structure and data types of incoming HTTP requests (both params, body, and headers).
    • Enforcement: Fastify uses the ajv library to validate all incoming HTTP requests against the defined schemas before the route handler is called.
    • Error Handling: If a request doesn't conform to the schema, Fastify automatically returns a 400 error with information about the validation failure.
  1. Data Structure:

    • Data Definition: Schemas also help define the properties of the returned objects, which are later used to define interfaces using the json-schema-to-ts library such as Obj, Bucket, UploadMetadata, and more.
  2. Metadata Validation:

    • User metadata is validated as a generic JSONB, so it doesn't have specific validation of its content to avoid having schema errors during the upload, as the content can be anything.

How a request is authenticated and authorized

  1. Client Request: A client attempts to upload a file, create a bucket, download an object, or any other action.
  2. JWT Verification: The server verifies the client's JWT, extracting authentication information.
  3. Schema Validation: The server validates the client's request payload against the API schemas.
  4. Database Interaction: If authentication and validation are successful, a database transaction is created, and the data is sent to the database.
  5. RLS Enforcement: The database applies row-level security policies using data extracted from the JWT, restricting access to resources.
  6. Operation Execution: If authorization is successful, then the operation is executed.
  7. Response Generation: The system returns a response after completing all validation, auth, and permission steps.

Benefits

  • Improved Data Integrity: Schemas enforce consistency and correctness of input data, preventing invalid data from entering the system.
  • Declarative Approach: Using schemas in code makes it easier to see what the expected parameters are for every API call.
  • Developer Experience: The process provides a better developer experience by adding type safety and auto-validation features.
  • Extensible: Since the system only works on two levels—one is JWT and the other is RLS—any system that uses JWT and RLS can be used with the storage repository. So, you only need JWT and Postgres to use the storage repository.

This ends our exploration of the auth/authentication, RLS, and schema workflow. You should now have a clear view of how those pieces play an important role in every request, making the Supabase Storage Engine a reliable and secure system. Let me know if you have more questions or if you want to explore any topic in more detail.

supabase Article's
30 articles in total
Favicon
Building Production-Grade Web Applications with Supabase – Part 1
Favicon
Tracing and Metrics in supabase/storage
Favicon
Understanding Storage backends in supabase/storage
Favicon
Auth in Supabase storage
Favicon
Overview of supabase storage repository
Favicon
Harnessing the Power of Self-Hosted Supabase on Coolify: A Complete Guide to Server Setup and OAuth Providers Integration
Favicon
checa como se hace una conexión entre nextjs y la autenticación de supabase
Favicon
Deploying an Existing Express API + Prisma + Supabase Project to Vercel
Favicon
Custom schema specific Supabase Server Component clients in Grida Form workspace
Favicon
Custom schema specific Supabase Client Component clients in Grida Form workspace
Favicon
Introducing Supabase Client Playground: The Ultimate Tool for Streamlined Query Testing
Favicon
hCaptcha, a bot detection tool, usage in Supabase and Chatwoot
Favicon
Securing Client-Side Routes in Next.js with Supabase
Favicon
How to Transfer PostgreSQL Database from Local to Supabase on macOS
Favicon
Supabase | My Way of Designing & Managing DB
Favicon
What does Supabase use for its Authentication?
Favicon
É seguro guardar dados do usuário no localStorage?
Favicon
Supabase RLS Alternative
Favicon
Build Queue Worker using Supabase Cron, Queue and Edge Function
Favicon
Supabase Just Got More Powerful: Queue, Cron, and Background Tasks in Edge Functions
Favicon
Comparison of the middleware implementation between Supabase Auth documentation and the nextjs-stripe-supabase.
Favicon
How Supabase implemented micro-frontends using Multi Zones in Next.js
Favicon
Unlocking User Data: Building a Secure Supabase Edge Function
Favicon
Usecase: TumbleLog
Favicon
Supabase Edge Functions
Favicon
Setup Astro With Supabase and Prisma
Favicon
We launched SupaCharts! Visualize Beautiful Charts from your Supabase Data.
Favicon
A Free Minimalistic SaaS Starter Kit for Fast MVP Building
Favicon
supabase注册并创建项目和添加数据表
Favicon
Integrating GitHub Authentication with NextAuth.js: A Step-by-Step Guide

Featured ones: