Connecting a database securely
Keep your data in Supabase, Neon or another managed database, in the EU, and connect your site to it safely.
Databases6 min read
Where your data should live
ProHostiva runs your website. Your data, such as users, orders or posts, belongs in a managed database service: a company whose job is to run databases, keep them updated and back them up. Your website connects to it through an address and a password that you store on ProHostiva as environment variables.
Not inside the website
- Supabase: a Postgres database with sign-in, file storage and an API your browser code can use. Lovable and Bolt projects usually use it already.
- Neon: a plain Postgres database, for apps with their own server code (Next.js, Node.js, Python, PHP, Rails).
- Any other managed Postgres or MySQL service works the same way: your site connects to it with a URL.
You create the account with the provider and agree to their terms directly, so your data is held under your contract with them. ProHostiva never has a copy of your database.
Pick an EU region
When you create the project, choose a region in the EU, for example Frankfurt (shown as eu-central-1). It keeps your data in the EU, and close to ProHostiva's servers, which makes your site faster. The region can't be changed later: moving means creating a new project and copying the data.
Apps that talk to Supabase from the browser
Most apps built with Lovable, Bolt or v0 call Supabase directly from the visitor's browser. They need two values, which you add under Developer settings → Environment variables and then deploy again:
VITE_SUPABASE_URL: your project's address, from Project Settings → API in Supabase.VITE_SUPABASE_PUBLISHABLE_KEY: the publishable key (it starts withsb_publishable_). Older projects call it the anon key and the code may readVITE_SUPABASE_ANON_KEY; use whichever name your code expects.
These two are meant to be public: they end up in the browser. What protects your data is Row Level Security (RLS), the rules that say which rows each visitor may read or change.
Turn on Row Level Security for every table
In Supabase, open Table Editor, check every table shows RLS as enabled, and add policies that allow only what your app needs. A table without RLS can be read and changed by anyone who has your publishable key, which is everyone who visits your site.
Run the Security Advisor
Advisors → Security Advisor lists tables without RLS and other risky settings. Fix everything it marks as an error before you go live.
Keep the secret key off the website
The secret key (
sb_secret_…, or service_role on older projects) skips every RLS rule. Never give it a name starting withVITE_, never put it in your code, and only use it in server code or Supabase Edge Functions.
VITE_ variable, treat it as leaked: create a new one in Supabase under Settings → API Keys, switch your app to it, then delete the old one.Apps with server code: the connection string
Apps with their own server code connect to Postgres with a connection string, usually read from a variable named DATABASE_URL. It contains the password, so add it as a Secret variable, with a name that does not start with VITE_, NEXT_PUBLIC_, NUXT_PUBLIC_ or PUBLIC_.
Supabase
In your project, open Connect and copy the Session pooler connection string. Use the pooler, not the direct connection: Supabase's direct connections use IPv6 unless you buy their IPv4 add-on, and your site connects over IPv4.
Neon
Open Connect and copy the pooled connection string (its host contains -pooler). Keep the sslmode=require at the end, and add &channel_binding=require if your database library supports it. For database migrations, use the direct (non-pooled) string from your own computer.
For both
- Always use an encrypted connection. Keep
sslmode=require(or stricter) in the URL. Without it, the password and your data could travel unencrypted. - Use a long, generated password and don't reuse it anywhere else.
- Give the app its own database user with only the rights it needs, instead of the owner account. Run the commands below in the provider's SQL editor (with your own names and a generated password), and put that user in the connection string.
CREATE ROLE myapp LOGIN PASSWORD 'a-long-generated-password';
GRANT USAGE ON SCHEMA public TO myapp;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO myapp;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO myapp;For developers
Tables created later need their own grants, or set them up once with ALTER DEFAULT PRIVILEGES. Run migrations as the owner, from your computer or CI, not from the running website.
With Supabase's transaction pooler (port 6543), prepared statements don't work: turn them off in your library. The session pooler (port 5432) doesn't have this limit.
How ProHostiva keeps your keys
- Environment variable values are stored encrypted. Values marked Secret are never shown again, not even to you; to change one, enter a new value.
- Only names starting with
VITE_,NEXT_PUBLIC_,NUXT_PUBLIC_orPUBLIC_are passed to the build, because those end up in the browser. All other variables are only given to your running app and never put in its image. - Each website runs on a private network of its own: other customers' sites can't connect to yours.
- After you change a variable, deploy again so the site picks it up.
Optional: only allow your website's address
Some plans let you accept database connections only from addresses you list: Network Restrictions in Supabase, IP Allow in Neon. It's an extra layer, on top of the encrypted connection and the password, not a replacement.
- Email support@prohostiva.com and we'll tell you the address your website connects from.
- Websites aren't moved between our servers automatically, so the address stays the same. If we ever need to move yours, we'll tell you first, so you can add the new address.
- In Supabase, Network Restrictions protect the database connection only. Browser apps use Supabase's API, which they don't cover: for those, Row Level Security is what matters.
Backups and personal data
- Check your provider's backups. What's included and how far back you can restore depends on your plan; free plans include little or nothing. Find out before you store anything you can't lose.
- Free projects can be paused. Supabase pauses inactive free projects, and Neon's free databases sleep when idle and take a moment to wake up. For a site people depend on, use a paid plan.
- Personal data: if you store your visitors' data, your database provider processes it for you. Read their data processing agreement, and name them in your privacy policy.
Checklist before you go live
- The database is with a managed provider, in an EU region, not inside the website.
- Browser apps: Row Level Security is on for every table, and the Security Advisor shows no errors.
- No secret key or database password is in your code, your repository, a ZIP or a
VITE_-style variable. - Server apps: the connection string is a Secret variable, uses
sslmode=requireand a database user with only the rights it needs. - Backups are on, and you know how to restore one.
Stuck? Email support@prohostiva.com with your website's address and what you're trying to connect, without any passwords or keys.