firebase setup
Firebase provides Owlette's browser authentication, Firestore control/state database, and Firebase Storage bucket. Cloudflare R2 is configured separately for roost project content; see environment variables for the complete runtime variable list.
step 1: create the firebase project
- Open the Firebase Console.
- Select Add project.
- Name the project, for example
owlette-prodorowlette-dev. - Disable Google Analytics unless you explicitly need it.
- Finish project creation and open Project settings.
Use separate Firebase projects for development, staging, and production.
step 2: create the firestore database
- In the Firebase Console, open Firestore Database.
- Select Create database.
- Choose Start in production mode. The repository rules are deployed in a later step.
- Pick the Firestore location closest to the operators and machines you manage.
- Select Enable.
Do not manually create collections during setup. Owlette creates application documents through the dashboard, API routes, agents, and trusted server code.
step 3: enable authentication
- Open Authentication.
- Select Get started.
- Enable these sign-in providers:
- Email/Password
- Google, if you want Google sign-in in the dashboard
- In Authentication -> Settings -> Authorized domains, add the production dashboard domain and any preview/staging domains that will host the web app.
Passkeys use Firebase custom tokens created by the Owlette server; they do not require a separate Firebase provider toggle.
step 4: enable firebase storage
Firebase Storage is required for full Owlette functionality. The current web and agent flows use it for installer binaries, screenshots, chat images, and user avatars.
- Open Storage.
- Select Get started.
- Start in production mode.
- Keep the default bucket unless you have a deployment-specific reason to use another bucket.
The bucket name becomes NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET. New Firebase projects commonly use <project-id>.firebasestorage.app; older projects may use <project-id>.appspot.com. Copy the exact value from the Firebase web app configuration in the next step.
step 5: create a web app and copy client config
- Open Project settings -> General.
- Under Your apps, select Add app -> Web.
- Register the app, for example
owlette dashboard. - Copy the Firebase config values into the web deployment environment:
NEXT_PUBLIC_FIREBASE_API_KEY=...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.firebasestorage.app
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789012
NEXT_PUBLIC_FIREBASE_APP_ID=1:123456789012:web:abc123These values are public browser configuration. Access control comes from Firebase Auth, Firestore rules, Storage rules, and server-side authorization.
step 6: create service account credentials
Owlette server routes use the Firebase Admin SDK for privileged operations such as verifying sessions, creating agent custom tokens, writing server-only collections, and coordinating Storage uploads.
- Open Project settings -> Service accounts.
- Select Generate new private key.
- Download the JSON file.
- Extract these three fields into separate server-side environment variables:
| JSON field | environment variable |
|---|---|
project_id | FIREBASE_PROJECT_ID |
client_email | FIREBASE_CLIENT_EMAIL |
private_key | FIREBASE_PRIVATE_KEY |
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxxx@your-project-id.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"Keep the service account private
Never commit the downloaded JSON file or the extracted private key. In Railway and similar platforms, wrap FIREBASE_PRIVATE_KEY in double quotes and preserve the \n escape sequences.
Do not set FIREBASE_SERVICE_ACCOUNT_KEY; the current web code reads the split variables above.
step 7: deploy rules and indexes
Run these commands from the repository root so firebase.json can find firestore.rules, firestore.indexes.json, and storage.rules.
npm install -g firebase-tools
firebase login
firebase use --add
firebase deploy --only firestore:rules,firestore:indexes
firebase deploy --only storageChoose the Firebase project created in step 1 when firebase use --add prompts for a project. The deploy uses:
| file | purpose |
|---|---|
firestore.rules | Firestore client access rules |
firestore.indexes.json | Composite indexes for chat, logs, audit logs, and webhook queries |
storage.rules | Firebase Storage access rules |
Indexes are required
Do not skip the firestore:indexes deploy. Features that query conversation history, autonomous events, logs, audit records, or webhooks can fail with a "requires an index" error until the composite indexes are live.
See Firestore Rules for rule architecture and testing guidance.
step 8: deploy the web app with firebase env vars
Add every variable from steps 5 and 6 to the web app's production environment, then deploy the web app. The Firebase setup is not complete until the running web deployment has both:
- the
NEXT_PUBLIC_FIREBASE_*client variables - the
FIREBASE_PROJECT_ID,FIREBASE_CLIENT_EMAIL, andFIREBASE_PRIVATE_KEYserver variables
See environment variables and web deployment for the full production checklist, including session, email, rate-limit, cron, Cortex, and R2 variables.
step 9: bootstrap the first superadmin
New users are created as member with an empty sites array. The first platform operator must be promoted manually after signing in once.
- Open the deployed dashboard.
- Register or sign in with the first operator account.
- In Firebase Console, open Firestore Database -> Data -> users ->
{uid}for that account. - Change
rolefrom"member"to"superadmin". - Save the document, then sign out and sign back in to refresh the dashboard session.
After the first superadmin exists, use Admin Panel -> User Management to promote other users or assign site access.
access model summary
Owlette enforces site-based access through Firestore rules and server-side API authorization.
| role | access |
|---|---|
member | Reads assigned sites listed in users/{uid}.sites[] |
admin | Site-scoped write access for assigned sites |
superadmin | Platform admin access and implicit access to every site |
agent | Custom-token access to one site and one machine |
Client rules name the helpers isSuperadmin(), isSiteAdmin(siteId), canAccessSite(siteId), isServiceAccount(), and agent claim helpers. Trusted server APIs and the Admin SDK handle server-only collections and control-plane writes.
firestore paths used by owlette
This is the operational shape a fresh project should expect after users, sites, and agents start using the system:
sites/{siteId}
sites/{siteId}/machines/{machineId}
sites/{siteId}/machines/{machineId}/commands/{commandDoc}
sites/{siteId}/machines/{machineId}/screenshots/{screenshotId}
sites/{siteId}/machines/{machineId}/installed_software/{softwareId}
sites/{siteId}/machines/{machineId}/hardware/{docId}
sites/{siteId}/machines/{machineId}/metrics_history/{bucketId}
sites/{siteId}/roosts/{roostId}
sites/{siteId}/roosts/{roostId}/target_state/{machineId}
sites/{siteId}/roosts/{roostId}/versions/{versionId}
sites/{siteId}/deployments/{deploymentId}
sites/{siteId}/installer_templates/{templateId}
sites/{siteId}/project_templates/{templateId}
sites/{siteId}/webhooks/{webhookId}
sites/{siteId}/logs/{logId}
sites/{siteId}/audit_log/{entryId}
config/{siteId}/machines/{machineId}
config/{siteId}/schedule_presets/{presetId}
config/{siteId}/reboot_presets/{presetId}
config/{siteId}/project_distribution_presets/{presetId}
users/{uid}
users/{uid}/api_keys/{keyId}
users/{uid}/settings/{settingId}
users/{uid}/devicePrefs/{docId}
chats/{chatId}/messages/{messageId}
system_presets/{presetId}
installer_metadata/{document}
agent_tokens/{tokenId}
agent_refresh_tokens/{tokenHash}
device_codes/{phrase}
api_keys/{keyHash}Server-only paths such as agent_tokens, agent_refresh_tokens, device_codes, top-level api_keys, and most installer upload state are intentionally denied to normal client reads and writes. They are managed through trusted Owlette server routes.
verification checklist
- Email/password login works.
- Google login works if the provider is enabled.
- A signed-in user's
users/{uid}document exists. - The first operator has
role: "superadmin". firebase deploy --only firestore:rules,firestore:indexescompletes successfully.firebase deploy --only storagecompletes successfully.- The web deployment has all
NEXT_PUBLIC_FIREBASE_*and Firebase Admin variables. - The dashboard can create or open a site without Firestore permission errors.
- Installer upload, screenshot capture, chat image upload, and profile photo upload can access Firebase Storage.
troubleshooting
cannot find the rules tab
Create the Firestore database first. The Firestore console shows Data, Rules, Indexes, and Usage only after the database exists.
permission denied in the dashboard
- Confirm the user is signed in.
- Confirm
users/{uid}exists. - Confirm the user's
roleandsitesarray are correct. - Confirm Firestore rules were deployed from
firestore.rules. - Use the Firebase Rules Playground with the same path and auth claims.
admin features fail but the app loads
Check the server-side Firebase Admin variables: FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, and FIREBASE_PRIVATE_KEY. Admin routes can fail even when browser login works, because browser login only proves the NEXT_PUBLIC_FIREBASE_* client variables are present.
storage upload fails
- Confirm Firebase Storage is enabled.
- Confirm
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKETmatches the bucket in Firebase Console. - Confirm
storage.ruleswas deployed withfirebase deploy --only storage. - Confirm the caller has the expected role for the upload path.
self-hosting
owlette is available as a hosted service at owlette.app - no setup required. If you run your own instance, this section covers the Firebase, storage, web runtime, and agent pieces you need to operate the full stack.
firestore security rules
Firestore security rules control who can read and write data. owlette's rules enforce site-scoped access, agent isolation, and role-based permissions.