> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Co-exist with Firebase

Learn how to integrate Scalekit with Firebase for enterprise SSO, using either Firebase's OIDC provider or direct SSO with custom tokens.
This guide explains how to integrate Scalekit with Firebase applications for enterprise Single Sign-On (SSO) authentication. You'll learn two distinct approaches based on your Firebase Authentication setup.

> Image: Scalekit - Firebase Integration

## Before you begin

Review your Firebase Authentication setup to determine which integration approach suits your application:

- **Option 1**: Requires Firebase Authentication with Identity Platform (paid tier)
- **Option 2**: Works with Legacy Firebase Authentication (free tier)

You also need:
- Access to a [Scalekit account](https://app.scalekit.com)
- Firebase project with Authentication enabled
- Basic understanding of [Firebase Admin SDK](https://firebase.google.com/docs/reference/admin) (for Option 2)

Checkout our [Firebase integration example](https://github.com/scalekit-inc/scalekit-firebase-sso) for a complete implementation.

## Option 1: Configure Scalekit as an OIDC Provider

Use this approach if you have **Firebase Authentication with Identity Platform**. Firebase acts as an OpenID Connect (OIDC) relying party that integrates directly with Scalekit.

> note
>
> OpenID Connect providers are not available in Legacy Firebase Authentication. See the [Firebase product comparison](https://cloud.google.com/identity-platform/docs/product-comparison) for details.

```d2 layout=elk
direction: right

User: "User"
FirebaseOIDC: "Firebase OIDC"
Scalekit: "Scalekit"
IdentityProvider: "Identity Provider"
YourApp: "Your App"

User -> FirebaseOIDC
FirebaseOIDC -> Scalekit
Scalekit -> IdentityProvider
IdentityProvider -> Scalekit
Scalekit -> FirebaseOIDC
FirebaseOIDC -> YourApp
```

Firebase handles the OAuth 2.0 flow automatically using its built-in OIDC provider support.

1. #### Configure Firebase to accept Scalekit as an identity provider

   Log in to the [Firebase Console](https://console.firebase.google.com/) and navigate to your project.

   - Go to **Authentication** > **Sign-in method**
   - Click **Add new provider** and select **OpenID Connect**
   - Set the **Name** to "Scalekit"
   - Choose **Code flow** for the **Grant Type**

   > Image: Sign-in tab in your Firebase Console

2. #### Copy your Scalekit API credentials

   In your Scalekit Dashboard, navigate to **Settings** > **API Config** and copy these values:

   - **Client ID**: Your Scalekit application identifier
   - **Environment URL**: Your Scalekit environment (e.g., `https://your-subdomain.scalekit.dev`)
   - **Client Secret**: Generate a new secret if needed

   > Image: Scalekit API Configuration

3. #### Connect Firebase to Scalekit using your API credentials

   In Firebase Console, paste the Scalekit values into the corresponding fields:

   - **Client ID**: Paste your Scalekit Client ID
   - **Issuer URL**: Paste your Scalekit Environment URL
   - **Client Secret**: Paste your Scalekit Client Secret

   > Image: Firebase OIDC Provider Configuration

4. #### Allow Firebase to redirect users back to your app

   Copy the **Callback URL** from your Firebase OIDC Integration settings.

   > Image: Firebase Callback URL

   Add this URL as a **Allowed Callback URI** in your Scalekit Authentication > Redirects section.

   > Image: Scalekit Redirect URI Configuration

5. #### Configure allowed callback URIs in Scalekit

   In your Scalekit Dashboard, navigate to **Authentication** > **Redirects** > **Allowed Callback URIs**.

   Add your Firebase callback URL to the allowed callback URIs list:

   - **For development**: `https://your-firebase-domain.com/__/auth/handler`
   - **For production**: `https://your-domain.com/__/auth/handler`

   > note
>
> Firebase automatically generates the callback URL format. Make sure to use the exact URL provided by Firebase in your OIDC provider configuration.

6. #### Add SSO login to your frontend code

   Use Firebase's standard OIDC authentication in your frontend:

   ```javascript title="Login Implementation"
   import { getAuth, OAuthProvider, signInWithPopup } from 'firebase/auth';

   const auth = getAuth();

   // Initialize Scalekit as an OIDC provider
   const scalekitProvider = new OAuthProvider('oidc.scalekit');

   // Set SSO parameters
   scalekitProvider.setCustomParameters({
     domain: 'customer@company.com', // or organization_id, connection_id
   });

   // Handle SSO login
   const loginButton = document.getElementById('sso-login');
   loginButton.onclick = async () => {
     try {
       const result = await signInWithPopup(auth, scalekitProvider);
       const user = result.user;

       console.log('Authenticated user:', user.email);
       // User is now signed in to Firebase
     } catch (error) {
       console.error('Authentication failed:', error);
     }
   };
   ```

## Option 2: Direct SSO with Custom Tokens

Use this approach if you have **Legacy Firebase Authentication** or need full control over the authentication flow. Your backend integrates directly with Scalekit and creates custom Firebase tokens.

## View authentication flow summary

```d2 layout=elk
direction: down

S1: "1. User clicks \"Sign In\""
S2: "2. Frontend calls backend → Backend generates Scalekit auth URL"
S3: "3. Frontend redirects to Scalekit auth URL"
S4: "4. Scalekit redirects to Identity Provider"
S5: "5. User authenticates with IdP"
S6: "6. IdP redirects back to Scalekit"
S7: "7. Scalekit redirects to your backend callback URL with code"
S8: "8. Backend exchanges code for user profile with Scalekit"
S9: "9. Backend creates custom Firebase token"
S10: "10. Backend returns custom token to frontend"
S11: "11. Frontend calls signInWithCustomToken(firebase, customToken)"
S12: "12. Firebase creates/updates user and returns Firebase user object"
S13: "13. User is authenticated and can access your app!"

S1 -> S2 -> S3 -> S4 -> S5 -> S6 -> S7 -> S8 -> S9 -> S10 -> S11 -> S12 -> S13
```

Your backend handles SSO authentication and creates custom tokens for Firebase.

1. #### Install Scalekit and Firebase Admin SDKs

   Install the Scalekit SDK and configure your backend server with Firebase Admin SDK:

   ```bash
   npm install @scalekit-sdk/node firebase-admin
   ```

   ```javascript title="backend/server.js"
   import { ScalekitClient } from '@scalekit-sdk/node';
   import admin from 'firebase-admin';

   // Initialize Scalekit
   const scalekit = new ScalekitClient(
     process.env.SCALEKIT_ENVIRONMENT_URL,
     process.env.SCALEKIT_CLIENT_ID,
     process.env.SCALEKIT_CLIENT_SECRET
   );

   // Initialize Firebase Admin
   ```

2. #### Handle SSO callback and create Firebase tokens

   Implement the SSO callback handler that exchanges the authorization code for user details and creates custom Firebase tokens:

   ```javascript title="SSO Callback Handler"
   app.get('/auth/callback', async (req, res) => {
     const { code, error, error_description } = req.query;

     if (error) {
       return res.status(400).json({
         error: 'Authentication failed',
         details: error_description
       });
     }

     try {
       // Exchange code for user profile
       const result = await scalekit.authenticateWithCode(
         code,
         'https://your-app.com/auth/callback'
       );

       const user = result.user;

       // Create custom Firebase token
       const customToken = await admin.auth().createCustomToken(user.id, {
         email: user.email,
         name: `${user.givenName} ${user.familyName}`,
         organizationId: user.organizationId,
       });

       res.json({
         customToken,
         user: {
           email: user.email,
           name: `${user.givenName} ${user.familyName}`,
         }
       });
     } catch (error) {
       console.error('SSO authentication failed:', error);
       res.status(500).json({ error: 'Internal server error' });
     }
   });
   ```

3. #### Generate authorization URL to initiate SSO

   Create an endpoint to generate Scalekit authorization URLs:

   
   ### Node.js

```javascript title="Authorization URL Endpoint"
app.post('/auth/start-sso', async (req, res) => {
  const { organizationId, domain, connectionId } = req.body;

  try {
    const options = {};
    if (organizationId) options.organizationId = organizationId;
    if (domain) options.domain = domain;
    if (connectionId) options.connectionId = connectionId;

    const authorizationUrl = scalekit.getAuthorizationUrl(
      'https://your-app.com/auth/callback',
      options
    );

    res.json({ authorizationUrl });
  } catch (error) {
    console.error('Failed to generate authorization URL:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});
```

   ### Python

```python title="Authorization URL Endpoint"
@app.route('/auth/start-sso', methods=['POST'])
def start_sso():
    data = request.get_json()
    organization_id = data.get('organizationId')
    domain = data.get('domain')
    connection_id = data.get('connectionId')

    try:
        options = {}
        if organization_id:
            options['organization_id'] = organization_id
        if domain:
            options['domain'] = domain
        if connection_id:
            options['connection_id'] = connection_id

        authorization_url = scalekit.get_authorization_url(
            'https://your-app.com/auth/callback',
            options
        )

        return jsonify({'authorizationUrl': authorization_url})
    except Exception as e:
        print(f'Failed to generate authorization URL: {e}')
        return jsonify({'error': 'Internal server error'}), 500
```

   ### Go

```go title="Authorization URL Endpoint"
func startSSOHandler(w http.ResponseWriter, r *http.Request) {
    var requestData struct {
        OrganizationID string `json:"organizationId"`
        Domain         string `json:"domain"`
        ConnectionID   string `json:"connectionId"`
    }

    if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
        http.Error(w, "Invalid request body", http.StatusBadRequest)
        return
    }

    options := scalekit.AuthorizationUrlOptions{}
    if requestData.OrganizationID != "" {
        options.OrganizationId = requestData.OrganizationID
    }
    if requestData.Domain != "" {
        options.Domain = requestData.Domain
    }
    if requestData.ConnectionID != "" {
        options.ConnectionId = requestData.ConnectionID
    }

    authorizationURL := scalekitClient.GetAuthorizationUrl(
        "https://your-app.com/auth/callback",
        options,
    )

    response := map[string]string{
        "authorizationUrl": authorizationURL,
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}
```

   ### Java

```java title="Authorization URL Endpoint"
@PostMapping("/auth/start-sso")
public ResponseEntity<?> startSSO(@RequestBody Map request) {
    String organizationId = request.get("organizationId");
    String domain = request.get("domain");
    String connectionId = request.get("connectionId");

    try {
        AuthorizationUrlOptions options = new AuthorizationUrlOptions();
        if (organizationId != null) options.setOrganizationId(organizationId);
        if (domain != null) options.setDomain(domain);
        if (connectionId != null) options.setConnectionId(connectionId);

        String authorizationUrl = scalekitClient.authentication()
            .getAuthorizationUrl("https://your-app.com/auth/callback", options)
            .toString();

        return ResponseEntity.ok(Map.of("authorizationUrl", authorizationUrl));
    } catch (Exception e) {
        System.err.println("Failed to generate authorization URL: " + e.getMessage());
        return ResponseEntity.status(500).body(Map.of("error", "Internal server error"));
    }
}
```

   

4. #### Build frontend SSO flow with custom tokens

   Create the frontend flow that initiates SSO and handles the custom token:

   ```javascript title="Frontend SSO Implementation"
   import { getAuth, signInWithCustomToken } from 'firebase/auth';

   const auth = getAuth();

   // Initiate SSO flow
   const initiateSSO = async () => {
     try {
       // Get authorization URL from your backend
       const response = await fetch('/auth/start-sso', {
         method: 'POST',
         headers: { 'Content-Type': 'application/json' },
         body: JSON.stringify({
           organizationId: 'org_123456789', // or domain, connectionId
         }),
       });

       const { authorizationUrl } = await response.json();

       // Redirect to SSO
       window.location.href = authorizationUrl;
     } catch (error) {
       console.error('Failed to initiate SSO:', error);
     }
   };

   // Handle SSO callback (call this on your callback page)
   const handleSSOCallback = async () => {
     const urlParams = new URLSearchParams(window.location.search);
     const code = urlParams.get('code');
     const error = urlParams.get('error');

     if (error) {
       console.error('SSO failed:', error);
       return;
     }

     try {
       // Exchange code for custom token
       const response = await fetch(`/auth/callback?code=${code}`);
       const { customToken, user } = await response.json();

       // Sign in to Firebase with custom token
       const userCredential = await signInWithCustomToken(auth, customToken);
       const firebaseUser = userCredential.user;

       console.log('Successfully authenticated:', firebaseUser);

       // Redirect to your app
       window.location.href = '/dashboard';
     } catch (error) {
       console.error('Authentication failed:', error);
     }
   };
   ```

## Handle identity provider-initiated SSO

Both approaches support IdP-initiated SSO, where users access your application directly from their identity provider portal. Create a dedicated endpoint to handle these requests.

For detailed implementation instructions, refer to the [IdP-Initiated SSO guide](/sso/guides/idp-init-sso/).

Both approaches provide secure, enterprise-grade SSO authentication while maintaining compatibility with Firebase's ecosystem and features.


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
