Skip to content

Secrets & Environment Variables

The Secrets screen is where you set the environment variables your app uses. Mosayic distinguishes between two categories:

  • Public env vars — values that ship in your mobile app’s bundle (URLs, public keys). These are stored in your .env files and in EAS build config.
  • Secrets — values that must never be exposed to users (service role keys, API keys for paid services). These are stored in Google Cloud Secret Manager and injected into your deployed API at runtime.

Anything prefixed with EXPO_PUBLIC_ is bundled into your mobile app at build time. These are public by definition — anyone who downloads your app can extract them.

VariableWhat it is
EXPO_PUBLIC_SUPABASE_URLURL of your Supabase project
EXPO_PUBLIC_SUPABASE_PUB_KEYSupabase anon (publishable) key
EXPO_PUBLIC_API_URLYour deployed API URL (set automatically after first prod deploy)

The dashboard maintains the values in two places:

  1. The mobile/.env file on your machine (used during local development)
  2. The eas.json config (used when EAS builds production binaries)

When you change a value via the dashboard, both are updated.

These never end up in mobile code. They live only on the server side.

VariableWhat it is
SUPABASE_SECRET_KEYSupabase service role key — full DB access
DB_CONNECTION_STRINGPostgres connection string for GitHub Actions migrations
(anything else you add)API keys for OpenAI, Stripe, Resend, etc.

For secrets, the dashboard:

  1. Asks you for the value via a password-style input field.

  2. Sends the value through Mosayic’s WebSocket relay to your VS Code extension. The value is never persisted on Mosayic’s servers — it’s a write-through.

  3. The extension runs the appropriate CLI command:

    • For GCP secrets: gcloud secrets create <name> + gcloud secrets versions add <name> --data-file=-
    • For GitHub Actions secrets: gh secret set <name> --body <value>
  4. Mosayic flips a boolean in its database (supabase_secret_is_set, db_connection_string_is_set, etc.) so the dashboard knows the secret exists. The value itself is not stored.

The dashboard never displays a secret value back to you. If you forget what you set, you have to look it up in the source service (Supabase Studio, your password manager, etc.).

When your API is deployed to Cloud Run, the deployment is configured to read secrets from Google Cloud Secret Manager at runtime. Specifically:

  • The Cloud Run service has a secret-mounted environment variable binding for each declared secret
  • On every cold start, Cloud Run fetches the latest secret version from Secret Manager
  • The Compute Engine service account (which Cloud Run uses by default) is granted roles/secretmanager.secretAccessor for each secret

This is set up automatically by Mosayic when you deploy. You don’t need to manually wire IAM permissions.

Some secrets — notably DB_CONNECTION_STRING — are needed by GitHub Actions for the migrations workflow. These are stored as repository secrets on your <project>-api repo and injected into the Action via:

env:
DB_CONNECTION_STRING: ${{ secrets.DB_CONNECTION_STRING }}

The dashboard runs gh secret set from your api/ folder, so secrets land on the right repo automatically.

The Secrets screen has an Add secret button. You give it:

  • A name (uppercase, underscore-separated, e.g. OPENAI_API_KEY)
  • A value
  • A target — Google Secret Manager (for runtime use by your API) or GitHub Actions (for CI/CD use)

After adding, you’ll need to update your API code to read it (os.environ["OPENAI_API_KEY"]) and re-deploy.