Preparations
Huawei Cloud RDS Supabase provides four out-of-the-box capabilities: database, user authentication, file storage, and real-time subscriptions. These capabilities can be integrated directly as the backend foundation for systems or applications, eliminating the need to build backend services yourself. Before using these capabilities, complete the integration preparations to access the platform's services quickly, efficiently, and securely through APIs or SDKs.
Step 1: Obtain the Access URL
The application service port for RDS Supabase is fixed at 8443. All SDK and REST API requests are sent through this port. Depending on the client's network environment, there are three access methods, each with a different URL.
| Access Method | Scenarios | Access URL |
|---|---|---|
| Private network access | The client and application are in the same VPC and subnet, with network connectivity between them. | http(s)://{Application_private_IP}:8443 |
| Public network access (DNAT gateway) | Multiple instances share a public IP address and port mapping is required. | http(s)://{DNAT_public_IP}:{Public_port} |
| Public network access (EIP) | An independent public IP address is bound to the application. | http (s)://{EIP}:8443 |
- Private Network Access
Use the application's private IP address directly. This method is suitable for clients that are in the same VPC and subnet as the Supabase application and have network connectivity to it.
- An IPv4 private IP address is automatically assigned when the application is created and cannot be changed afterward.
- The client must be able to reach the application's private IP address over the network. Using the same VPC and subnet is recommended.
- Public Network Access (DNAT Gateway)
Use a public NAT gateway and a DNAT rule to map a specified port on a public IP address to port 8443 of the application on the private network. This method is suitable when multiple instances share a public IP address and port mapping is required.
- Purchase a public NAT gateway and an EIP first, associate them with the VPC and subnet where the application resides, and configure a DNAT rule that maps to the application's private IP address.
- The public port is determined by the DNAT rule and can differ from 8443.
- The NAT gateway and EIP are billed separately.
- For binding and unbinding instructions, see Binding and Unbinding a DNAT Gateway Address.
- Email and GitHub authentication are not supported with this access method. For details, see Configuring and Managing User Authentication (Auth).
- Public Network Access (EIP)
Bind an EIP directly to the application. Clients can access the application through the EIP on port 8443. This method is suitable when an independent public endpoint is required and port mapping is unnecessary.
- Bind an EIP to the application first.
- For binding and unbinding instructions, see Binding and Unbinding an EIP.
- This method is required for email authentication over the public network and GitHub authentication. For details, see Configuring and Managing User Authentication (Auth).
- Security Group Configuration
Regardless of the public access method, ensure that the security group associated with the application allows inbound TCP traffic on port 8443. Otherwise, public requests will be blocked.
- Each application supports only one security group. Plan the rules accordingly.
- For details about how to create security groups and manage their rules, see Managing the Security Group of an Application.
- SSL and HTTPS
SSL is optional and disabled by default. To access the application over HTTPS (https://):
- SSL certificates are provided by Huawei Cloud Cloud Certificate & Manager (CCM) and must be purchased separately.
- On the application details page, enable SSL in the Network Info area and select a certificate. The address prefix changes from http:// to https://.
- For details about how to enable or disable SSL, see Enabling or Disabling SSL.
If an EIP is used for user authentication, such as email authentication, GitHub authentication callbacks, or references in email templates, do not unbind it directly. First, disable the relevant features in the user authentication configuration and confirm that the EIP is no longer referenced. Otherwise, authentication callback URLs will become invalid and interrupt workloads. For details, see Configuring and Managing User Authentication (Auth).
Step 2: Obtain an API Key
Obtain an API key by referring to Viewing API Keys. Huawei Cloud RDS Supabase provides four types of API keys. Choose one based on your use case.
| Key Type | Prefix | Permissions | Use Case | Browser Security |
|---|---|---|---|---|
| Publishable Key | sb_publishable_xxx | Low privilege (subject to RLS) | Client-side JavaScript SDK and REST API | ✅ Safe to include in source code delivered to clients, as access remains subject to RLS. Disclosure does not grant additional privileges. |
| Secret Key | sb_secret_xxx | High privilege (BYPASSRLS) | Server-side JavaScript SDK (Node.js) | ❌ Returns error 401 when used in a browser; server-side use only. |
| Anon Key | JWT format | Low privilege | Legacy format of the Publishable Key | ✅ |
| Service Role Key | JWT format | High privilege (BYPASSRLS) | Legacy format of the Secret Key | ❌ Server-side use only. |
Integration generally requires only two keys: Use a Publishable Key for clients (browsers and mobile devices) and a Secret Key for the server (Node.js). Anon Keys and Service Role Keys are legacy formats with functionality equivalent to that of Publishable Keys and Secret Keys, respectively. Existing projects can continue using them.
Row-level security (RLS) is a database mechanism that controls access on a row-by-row basis. It determines which rows a key can read or modify. BYPASSRLS bypasses these row-level controls and grants full data access. For more information, see Follow-up Operations.
Security notice: Secret Keys and Service Role Keys have elevated privileges that bypass RLS. They must be used only on the server and must never be included in frontend code or exposed to browsers. For the mapping between keys and database roles, see Follow-up Operations.
Step 3: Integrate Features
This section uses JavaScript as an example. The SDK approach uses @supabase/supabase-js to encapsulate calls and automatically handles authentication and request details, making it suitable for most scenarios. For other languages, see the open-source Supabase documentation.
Initializing the SDK
Install the SDK dependency package:
npm install @supabase/supabase-js
Create a Supabase client object:
// {Supabase_application_URL} and {Supabase_application_API_key} are placeholders. Replace them with the actual values obtained in Step 1: Obtain the Access URL and Step 2: Obtain an API Key, respectively.
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = "{Supabase_application_URL}";
const supabaseApiKey = "{Supabase_application_API_key}"
export const supabase = createClient(supabaseUrl, supabaseApiKey) Calling the SDK
The following examples read from and write to the products table. Create this table as described in 1 and configure the required GRANT permissions and RLS policies first. Otherwise, queries may return empty results and write operations may be rejected.
Client-side JavaScript SDK (Browser)
This approach is suitable for clients running on user devices, such as browsers and mobile devices. Because the code is delivered with the application and the key can be extracted, use a browser-safe Publishable Key (sb_publishable_xxx). The key is subject to RLS and can operate only on rows permitted by the applicable policies. Disclosure does not grant additional privileges. Run queries and other operations through the initialized supabase instance:
const { data } = await supabase.from('products').select('*') Initialize the instance once and reuse it globally. The Publishable Key can securely be included in client-side source code. Cross-origin requests from browsers are subject to CORS restrictions. If the frontend domain and the Supabase access URL have different origins, requests will be blocked. Ensure that the frontend domain is allowed by the instance.
Server-side JavaScript SDK (Node.js)
This approach is suitable for trusted backends, such as servers, cloud functions, and serverless environments, where the key remains on the server and is not exposed to users. These scenarios often require privileged operations, such as data migration and batch processing. Therefore, enter the server-side-only Secret Key (sb_secret_xxx) in the API Key field. This key has BYPASSRLS privileges and full data access. Never expose it to clients. Run queries and other operations through the initialized supabase instance:
const { data } = await supabase.from('products').select('*') The legacy Service Role Key (JWT format) is functionally equivalent to the Secret Key and is used in the same way. Initialize the instance once and reuse it. This approach is suitable for write operations that are not subject to row-level security (RLS) restrictions, such as background tasks and scheduled synchronization. Do not use it in APIs that respond directly to end users.
The API approach calls the Data API directly over HTTP without introducing an SDK dependency. It is suitable for environments where adding dependencies is inconvenient. Both approaches access the same Data API and provide equivalent capabilities.
REST API (fetch)
This approach is suitable when you want to call the Data API directly over HTTP without using an SDK. You must manually add the key that the SDK would otherwise attach automatically. Include both the apikey and Authorization headers:
const res = await fetch('{Supabase_application_URL}/rest/v1/products', {
headers: {
apikey: 'sb_publishable_xxxx_xx',
Authorization: 'Bearer sb_publishable_xxxx_xx'
}
})
const data = await res.json() Note: Both apikey and Authorization are required. The URL follows the format {Supabase_application_URL}/rest/v1/{Table_name}. The response is returned in JSON, and API parameters follow the PostgREST conventions. A non-2xx response usually indicates an invalid key or an RLS policy that does not permit the operation. Check res.ok and troubleshoot based on the status code.
Follow-up Operations
After integration, client access to data is subject to RLS. RLS determines which rows a key and a user's authentication state can read or modify, making it a core mechanism for data isolation. This section explains how API keys relate to access results. For details on configuring RLS policies, see Database Data APIs.
- RLS
RLS consists of two layers of protection, both of which are required.
Table 3 Two layers of RLS protection Layer
Mechanism
Function
Analogy
First layer
GRANT permissions
Table-level access control that determines whether a role can perform SELECT, INSERT, UPDATE, or DELETE operations
Room access control
Second layer
RLS policies
Row-level filtering that determines which rows each role can access
Drawers that can be opened within the access-controlled area
- RLS enabled without GRANT permissions: The role cannot access the table, so the RLS policies have no effect.
- GRANT without RLS policies: All rows are accessible to the authorized role, meaning that there is no row-level protection.
- Key-to-Role Mapping
An API key does not read or write data directly. Actual operations are performed by the database role mapped to the key. The role depends on both the key type and the authentication status, as shown below.
Table 4 Key-to-role mapping Key + Authentication Status
Mapped Role
Description
Publishable Key + Unauthenticated
anon
Anonymous access; allowed to operate only on rows permitted by RLS policies.
Publishable Key + Authenticated
authenticated
Authenticated access; subject to RLS policies.
Secret Key / Service Role Key
BYPASSRLS
Bypasses all row-level security policies and provides full data access.
Reference
The following open-source Supabase documents are provided for reference only.
What is your overall rating for this page?
Thank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot