# MastraAuthFirebase Class The `MastraAuthFirebase` class provides authentication for Mastra using Firebase Authentication. It verifies incoming requests using Firebase ID tokens and integrates with the Mastra server using the `auth` option. ## Prerequisites This example uses Firebase Authentication. Make sure to: 1. Create a Firebase project in the [Firebase Console](https://console.firebase.google.com/) 2. Enable Authentication and configure your preferred sign-in methods (Google, Email/Password, etc.) 3. Generate a service account key from Project Settings > Service Accounts 4. Download the service account JSON file ```env FIREBASE_SERVICE_ACCOUNT=/path/to/your/service-account-key.json FIRESTORE_DATABASE_ID=(default) # Alternative environment variable names: # FIREBASE_DATABASE_ID=(default) ``` > **Note:** Store your service account JSON file securely and never commit it to version control. ## Installation Before you can use the `MastraAuthFirebase` class you have to install the `@mastra/auth-firebase` package. ```bash npm install @mastra/auth-firebase@latest ``` ## Usage examples ### Basic usage with environment variables If you set the required environment variables (`FIREBASE_SERVICE_ACCOUNT` and `FIRESTORE_DATABASE_ID`), you can initialize `MastraAuthFirebase` without any constructor arguments. The class will automatically read these environment variables as configuration: ```typescript import { Mastra } from "@mastra/core"; import { MastraAuthFirebase } from "@mastra/auth-firebase"; // Automatically uses FIREBASE_SERVICE_ACCOUNT and FIRESTORE_DATABASE_ID env vars export const mastra = new Mastra({ server: { auth: new MastraAuthFirebase(), }, }); ``` ### Custom configuration ```typescript import { Mastra } from "@mastra/core"; import { MastraAuthFirebase } from "@mastra/auth-firebase"; export const mastra = new Mastra({ server: { auth: new MastraAuthFirebase({ serviceAccount: "/path/to/service-account.json", databaseId: "your-database-id", }), }, }); ``` ## Configuration The `MastraAuthFirebase` class can be configured through constructor options or environment variables. ### Environment Variables - `FIREBASE_SERVICE_ACCOUNT`: Path to Firebase service account JSON file - `FIRESTORE_DATABASE_ID` or `FIREBASE_DATABASE_ID`: Firestore database ID > **Note:** When constructor options are not provided, the class automatically reads these environment variables. This means you can simply call `new MastraAuthFirebase()` without any arguments if your environment variables are properly configured. ### User Authorization By default, `MastraAuthFirebase` uses Firestore to manage user access. It expects a collection named `user_access` with documents keyed by user UIDs. The presence of a document in this collection determines whether a user is authorized. ```typescript user_access/ {user_uid_1}/ // Document exists = user authorized {user_uid_2}/ // Document exists = user authorized ``` To customize user authorization, provide a custom `authorizeUser` function: ```typescript import { MastraAuthFirebase } from "@mastra/auth-firebase"; const firebaseAuth = new MastraAuthFirebase({ authorizeUser: async (user) => { // Custom authorization logic return user.email?.endsWith("@yourcompany.com") || false; }, }); ``` > **Info:** Visit [MastraAuthFirebase](https://mastra.ai/reference/auth/firebase) for all available configuration options. ## Client-side setup When using Firebase auth, you'll need to initialize Firebase on the client side, authenticate users, and retrieve their ID tokens to pass to your Mastra requests. ### Setting up Firebase on the client First, initialize Firebase in your client application: ```typescript import { initializeApp } from "firebase/app"; import { getAuth, GoogleAuthProvider } from "firebase/auth"; const firebaseConfig = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, }; const app = initializeApp(firebaseConfig); export const auth = getAuth(app); export const googleProvider = new GoogleAuthProvider(); ``` ### Authenticating users and retrieving tokens Use Firebase authentication to sign in users and retrieve their ID tokens: ```typescript import { signInWithPopup, signOut, User } from "firebase/auth"; import { auth, googleProvider } from "./firebase"; export const signInWithGoogle = async () => { try { const result = await signInWithPopup(auth, googleProvider); return result.user; } catch (error) { console.error("Error signing in:", error); throw error; } }; export const getIdToken = async (user: User) => { try { const idToken = await user.getIdToken(); return idToken; } catch (error) { console.error("Error getting ID token:", error); throw error; } }; export const signOutUser = async () => { try { await signOut(auth); } catch (error) { console.error("Error signing out:", error); throw error; } }; ``` > **Note:** Refer to the [Firebase documentation](https://firebase.google.com/docs/auth) for other authentication methods like email/password, phone authentication, and more. ## Configuring `MastraClient` When `auth` is enabled, all requests made with `MastraClient` must include a valid Firebase ID token in the `Authorization` header: ```typescript import { MastraClient } from "@mastra/client-js"; export const createMastraClient = (idToken: string) => { return new MastraClient({ baseUrl: "https://", headers: { Authorization: `Bearer ${idToken}`, }, }); }; ``` > **Info:** The ID token must be prefixed with `Bearer` in the Authorization header. > > Visit [Mastra Client SDK](https://mastra.ai/docs/server/mastra-client) for more configuration options. ### Making authenticated requests Once `MastraClient` is configured with the Firebase ID token, you can send authenticated requests: **React**: ```tsx "use client"; import { useAuthState } from 'react-firebase-hooks/auth'; import { MastraClient } from "@mastra/client-js"; import { auth } from '../lib/firebase'; import { getIdToken } from '../lib/auth'; export const TestAgent = () => { const [user] = useAuthState(auth); async function handleClick() { if (!user) return; const token = await getIdToken(user); const client = createMastraClient(token); const weatherAgent = client.getAgent("weatherAgent"); const response = await weatherAgent.generate("What's the weather like in New York"); console.log({ response }); } return ( ); }; ``` **Node.js**: ```typescript const express = require('express'); const admin = require('firebase-admin'); const { MastraClient } = require('@mastra/client-js'); // Initialize Firebase Admin admin.initializeApp({ credential: admin.credential.cert({ // Your service account credentials }) }); const app = express(); app.use(express.json()); app.post('/generate', async (req, res) => { try { const { idToken } = req.body; // Verify the token await admin.auth().verifyIdToken(idToken); const mastra = new MastraClient({ baseUrl: "http://localhost:4111", headers: { Authorization: `Bearer ${idToken}` } }); const weatherAgent = mastra.getAgent("weatherAgent"); const response = await weatherAgent.generate("What's the weather like in Nairobi"); res.json({ response: response.text }); } catch (error) { res.status(401).json({ error: 'Unauthorized' }); } }); ``` **cURL**: ```bash curl -X POST http://localhost:4111/api/agents/weatherAgent/generate \ -H "Content-Type: application/json" \ -H "Authorization: Bearer " \ -d '{ "messages": "Weather in London" }' ```