PostgREST
Using KeyHippo with PostgREST for API key authentication
Prerequisite: The KeyHippo extension should be installed in your Supabase database, and PostgREST configured for your project.
Overview
KeyHippo integrates with PostgREST, enabling API key authentication for RESTful API endpoints. This integration allows you to authenticate requests using API keys, while enforcing Row Level Security (RLS) policies in Postgres.
Configuration
When you install KeyHippo, it automatically configures PostgREST to use KeyHippo’s check_request
function for API key validation. Specifically, the role pgrst.db_pre_request
is set to invoke this function before handling requests:
While this setup happens automatically, it can be useful to understand the underlying mechanism. Here’s an outline of the keyhippo.check_request
function:
This function checks for a valid API key in the x-kh-api-key
header and sets the appropriate user context for further request handling.
Example: Protecting Private Functions in RLS Policies
When using PostgREST with KeyHippo, your RLS policies might require anon access to functions that are critical for business logic. Granting direct access to private functions can pose a security risk, but you can avoid this by using public wrapper functions that enforce access control before calling the private function.
Here’s how to handle this securely while keeping sensitive functions protected:
Suppose you have an RLS policy that checks whether a user or API key holder can access certain records using the private.can_access_record
function. To avoid exposing this function directly, you can use a public wrapper to manage access control.
The Issue
If anon doesn’t have access to the private function, PostgREST will return an error when trying to evaluate the policy:
Rather than granting anon or authenticator execute permissions on private.can_access_record
:
You can define a public wrapper function to handle this more securely.
Step 1: Revoke Direct Access to the Private Function
Ensure that anon and authenticator do not have direct access to the private function:
Step 2: Create a Public Wrapper
Define a public function that resolves the user’s identity (either session-based or API key-based) and then calls the private function securely:
This ensures that the private function is only called after proper authentication has been verified.
Step 3: Update the RLS Policy
Update the RLS policy to use the public wrapper function instead of directly calling the private function:
This ensures that all access checks are routed through the public wrapper, which safely handles user authentication.
Benefits
- Security: The private function remains protected and inaccessible to anon users.
- Flexibility: The public wrapper provides a clean interface for RLS policies to check access without exposing sensitive logic.
- Consistency: The same logic applies to both session-based and API key-based authentication.
Performance Considerations
KeyHippo’s PostgREST integration ensures efficient API key validation:
- API key validation does not require additional database queries.
- The
keyhippo.check_request
function runs only for anonymous requests, minimizing overhead for authenticated users.
However, complex RLS policies can affect performance. It’s important to test and optimize your policies for production use, ensuring database indexes are applied to frequently queried columns.
Troubleshooting
Common issues and solutions:
For detailed troubleshooting, refer to the KeyHippo GitHub repository or consult the documentation.
Advanced RLS Techniques
Learn more about creating advanced RLS policies with KeyHippo.