# Server-Side Supabase Service Role Key Security in Awesome-GPT-Image-2 Repository

> Learn how to secure your Supabase service role key in the Awesome-GPT-Image-2 repository. Keep your key server-side only to prevent client-side exposure and enhance application security.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: security
- Published: 2026-08-31

---

**The Awesome-GPT-Image-2 repository protects the `SUPABASE_SERVICE_ROLE_KEY` by restricting it strictly to server-side environments and never exposing it to client-side code.**

This open-source web gallery project uses the GPT-Image-2 API for AI image generation while implementing defense-in-depth security for its Supabase backend credentials. The service role key—a credential with elevated database privileges—follows a rigorous server-only deployment pattern that prevents credential leakage and unauthorized access.

## What Is the Service Role Key and Why It Needs Protection

The **service role key** is a Supabase JWT that bypasses Row Level Security (RLS) policies, granting full database access. Unlike the anonymous or authenticated client keys, this credential can read, write, and delete any data in the Supabase project.

In the Awesome-GPT-Image-2 architecture, this key enables privileged operations such as:

- Credit balance adjustments per user
- Membership billing state mutations
- Administrative data corrections

Exposing this key to browsers or mobile clients would allow any user to escalate privileges and compromise the entire database.

## Server-Side Only Implementation Pattern

The repository enforces a **strict separation** between client and server code. All files that reference `SUPABASE_SERVICE_ROLE_KEY` live in server-only paths that build tools never bundle for the browser.

### Supabase Helper Module

The centralized database client in [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) reads the key exclusively from `process.env`:

```javascript
// api/_lib/supabase.js
import { createClient } from '@supabase/supabase-js'

// Line 7: Server-only environment variable access
const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY

export const supabase = createClient(
  process.env.VITE_SUPABASE_URL,
  serviceRoleKey
)

```

This module is imported **only by server routes**—never by React components or browser code. The build system treats `api/_lib/` as a server-only boundary.

### Vite Proxy Validation

The local development server at `scripts/vite-local-api.mjs` adds a runtime guard that fails fast if the key is missing:

```javascript
// scripts/vite-local-api.mjs
// Line 27: Environment validation before server starts
if (!process.env.SUPABASE_SERVICE_ROLE_KEY) {
  throw new Error('Missing SUPABASE_SERVICE_ROLE_KEY')
}

// Subsequent proxy setup uses the key for authenticated GPT-Image-2 API calls

```

This validation ensures developers cannot accidentally start the server without proper credentials configured.

## Environment Variable Security Architecture

The project follows platform-native secret management rather than file-based configuration in production.

### Vercel Deployment Pattern

As documented in [`README.md`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/README.md) (lines 318-344), production deployments use Vercel's encrypted environment variable system:

1. **Dashboard configuration** — Secrets are entered through Vercel's UI, not committed to git
2. **Runtime injection** — Values populate `process.env` only on the server compute instances
3. **Zero client exposure** — Build logs and edge functions never receive the raw key

### Local Development Safeguards

The `.env.example` file (line 6) includes an empty placeholder:

```bash
SUPABASE_SERVICE_ROLE_KEY=

```

This pattern reminds developers to:
- Copy the file to `.env.local` (gitignored by default)
- Populate secrets manually from Supabase dashboard
- **Never** hardcode values or commit the local file

## Client-Side Isolation Guarantees

The repository's build architecture provides multiple enforcement layers:

| Layer | Mechanism | File |
|-------|-----------|------|
| Import constraints | Server-only modules tree-shaken from browser bundle | [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) |
| Runtime guards | Explicit `process.env` checks fail in browser context | `scripts/vite-local-api.mjs` |
| Build tooling | Vite server-proxy separation prevents client bundling | [`vite.config.ts`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/vite.config.ts) patterns |
| CI/CD validation | `.env.example` linting ensures no defaults checked in | GitHub Actions workflows |

The **style-library skill** demonstrates this separation clearly. The client-side agent tool at [`agents/skills/gpt-image-2-style-library/SKILL.md`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/agents/skills/gpt-image-2-style-library/SKILL.md) operates entirely on public JSON data from [`data/style-library.json`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/data/style-library.json)—no Supabase credentials required:

```bash

# Client-only installation - zero database access

npm install -g gpt-image-2-style-library
gpt-image-2-style-library install all

```

## Threat Mitigation Summary

The repository's `SUPABASE_SERVICE_ROLE_KEY` handling mitigates these specific attack vectors:

- **Source control leakage** — No production values in repository; placeholder-only `.env.example`
- **Client bundle extraction** — Server-only code paths excluded from browser builds
- **Build-time exposure** — Vercel injects at runtime, not during static generation
- **Developer error** — Runtime validation throws before server accepts traffic

## Summary

- **Server-only scope**: All `SUPABASE_SERVICE_ROLE_KEY` references exist in `api/` and `scripts/` directories that never reach the browser
- **Environment isolation**: Production uses platform secret management (Vercel) rather than file-based configuration
- **Fail-fast validation**: Missing credentials trigger immediate errors at server startup
- **Clear documentation**: [`README.md`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/README.md) and `.env.example` establish security expectations for contributors
- **Functional separation**: Client features like the style-library skill operate without privileged database access

## Frequently Asked Questions

### What happens if SUPABASE_SERVICE_ROLE_KEY leaks to the client?

A leaked service role key grants full database access bypassing all RLS policies. Attackers could read any user's data, modify credit balances, or delete entire tables. The Awesome-GPT-Image-2 repository prevents this through server-only module boundaries and build-time tree shaking that excludes [`api/_lib/supabase.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/supabase.js) from client bundles.

### How does the repository validate the key is server-side only?

The `scripts/vite-local-api.mjs` file contains an explicit check at line 27 that throws if `process.env.SUPABASE_SERVICE_ROLE_KEY` is undefined. Since browser environments lack `process.env` entirely, any accidental client import would fail immediately. Additionally, Vite's architecture treats `api/` routes as server-only endpoints.

### Can I use the style-library skill without Supabase credentials?

Yes. The `gpt-image-2-style-library` command-line tool reads exclusively from [`data/style-library.json`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/data/style-library.json), a public JSON file. No database connection or authentication is required for style installation and local usage. Supabase credentials are only needed for the web gallery's credit and membership features.

### Where should I store SUPABASE_SERVICE_ROLE_KEY in production?

Store it in your hosting platform's encrypted environment variable system. For Vercel deployments, use **Settings → Environment Variables** in the dashboard, marking it for Production/Preview/Development scopes as needed. Never commit the value to `.env.production` or any file tracked by git.