Skip to content

Latest commit

 

History

History
338 lines (270 loc) · 10.1 KB

File metadata and controls

338 lines (270 loc) · 10.1 KB
title OAuth Authentication
icon shield-halved
description Integrate your application with Omi using OAuth 2.0 to securely access user data with explicit consent.

Overview

Omi uses an OAuth 2.0-like flow to allow third-party applications to access user data with explicit consent. This ensures users maintain control over their data and what applications can access.

sequenceDiagram
    participant App as Your App
    participant User as User Browser
    participant Omi as Omi Auth Server
    participant Firebase as Firebase Auth

    App->>User: Redirect to /v1/oauth/authorize
    User->>Omi: Visit authorization page
    Omi->>Firebase: User logs in (Google/Apple)
    Firebase-->>Omi: Firebase ID token
    Omi->>Omi: Exchange token for uid
    Omi->>User: Redirect to App Home URL
    User->>App: ?uid=USER_ID&state=STATE
    App->>App: Store uid for API calls
Loading
Users explicitly approve what data your app can access Firebase authentication ensures secure identity verification

Prerequisites

Before implementing OAuth, ensure you have:

Your app must be registered with Omi and have an **App ID** Set your **App Home URL** in your app's settings - this is where users are redirected after authorization Your App Home URL must use HTTPS

OAuth Flow

Your app redirects the user to Omi's authorization endpoint:
```
https://api.omi.me/v1/oauth/authorize?app_id=YOUR_APP_ID&state=YOUR_STATE
```

| Parameter | Required | Description |
|-----------|----------|-------------|
| `app_id` | Yes | Your application's unique ID |
| `state` | No | Opaque value for CSRF protection and maintaining state |

<Tip>
Always use the `state` parameter to prevent CSRF attacks. Generate a random string and verify it when the user returns.
</Tip>
On the Omi authorization page, the user:
1. Logs in with their Firebase credentials (Google or Apple)
2. Reviews the permissions your app is requesting
3. Grants or denies access

**Example permissions shown to users:**
- "Engage in chat conversations with Omi"
- "Access and manage your conversations"
- "Process audio data in real-time"
- "Create new conversations on your behalf"
- "Access and read your stored memories"
After user approval, Omi's authorization page handles the token exchange internally:
```http
POST https://api.omi.me/v1/oauth/token
Content-Type: application/x-www-form-urlencoded

firebase_id_token=FIREBASE_TOKEN&app_id=YOUR_APP_ID&state=YOUR_STATE
```

**Response:**
```json
{
  "uid": "USER_UNIQUE_ID",
  "redirect_url": "YOUR_APP_HOME_URL",
  "state": "YOUR_STATE_IF_PROVIDED"
}
```

<Note>
This step is handled automatically by Omi's authorization page - you don't need to implement this yourself.
</Note>
The user's browser is redirected to your App Home URL with query parameters:
```
https://your-app.com/callback?uid=USER_UNIQUE_ID&state=YOUR_STATE
```

Your app should:
1. Validate the `state` parameter matches what you sent
2. Store the `uid` for making API calls on behalf of the user

Handling the Callback

Example implementation for handling the OAuth callback:

```python from fastapi import FastAPI, Request, HTTPException from fastapi.responses import RedirectResponse import secrets
app = FastAPI()

# Store state tokens (use Redis in production)
pending_states = {}

@app.get("/start-oauth")
async def start_oauth():
    # Generate CSRF token
    state = secrets.token_urlsafe(32)
    pending_states[state] = True

    # Redirect to Omi
    return RedirectResponse(
        f"https://api.omi.me/v1/oauth/authorize"
        f"?app_id=YOUR_APP_ID&state={state}"
    )

@app.get("/callback")
async def oauth_callback(uid: str, state: str):
    # Validate state
    if state not in pending_states:
        raise HTTPException(400, "Invalid state parameter")

    del pending_states[state]

    # Store uid for this user's session
    # Now you can make API calls with this uid
    return {"message": f"Successfully connected! User ID: {uid}"}
```
```javascript const express = require('express'); const crypto = require('crypto');
const app = express();
const pendingStates = new Map();

app.get('/start-oauth', (req, res) => {
  // Generate CSRF token
  const state = crypto.randomBytes(32).toString('hex');
  pendingStates.set(state, true);

  // Redirect to Omi
  res.redirect(
    `https://api.omi.me/v1/oauth/authorize` +
    `?app_id=YOUR_APP_ID&state=${state}`
  );
});

app.get('/callback', (req, res) => {
  const { uid, state } = req.query;

  // Validate state
  if (!pendingStates.has(state)) {
    return res.status(400).send('Invalid state parameter');
  }

  pendingStates.delete(state);

  // Store uid for this user's session
  res.send(`Successfully connected! User ID: ${uid}`);
});
```

Automatic App Enablement

When a user completes the OAuth flow, Omi automatically attempts to enable your app for them.

Omi performs several checks before enabling:
| Check | Description |
|-------|-------------|
| **Privacy** | If app is private, only owner/testers can enable |
| **Setup Completion** | If `setup_completed_url` is configured, it must return `true` |
| **Payment** | If app is paid, user must have active subscription |

If any check fails, the OAuth flow halts and shows an error to the user.
If your app requires setup (e.g., connecting to external services), configure a `setup_completed_url`:
**Request from Omi:**
```
GET https://your-app.com/setup-status?uid=USER_ID
```

**Expected Response:**
```json
{
  "is_setup_completed": true
}
```

Return `false` if the user hasn't completed setup yet. Omi will show an appropriate message.
When a user successfully enables your public app through OAuth, the public install count is incremented (if applicable).

App Configuration

Unique identifier for your app, provided when you register Where users are redirected after authorization (must be HTTPS)

Configure these settings in the Omi developer portal or during app submission:

Field Location Description
App ID Auto-generated Your unique application identifier
App Home URL external_integration.app_home_url Callback URL after OAuth (HTTPS required)
Setup Completed URL external_integration.setup_completed_url Optional endpoint to verify user setup

Security Best Practices

Generate a cryptographically random `state` parameter and validate it on callback to prevent CSRF attacks Ensure the `uid` came from a legitimate OAuth flow, not a forged request Store user `uid` values securely, treating them as sensitive credentials Always use HTTPS for your App Home URL and all API communications Never expose your App ID in client-side code where it could be extracted. While the App ID itself isn't secret, it should be treated as sensitive for your integration's integrity.

Troubleshooting

**Possible causes:** - App Home URL not configured or incorrect - App Home URL doesn't use HTTPS - User denied permissions
**Solution:** Verify your App Home URL in the developer portal
**Possible causes:** - State expired before user completed flow - State not properly stored server-side - CSRF attack attempt
**Solution:** Implement proper session/state management with reasonable expiration
**Possible causes:** - `setup_completed_url` returning `false` or error - Endpoint not accessible from Omi servers - JSON response malformed
**Solution:** Test your endpoint directly and check server logs

Related Documentation

Build webhook-based integrations Add custom tools to Omi chat Send push notifications to users Publish your app to the store